commit 10191547db64537e9393892c77dbc3fb09f2f5cb
parent 67645c1dff4b1482e6730c6e00001072e5c695af
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Sat, 4 Dec 2021 22:28:15 -0600
add loops
Diffstat:
3 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/main.c b/main.c
@@ -39,6 +39,9 @@ lex(struct slice start)
} else if (slice_cmplit(&start, "else") == 0) {
cur->type = TOK_ELSE;
ADVANCE(4);
+ } else if (slice_cmplit(&start, "loop") == 0) {
+ cur->type = TOK_LOOP;
+ ADVANCE(4);
} else if (isblank(*start.ptr)) {
ADVANCE(1);
continue;
@@ -248,6 +251,11 @@ parseexpr(struct token **tok)
{
struct expr expr = { 0 };
switch ((*tok)->type) {
+ case TOK_LOOP:
+ *tok = (*tok)->next;
+ expr.kind = EXPR_LOOP;
+ expr.d.loop.block = parse(tok);
+ break;
case TOK_IF:
*tok = (*tok)->next;
expr.kind = EXPR_COND;
@@ -345,7 +353,7 @@ parse(struct token **tok)
while ((*tok)->type != TOK_NONE && (*tok)->type != TOK_RCURLY) {
item = (struct item){ 0 };
- if ((*tok)->type != TOK_IF) {
+ if ((*tok)->type != TOK_IF && (*tok)->type != TOK_LOOP) {
expect((*tok), TOK_NAME);
name = (*tok);
}
@@ -526,6 +534,10 @@ genblock(char *buf, struct block *block)
total += genblock(buf ? buf + total : NULL, &expr.d.cond.bif);
total += jmp(buf ? buf + total: NULL, elselen);
total += genblock(buf ? buf + total : NULL, &expr.d.cond.belse);
+ } else if (expr.kind == EXPR_LOOP) {
+ size_t back = genblock(NULL, &expr.d.loop.block) + jmp(NULL, 0);
+ total += genblock(buf ? buf + total : NULL, &expr.d.loop.block);
+ total += jmp(buf ? buf + total: NULL, -back);
} else {
error("unhandled toplevel expression type!");
}
diff --git a/nooc.h b/nooc.h
@@ -21,7 +21,8 @@ enum tokentype {
TOK_STRING,
TOK_IF,
- TOK_ELSE
+ TOK_ELSE,
+ TOK_LOOP
};
struct slice {
@@ -91,6 +92,10 @@ struct cond {
struct block belse;
};
+struct loop {
+ struct block block;
+};
+
enum binop {
OP_PLUS,
@@ -110,7 +115,8 @@ enum exprkind {
EXPR_IDENT,
EXPR_BINARY,
EXPR_FCALL,
- EXPR_COND
+ EXPR_COND,
+ EXPR_LOOP
};
enum class {
@@ -127,6 +133,7 @@ struct expr {
struct slice s;
struct fcall call;
struct cond cond;
+ struct loop loop;
} d;
size_t left;
size_t right;
diff --git a/prog.nc b/prog.nc
@@ -1,8 +1,6 @@
exit i64 = 60
write i64 = 1
-if > 0 1 {
+loop {
syscall(write, 0, "hello", 5)
-} else {
- syscall(write, 0, "world", 5)
}
syscall(exit, 0)