aboutsummaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-30 12:14:04 +0200
committerhachem <im@hachem.wtf>2026-08-30 12:14:04 +0200
commit53946c982cb3290a25f7c8529ef1399f0635ef37 (patch)
tree969bc78c304e13d733b794ffc98d44bf44b53621 /src/parser
parent6532b074e5c1db4a1c32298cc338a1a533208641 (diff)
add: parse labels and syscalls
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/ast.h15
-rw-r--r--src/parser/parser.c27
2 files changed, 40 insertions, 2 deletions
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;