summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/lexer/keywords.c1
-rw-r--r--compiler/main.c97
-rw-r--r--compiler/parser/proc.c22
-rw-r--r--compiler/parser/stmt.c62
4 files changed, 99 insertions, 83 deletions
diff --git a/compiler/lexer/keywords.c b/compiler/lexer/keywords.c
index 88c2e67..dbae881 100644
--- a/compiler/lexer/keywords.c
+++ b/compiler/lexer/keywords.c
@@ -69,6 +69,7 @@ keywords_init(void)
add_keyword("type", TK_TYPE);
add_keyword("enum", TK_ENUM);
add_keyword("struct", TK_STRUCT);
+ add_keyword("ret", TK_RET);
initialized = true;
}
diff --git a/compiler/main.c b/compiler/main.c
index e614be6..aa3bcdc 100644
--- a/compiler/main.c
+++ b/compiler/main.c
@@ -183,69 +183,31 @@ print_ptrs(int n_ptrs)
}
static void
-print_alias(struct type *typ)
+print_ret(struct ast_node *node)
{
- printf("alias (%lu bytes, %d pointer(s));\n", typ->size, typ->n_ptrs);
-}
-
-static void
-print_enum(struct type *typ)
-{
- struct enum_member *mem;
+ (void)node;
- printf("enum {\n");
-
- for (size_t r = 0; r < typ->members.n_rows; r++) {
- mem = (struct enum_member*)typ->members.rows[r].head;
- while (mem != (struct enum_member*)&typ->members.rows[r]) {
- printf(" %.*s,\n", (int)mem->name_len, mem->name);
-
- mem = (struct enum_member*)mem->hashmap_entry.list_entry.next;
- }
- }
-
- printf("}\n");
+ /* TODO: Print return value */
+ printf(" ret;\n");
}
static void
-print_struct(struct type *typ)
+print_stmt_block(struct ast_node *parent)
{
- struct struct_member *mem;
-
- printf("struct (%lu bytes) {\n", typ->size);
-
- for (size_t r = 0; r < typ->members.n_rows; r++) {
- mem = (struct struct_member*)typ->members.rows[r].head;
- while (mem != (struct struct_member*)&typ->members.rows[r]) {
- printf(" %.*s ", (int)mem->typ->name_len, mem->typ->name);
- print_ptrs(mem->n_ptrs);
- printf("%.*s;\n", (int)mem->name_len, mem->name);
-
- mem = (struct struct_member*)mem->hashmap_entry.list_entry.next;
+ struct ast_node *node;
+
+ node = (struct ast_node*)parent->children.head;
+ while (node != (struct ast_node*)&parent->children) {
+ switch (node->kind) {
+ case NK_RETURN:
+ print_ret(node);
+ break;
+ default:
+ printf(" /* Unknown */\n");
+ break;
}
- }
-
- printf("}\n");
-}
-static void
-print_type(struct type *typ)
-{
- printf("type %.*s: ", (int)typ->name_len, typ->name);
-
- switch (typ->kind) {
- case TYK_ALIAS:
- print_alias(typ);
- break;
- case TYK_ENUM:
- print_enum(typ);
- break;
- case TYK_STRUCT:
- print_struct(typ);
- break;
- default:
- printf("unknown;\n");
- break;
+ node = (struct ast_node*)node->list_entry.next;
}
}
@@ -281,26 +243,14 @@ print_proc(struct procedure *proc)
print_ptrs(proc->ret_n_ptrs);
}
- printf(";\n");
-}
-
-static void
-dump_types(struct hashmap *map)
-{
- struct type *typ, *next;
-
- for (size_t r = 0; r < map->n_rows; r++) {
- typ = (struct type*)map->rows[r].head;
- while (typ != (struct type*)&map->rows[r]) {
- print_type(typ);
-
- next = (struct type*)typ->hashmap_entry.list_entry.next;
- free(typ);
- typ = next;
- }
+ if (list_is_empty(&proc->node->children)) {
+ printf(";\n");
+ return;
}
- free(map->rows);
+ printf(" {\n");
+ print_stmt_block(proc->node);
+ printf("}\n");
}
static void
@@ -362,7 +312,6 @@ main(int argc, char **argv)
parser_init(&parser, input);
parser_parse(&parser);
- dump_types(parser.types);
dump_procs(parser.procs);
free(input);
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);
+}