From faf69726d4fc619bc55a2c1105bd542673cce342 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Tue, 18 Jun 2024 22:19:24 +0200 Subject: Add basic while loop --- Makefile | 7 +++++-- src/main.c | 21 ++++++++++++++++++++- tests/loops.bad | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 tests/loops.bad diff --git a/Makefile b/Makefile index 5af466c..732766e 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ BUILD_DIR := build TESTS_DIR := tests TEST_FILES := $(wildcard $(TESTS_DIR)/*.bad) SRC_MAIN := $(SRC_DIR)/main.c -SRC_RUN := tests/conditionals.bad +SRC_RUN := tests/loops.bad WATCH_SRC := $(shell find $(SRC_DIR) -name "*.c" -or -name "*.s" -or -name "*.h") INC_DIRS := $(shell find $(SRC_DIR) -type d) INC_FLAGS := $(addprefix -I,$(INC_DIRS)) @@ -74,8 +74,11 @@ graph-symbols: $(BIN) tests: $(BIN) @for name in $(TEST_FILES); do\ + line=" OK";\ printf "$${name}\r" ;\ - $(BIN) $${name} && printf "$${name}\tOK!\n";\ + $(BIN) $${name} \ + && printf "$$line\r" \ + && printf "$${name}\n";\ done # Remove build directory. diff --git a/src/main.c b/src/main.c index 1c0d2e1..666a664 100644 --- a/src/main.c +++ b/src/main.c @@ -82,6 +82,7 @@ typedef enum NodeKind { NODE_ENUM, NODE_BREAK, NODE_CONTINUE, + NODE_WHILE, // Helpers. NODE_SYMBOL_IDX, NODE_TYPE, @@ -135,6 +136,7 @@ Str node_str[] = { [NODE_ENUM] = cstr("ENUM"), [NODE_BREAK] = cstr("BREAK"), [NODE_CONTINUE] = cstr("CONTINUE"), + [NODE_WHILE] = cstr("WHILE"), // Helpers. [NODE_TYPE] = cstr("TYPE"), [NODE_ARR_TYPE] = cstr("TYPE (ARR)"), @@ -171,6 +173,10 @@ typedef struct Node { struct Node *var_type; struct Node *var_val; }; + struct { + struct Node *while_cond; + struct Node *while_expr; + }; struct { struct Node *cond_if; struct Node *cond_expr; @@ -209,6 +215,7 @@ typedef struct Parser { // Error handling. bool err; bool panic; + Str file_name; // Storage. Node **nodes; @@ -328,7 +335,8 @@ parse_emit_err(Parser *parser, Token token, Str msg) { if (parser->panic) return; parser->panic = true; parser->err = true; - eprint("%d:%d: error: %s", token.line, token.col, msg); + eprint("%s:%d:%d: error: %s", parser->file_name, token.line, token.col, + msg); if (token.kind == TOK_EOF) { eprintln(" at end of the file"); @@ -675,6 +683,16 @@ parse_keyword(Parser *parser) { node = node_alloc(parser, NODE_CONTINUE, prev); if (!node) return; } break; + case TOK_WHILE: { + node = node_alloc(parser, NODE_WHILE, prev); + if (!node) return; + parse_expr(parser, PREC_LOW); + node->while_cond = array_pop(parser->nodes); + parse_consume(parser, TOK_ASSIGN, + cstr("malformed while expression")); + parse_expr(parser, PREC_LOW); + node->while_expr = array_pop(parser->nodes); + } break; default: return; // Unreachable. } array_push(parser->nodes, node, parser->storage); @@ -1009,6 +1027,7 @@ process_file(Str path) { Parser parser = { .tokens = tokens, .storage = &lexer_arena, + .file_name = path, }; array_init(parser.nodes, 256, parser.storage); parse_advance(&parser); diff --git a/tests/loops.bad b/tests/loops.bad new file mode 100644 index 0000000..5221844 --- /dev/null +++ b/tests/loops.bad @@ -0,0 +1,18 @@ +; The most basic loop is the while loop. +while abc = "heelo" + +while 1 + 2 == 3 = { + "hello" +} + +while symbol = { + "hello" +} + + +; We could use some sugar for this. +let i = 0 +while i < 10 = { + "hello" + set i = i + 1 +} -- cgit v1.2.1