very basic while loop
This commit is contained in:
parent
61d5661b96
commit
10d436107c
@ -1,15 +1,4 @@
|
||||
a := 0
|
||||
{
|
||||
a := 1
|
||||
b := a
|
||||
}
|
||||
|
||||
//a := 1
|
||||
//b := 1 - 2 * 2 + 5
|
||||
//c := a + b * 2 * b
|
||||
//d := a + 4 * b * a
|
||||
|
||||
/*x := 1
|
||||
x := 1
|
||||
y := 1
|
||||
|
||||
i := 60
|
||||
@ -17,6 +6,6 @@ while i {
|
||||
z := x + y
|
||||
y = x
|
||||
x = z
|
||||
print(z)
|
||||
//print(z)
|
||||
i = i - 1
|
||||
}*/
|
||||
}
|
||||
|
6
ir.c
6
ir.c
@ -69,6 +69,7 @@ static void print_irparam(const IRParam *p) {
|
||||
|
||||
void print_ir(IRToks *v) {
|
||||
for (size_t i = 0; i < v->len; i++) {
|
||||
printf("%04zx ", i);
|
||||
printf("%s", irinstr_str[v->toks[i].instr]);
|
||||
switch (v->toks[i].instr) {
|
||||
case IRSet:
|
||||
@ -92,13 +93,12 @@ void print_ir(IRToks *v) {
|
||||
}
|
||||
break;
|
||||
case IRJmp:
|
||||
printf(" ");
|
||||
printf(" %zu", v->toks[i].Jmp.iaddr);
|
||||
printf(" %zx", v->toks[i].Jmp.iaddr);
|
||||
break;
|
||||
case IRJnz:
|
||||
printf(" ");
|
||||
print_irparam(&v->toks[i].CJmp.condition);
|
||||
printf(" %zu", v->toks[i].CJmp.iaddr);
|
||||
printf(" %zx", v->toks[i].CJmp.iaddr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
59
parse.c
59
parse.c
@ -356,9 +356,66 @@ static void stmt(State *s, Scope *sc, TokListItem *t) {
|
||||
if (t->next->tok.Op == OpRCurl)
|
||||
break;
|
||||
}
|
||||
TRY(stmt(s, &inner_sc, t->next));
|
||||
TRY_ELSE(stmt(s, &inner_sc, t->next), term_scope(&inner_sc));
|
||||
}
|
||||
term_scope(&inner_sc);
|
||||
t = t->next;
|
||||
} else if (t->tok.kind == TokWhile) {
|
||||
/* How while is generally implemented in IR:
|
||||
* 0: jmp to 3
|
||||
* 1: some_code
|
||||
* 2: some_code
|
||||
* 3: some stuff evaluating condition xyz
|
||||
* 4: jmp to 1 if condition xyz is met
|
||||
* */
|
||||
|
||||
size_t jmp_instr_iaddr = s->ir->len;
|
||||
irtoks_app(s->ir, (IRTok){
|
||||
.ln = t->tok.ln,
|
||||
.col = t->tok.col,
|
||||
.instr = IRJmp,
|
||||
.Jmp = {
|
||||
.iaddr = 0, /* unknown for now */
|
||||
},
|
||||
});
|
||||
|
||||
t = t->next;
|
||||
|
||||
/* find beginning of while loop body */
|
||||
TokListItem *lcurl;
|
||||
for (TokListItem *i = t;; i++) {
|
||||
if (i == NULL) {
|
||||
mark_err(&start->tok);
|
||||
set_err("Expected '{' after 'while' loop condition");
|
||||
return;
|
||||
}
|
||||
if (i->tok.kind == TokOp && i->tok.Op == OpLCurl) {
|
||||
lcurl = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* write loop body to IR stream */
|
||||
TRY(stmt(s, sc, lcurl));
|
||||
|
||||
/* finally we know where the jmp from the beginning has to jump to */
|
||||
s->ir->toks[jmp_instr_iaddr].Jmp.iaddr = s->ir->len;
|
||||
|
||||
size_t addr = sc->mem_addr++;
|
||||
TRY(expr(s, sc, t, true, true, addr));
|
||||
|
||||
irtoks_app(s->ir, (IRTok){
|
||||
.ln = t->tok.ln,
|
||||
.col = t->tok.col,
|
||||
.instr = IRJnz,
|
||||
.CJmp = {
|
||||
.iaddr = jmp_instr_iaddr + 1,
|
||||
.condition = {
|
||||
.kind = IRParamAddr,
|
||||
.Addr = addr,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
toklist_del(s->toks, start, t);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user