very basic while loop
This commit is contained in:
parent
61d5661b96
commit
10d436107c
@ -1,15 +1,4 @@
|
|||||||
a := 0
|
x := 1
|
||||||
{
|
|
||||||
a := 1
|
|
||||||
b := a
|
|
||||||
}
|
|
||||||
|
|
||||||
//a := 1
|
|
||||||
//b := 1 - 2 * 2 + 5
|
|
||||||
//c := a + b * 2 * b
|
|
||||||
//d := a + 4 * b * a
|
|
||||||
|
|
||||||
/*x := 1
|
|
||||||
y := 1
|
y := 1
|
||||||
|
|
||||||
i := 60
|
i := 60
|
||||||
@ -17,6 +6,6 @@ while i {
|
|||||||
z := x + y
|
z := x + y
|
||||||
y = x
|
y = x
|
||||||
x = z
|
x = z
|
||||||
print(z)
|
//print(z)
|
||||||
i = i - 1
|
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) {
|
void print_ir(IRToks *v) {
|
||||||
for (size_t i = 0; i < v->len; i++) {
|
for (size_t i = 0; i < v->len; i++) {
|
||||||
|
printf("%04zx ", i);
|
||||||
printf("%s", irinstr_str[v->toks[i].instr]);
|
printf("%s", irinstr_str[v->toks[i].instr]);
|
||||||
switch (v->toks[i].instr) {
|
switch (v->toks[i].instr) {
|
||||||
case IRSet:
|
case IRSet:
|
||||||
@ -92,13 +93,12 @@ void print_ir(IRToks *v) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IRJmp:
|
case IRJmp:
|
||||||
printf(" ");
|
printf(" %zx", v->toks[i].Jmp.iaddr);
|
||||||
printf(" %zu", v->toks[i].Jmp.iaddr);
|
|
||||||
break;
|
break;
|
||||||
case IRJnz:
|
case IRJnz:
|
||||||
printf(" ");
|
printf(" ");
|
||||||
print_irparam(&v->toks[i].CJmp.condition);
|
print_irparam(&v->toks[i].CJmp.condition);
|
||||||
printf(" %zu", v->toks[i].CJmp.iaddr);
|
printf(" %zx", v->toks[i].CJmp.iaddr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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)
|
if (t->next->tok.Op == OpRCurl)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
TRY(stmt(s, &inner_sc, t->next));
|
TRY_ELSE(stmt(s, &inner_sc, t->next), term_scope(&inner_sc));
|
||||||
}
|
}
|
||||||
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);
|
toklist_del(s->toks, start, t);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user