diff options
| author | hachem <im@hachem.wtf> | 2026-08-30 12:14:04 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-08-30 12:14:04 +0200 |
| commit | 53946c982cb3290a25f7c8529ef1399f0635ef37 (patch) | |
| tree | 969bc78c304e13d733b794ffc98d44bf44b53621 /src | |
| parent | 6532b074e5c1db4a1c32298cc338a1a533208641 (diff) | |
add: parse labels and syscalls
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 27 | ||||
| -rw-r--r-- | src/parser/ast.h | 15 | ||||
| -rw-r--r-- | src/parser/parser.c | 27 |
3 files changed, 60 insertions, 9 deletions
@@ -62,14 +62,27 @@ int main(int argc, char** argv) for (size_t s = 0; s < proc.body_count; s += 1) { struct Statement statement = proc.body[s]; - if (statement.kind == STATEMENT_ASSIGN) + switch (statement.kind) { - struct AssignStatement assign = statement.assign; - printf(" %s%.*s %.*s %.*s\n", - assign.target_deref ? "^" : "", - (int)assign.target.length, assign.target.start, - (int)assign.op.length, assign.op.start, - (int)assign.value.length, assign.value.start); + case STATEMENT_ASSIGN: + { + struct AssignStatement assign = statement.assign; + printf(" %s%.*s %.*s %.*s\n", + assign.target_deref ? "^" : "", + (int)assign.target.length, assign.target.start, + (int)assign.op.length, assign.op.start, + (int)assign.value.length, assign.value.start); + break; + } + case STATEMENT_LABEL: + printf(" %.*s:\n", (int)statement.label.name.length, statement.label.name.start); + break; + case STATEMENT_GOTO: + printf(" goto %.*s\n", (int)statement.jump.label.length, statement.jump.label.start); + break; + case STATEMENT_SYSCALL: + printf(" syscall\n"); + break; } } } diff --git a/src/parser/ast.h b/src/parser/ast.h index 83483e9..4604e1a 100644 --- a/src/parser/ast.h +++ b/src/parser/ast.h @@ -26,6 +26,9 @@ struct Param enum StatementKind { STATEMENT_ASSIGN, + STATEMENT_LABEL, + STATEMENT_GOTO, + STATEMENT_SYSCALL, }; struct AssignStatement @@ -36,12 +39,24 @@ struct AssignStatement struct Token value; }; +struct LabelStatement +{ + struct Token name; +}; + +struct GotoStatement +{ + struct Token label; +}; + struct Statement { enum StatementKind kind; union { struct AssignStatement assign; + struct LabelStatement label; + struct GotoStatement jump; }; }; diff --git a/src/parser/parser.c b/src/parser/parser.c index d86502f..a125b7d 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -138,11 +138,34 @@ static bool parse_value(struct Parser* parser, struct Token* out) static bool parse_statement(struct Parser* parser, struct Statement* out) { + if (match_token(parser, TOKEN_SYSCALL)) + { + out->kind = STATEMENT_SYSCALL; + return true; + } + + if (match_token(parser, TOKEN_GOTO)) + { + if (!consume(parser, TOKEN_IDENTIFIER, "expected label after 'goto'")) + return false; + + out->kind = STATEMENT_GOTO; + out->jump.label = parser->previous; + return true; + } + bool deref = match_token(parser, TOKEN_CARET); if (!consume(parser, TOKEN_IDENTIFIER, "expected a statement")) return false; - struct Token target = parser->previous; + struct Token name = parser->previous; + + if (!deref && match_token(parser, TOKEN_COLON)) + { + out->kind = STATEMENT_LABEL; + out->label.name = name; + return true; + } if (!is_assign_op(parser->current.type)) { @@ -152,7 +175,7 @@ static bool parse_statement(struct Parser* parser, struct Statement* out) struct AssignStatement assign; assign.target_deref = deref; - assign.target = target; + assign.target = name; advance_parser(parser); assign.op = parser->previous; |
