aboutsummaryrefslogtreecommitdiff
path: root/compiler/parser.cup
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/parser.cup')
-rw-r--r--compiler/parser.cup38
1 files changed, 37 insertions, 1 deletions
diff --git a/compiler/parser.cup b/compiler/parser.cup
index 40df5a3..ffd8d8a 100644
--- a/compiler/parser.cup
+++ b/compiler/parser.cup
@@ -8,6 +8,9 @@ let p_current_function: Node* = null;
let p_block_stack = vector_new();
let p_cur_stack_offset = 0;
+let p_global_variables = vector_new();
+let p_global_offset = 0;
+
fn block_stack_push(block: Node*) {
vector_push(p_block_stack, block);
}
@@ -41,6 +44,16 @@ fn find_local_variable(token: Token*): Variable* {
return null;
}
+fn find_global_variable(token: Token*): Variable* {
+ for (let i = 0; i < p_global_variables.size; ++i) {
+ let var: Variable* = p_global_variables.data[i];
+ if (streq(token.value.as_string, var.name)) {
+ return var;
+ }
+ }
+ return null;
+}
+
fn find_function_definition(token: Token*): Node* {
for (let i = 0; i < p_all_functions.size; ++i) {
let func: Node* = p_all_functions.data[i];
@@ -53,6 +66,7 @@ fn find_function_definition(token: Token*): Node* {
fn identifier_exists(token: Token*): int {
if (find_local_variable(token)) return true;
+ if (find_global_variable(token)) return true;
if (find_function_definition(token)) return true;
if (find_builtin_function(token)) return true;
return false;
@@ -156,6 +170,14 @@ fn parse_identifier(lexer: Lexer*): Node* {
return node;
}
+ var = find_global_variable(&token);
+ if (var != null) {
+ node = node_new(AST_GLOBAL_VAR);
+ node.d.variable = var;
+ node.etyp = var.typ;
+ return node;
+ }
+
let func = find_function_definition(&token);
if (func != null) {
return parse_function_call_args(lexer, func);
@@ -418,11 +440,21 @@ fn add_variable_to_current_block(var: Variable*) {
p_current_function.d.func.max_locals_size = max_offset;
}
+fn add_global_variable(var: Variable*) {
+ var.offset = p_global_offset;
+ let var_size = align_up(size_for_type(var.typ), 8);
+ p_global_offset = p_global_offset + var_size;
+ vector_push(p_global_variables, var);
+}
+
fn parse_var_declaration(lexer: Lexer*): Node* {
let token: Token;
lexer_next_assert(lexer, &token, TOKEN_LET);
lexer_next_assert(lexer, &token, TOKEN_IDENTIFIER);
+
+ let is_global = (p_current_function == null);
+
// TODO: check if identifier is already defined
let node = node_new(AST_VARDECL);
let decl = &node.d.var_decl;
@@ -442,7 +474,11 @@ fn parse_var_declaration(lexer: Lexer*): Node* {
die_loc(&token.loc, "Expected ':' or '=' after variable declaration");
}
- add_variable_to_current_block(&decl.var);
+ if (is_global) {
+ add_global_variable(&decl.var);
+ } else {
+ add_variable_to_current_block(&decl.var);
+ }
return node;
}