Basic order independent decls working

This commit is contained in:
Krzosa Karol
2022-05-26 21:30:50 +02:00
parent b773ad1c17
commit 18a895153e
4 changed files with 51 additions and 62 deletions

View File

@@ -180,7 +180,7 @@ gen_ast(Ast *ast){
switch(ast->kind){ switch(ast->kind){
Ast_Begin(AST_PACKAGE, Ast_Package){ Ast_Begin(AST_PACKAGE, Ast_Package){
For(node->decls) { For(node->ordered) {
genln(""); genln("");
gen_ast(*it); gen_ast(*it);
} }

View File

@@ -23,7 +23,7 @@ int main(){
String result = compile_file("order_independent_globals.kl"_s); String result = compile_file("order_independent_globals.kl"_s);
printf("%s", result.str); printf("%s", result.str);
compile_file("lambdas.kl"_s); // compile_file("lambdas.kl"_s);
compile_file("globals.kl"_s); // compile_file("globals.kl"_s);
__debugbreak(); __debugbreak();
} }

View File

@@ -77,17 +77,24 @@ scope_pop(S64 local_sym_count){
} }
function Sym * function Sym *
sym_new(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Ast *ast){ sym_new(Sym_Kind kind, Intern_String name, Ast *ast){
Sym *result = exp_alloc_type(pctx->perm, Sym, AF_ZeroMemory); Sym *result = exp_alloc_type(pctx->perm, Sym, AF_ZeroMemory);
result->name = name; result->name = name;
result->kind = kind; result->kind = kind;
result->type = type;
result->ast = ast; result->ast = ast;
assert(ast); assert(ast);
map_insert(&pctx->resolved, ast, result); map_insert(&pctx->resolved, ast, result);
return result; return result;
} }
function Sym *
sym_new_resolved(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Ast *ast){
Sym *result = sym_new(kind, name, ast);
result->type = type;
result->state = SYM_RESOLVED;
return result;
}
function Sym * function Sym *
resolved_get(Ast *ast){ resolved_get(Ast *ast){
Sym *result = (Sym *)map_get(&pctx->resolved, ast); Sym *result = (Sym *)map_get(&pctx->resolved, ast);
@@ -98,7 +105,7 @@ resolved_get(Ast *ast){
function void function void
sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ sym_insert_builtin_type(String name, Ast_Resolved_Type *type){
Intern_String string = intern_string(&pctx->interns, name); Intern_String string = intern_string(&pctx->interns, name);
Sym *sym = sym_new(SYM_TYPE, string, type, &empty_decl); Sym *sym = sym_new_resolved(SYM_TYPE, string, type, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
@@ -111,23 +118,24 @@ sym_insert_builtins(){
{ {
Intern_String string = intern_string(&pctx->interns, "true"_s); Intern_String string = intern_string(&pctx->interns, "true"_s);
Sym *sym = sym_new(SYM_CONST, string, type_bool, &empty_decl); Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
{ {
Intern_String string = intern_string(&pctx->interns, "false"_s); Intern_String string = intern_string(&pctx->interns, "false"_s);
Sym *sym = sym_new(SYM_CONST, string, type_bool, &empty_decl); Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
{ {
Intern_String string = intern_string(&pctx->interns, "null"_s); Intern_String string = intern_string(&pctx->interns, "null"_s);
Sym *sym = sym_new(SYM_CONST, string, type_null, &empty_decl); Sym *sym = sym_new_resolved(SYM_CONST, string, type_null, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
} }
function Sym *resolve_name(Token *pos, Intern_String name);
function Operand eval_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0); function Operand eval_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0);
function Ast_Resolved_Type * function Ast_Resolved_Type *
eval_typespec(Ast_Typespec *ast){ eval_typespec(Ast_Typespec *ast){
@@ -197,7 +205,7 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){
return result; return result;
} }
function void eval_decl(Ast *ast); function Operand eval_decl(Ast *ast);
function void function void
eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
switch(ast->kind){ switch(ast->kind){
@@ -211,12 +219,16 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
} }
Ast_Begin(AST_VAR, Ast_Var){ Ast_Begin(AST_VAR, Ast_Var){
eval_decl(node); Operand op = eval_decl(node);
Sym *sym = sym_new_resolved(SYM_VAR, node->name, op.type, node);
sym_insert(sym);
Ast_End(); Ast_End();
} }
Ast_Begin(AST_CONST, Ast_Const){ Ast_Begin(AST_CONST, Ast_Const){
eval_decl(node); Operand op = eval_decl(node);
Sym *sym = sym_new_resolved(SYM_CONST, node->name, op.type, node);
sym_insert(sym);
Ast_End(); Ast_End();
} }
@@ -224,7 +236,7 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
switch(node->op){ switch(node->op){
case TK_Comma:{ case TK_Comma:{
Operand op = eval_expr(node->expr); Operand op = eval_expr(node->expr);
Sym *sym = sym_new(SYM_VAR, node->ident->intern_val, op.type, node); Sym *sym = sym_new_resolved(SYM_VAR, node->ident->intern_val, op.type, node);
sym_insert(sym); sym_insert(sym);
}break; }break;
invalid_default_case; invalid_default_case;
@@ -267,10 +279,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){
} }
Ast_Begin(AST_IDENT, Ast_Atom){ Ast_Begin(AST_IDENT, Ast_Atom){
Sym *sym = sym_get(node->intern_val); Sym *sym = resolve_name(node->pos, node->intern_val);
if(!sym){
parsing_error(node->pos, "Identifier is undefined");
}
// @note: check if null and rewrite the expression to match the expected type // @note: check if null and rewrite the expression to match the expected type
Operand result = {}; Operand result = {};
@@ -323,7 +332,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){
S64 scope_index = scope_push(); S64 scope_index = scope_push();
For(node->args){ For(node->args){
Ast_Resolved_Type *type = eval_typespec(it[0]->typespec); Ast_Resolved_Type *type = eval_typespec(it[0]->typespec);
Sym *arg_sym = sym_new(SYM_VAR, it[0]->name, type, it[0]); Sym *arg_sym = sym_new_resolved(SYM_VAR, it[0]->name, type, it[0]);
sym_insert(arg_sym); sym_insert(arg_sym);
} }
For(node->block->stmts){ For(node->block->stmts){
@@ -453,22 +462,15 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){
return {}; return {};
} }
function void function Operand
eval_decl(Ast *ast){ eval_decl(Ast *ast){
switch(ast->kind){ switch(ast->kind){
Ast_Begin(AST_PACKAGE, Ast_Package){
For(node->decls) eval_decl(*it);
Ast_End();
}
Ast_Begin(AST_VAR, Ast_Var){ Ast_Begin(AST_VAR, Ast_Var){
Ast_Resolved_Type *type = eval_typespec(node->typespec); Ast_Resolved_Type *type = eval_typespec(node->typespec);
Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{}; Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{};
Ast_Resolved_Type *resolved_type = resolve_type_pair(node->pos, type, expr.type); expr.type = resolve_type_pair(node->pos, type, expr.type);
return expr;
Sym *sym = sym_new(SYM_VAR, node->name, resolved_type, node);
sym_insert(sym);
Ast_End(); Ast_End();
} }
@@ -476,16 +478,11 @@ eval_decl(Ast *ast){
Operand expr = eval_expr(node->expr); Operand expr = eval_expr(node->expr);
if(!expr.type) parsing_error(node->pos, "Constant value without expression"); if(!expr.type) parsing_error(node->pos, "Constant value without expression");
if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression"); if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression");
Ast_Resolved_Type *resolved_type = expr.type; return expr;
Sym *sym = sym_new(SYM_CONST, node->name, resolved_type, node);
if(resolved_type == type_int) sym->int_val = expr.int_val;
else if(resolved_type == type_string) sym->intern_val = expr.intern_val;
sym_insert(sym);
Ast_End(); Ast_End();
} }
invalid_default_case; invalid_default_case; return {};
} }
} }
@@ -495,35 +492,18 @@ resolve_sym(Sym *sym){
else if(sym->state == SYM_RESOLVING){ parsing_error(sym->ast->pos, "Cyclic dependency"); return; } else if(sym->state == SYM_RESOLVING){ parsing_error(sym->ast->pos, "Cyclic dependency"); return; }
assert(sym->state == SYM_NOT_RESOLVED); assert(sym->state == SYM_NOT_RESOLVED);
assert(sym->ast->kind == AST_VAR || sym->ast->kind == AST_CONST);
sym->state = SYM_RESOLVING; sym->state = SYM_RESOLVING;
Ast_Named *ast = (Ast_Named *)sym->ast; Operand op = eval_decl(sym->ast);
switch(ast->kind){ sym->type = op.type;
Ast_Begin(AST_VAR, Ast_Var){ if(sym->kind == SYM_CONST){
Ast_Resolved_Type *type = eval_typespec(node->typespec); assert(op.is_const);
Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{}; if(op.type == type_int) sym->int_val = op.int_val;
Ast_Resolved_Type *resolved_type = resolve_type_pair(node->pos, type, expr.type); else if(op.type == type_string) sym->intern_val = op.intern_val;
sym->type = resolved_type;
Ast_End();
}
Ast_Begin(AST_CONST, Ast_Const){
Operand expr = eval_expr(node->expr);
if(!expr.type) parsing_error(node->pos, "Constant value without expression");
if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression");
Ast_Resolved_Type *resolved_type = expr.type;
sym->type = resolved_type;
if(resolved_type == type_int) sym->int_val = expr.int_val;
else if(resolved_type == type_string) sym->intern_val = expr.intern_val;
Ast_End();
}
invalid_default_case;
} }
sym->state = SYM_RESOLVED; sym->state = SYM_RESOLVED;
pctx->resolving_package->ordered.add(ast); pctx->resolving_package->ordered.add((Ast_Named *)sym->ast);
} }
function Sym * function Sym *
@@ -544,7 +524,7 @@ resolve_package(Ast_Package *package){
function Ast_Package * function Ast_Package *
parse_file(){ parse_file(){
Scratch scratch; Scratch scratch;
// //
// @note: pop the first token with token_next() / token_expect() // @note: pop the first token with token_next() / token_expect()
// which always should be an indentation token, // which always should be an indentation token,
@@ -564,7 +544,7 @@ parse_file(){
else if(decl->kind == AST_VAR) kind = SYM_VAR; else if(decl->kind == AST_VAR) kind = SYM_VAR;
else invalid_codepath; else invalid_codepath;
Sym *sym = sym_new(kind, decl->name, 0, decl); Sym *sym = sym_new(kind, decl->name, decl);
sym_insert(sym); sym_insert(sym);
decls.add(decl); decls.add(decl);

View File

@@ -1,4 +1,13 @@
lambda :: (thing: int)
some_value := thing + const_in_lambda
const_in_lambda :: 10
not_const := val + 10
val := 10
DEPENDENCE :: CONSTANT_VAL DEPENDENCE :: CONSTANT_VAL
CONSTANT_VAL :: 10 CONSTANT_VAL :: 10