diff --git a/ccodegen.cpp b/ccodegen.cpp index 6dc19d9..0108f75 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -28,6 +28,10 @@ gen_simple_decl_prefix(Ast_Resolved_Type *ast){ case TYPE_Pointer:{gen_simple_decl_prefix(ast->base); gen("*");} break; case TYPE_Array: gen_simple_decl_prefix(ast->base); break; case TYPE_Lambda:break; + case TYPE_Struct: { + auto name = ast->sym->name; + gen("%s ", name.str); + }break; invalid_default_case; } } @@ -43,6 +47,7 @@ gen_simple_decl_postfix(Ast_Resolved_Type *ast){ case TYPE_Pointer: gen_simple_decl_postfix(ast->base); break; case TYPE_Array: gen("[%d]", (int)ast->arr.size); gen_simple_decl_postfix(ast->arr.base); break; case TYPE_Lambda:break; + case TYPE_Struct:break; invalid_default_case; } } @@ -279,15 +284,20 @@ gen_ast(Ast *ast){ } else if(sym->type == type_type){ if(sym->type_val->kind == TYPE_Struct){ - Ast_Struct *agg = (Ast_Struct *)node->value; - gen("struct %s{", node->name.str); - global_indent++; - For(agg->members){ - genln(""); - gen_ast(it[0]); + Ast_Struct *agg = const_get_struct(sym->type_val->sym->ast); + if(node->value->kind == AST_STRUCT){ + gen("struct %s{", node->name.str); + global_indent++; + For(agg->members){ + genln(""); + gen_ast(it[0]); + } + global_indent--; + genln("};"); + } + else{ + // type alias } - global_indent--; - genln("};"); } else{ gen("// typedef "); diff --git a/main.cpp b/main.cpp index d4bd39c..6735718 100644 --- a/main.cpp +++ b/main.cpp @@ -48,8 +48,8 @@ int main(){ test_intern_table(); lex_test(); - // String result = compile_file("globals.kl"_s); - String result = compile_file("structs.kl"_s); + String result = compile_file("globals.kl"_s); + // String result = compile_file("structs.kl"_s); // String result = compile_file("order_independent_globals.kl"_s); printf("%s", result.str); diff --git a/new_ast.cpp b/new_ast.cpp index 5489b16..ff49ba1 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -111,6 +111,7 @@ enum{ AST_STMT = 2, AST_BINDING = 4, AST_AGGREGATE = 8, + AST_ATOM = 16, }; struct Ast{ @@ -120,12 +121,6 @@ struct Ast{ Ast_Kind kind; Ast *parent; Ast_Flag flags; - // @todo? - // bool is_atom: 1; - // bool is_stmt: 1; - // bool is_decl: 1; - // bool is_expr: 1; - // bool is_named: 1; }; struct Ast_Resolved_Type; @@ -252,21 +247,21 @@ struct Ast_Package:Ast{ function Ast_Atom * ast_str(Token *pos, Intern_String string, Ast_Flag flags = 0){ - AST_NEW(Atom, STR, pos,flags); + AST_NEW(Atom, STR, pos, AST_ATOM | flags); result->intern_val = string; return result; } function Ast_Atom * ast_ident(Token *pos, Intern_String string, Ast_Flag flags = 0){ - AST_NEW(Atom, IDENT, pos,flags); + AST_NEW(Atom, IDENT, pos, AST_ATOM | flags); result->intern_val = string; return result; } function Ast_Atom * ast_int(Token *pos, S64 integer, Ast_Flag flags = 0){ - AST_NEW(Atom, INT, pos,flags); + AST_NEW(Atom, INT, pos, AST_ATOM | flags); result->int_val = integer; return result; } diff --git a/new_resolve.cpp b/new_resolve.cpp index 999c6ab..1a56e25 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -153,6 +153,19 @@ 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, Sym *lambda_to_complete = 0); +enum{ + AST_CANT_BE_NULL = 0, + AST_CAN_BE_NULL = 1 +}; + +function Ast_Resolved_Type * +eval_typespec(Ast_Expr *ast, B32 ast_can_be_null = AST_CANT_BE_NULL){ + if(ast_can_be_null && ast == 0) return 0; + Operand resolved = eval_expr(ast); + if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", resolved.type->kind); + return resolved.type_val; +} + function Ast_Resolved_Type * resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){ Ast_Resolved_Type *result = 0; @@ -227,18 +240,6 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ } } -enum{ - AST_CAN_BE_NULL = 1 -}; - -function Ast_Resolved_Type * -eval_typespec(Ast_Expr *ast, B32 ast_can_be_null){ - if(ast_can_be_null && ast == 0) return 0; - Operand resolved = eval_expr(ast); - if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", resolved.type->kind); - return resolved.type_val; -} - function Operand eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_complete){ switch(ast->kind){ @@ -266,33 +267,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple if(!expected_type) parsing_error(node->pos, "Couldn't infer type of null"); result.type = expected_type; result.is_const = true; - if(expected_type == type_int){ - result.int_val = 0; - node->kind = AST_INT; - node->int_val = 0; - } - else if(expected_type->kind == TYPE_Pointer){ - result.int_val = 0; - node->kind = AST_IDENT; - node->intern_val = pctx->intern("NULL_POINTER"_s); - } - else if(expected_type->kind == TYPE_Lambda){ - result.int_val = 0; - node->kind = AST_IDENT; - node->intern_val = pctx->intern("NULL_LAMBDA"_s); - } - else if(expected_type == type_bool){ - result.int_val = 0; - node->kind = AST_IDENT; - node->intern_val = pctx->intern("false"_s); - } - else if(expected_type == type_string){ - result.intern_val = pctx->intern(""_s); - node->kind = AST_STR; - node->intern_val = result.intern_val; - } } - else if(sym->kind == SYM_CONST || sym->kind == SYM_VAR){ result.type = sym->type; result.is_const = sym->kind == SYM_CONST ? true : false; @@ -322,15 +297,14 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple // @note: first resolve type of lambda Scratch scratch; Ast_Resolved_Type *lambda_type = 0; - Operand ret_op = eval_expr(node->ret); + Ast_Resolved_Type *ret_type = eval_typespec(node->ret); Array args = {scratch}; - if(ret_op.type != type_type) parsing_error(node->pos, "Return type of [Lambda] should be a [Type] not %s", ret_op.type); For(node->args){ Operand type = eval_expr(it[0]->typespec); if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]"); args.add(type.type_val); } - lambda_type = type_lambda(ret_op.type_val, args); + lambda_type = type_lambda(ret_type, args); { assert(lambda_type); Value val; val.type_val = lambda_type; @@ -355,7 +329,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple sym_insert(arg_sym); } For(node->block->stmts){ - eval_stmt(it[0], ret_op.type_val); + eval_stmt(it[0], ret_type); } scope_close(scope_index); result.type = lambda_type; @@ -410,9 +384,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Ast_Begin(AST_CAST, Ast_Cast){ Operand expr = eval_expr(node->expr); - Operand typespec = eval_expr(node->typespec); - if(typespec.type != type_type) parsing_error(node->pos, "Expected type in left of cast got instead %s", type_names[typespec.type->kind]); - Ast_Resolved_Type *type = typespec.type_val; + Ast_Resolved_Type *type = eval_typespec(node->typespec); if(type == expr.type) return expr; @@ -484,7 +456,10 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Ast_End(); } + // @todo: add const prepass? expecting only structs, exprs, lambdas Ast_Begin(AST_STRUCT, Ast_Struct){ + assert(lambda_to_complete); + Scratch scratch; Array members = {scratch}; For(node->members){ @@ -499,7 +474,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]); members.add({op.type, name}); } - Ast_Resolved_Type *resolved = type_struct(members); + Ast_Resolved_Type *resolved = type_struct(lambda_to_complete, members); Operand result = {type_type, true}; result.type_val = resolved; return result; @@ -517,10 +492,9 @@ eval_binding(Ast *ast, Sym *sym){ switch(ast->kind){ Ast_Begin(AST_VAR, Ast_Var){ - Operand type = node->typespec ? eval_expr(node->typespec) : Operand{}; - if(type.type && (type.type != type_type)) parsing_error(node->typespec->pos, "Expected [Type] got instead %s", type_names[type.type->kind]); - Operand expr = node->expr ? eval_expr(node->expr, type.type_val) : Operand{}; - expr.type = resolve_type_pair(node->pos, type.type_val, expr.type); + Ast_Resolved_Type *type = eval_typespec(node->typespec, AST_CAN_BE_NULL); + Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{}; + expr.type = resolve_type_pair(node->pos, type, expr.type); return expr; Ast_End(); } @@ -537,18 +511,12 @@ eval_binding(Ast *ast, Sym *sym){ } } -function Ast_Lambda * -ast_get_lambda(Ast *ast){ - if(ast->kind == AST_CONST){ - auto ast_const = (Ast_Const *)ast; - if(ast_const->value){ - auto ast_expr = ast_const->value; - if(ast_expr->kind == AST_LAMBDA){ - return (Ast_Lambda *)ast_expr; - } - } - } - return 0; +function Ast_Struct * +const_get_struct(Ast *ast){ + assert(ast->kind == AST_CONST); + Ast_Const *constant = (Ast_Const *)ast; + assert(constant->value->kind == AST_STRUCT); + return (Ast_Struct *)constant->value; } function void @@ -610,6 +578,13 @@ parse_file(){ else invalid_codepath; Sym *sym = sym_new(kind, decl->name, decl); + // if(kind == SYM_CONST){ + // auto constant = (Ast_Const *)decl; + // if(constant->value->kind == AST_STRUCT) { + // sym->type = type_incomplete(sym); + // sym->state = SYM_RESOLVED; + // } + // } sym_insert(sym); decls.add(decl); diff --git a/new_type.cpp b/new_type.cpp index bebc8bd..32f2958 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -1,6 +1,7 @@ enum Ast_Resolved_Type_Kind{ TYPE_None, TYPE_Null, + TYPE_Incomplete, TYPE_Int, TYPE_Bool, TYPE_Unsigned, @@ -18,6 +19,7 @@ enum Ast_Resolved_Type_Kind{ const char *type_names[] = { "[Invalid Ast_Resolved_Type]", "[Null]", + "[Incomplete]", "[Int]", "[Bool]", "[Unsigned]", @@ -42,6 +44,8 @@ struct Ast_Resolved_Type{ Ast_Resolved_Type_Kind kind; SizeU size; SizeU align; + + Sym *sym; union{ Ast_Resolved_Type *base; struct{ @@ -145,9 +149,23 @@ type_lambda(Ast_Resolved_Type *ret, Array args){ } function Ast_Resolved_Type * -type_struct(Array fields){ +type_incomplete(Sym *sym){ + Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_Incomplete, 0, 0); + result->sym = sym; + return result; +} + +function void +type_complete_struct(Ast_Resolved_Type *type, Array fields){ + type->agg.fields = fields.tight_copy(pctx->perm); + type->kind = TYPE_Struct; +} + +function Ast_Resolved_Type * +type_struct(Sym *sym, Array fields){ Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_Struct, 0, 0); // @todo: align,size result->agg.fields = fields.tight_copy(pctx->perm); + result->sym = sym; return result; } diff --git a/structs.kl b/structs.kl index 1d64196..e3ec23d 100644 --- a/structs.kl +++ b/structs.kl @@ -1,6 +1,22 @@ +arena_pointer: *Arena = null Arena :: struct +// next: *Arena data: *int len : int cap : int +string16: Str16 + +String16 :: struct + data: *void + len : int + +thing: Arena +no_type := thing +with_type: Arena = thing +pointer := &with_type +deref := *pointer + + +Str16 :: String16 \ No newline at end of file