Recursive functions working
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user