Skip to content

Commit 07ffffa

Browse files
committed
generalize condition control flow blocks
also adds support for while loops
1 parent 4342d18 commit 07ffffa

File tree

2 files changed

+77
-45
lines changed

2 files changed

+77
-45
lines changed

src/compiler.rs

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,56 @@ impl Compiler {
293293
}
294294
}
295295

296+
fn compile_conditional_control(
297+
&mut self,
298+
opcode: &str,
299+
cond: &Expr,
300+
substacks: (Option<&Vec<Stmt>>, Option<&Vec<Stmt>>),
301+
current_id: String,
302+
parent_id: String,
303+
index: usize,
304+
body_len: usize,
305+
) {
306+
let condition_id = self.gen_block_id();
307+
308+
self.compile_condition(cond, current_id.clone(), condition_id.clone());
309+
310+
let mut inputs = HashMap::new();
311+
inputs.insert("CONDITION".to_string(), json!([2, condition_id]));
312+
313+
// TODO: remove this code-duplication
314+
if let Some(substack) = substacks.0 {
315+
let substack_id = self.peek_next_block_id();
316+
self.compile_body_statements(substack, current_id.clone());
317+
inputs.insert("SUBSTACK".to_string(), json!([2, substack_id]));
318+
}
319+
320+
if let Some(substack) = substacks.1 {
321+
let substack_id = self.peek_next_block_id();
322+
self.compile_body_statements(substack, current_id.clone());
323+
inputs.insert("SUBSTACK2".to_string(), json!([2, substack_id]));
324+
}
325+
326+
let next_id = if (index + 1) >= body_len {
327+
None
328+
} else {
329+
Some(self.peek_next_block_id())
330+
};
331+
332+
self.push_block(
333+
&Block {
334+
opcode: opcode.to_string(),
335+
next: next_id,
336+
parent: Some(parent_id.clone()),
337+
inputs: Some(inputs),
338+
shadow: Some(false),
339+
top_level: Some(false),
340+
..Default::default()
341+
},
342+
current_id,
343+
);
344+
}
345+
296346
fn value_from_expr(&mut self, expr: &Expr, parent_id: String) -> Value {
297347
match expr {
298348
Expr::String(value) => json!([1, [10, value.to_string()]]),
@@ -610,56 +660,40 @@ impl Compiler {
610660
current_id,
611661
);
612662
}
663+
Stmt::While(cond, body_true) => {
664+
self.compile_conditional_control(
665+
"control_while",
666+
cond,
667+
(Some(body_true), None),
668+
current_id,
669+
parent_id.clone(),
670+
index,
671+
body.len(),
672+
);
673+
}
613674
Stmt::If(cond, body_true, body_false) => {
614-
let condition_id = self.gen_block_id();
615-
616-
let next_id = if (index + 1) >= body.len() {
617-
None
618-
} else {
619-
Some(self.peek_next_block_id())
620-
};
621-
622-
self.compile_condition(cond, current_id.clone(), condition_id.clone());
623-
624-
let substack_id = self.peek_next_block_id();
625-
self.compile_body_statements(body_true, current_id.clone());
626-
627-
let mut inputs = HashMap::new();
628-
inputs.insert("CONDITION".to_string(), json!([2, condition_id]));
629-
inputs.insert("SUBSTACK".to_string(), json!([2, substack_id]));
630-
631675
// if-else
632676
if let Some(body_false) = body_false {
633-
let substack2_id = self.peek_next_block_id();
634-
self.compile_body_statements(body_false, current_id.clone());
635-
inputs.insert("SUBSTACK2".to_string(), json!([2, substack2_id]));
636-
637-
self.push_block(
638-
&Block {
639-
opcode: "control_if_else".to_string(),
640-
next: next_id,
641-
parent: Some(parent_id.clone()),
642-
inputs: Some(inputs),
643-
shadow: Some(false),
644-
top_level: Some(false),
645-
..Default::default()
646-
},
677+
self.compile_conditional_control(
678+
"control_if_else",
679+
cond,
680+
(Some(body_true), Some(body_false)),
647681
current_id,
682+
parent_id.clone(),
683+
index,
684+
body.len(),
648685
);
649686
}
650687
// if
651688
else {
652-
self.push_block(
653-
&Block {
654-
opcode: "control_if".to_string(),
655-
next: next_id,
656-
parent: Some(parent_id.clone()),
657-
inputs: Some(inputs),
658-
shadow: Some(false),
659-
top_level: Some(false),
660-
..Default::default()
661-
},
689+
self.compile_conditional_control(
690+
"control_if",
691+
cond,
692+
(Some(body_true), None),
662693
current_id,
694+
parent_id.clone(),
695+
index,
696+
body.len(),
663697
);
664698
}
665699
}

test_project/sprite1.scuff

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
event flag_clicked {
2-
if (1 != 2) {
3-
say("hello, world");
2+
while (1 == 1) {
3+
let x: string = (x & "a");
44
}
55
}
6-
7-

0 commit comments

Comments
 (0)