Add while. Save the position before the condition. Loop: re-parse the condition from the saved position each time, execute or skip the body.
testCase(
\\var s: i64 = 0; var i: i64 = 1;
\\while (i < 6) {
\\ s = s + i;
\\ i = i + 1;
\\}
\\s
, 15, &varNames, &varValues, &varCount);
Add to executeStatement's keyword chain, next to if:
if (stringsEqual(firstWord, "while")) {
const loopPos = pos.*;
var last: i64 = 0;
while (true) {
pos.* = loopPos;
if (source[pos.*] == '(') {
pos.* += 1;
skipSpaces(source, pos);
}
const cond = parseExpression(source, pos, names, values, count);
if (source[pos.*] == ')') {
pos.* += 1;
skipSpaces(source, pos);
}
if (cond == 0) {
skipBlock(source, pos);
break;
}
last = executeBlock(source, pos, names, values, count);
}
return last;
}
Notice something weird: we're re-parsing the condition string from scratch every iteration. We jump pos.* back to loopPos, re-read the characters, re-evaluate the expression. It works, but it means we're paying the parsing cost every loop iteration. This is one reason we'll eventually want a tree -- you parse once, walk the tree as many times as you like.