From ef9c2f4ee542403325c089a12231f409eb495b3f Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Tue, 31 May 2022 15:53:49 +0200 Subject: [PATCH] Cleanup --- main.cpp | 3 +- order2.kl | 6 +-- typechecking.cpp | 125 ++++++++++++++++++++++------------------------- 3 files changed, 63 insertions(+), 71 deletions(-) diff --git a/main.cpp b/main.cpp index e36b2da..9c931be 100644 --- a/main.cpp +++ b/main.cpp @@ -48,6 +48,7 @@ For now I don't thing it should be overloadable. [ ] - For loop [ ] - Switch [ ] - More basic types +[ ] - Array of inferred size [ ] - Lexer: Need to insert scope endings when hitting End of file [ ] - Add single line lambda expressions @@ -88,9 +89,9 @@ int main(){ String result = {}; result = compile_file("globals.kl"_s); result = compile_file("enums.kl"_s); - result = compile_file("order2.kl"_s); result = compile_file("lambdas.kl"_s); result = compile_file("order1.kl"_s); + result = compile_file("order2.kl"_s); printf("%s", result.str); __debugbreak(); diff --git a/order2.kl b/order2.kl index 2fc7e1a..4629b40 100644 --- a/order2.kl +++ b/order2.kl @@ -11,7 +11,7 @@ arena := Arena( cap = 1000, ) -// lambda_value := (val: int) // What to do with this??? +// lambda_value := (val: int) // @todo // return Arena :: struct @@ -21,13 +21,13 @@ Arena :: struct len : int cap : int - get_len :: (s: *Arena): int + get_len :: (s: *Arena): int // @todo return s.next.len - constant_inside :: 10000 + string16: Str16 String16 :: struct diff --git a/typechecking.cpp b/typechecking.cpp index 97fbbcf..182e3b1 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -13,9 +13,9 @@ enum Sym_State{ SYM_RESOLVED, }; -#define VALUE_FIELDS \ - S64 int_val; \ - Intern_String intern_val; \ +#define VALUE_FIELDS \ + S64 int_val; \ + Intern_String intern_val; \ Ast_Resolved_Type *type_val; #define INLINE_VALUE_FIELDS union{Value value; union{VALUE_FIELDS};} @@ -37,10 +37,6 @@ struct Operand{ INLINE_VALUE_FIELDS; }; -enum{ - AST_CANT_BE_NULL = 0, - AST_CAN_BE_NULL = 1 -}; struct Typecheck_Ctx{ // @todo Ast_Resolved_Type *required_type; @@ -48,6 +44,7 @@ struct Typecheck_Ctx{ // @todo B32 expr_can_be_null; }; +enum{AST_CANT_BE_NULL = 0, AST_CAN_BE_NULL = 1}; function Ast_Resolved_Type *resolve_typespec(Ast_Expr *ast, B32 ast_can_be_null = AST_CANT_BE_NULL); function Sym *resolve_name(Token *pos, Intern_String name); function Operand resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0, Sym *const_sym = 0); @@ -93,20 +90,26 @@ scope_close(S64 local_sym_count){ pctx->local_syms.len = local_sym_count; } +function void +sym_associate(Ast *ast, Sym *sym){ + assert(ast); + assert(sym); + map_insert(&pctx->resolved, ast, sym); +} + function Sym * -sym_new(Sym_Kind kind, Intern_String name, Ast *ast){ +sym_new(Sym_Kind kind, Intern_String name, Ast *ast, B32 associate = true){ Sym *result = exp_alloc_type(pctx->perm, Sym, AF_ZeroMemory); result->name = name; result->kind = kind; result->ast = ast; - assert(ast); - map_insert(&pctx->resolved, ast, result); + if(associate) sym_associate(ast, result); return result; } function Sym * -sym_new_resolved(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value value, Ast *ast){ - Sym *result = sym_new(kind, name, ast); +sym_new_resolved(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value value, Ast *ast, B32 associate = true){ + Sym *result = sym_new(kind, name, ast, associate); result->type = type; result->state = SYM_RESOLVED; result->value = value; @@ -129,11 +132,24 @@ resolved_type_get(Ast_Expr *ast){ return result->type_val; } +function Sym * +sym_type(Ast *ast, Ast_Resolved_Type *type, Intern_String name = {}, B32 associate = true){ + Value value; value.type_val = type; + Sym *result = sym_new_resolved(SYM_CONST, name, type_type, value, ast, associate); + return result; +} + +function Sym * +sym_insert(Sym_Kind kind, Intern_String name, Ast_Resolved_Type *type, Value value, Ast *ast){ + Sym *sym = sym_new_resolved(kind, name, type, value, ast); + sym_insert(sym); + return sym; +} + function void sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ Intern_String string = intern_string(&pctx->interns, name); - Value val; val.type_val = type; - Sym *sym = sym_new_resolved(SYM_CONST, string, type_type, val, &empty_decl); + Sym *sym = sym_type(&empty_decl, type, string, false); sym_insert(sym); } @@ -147,21 +163,21 @@ sym_insert_builtins(){ { Intern_String string = intern_string(&pctx->interns, "true"_s); Value val; val.int_val = 1; - Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl); + Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl, false); sym_insert(sym); } { Intern_String string = intern_string(&pctx->interns, "false"_s); Value val; val.int_val = 0; - Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl); + Sym *sym = sym_new_resolved(SYM_CONST, string, type_bool, val, &empty_decl, false); sym_insert(sym); } { Intern_String string = intern_string(&pctx->interns, "null"_s); Value val; val.int_val = 0; - Sym *sym = sym_new_resolved(SYM_CONST, string, type_null, val, &empty_decl); + Sym *sym = sym_new_resolved(SYM_CONST, string, type_null, val, &empty_decl, false); sym_insert(sym); } } @@ -194,13 +210,13 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){ function void resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ + if(!ast) return; + switch(ast->kind){ CASE(RETURN, Return){ // @todo: need to check if all paths return a value - Operand op = {}; - if(node->expr) op = resolve_expr(node->expr); + Operand 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 [%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(); } @@ -232,12 +248,10 @@ resolve_stmt(Ast *ast, Ast_Resolved_Type *ret){ CASE(IF, If){ For(node->ifs){ - if(it->init) resolve_stmt(it->init, ret); - if(it->expr) resolve_expr(it->expr); + resolve_stmt(it->init, ret); + resolve_expr(it->expr); // @todo: typechecking S64 scope_index = scope_open(); - For_It(it->block->stmts, jt){ - resolve_stmt(jt, ret); - } + For_It(it->block->stmts, jt) resolve_stmt(jt, ret); scope_close(scope_index); } BREAK(); @@ -266,18 +280,14 @@ operand_type(Ast_Resolved_Type *type){ function Operand require_const_int(Ast_Expr *expr, B32 ast_can_be_null){ Operand op = resolve_expr(expr); - if(expr == 0 && ast_can_be_null){ - return op; - } + if(expr == 0 && ast_can_be_null) return op; else if(expr == 0) parsing_error(expr->pos, "This field cannot be null"); - if(!op.is_const) parsing_error(expr->pos, "Expected a const value"); if(op.type != type_int) parsing_error(expr->pos, "Expected a constant integer"); 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; @@ -293,6 +303,7 @@ _rewrite_into_const(Ast *node, U64 ast_size, Sym *sym){ ast->int_val = sym->int_val; } else invalid_codepath; } +#define rewrite_into_const(ast,T,sym) _rewrite_into_const(ast,sizeof(T),sym) function Operand resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ @@ -315,8 +326,8 @@ 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); - // @note: check if null and rewrite the expression to match the expected type Operand result = {}; + // @note: check if null and rewrite the expression to match the expected type if(sym->type->kind == TYPE_NULL){ if(!expected_type) parsing_error(node->pos, "Couldn't infer type of null"); result.type = expected_type; @@ -328,7 +339,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_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); + sym_associate(node, sym); } else invalid_codepath; @@ -339,12 +350,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ CASE(ARRAY, Array){ Operand type = resolve_expr(node->base); if(type.type != type_type) parsing_error(node->pos, "Prefix array operator is only allowed on types"); - Operand expr = resolve_expr(node->expr); - if(!expr.is_const) parsing_error(node->pos, "Array operator requires a constant value"); - if(expr.type != type_int) parsing_error(node->pos, "Array index requires type [Int]"); + Operand expr = require_const_int(node->expr, AST_CANT_BE_NULL); // @todo: type.type_val = type_array(type.type_val, expr.int_val); - sym_new_resolved(SYM_CONST, {}, type_type, type.value, node); + sym_type(node, type.type_val); return type; BREAK(); } @@ -364,9 +373,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ op.int_val = value++; } - - Sym *arg_sym = sym_new_resolved(SYM_CONST, it->name, op.type, op.value, it); - sym_insert(arg_sym); + sym_insert(SYM_CONST, it->name, op.type, op.value, it); } scope_close(scope_index); @@ -390,9 +397,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ lambda_type = type_lambda(node, ret_type, args); { - assert(lambda_type); - Value val; val.type_val = lambda_type; - sym_new_resolved(SYM_CONST, {}, type_type, val, node); + sym_type(node, lambda_type); if(const_sym){ const_sym->type = lambda_type; const_sym->state = SYM_RESOLVED; @@ -408,9 +413,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ For(node->args){ S64 i = node->args.get_index(&it); Ast_Resolved_Type *type = args[i]; - - Sym *arg_sym = sym_new_resolved(SYM_VAR, it->name, type, {}, it); - sym_insert(arg_sym); + sym_insert(SYM_VAR, it->name, type, {}, it); } For(node->block->stmts){ resolve_stmt(it, ret_type); @@ -633,16 +636,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ required_to_be_const = true; } // @copy_paste - if(is_pointer(type)){ - type = type->base; - } + if(is_pointer(type)) type = type->base; type_complete(type); - if(!(is_struct(type) || is_enum(type))){ - parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); - } + if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); sym_new_resolved(SYM_VAR, {}, resolved_ident.type, {}, node->left); // This happens only on binary nodes which further chain with dots and require lookups + // This part cant happen on enums // x.resolve.y Ast_Binary *binary = (Ast_Binary *)node->right; for(;!is_ident(binary); binary=(Ast_Binary *)binary->right){ @@ -652,24 +652,20 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Ast_Struct *agg = (Ast_Struct *)type->ast; Ast *query = query_struct(agg, ident->intern_val); - // @copy_paste if(query){ Sym *sym = resolved_get(query); if(required_to_be_const && sym->kind != SYM_CONST) parsing_error(ident->pos, "Required to be constant"); type = sym->type; + // @copy_paste if(type == type_type){ required_to_be_const = true; type = sym->type_val; } - if(is_pointer(type)){ - type = type->base; - } + if(is_pointer(type)) type = type->base; type_complete(type); - if(!(is_struct(type) || is_enum(type))){ - parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); - } + if(!(is_struct(type) || is_enum(type))) parsing_error(node->pos, "Trying to access inside a value that is not a struct or enum"); + sym_associate(ident, sym); - sym_new_resolved(sym->kind, {}, sym->type, sym->value, ident); } else parsing_error(ident->pos, "No such member in struct"); } @@ -694,13 +690,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ Sym *sym = resolved_get(query); result = operand(sym); assert(sym); - // @warning rewriting nodes with constant values - if(sym->kind == SYM_CONST){ - rewrite_into_const(node, Ast_Binary, sym); - } - else{ - sym_new_resolved(sym->kind, {}, sym->type, sym->value, ident); - } + if(sym->kind == SYM_CONST) rewrite_into_const(node, Ast_Binary, sym); + else sym_associate(ident, sym); } else parsing_error(ident->pos, "No such member in struct"); } @@ -746,7 +737,7 @@ resolve_binding(Ast *ast, Sym *sym){ switch(ast->kind){ CASE(VAR, Var){ Ast_Resolved_Type *type = resolve_typespec(node->typespec, AST_CAN_BE_NULL); - Operand expr = node->expr ? resolve_expr(node->expr, type) : Operand{}; + Operand expr = resolve_expr(node->expr, type); expr.type = resolve_type_pair(node->pos, type, expr.type); type_complete(expr.type); return expr;