From 37e56a09145c6e6292f69193123b67b9a31364ee Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 10 Jun 2022 22:06:35 +0200 Subject: [PATCH] Compiling global, work on AST_LAMBDA_EXPR --- ast.cpp | 5 +- ccodegen.cpp | 137 ++++++++++++++++++++++++----------------------- globals.kl | 11 +--- main.cpp | 11 +--- parsing.cpp | 2 +- typechecking.cpp | 80 +++++++++++++++------------ 6 files changed, 121 insertions(+), 125 deletions(-) diff --git a/ast.cpp b/ast.cpp index a99954b..2c94d7f 100644 --- a/ast.cpp +++ b/ast.cpp @@ -152,7 +152,7 @@ struct Ast_Lambda : Ast_Expr { Array args; Ast_Expr *ret; Ast_Scope *scope; - B32 has_var_args; + Ast_Resolved_Type *type; }; struct Ast_Array: Ast_Expr{ @@ -327,13 +327,12 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ } function Ast_Lambda * -ast_lambda(Token *pos, Array params, B32 has_var_args, Ast_Expr *ret, Ast_Scope *scope){ +ast_lambda(Token *pos, Array params, Ast_Expr *ret, Ast_Scope *scope){ AST_NEW(Lambda, LAMBDA_EXPR, pos, AST_EXPR); result->flags = AST_EXPR; result->args = params.tight_copy(pctx->perm); result->scope = scope; result->ret = ret; - result->has_var_args = has_var_args; if(!ret) result->ret = ast_ident(result->pos, intern_void); return result; diff --git a/ccodegen.cpp b/ccodegen.cpp index 5b2f0c7..b1f40b3 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -5,12 +5,19 @@ global S32 global_indent; global S32 is_inside_struct; function void gen_ast(Ast *ast); +function void gen_expr(Ast_Expr *ast); function void gen_indent(){ for(S32 i = 0; i < global_indent; i++) gen(" "); } +function void +gen_line(Ast *node){ + if(emit_line_directives) + genln("#line %d", node->pos->line+1); +} + // @todo: Gen complicated decl //array 10 ( pointer (pointer array 5 int a)) // int (*(*(a[5])))[10] @@ -91,6 +98,60 @@ gen_value(Value a){ return result; } +function void +gen_stmt_scope(Ast_Scope *scope){ + gen("{"); + global_indent++; + For(scope->stmts) { + gen_line(it); + genln(""); + gen_ast(it); + } + global_indent--; + genln("}"); +} + +enum { + ALWAYS_EMIT_VALUE = 0, + DONT_EMIT_VALUE = 1, +}; + +function void +gen_var(Intern_String name, Ast_Resolved_Type *type, Ast_Expr *expr, B32 emit_value){ + gen_simple_decl(type, name); + + if(emit_value == DONT_EMIT_VALUE){ + return; + } + + if(expr){ + gen(" = "); + gen_expr(expr); + } else { // Default zero + if(is_numeric(type)){ + gen(" = 0"); + } else { + gen(" = {}"); + } + } +} + +function void +gen_lambda(Intern_String name, Ast_Lambda *lambda){ + gen_simple_decl(lambda->type->func.ret, name); + gen("("); + For(lambda->args){ + gen_var(it->name, it->type, 0, DONT_EMIT_VALUE); + if(&it != (lambda->args.end() - 1)) gen(", "); + } + gen(")"); + + if(lambda->scope) { + gen_stmt_scope(lambda->scope); + } + else gen(";"); +} + function void gen_expr(Ast_Expr *ast){ switch(ast->kind){ @@ -115,6 +176,11 @@ gen_expr(Ast_Expr *ast){ BREAK(); } + CASE(LAMBDA_EXPR, Lambda){ + gen_lambda({}, node); + BREAK(); + } + CASE(BINARY, Binary){ if(node->op == TK_Dot){ gen_expr(node->left); @@ -172,50 +238,6 @@ gen_expr(Ast_Expr *ast){ } } -function void -gen_line(Ast *node){ - if(emit_line_directives) - genln("#line %d", node->pos->line+1); -} - -function void -gen_stmt_scope(Ast_Scope *scope){ - gen("{"); - global_indent++; - For(scope->stmts) { - gen_line(it); - genln(""); - gen_ast(it); - } - global_indent--; - genln("}"); -} - -enum { - ALWAYS_EMIT_VALUE = 0, - DONT_EMIT_VALUE = 1, -}; - -function void -gen_var(Intern_String name, Ast_Resolved_Type *type, Ast_Expr *expr, B32 emit_value){ - gen_simple_decl(type, name); - - if(emit_value == DONT_EMIT_VALUE){ - return; - } - - if(expr){ - gen(" = "); - gen_expr(expr); - } else { // Default zero - if(is_numeric(type)){ - gen(" = 0"); - } else { - gen(" = {}"); - } - } -} - function void gen_ast(Ast *ast){ switch(ast->kind){ @@ -283,31 +305,10 @@ gen_ast(Ast *ast){ } CASE(LAMBDA, Decl){ - if(node->kind == AST_LAMBDA){ - if(is_flag_set(node->flags, AST_FOREIGN)){ - return; - } - Ast_Lambda *lambda = node->lambda; - Ast_Resolved_Type *ret = node->type->func.ret; - gen_simple_decl(ret, node->name); - gen("("); - For(lambda->args){ - gen_var(it->name, it->type, 0, DONT_EMIT_VALUE); - if(&it != (lambda->args.end() - 1)) gen(", "); - } - gen(")"); - - if(lambda->scope) { - gen_stmt_scope(lambda->scope); - } - else gen(";"); - } - else{ - gen_simple_decl(node->type, node->name); - gen(" = "); - gen_expr((Ast_Expr *)node->expr); - gen(";"); + if(is_flag_set(node->flags, AST_FOREIGN)){ + gen("/*foreign*/"); } + gen_lambda(node->name, node->lambda); BREAK(); } diff --git a/globals.kl b/globals.kl index c2a847b..ad9b149 100644 --- a/globals.kl +++ b/globals.kl @@ -21,16 +21,7 @@ Boolean: Bool = true //----------------------------------------------------------------------------- // Compound expressions //----------------------------------------------------------------------------- -array1: [4]S64 = [4]S64(1,2,3,4) -array2 := [32]S64(1,2,3,4) -array3 := [32]S64( - [0] = 0, - [1] = 1, - [2] = 2, - [31] = 31, -) -array_item := array1[0] -array_item_imp: S64 = array2[2] +array1: [4]S64 //----------------------------------------------------------------------------- // Pointers diff --git a/main.cpp b/main.cpp index 866595a..b970ee4 100644 --- a/main.cpp +++ b/main.cpp @@ -201,17 +201,7 @@ int main(int argument_count, char **arguments){ system((const char *)run_program.str); } else{ - String result = {}; - #if 1 - result = compile_file("globals.kl"_s); - printf("%s", result.str); - result = compile_file("enums.kl"_s); - printf("%s", result.str); - - result = compile_file("new_types.kl"_s); - printf("%s", result.str); - #endif } #endif Scratch scratch; @@ -221,6 +211,7 @@ int main(int argument_count, char **arguments){ files.add("order2.kl"_s); files.add("new_types.kl"_s); files.add("enums.kl"_s); + files.add("globals.kl"_s); String result = compile_files(files); printf("%s", result.str); __debugbreak(); diff --git a/parsing.cpp b/parsing.cpp index 3653292..a54af73 100644 --- a/parsing.cpp +++ b/parsing.cpp @@ -321,7 +321,7 @@ parse_lambda(Token *token){ Ast_Expr *ret = parse_optional_type(); Ast_Scope *scope = token_is(OPEN_SCOPE) ? parse_stmt_scope() : 0; - Ast_Lambda *result = ast_lambda(token, params, has_var_args, ret, scope); + Ast_Lambda *result = ast_lambda(token, params, ret, scope); return result; } diff --git a/typechecking.cpp b/typechecking.cpp index be33e43..4544a59 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -496,6 +496,41 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ } } +function Ast_Resolved_Type * +resolve_lambda_type(Ast_Lambda *lambda){ + Scratch scratch; + Ast_Resolved_Type *ret_type = resolve_typespec(lambda->ret, AST_CANT_BE_NULL); + Array args = {scratch}; + + For(lambda->args){ + Ast_Resolved_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL); + Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL); + make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL); + it->type = type; + args.add(type); + } + + return type_lambda(lambda, ret_type, args); +} + +function void +try_resolving_lambda_scope(Operand *op, Ast_Lambda *lambda, Ast_Resolved_Type *lambda_type){ + if(lambda->scope){ + For(lambda->args){ + insert_into_scope(lambda->scope, it); + } + For(lambda->scope->stmts){ + resolve_stmt(it, lambda_type->func.ret); + } + + *op = operand_lambda(lambda_type); + } + else if(is_flag_set(lambda->flags, AST_FOREIGN)){ + // @todo: Add foreign + *op = operand_lambda(lambda_type); + } +} + function Operand resolve_cast(Ast_Cast *node){ Operand expr = resolve_expr(node->expr, AST_CANT_BE_NULL); @@ -637,6 +672,14 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){ BREAK(); } + CASE(LAMBDA_EXPR, Lambda){ + node->type = resolve_lambda_type(node); + Operand result = operand_type(node->type); + try_resolving_lambda_scope(&result, node, node->type); + return result; + BREAK(); + } + CASE(INDEX, Index){ Operand left = resolve_expr(node->expr, AST_CANT_BE_NULL); Operand index = resolve_expr(node->index, AST_CANT_BE_NULL); @@ -811,45 +854,16 @@ resolve_decl(Ast_Decl *ast){ switch(ast->kind){ CASE(LAMBDA, Decl){ Ast_Lambda *lambda = node->lambda; - - Scratch scratch; - Ast_Resolved_Type *lambda_type = 0; - Ast_Resolved_Type *ret_type = resolve_typespec(lambda->ret, AST_CANT_BE_NULL); - Array args = {scratch}; - - For(lambda->args){ - Ast_Resolved_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL); - Operand default_value = resolve_expr(it->expr, AST_CAN_BE_NULL); - make_sure_value_is_compatible_with_type(it->pos, &default_value, type, EXPR_CAN_BE_NULL); - it->type = type; - args.add(type); - } - - lambda_type = type_lambda(lambda, ret_type, args); - Operand result = operand_type(lambda_type); + lambda->type = resolve_lambda_type(lambda); + Operand result = operand_type(lambda->type); // @note: top level lambda needs to get marked as resolved // so that the cyclic dependency wont trigger - node->type = lambda_type; + node->type = lambda->type; node->state = DECL_RESOLVED; // @todo: We also need to make sure there is a return value when ret type is not void - // @note: then try resolving the block of lambda - if(lambda->scope){ - For(lambda->args){ - insert_into_scope(lambda->scope, it); - } - For(lambda->scope->stmts){ - resolve_stmt(it, ret_type); - } - - result = operand_lambda(lambda_type); - } - else if(is_flag_set(lambda->flags, AST_FOREIGN)){ - // @todo: Add foreign - result = operand_lambda(lambda_type); - } - + try_resolving_lambda_scope(&result, lambda, node->type); node->value = result.value; BREAK(); }