diff --git a/new_resolve.cpp b/new_resolve.cpp index 76d42ab..3a901fa 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -136,7 +136,7 @@ sym_insert_builtins(){ } 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, Sym *lambda_to_complete = 0); function Ast_Resolved_Type * eval_typespec(Ast_Typespec *ast){ if(!ast) return 0; @@ -205,7 +205,7 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){ return result; } -function Operand eval_decl(Ast *ast); +function Operand eval_decl(Ast *ast, Sym *sym = 0); function void eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ switch(ast->kind){ @@ -261,8 +261,16 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ } } +function void +try_completing_lambda(Sym *sym, Ast_Resolved_Type *type){ + if(sym && sym->state == SYM_RESOLVING){ + sym->state = SYM_RESOLVED; + sym->type = type; + } +} + function Operand -eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){ +eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_complete){ switch(ast->kind){ Ast_Begin(AST_INT, Ast_Atom){ Operand result = {type_int, true}; @@ -326,6 +334,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){ Ast_Begin(AST_LAMBDA, Ast_Lambda){ Ast_Resolved_Type *type = eval_typespec(ast_typespec_lambda(0, node)); + try_completing_lambda(lambda_to_complete, type); // @todo: We also need to make sure there is a return value when ret type is not void if(node->block){ @@ -463,7 +472,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){ } function Operand -eval_decl(Ast *ast){ +eval_decl(Ast *ast, Sym *sym){ switch(ast->kind){ Ast_Begin(AST_VAR, Ast_Var){ @@ -475,7 +484,7 @@ eval_decl(Ast *ast){ } Ast_Begin(AST_CONST, Ast_Const){ - Operand expr = eval_expr(node->expr); + Operand expr = eval_expr(node->expr, 0, sym); 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"); return expr; @@ -494,7 +503,7 @@ resolve_sym(Sym *sym){ assert(sym->ast->kind == AST_VAR || sym->ast->kind == AST_CONST); sym->state = SYM_RESOLVING; - Operand op = eval_decl(sym->ast); + Operand op = eval_decl(sym->ast, sym); sym->type = op.type; if(sym->kind == SYM_CONST){ assert(op.is_const); diff --git a/order_independent_globals.kl b/order_independent_globals.kl index 0a5abe5..0094336 100644 --- a/order_independent_globals.kl +++ b/order_independent_globals.kl @@ -1,7 +1,9 @@ lambda :: (thing: int) + in_val := lambda some_value := thing + const_in_lambda + const_in_lambda :: 10 not_const := val + 10