summaryrefslogtreecommitdiff
path: root/compiler/parser
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/parser')
-rw-r--r--compiler/parser/proc.c22
-rw-r--r--compiler/parser/stmt.c62
2 files changed, 75 insertions, 9 deletions
diff --git a/compiler/parser/proc.c b/compiler/parser/proc.c
index bbbdad1..b32f5e9 100644
--- a/compiler/parser/proc.c
+++ b/compiler/parser/proc.c
@@ -7,6 +7,7 @@
#include <stdbool.h>
#include "debug.h"
#include "parser/proc.h"
+#include "parser/stmt.h"
#include "parser/type.h"
#include "parser.h"
@@ -119,26 +120,29 @@ parse_proc(struct parser *ctx)
}
}
- /* Add procedure to parser's registry */
- hashmap_add(ctx->procs, &proc->hashmap_entry);
-
/* We are finished now if this is just a declaration */
if (ctx->tok.kind == TK_SEMICOLON) {
+ proc->node = NULL;
+
+ /* Add procedure to parser's registry */
+ hashmap_add(ctx->procs, &proc->hashmap_entry);
+
next_token(ctx);
return;
}
if (ctx->tok.kind != TK_LBRACE) {
+ proc->node = NULL;
tok_error(&ctx->tok, "Expected \";\" or \"{\"\n");
return;
}
- /* TODO: Parse body/code */
+ /* Allocate AST root node for body */
+ proc->node = ast_new_node(NK_PROCEDURE);
- if (next_token(ctx)->kind != TK_RBRACE) {
- tok_error(&ctx->tok, "Expected \"}\" after procedure body\n");
- return;
- }
+ /* Parse procedure body (code) */
+ parse_stmt_block(ctx, proc->node, proc);
- next_token(ctx);
+ /* Add procedure to parser's registry */
+ hashmap_add(ctx->procs, &proc->hashmap_entry);
}
diff --git a/compiler/parser/stmt.c b/compiler/parser/stmt.c
new file mode 100644
index 0000000..6fe3d6d
--- /dev/null
+++ b/compiler/parser/stmt.c
@@ -0,0 +1,62 @@
+/*
+ * Statement parser.
+ * Copyright (c) 2023-2024, Quinn Stephens and the OSMORA team.
+ * Provided under the BSD 3-Clause license.
+ */
+
+#include <stdbool.h>
+#include "debug.h"
+#include "parser/ast.h"
+#include "parser/stmt.h"
+#include "parser/proc.h"
+#include "parser.h"
+
+static bool
+parse_ret(struct parser *ctx, struct ast_node *parent, struct procedure *proc)
+{
+ struct ast_node *node;
+
+ (void)proc;
+
+ debug("Parsing return statement...\n");
+
+ /* TODO: Parse return value */
+ next_token(ctx);
+
+ if (ctx->tok.kind != TK_SEMICOLON) {
+ tok_error(&ctx->tok, "Expected \";\"\n");
+ return false;
+ }
+ next_token(ctx);
+
+ node = ast_new_node(NK_RETURN);
+ ast_append_child(parent, node);
+
+ return true;
+}
+
+void
+parse_stmt_block(struct parser *ctx, struct ast_node *parent, struct procedure *proc)
+{
+ bool success;
+
+ debug("Parsing statement block...\n");
+
+ next_token(ctx);
+ while (ctx->tok.kind != TK_RBRACE) {
+ switch (ctx->tok.kind) {
+ case TK_RET:
+ success = parse_ret(ctx, parent, proc);
+ break;
+ default:
+ tok_error(&ctx->tok, "Expected statement\n");
+ success = false;
+ break;
+ }
+
+ if (!success) {
+ return;
+ }
+ }
+ next_token(ctx);
+}