From 006015c6073235010895f4d181c188711246d8a6 Mon Sep 17 00:00:00 2001 From: Lorenzo Torres Date: Wed, 3 Dec 2025 22:41:55 +0100 Subject: [PATCH] finished while loops --- examples/for.l | 5 +++-- examples/hello_world.l | 2 +- lc.c | 2 +- lexer.c | 3 ++- lexer.h | 3 ++- parser.c | 31 ++++++++++++++++++++++++++++--- parser.h | 5 +++++ 7 files changed, 42 insertions(+), 9 deletions(-) diff --git a/examples/for.l b/examples/for.l index dbe34d1..24181ba 100644 --- a/examples/for.l +++ b/examples/for.l @@ -3,9 +3,10 @@ import std; i32 main() { u32 x = 4; - loop x == 3 { + loop { u32 b = 3; - } + } + x == 3; loop (0.., test) |k, i| { diff --git a/examples/hello_world.l b/examples/hello_world.l index a323665..97b09a3 100644 --- a/examples/hello_world.l +++ b/examples/hello_world.l @@ -1,6 +1,6 @@ import std; -i32 main() +i32 main(usize argc, [*u8] argv) { print("Hello world!\n"); diff --git a/lc.c b/lc.c index ac6f4fe..1a0ec3c 100644 --- a/lc.c +++ b/lc.c @@ -220,7 +220,7 @@ void print_ast(ast_node *node, int depth) { int main(void) { - FILE *fp = fopen("examples/for.l", "r"); + FILE *fp = fopen("examples/hello_world.l", "r"); usize size = 0; fseek(fp, 0, SEEK_END); size = ftell(fp); diff --git a/lexer.c b/lexer.c index 6167bfa..26c1eb1 100644 --- a/lexer.c +++ b/lexer.c @@ -400,12 +400,13 @@ lexer *lexer_init(char *source, usize size, arena *arena) trie_insert(keywords, lex->allocator, "enum", TOKEN_ENUM); trie_insert(keywords, lex->allocator, "union", TOKEN_UNION); trie_insert(keywords, lex->allocator, "loop", TOKEN_LOOP); + trie_insert(keywords, lex->allocator, "while", TOKEN_WHILE); + trie_insert(keywords, lex->allocator, "until", TOKEN_UNTIL); trie_insert(keywords, lex->allocator, "goto", TOKEN_GOTO); trie_insert(keywords, lex->allocator, "if", TOKEN_IF); trie_insert(keywords, lex->allocator, "else", TOKEN_ELSE); trie_insert(keywords, lex->allocator, "switch", TOKEN_SWITCH); trie_insert(keywords, lex->allocator, "break", TOKEN_BREAK); - trie_insert(keywords, lex->allocator, "do", TOKEN_DO); trie_insert(keywords, lex->allocator, "defer", TOKEN_DEFER); trie_insert(keywords, lex->allocator, "return", TOKEN_RETURN); trie_insert(keywords, lex->allocator, "import", TOKEN_IMPORT); diff --git a/lexer.h b/lexer.h index e41fa4a..2aa86ec 100644 --- a/lexer.h +++ b/lexer.h @@ -57,11 +57,12 @@ typedef enum { TOKEN_CHAR, TOKEN_GOTO, TOKEN_LOOP, + TOKEN_WHILE, + TOKEN_UNTIL, TOKEN_IF, TOKEN_ELSE, TOKEN_SWITCH, TOKEN_BREAK, - TOKEN_DO, TOKEN_DEFER, TOKEN_RETURN, TOKEN_IMPORT, diff --git a/parser.c b/parser.c index e867d39..af21aa6 100644 --- a/parser.c +++ b/parser.c @@ -76,9 +76,9 @@ static void parser_sync(parser *p) { case TOKEN_STRUCT: case TOKEN_ENUM: + case TOKEN_UNION: case TOKEN_IF: case TOKEN_LOOP: - case TOKEN_DO: case TOKEN_RETURN: case TOKEN_SWITCH: return; @@ -764,7 +764,6 @@ parse_captures: } parse_body:; - printf("%d %d\n", node->expr.fr.capture_len, node->expr.fr.slice_len); if (node->expr.fr.capture_len != node->expr.fr.slice_len) { error(p, "invalid number of captures."); return NULL; @@ -777,13 +776,39 @@ parse_body:; static ast_node *parse_while(parser *p) { + u8 flags = 0x0; + + if (match(p, TOKEN_WHILE)) { + flags |= LOOP_WHILE; + } else if (match(p, TOKEN_UNTIL)) { + flags |= LOOP_UNTIL; + } else if (!match_peek(p, TOKEN_LCURLY)) { + error(p, "expected `while`, `until` or `{`."); + return NULL; + } ast_node *condition = parse_expression(p); - //printf("%d %d\n", p->tokens->type, TOKEN_RCURLY); + if (!condition) { + flags |= LOOP_AFTER; + } ast_node *body = parse_compound(p); ast_node *node = arena_alloc(p->allocator, sizeof(ast_node)); node->type = NODE_WHILE; node->expr.whle.body = body; + + if (flags & LOOP_AFTER) { + if (match(p, TOKEN_WHILE)) { + flags |= LOOP_WHILE; + condition = parse_expression(p); + } else if (match(p, TOKEN_UNTIL)) { + flags |= LOOP_UNTIL; + condition = parse_expression(p); + } else { + node->expr.whle.condition = NULL; + } + } + node->expr.whle.condition = condition; + return node; } diff --git a/parser.h b/parser.h index fc6a688..17610a6 100644 --- a/parser.h +++ b/parser.h @@ -110,6 +110,10 @@ typedef enum { #define PTR_RAW 0x1 #define PTR_ARRAY 0x2 +#define LOOP_WHILE 0x1 +#define LOOP_UNTIL 0x2 +#define LOOP_AFTER 0x4 + typedef struct _ast_node { node_type type; union { @@ -183,6 +187,7 @@ typedef struct _ast_node { struct { struct _ast_node *condition; struct _ast_node *body; + u8 flags; } whle; // while struct { struct _ast_node **statements;