aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-08-30 17:50:49 +0200
committerhachem <im@hachem.wtf>2026-08-30 17:50:49 +0200
commit542e15041ea1d93e74a06c588f16ce7956d6a9bb (patch)
tree3dda2b5c2b1b5f4d572a837bec879635371c0a20
parenta07b22097f3758558f4b35aa5aa5d8c1afc3402b (diff)
add: parse stack directive
-rw-r--r--src/main.c5
-rw-r--r--src/parser/ast.h8
-rw-r--r--src/parser/parser.c22
-rw-r--r--tests/parser_test.c17
4 files changed, 52 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
index e33734d..9a31f83 100644
--- a/src/main.c
+++ b/src/main.c
@@ -67,6 +67,11 @@ static void print_statement(struct Statement* statement, const char* indent)
}
printf(")\n");
break;
+ case STATEMENT_STACK:
+ printf("%sstack %.*s[%.*s]\n", indent,
+ (int)statement->stack.name.length, statement->stack.name.start,
+ (int)statement->stack.size.length, statement->stack.size.start);
+ break;
}
}
diff --git a/src/parser/ast.h b/src/parser/ast.h
index 3fa80da..8281085 100644
--- a/src/parser/ast.h
+++ b/src/parser/ast.h
@@ -67,6 +67,7 @@ enum StatementKind
STATEMENT_SYSCALL,
STATEMENT_IF,
STATEMENT_CALL,
+ STATEMENT_STACK,
};
struct AssignStatement
@@ -103,6 +104,12 @@ struct CallStatement
size_t arg_capacity;
};
+struct StackStatement
+{
+ struct Token name;
+ struct Token size;
+};
+
struct Statement
{
enum StatementKind kind;
@@ -113,6 +120,7 @@ struct Statement
struct GotoStatement jump;
struct IfStatement branch;
struct CallStatement call;
+ struct StackStatement stack;
};
};
diff --git a/src/parser/parser.c b/src/parser/parser.c
index 55203ca..d2a7285 100644
--- a/src/parser/parser.c
+++ b/src/parser/parser.c
@@ -310,6 +310,28 @@ static bool parse_statement(struct Parser* parser, struct Statement* out)
return true;
}
+ if (match_token(parser, TOKEN_STACK))
+ {
+ if (!consume(parser, TOKEN_IDENTIFIER, "expected buffer name after 'stack'"))
+ return false;
+ struct Token name = parser->previous;
+
+ if (!consume(parser, TOKEN_LEFT_BRACKET, "expected '[' after buffer name"))
+ return false;
+
+ if (!consume(parser, TOKEN_INTEGER, "expected buffer size"))
+ return false;
+ struct Token size = parser->previous;
+
+ if (!consume(parser, TOKEN_RIGHT_BRACKET, "expected ']' after buffer size"))
+ return false;
+
+ out->kind = STATEMENT_STACK;
+ out->stack.name = name;
+ out->stack.size = size;
+ return true;
+ }
+
if (match_token(parser, TOKEN_GOTO))
{
if (!consume(parser, TOKEN_IDENTIFIER, "expected label after 'goto'"))
diff --git a/tests/parser_test.c b/tests/parser_test.c
index 8e72402..bbbbaa2 100644
--- a/tests/parser_test.c
+++ b/tests/parser_test.c
@@ -172,6 +172,22 @@ static void test_parse_call(struct TestContext* context)
free_program(&program);
}
+static void test_parse_stack(struct TestContext* context)
+{
+ struct Lexer lexer = create_lexer("proc main\n{\nstack buffer[32]\n}\n");
+ struct Program program;
+
+ check(context, parse_program(&lexer, &program));
+ check(context, program.procs[0].body_count == 1);
+
+ struct Statement statement = program.procs[0].body[0];
+ check(context, statement.kind == STATEMENT_STACK);
+ check(context, text_is(statement.stack.name, "buffer"));
+ check(context, text_is(statement.stack.size, "32"));
+
+ free_program(&program);
+}
+
static void test_parse_errors(struct TestContext* context)
{
struct Program program;
@@ -199,5 +215,6 @@ void run_parser_tests(struct TestContext* context)
test_parse_expressions(context);
test_parse_if(context);
test_parse_call(context);
+ test_parse_stack(context);
test_parse_errors(context);
}