diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2022-11-24 11:08:33 +0100 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2022-11-27 21:48:21 +0100 |
commit | 9126afa2da0e1635d78429075cc44ca576f68169 (patch) | |
tree | 0836f3da0fdfee9af24ca5dabb8244af61e5283e /parse.c | |
parent | b5da3f3d64c857baf808220e202dc37c5c039eb8 (diff) | |
download | roux-9126afa2da0e1635d78429075cc44ca576f68169.tar.gz |
new hlt block terminator
It is handy to express when the end of a block cannot be reached. If a hlt terminator is executed, it traps the program. We don't go the llvm way and specify execution semantics as undefined behavior.
Diffstat (limited to 'parse.c')
-rw-r--r-- | parse.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/parse.c b/parse.c index 04ef8be..849c81d 100644 --- a/parse.c +++ b/parse.c @@ -44,6 +44,7 @@ enum { Tjmp, Tjnz, Tret, + Thlt, Texport, Tthread, Tfunc, @@ -99,6 +100,7 @@ static char *kwmap[Ntok] = { [Tjmp] = "jmp", [Tjnz] = "jnz", [Tret] = "ret", + [Thlt] = "hlt", [Texport] = "export", [Tthread] = "thread", [Tfunc] = "function", @@ -641,7 +643,10 @@ parseline(PState ps) curb->s2 = findblk(tokval.str); } if (curb->s1 == curf->start || curb->s2 == curf->start) - err("invalid jump to the start node"); + err("invalid jump to the start block"); + goto Close; + case Thlt: + curb->jmp.type = Jhlt; Close: expect(Tnl); closeblk(); @@ -1322,6 +1327,9 @@ printfn(Fn *fn, FILE *f) fprintf(f, ", :%s", typ[fn->retty].name); fprintf(f, "\n"); break; + case Jhlt: + fprintf(f, "\thlt\n"); + break; case Jjmp: if (b->s1 != b->link) fprintf(f, "\tjmp @%s\n", b->s1->name); @@ -1332,6 +1340,7 @@ printfn(Fn *fn, FILE *f) printref(b->jmp.arg, fn, f); fprintf(f, ", "); } + assert(b->s1 && b->s2); fprintf(f, "@%s, @%s\n", b->s1->name, b->s2->name); break; } |