From 04d38511a94f7680636b2d91325f113bea70d7f2 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Tue, 31 May 2022 14:01:18 +0200 Subject: [PATCH] Fix regression, constant variables now get properly rewritten --- ccodegen.cpp | 2 +- enums.kl | 2 +- main.cpp | 19 ++++++++++------- new_type.cpp | 35 ++++++-------------------------- order1.kl | 2 +- order2.kl | 4 ++-- typechecking.cpp | 53 ++++++++++++++++++++++++------------------------ 7 files changed, 49 insertions(+), 68 deletions(-) diff --git a/ccodegen.cpp b/ccodegen.cpp index 7b49966..ae3b4d6 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -147,7 +147,7 @@ gen_expr(Ast_Expr *ast){ CASE(CALL, Call){ // @todo: Reach into map instead of direct lookup - if(node->type->kind == TYPE_STRUCT){ // @todo: Should this be type_type maybe??? + if(is_struct(node->type) || is_array(node->type)){ // @todo: Should this be type_type maybe??? gen("("); gen_simple_decl(node->type, {}); gen(")"); diff --git a/enums.kl b/enums.kl index da28e47..5d9cb81 100644 --- a/enums.kl +++ b/enums.kl @@ -4,6 +4,7 @@ Thing :: struct Constant_String :: "Test" Constant :: 10 + Thing_Kind :: enum None Thing_Not @@ -19,6 +20,5 @@ Allocator_Kind :: enum Arena Heap - kind := Allocator_Kind.Heap diff --git a/main.cpp b/main.cpp index afdfee7..e36b2da 100644 --- a/main.cpp +++ b/main.cpp @@ -40,19 +40,24 @@ For now I don't thing it should be overloadable. ------------------------------------------------------------------------------- @todo -[ ] - Enums -[ ] - Enum . access to values [ ] - Fixing access to constants, in C we cant have constants inside of structs / functions so we need to rewrite the tree -[ ] - Access through struct names to constants Arena.CONSTANT [ ] - Default values in structs??? Should compound stmts bring values from default values?? Maybe not? Whats the alternative [ ] - Write up on order independent declarations +[ ] - Init statements +[ ] - lvalue, rvalue concept so we cant assign value to some arbitrary weird expression [ ] - For loop [ ] - Switch +[ ] - More basic types [ ] - Lexer: Need to insert scope endings when hitting End of file [ ] - Add single line lambda expressions +@ideas + @donzo +[x] - Access through struct names to constants Arena.CONSTANT +[x] - Enums +[x] - Enum . access to values [x] - Struct calls [x] - Default values in calls [x] - Resolving calls with default values @@ -81,11 +86,11 @@ int main(){ lex_test(); String result = {}; - // result = compile_file("order1.kl"_s); - // result = compile_file("lambdas.kl"_s); - // result = compile_file("order2.kl"_s); + result = compile_file("globals.kl"_s); result = compile_file("enums.kl"_s); - // result = compile_file("globals.kl"_s); + result = compile_file("order2.kl"_s); + result = compile_file("lambdas.kl"_s); + result = compile_file("order1.kl"_s); printf("%s", result.str); __debugbreak(); diff --git a/new_type.cpp b/new_type.cpp index f4b1dce..f34eebe 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -83,35 +83,12 @@ global Ast_Resolved_Type *type_string = &type__string; global Ast_Resolved_Type *type_bool = &type__bool; global Ast_Resolved_Type *type_null = &type__null; -function B32 -is_string(Ast_Resolved_Type *type){ - B32 result = type->kind == TYPE_STRING; - return result; -} - -function B32 -is_int(Ast_Resolved_Type *type){ - B32 result = type->kind == TYPE_INT; - return result; -} - -function B32 -is_struct(Ast_Resolved_Type *type){ - B32 result = type->kind == TYPE_STRUCT; - return result; -} - -function B32 -is_enum(Ast_Resolved_Type *type){ - B32 result = type->kind == TYPE_ENUM; - return result; -} - -function B32 -is_pointer(Ast_Resolved_Type *type){ - B32 result = type->kind == TYPE_POINTER; - return result; -} +force_inline B32 is_string(Ast_Resolved_Type *type){return type->kind == TYPE_STRING;} +force_inline B32 is_int(Ast_Resolved_Type *type){return type->kind == TYPE_INT;} +force_inline B32 is_struct(Ast_Resolved_Type *type){return type->kind == TYPE_STRUCT;} +force_inline B32 is_array(Ast_Resolved_Type *type){return type->kind == TYPE_ARRAY;} +force_inline B32 is_enum(Ast_Resolved_Type *type){return type->kind == TYPE_ENUM;} +force_inline B32 is_pointer(Ast_Resolved_Type *type){return type->kind == TYPE_POINTER;} function Ast_Resolved_Type * type_new(Allocator *allocator, Ast_Resolved_Type_Kind kind, SizeU size, SizeU align){ diff --git a/order1.kl b/order1.kl index b224a73..86b6518 100644 --- a/order1.kl +++ b/order1.kl @@ -9,7 +9,7 @@ recursive_lambda :: (thing: int) const_in_lambda :: 10 not_const := val + 10 -val := 10 +val := CONSTANT_VAL DEPENDENCE :: CONSTANT_VAL CONSTANT_VAL :: 10 diff --git a/order2.kl b/order2.kl index a9778cb..2fc7e1a 100644 --- a/order2.kl +++ b/order2.kl @@ -2,16 +2,16 @@ Str16 :: String16 arena_pointer: *Arena = null thing: Arena no_type := thing +constant_access := Arena.constant_inside arena := Arena( next = null, data = null, len = 1000, cap = 1000, - // constant_inside = 10, ) -// lambda_value := (val: int) // What to do with this??? +// lambda_value := (val: int) // What to do with this??? // return Arena :: struct diff --git a/typechecking.cpp b/typechecking.cpp index d8f6700..97fbbcf 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -198,7 +198,7 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ CASE(RETURN, Return){ // @todo: need to check if all paths return a value Operand op = {}; if(node->expr) op = resolve_expr(node->expr); - if(!op.type && ret != type_void) parsing_error(node->pos, "Function expects a void return value but the returned value is [x]"); + if(!op.type && ret != type_void) parsing_error(node->pos, "Function expects a void return value but the returned value is [%s]", type_names[op.type->kind]); if(op.type && op.type != ret) parsing_error(node->pos, "Return statement has different type then returned value"); BREAK(); @@ -277,6 +277,23 @@ require_const_int(Ast_Expr *expr, B32 ast_can_be_null){ return op; } +#define rewrite_into_const(ast,T,sym) _rewrite_into_const(ast,sizeof(T),sym) +function void +_rewrite_into_const(Ast *node, U64 ast_size, Sym *sym){ + auto ast = (Ast_Atom *)node; + assert(ast_size >= sizeof(Ast_Atom)); + if(sym->type == type_int){ + ast->kind = AST_INT; + ast->int_val = sym->int_val; + } else if(sym->type == type_string){ + ast->kind = AST_STR; + ast->intern_val = sym->intern_val; + } else if(sym->type == type_bool){ + ast->kind = AST_INT; + ast->int_val = sym->int_val; + } else invalid_codepath; +} + function Operand resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ if(!ast) return {}; // @todo: add option for better error prevention @@ -298,8 +315,6 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ CASE(IDENT, Atom){ Sym *sym = resolve_name(node->pos, node->intern_val); - - // @cleanup: due to Value being a union this portion probably can get cleaned // @note: check if null and rewrite the expression to match the expected type Operand result = {}; if(sym->type->kind == TYPE_NULL){ @@ -307,9 +322,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ result.type = expected_type; result.is_const = true; } - else if(sym->kind == SYM_CONST || sym->kind == SYM_VAR){ + else if(sym->kind == SYM_CONST && sym->type != type_type && sym->type->kind != TYPE_LAMBDA){ result = operand(sym); - sym_new_resolved(SYM_CONST, sym->name, sym->type, sym->value, node); + rewrite_into_const(node, Ast_Atom, sym); + } + else if(sym->kind == SYM_VAR || sym->kind == SYM_CONST){ + result = operand(sym); + sym_new_resolved(sym->kind, sym->name, sym->type, sym->value, node); } else invalid_codepath; @@ -663,20 +682,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Ast_Enum_Member *query = query_enum(enu, ident->intern_val); if(query){ Sym *resolved = resolved_get(query); - assert(resolved); - // @warning: rewrite entire node into a constant - { - Ast_Atom *rewrite = (Ast_Atom *)node; - static_assert(sizeof(Ast_Binary) > sizeof(Ast_Atom), "This wont work"); - if(resolved->type == type_int){ - rewrite->kind = AST_INT; - rewrite->int_val = resolved->int_val; - } else if(resolved->type == type_string){ - rewrite->kind = AST_STR; - rewrite->intern_val = resolved->intern_val; - } else invalid_codepath; - } + rewrite_into_const(node, Ast_Binary, resolved); result = operand(resolved); } } @@ -689,15 +696,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ assert(sym); // @warning rewriting nodes with constant values if(sym->kind == SYM_CONST){ - Ast_Atom *rewrite = (Ast_Atom *)node; - static_assert(sizeof(Ast_Binary) > sizeof(Ast_Atom), "This wont work"); - if(sym->type == type_int){ - rewrite->kind = AST_INT; - rewrite->int_val = sym->int_val; - } else if(sym->type == type_string){ - rewrite->kind = AST_STR; - rewrite->intern_val = sym->intern_val; - } else invalid_codepath; + rewrite_into_const(node, Ast_Binary, sym); } else{ sym_new_resolved(sym->kind, {}, sym->type, sym->value, ident);