summaryrefslogtreecommitdiff
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c53
1 files changed, 42 insertions, 11 deletions
diff --git a/parser.c b/parser.c
index 7de4ce9..699f345 100644
--- a/parser.c
+++ b/parser.c
@@ -1,5 +1,6 @@
#include "parser.h"
#include "lexer.h"
+#include "scope.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -16,6 +17,7 @@
}
static struct token tok;
+static struct scope* scope;
static void* protected_alloc(size_t sz) {
void* ptr = calloc(1, sz);
@@ -38,14 +40,27 @@ static void expect(enum token_type expected) {
if (tok.type != expected) unexpected_token(expected);
}
+static void peek_or_panic() {
+ if (!lexer_peek(&tok))
+ PARSER_PANIC("unexpected EOF");
+}
+
/* "handle" indicates that we've peeked already */
static void handle_expr(struct expr_node* p_node);
static void handle_stmt(struct stmt_node* p_node);
-static void parse_type(struct type_node* p_node) {
- expect(TK_IDENT);
- /* TODO: maybe check that this type is real haha */
- p_node->type = tok.data.ident;
+static void handle_type(struct type_node* p_node) {
+ /* TODO: need some concept of known types in scope */
+ /* TODO: modifiers, void rules, arrays, etc. */
+ /* TODO: struct, union, enum */
+ p_node->name = tok.data.ident;
+
+ peek_or_panic();
+ p_node->ptr_level = 0;
+ while (tok.type == TK_STAR) {
+ p_node->ptr_level++;
+ expect(TK_STAR);
+ }
}
static void parse_return(struct return_node* p_node) {
@@ -70,6 +85,11 @@ static void parse_int_lit(struct int_lit_node* p_node) {
p_node->val = tok.data.int_lit;
}
+static void parse_var_ref(struct var_ref_node* p_node) {
+ expect(TK_IDENT);
+ p_node->ident = tok.data.ident;
+}
+
static void handle_expr(struct expr_node* p_node) {
switch (tok.type) {
case TK_SEMI:
@@ -79,13 +99,17 @@ static void handle_expr(struct expr_node* p_node) {
p_node->type = EXPR_INT_LIT;
parse_int_lit(&p_node->as._int_lit);
return;
+ case TK_IDENT:
+ p_node->type = EXPR_VAR_REF;
+ parse_var_ref(&p_node->as._var_ref);
+ return;
default:
PARSER_PANIC("expected expression");
}
}
-static void parse_var_decl(struct var_decl_node* p_node) {
- parse_type(&p_node->type);
+static void handle_var_decl(struct var_decl_node* p_node) {
+ handle_type(&p_node->type);
expect(TK_IDENT);
p_node->ident = tok.data.ident;
}
@@ -118,11 +142,12 @@ static void handle_stmt(struct stmt_node* p_node) {
if (strcmp(tok.data.ident, "return") == 0) {
p_node->type = STMT_RETURN;
parse_return(&p_node->as._return);
- } else {
+ break;
+ } else if (scope_get_type(scope, NULL, tok.data.ident)) {
p_node->type = STMT_VAR_DECL;
- parse_var_decl(&p_node->as._var_decl);
+ handle_var_decl(&p_node->as._var_decl);
+ break;
}
- break;
default:
p_node->type = STMT_EXPR;
handle_expr(&p_node->as._expr);
@@ -132,8 +157,10 @@ static void handle_stmt(struct stmt_node* p_node) {
static void parse_arg_list(struct var_decl_node** pp_arg) {
for (;;) {
+ expect(TK_IDENT);
+
*pp_arg = protected_alloc(sizeof(struct var_decl_node));
- parse_var_decl(*pp_arg);
+ handle_var_decl(*pp_arg);
pp_arg = &((*pp_arg)->next);
if (!lexer_peek(&tok))
@@ -145,7 +172,8 @@ static void parse_arg_list(struct var_decl_node** pp_arg) {
}
static void parse_fn_decl(struct fn_decl_node* p_node) {
- parse_type(&p_node->return_type);
+ expect(TK_IDENT);
+ handle_type(&p_node->return_type);
expect(TK_IDENT);
p_node->name = tok.data.ident;
@@ -173,6 +201,8 @@ static bool parse_root(struct root_node* p_node) {
struct root_node* parse(const char* path) {
lexer_load(path);
+ scope_push(&scope);
+ scope_install_default_types(scope);
struct root_node* root;
struct root_node** p_node = &root;
@@ -187,6 +217,7 @@ struct root_node* parse(const char* path) {
p_node = &((*p_node)->next);
}
+ scope_pop(&scope);
lexer_close();
return root;
}