Add if/else. When we see the word if, parse the condition in (), then execute or skip the { } block.
Two helpers:
- skip_block() -- jump past { ... } without executing, counting brace depth
- exec_block() -- execute statements inside { ... }
check("if (5 > 3) { 10 } else { 20 }", 10);
check("if (2 > 7) { 10 } else { 20 }", 20);
check("var x: i64 = 10; if (x > 5) { x = 99; } x", 99);
fn skip_block() void {
if (cur() == '{') { pos += 1; skip(); }
var depth: i32 = 1;
while (depth > 0 and cur() != 0) {
if (cur() == '{') { depth += 1; }
if (cur() == '}') { depth -= 1; }
if (depth > 0) { pos += 1; }
}
if (cur() == '}') { pos += 1; skip(); }
}
fn exec_block() i64 {
if (cur() == '{') { pos += 1; skip(); }
var last: i64 = 0;
while (cur() != '}' and cur() != 0) {
last = exec_stmt();
if (return_flag) { break; }
}
if (cur() == '}') { pos += 1; skip(); }
return if (return_flag) return_val else last;
}
Add to exec_stmt, right after the var handler:
if (streq(word, "if")) {
if (cur() == '(') { pos += 1; skip(); }
const cond: i64 = expression();
if (cur() == ')') { pos += 1; skip(); }
if (cond != 0) {
const val: i64 = exec_block();
if (is_letter(cur())) {
const s2: usize = pos;
const w2: []const u8 = read_name();
if (streq(w2, "else")) { skip_block(); } else { pos = s2; }
}
return val;
} else {
skip_block();
if (is_letter(cur())) {
const s2: usize = pos;
const w2: []const u8 = read_name();
if (streq(w2, "else")) { return exec_block(); }
pos = s2;
}
return 0;
}
}