aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-04-10 11:49:43 -0400
committerBruce Hill <bruce@bruce-hill.com>2024-04-10 11:49:43 -0400
commit4f514378accd7a5ed8774d008761efa94f383148 (patch)
tree1682ac995b84327bee6ac29cd379aea4f02fa5ae /compile.c
parent438edf45c27da9aa2503a5bcf50f34475c8bc63d (diff)
Fix corecursive functions and global variables
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c26
1 files changed, 22 insertions, 4 deletions
diff --git a/compile.c b/compile.c
index 335134e8..0e23c948 100644
--- a/compile.c
+++ b/compile.c
@@ -443,7 +443,7 @@ CORD compile_statement(env_t *env, ast_t *ast)
code = CORD_cat("public ", code);
}
- env_t *body_scope = global_scope(env);
+ env_t *body_scope = fresh_scope(env);
for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
type_t *arg_type = get_arg_ast_type(env, arg);
set_binding(body_scope, arg->name, new(binding_t, .type=arg_type, .code=arg->name));
@@ -1887,9 +1887,27 @@ module_code_t compile_file(ast_t *ast)
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
bind_statement(env, stmt->ast);
- CORD code = compile_statement(env, stmt->ast);
- if (code)
- CORD_appendf(&env->code->main, "%r\n", code);
+ }
+ for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
+ if (stmt->ast->tag == Declare) {
+ auto decl = Match(stmt->ast, Declare);
+ type_t *t = get_type(env, decl->value);
+ if (t->tag == AbortType || t->tag == VoidType)
+ code_err(stmt->ast, "You can't declare a variable with a %T value", t);
+ if (!is_constant(decl->value))
+ code_err(decl->value, "This value is not a valid constant initializer.");
+ env->code->fndefs = CORD_all(
+ env->code->fndefs,
+ compile_declaration(env, t, Match(decl->var, Var)->name), ";\n");
+ env->code->staticdefs = CORD_all(
+ env->code->staticdefs,
+ "extern ", compile_type(env, t), " ", Match(decl->var, Var)->name, " = ",
+ compile(env, decl->value), ";\n");
+ } else {
+ CORD code = compile_statement(env, stmt->ast);
+ if (code)
+ CORD_appendf(&env->code->main, "%r\n", code);
+ }
}
return (module_code_t){