diff --git a/ccodegen.cpp b/ccodegen.cpp index 4aad217..6dc19d9 100644 --- a/ccodegen.cpp +++ b/ccodegen.cpp @@ -278,9 +278,22 @@ gen_ast(Ast *ast){ gen("String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str); } else if(sym->type == type_type){ - gen("// typedef "); - gen_simple_decl(sym->type_val, node->name); - gen(";"); + 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]); + } + global_indent--; + genln("};"); + } + else{ + gen("// typedef "); + gen_simple_decl(sym->type_val, node->name); + gen(";"); + } } else{ parsing_error(node->pos, "C_Codegen: Unhandled type of constant expression"); diff --git a/main.cpp b/main.cpp index 1936598..d4bd39c 100644 --- a/main.cpp +++ b/main.cpp @@ -27,6 +27,7 @@ /// @todo /// [x] - Typespecs should probably be expressions so stuff like would be possible :: *[32]int +/// [ ] - Lexer: Need to insert scope endings when hitting End of file /// [ ] - Add single line lambda expressions/ /// [ ] - Think about compound expressions, unify with calls - maybe Thing(a=1) instead of Thing{a=1} /// [ ] - Structs diff --git a/new_ast.cpp b/new_ast.cpp index bc117e6..5489b16 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -76,7 +76,7 @@ thread_local Parse_Ctx *pctx; //----------------------------------------------------------------------------- // AST //----------------------------------------------------------------------------- -enum Ast_Kind{ +enum Ast_Kind: U32{ AST_NONE, AST_PACKAGE, @@ -108,6 +108,9 @@ enum Ast_Kind{ typedef U32 Ast_Flag; enum{ AST_EXPR = 1, + AST_STMT = 2, + AST_BINDING = 4, + AST_AGGREGATE = 8, }; struct Ast{ @@ -213,10 +216,9 @@ struct Ast_Array: Ast_Expr{ Ast_Expr *expr; }; -struct Ast_Struct: Ast{ +struct Ast_Struct: Ast_Expr{ // Required to be Ast_Struct or Ast_Var or Ast_Const Array members; - }; struct Ast_Named:Ast{ @@ -229,7 +231,7 @@ struct Ast_Var: Ast_Named{ }; struct Ast_Const: Ast_Named{ - Ast *value; + Ast_Expr *value; }; struct Ast_Package:Ast{ @@ -241,40 +243,37 @@ struct Ast_Package:Ast{ //----------------------------------------------------------------------------- // AST Constructors beginning with expressions //----------------------------------------------------------------------------- -#define AST_NEW(T,ikind,ipos) \ +#define AST_NEW(T,ikind,ipos,iflags) \ Ast_##T *result = exp_alloc_type(pctx->perm, Ast_##T, AF_ZeroMemory);\ + result->flags = iflags; \ result->kind = AST_##ikind; \ result->pos = ipos; \ result->id = ++pctx->unique_ids function Ast_Atom * ast_str(Token *pos, Intern_String string, Ast_Flag flags = 0){ - AST_NEW(Atom, STR, pos); - result->flags = flags; + AST_NEW(Atom, STR, pos,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); - result->flags = flags; + AST_NEW(Atom, IDENT, pos,flags); result->intern_val = string; return result; } function Ast_Atom * -ast_int(Token *pos, S64 integer, Ast_Flag flags){ - AST_NEW(Atom, INT, pos); - result->flags = flags; +ast_int(Token *pos, S64 integer, Ast_Flag flags = 0){ + AST_NEW(Atom, INT, pos,flags); result->int_val = integer; return result; } function Ast_Expr * ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ - AST_NEW(Binary, BINARY, op); - result->flags = AST_EXPR; + AST_NEW(Binary, BINARY, op, AST_EXPR); result->op = op->kind; result->left = left; result->right = right; @@ -285,8 +284,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ function Ast_Compound * ast_expr_compound(Token *pos, Ast_Expr *typespec, Array exprs){ - AST_NEW(Compound, COMPOUND, pos); - result->flags = AST_EXPR; + AST_NEW(Compound, COMPOUND, pos, AST_EXPR); result->typespec = typespec; result->exprs = exprs.tight_copy(pctx->perm); if(result->typespec) result->typespec->parent = result; @@ -296,8 +294,7 @@ ast_expr_compound(Token *pos, Ast_Expr *typespec, Array exp function Ast_Compound_Item * ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){ - AST_NEW(Compound_Item, COMPOUND_ITEM, pos); - result->flags = AST_EXPR; + AST_NEW(Compound_Item, COMPOUND_ITEM, pos, AST_EXPR); result->name = name; result->index = index; result->item = item; @@ -309,7 +306,7 @@ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *it function Ast_Expr * ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){ - AST_NEW(Cast, CAST, pos); + AST_NEW(Cast, CAST, pos, AST_EXPR); result->flags = AST_EXPR; result->expr = expr; result->typespec = typespec; @@ -320,7 +317,7 @@ ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){ function Ast_Expr * ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){ - AST_NEW(Unary, UNARY, pos); + AST_NEW(Unary, UNARY, pos, AST_EXPR); result->flags = AST_EXPR; result->expr = expr; result->op = op; @@ -330,7 +327,7 @@ ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){ function Ast_Expr * ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ - AST_NEW(Index, INDEX, pos); + AST_NEW(Index, INDEX, pos, AST_EXPR); result->flags = AST_EXPR; result->expr = expr; result->index = index; @@ -341,7 +338,7 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ function Ast_Lambda * ast_lambda(Token *pos, Array params, Ast_Expr *ret, Ast_Block *block){ - AST_NEW(Lambda, LAMBDA, pos); + AST_NEW(Lambda, LAMBDA, pos, AST_EXPR); result->flags = AST_EXPR; result->args = params.tight_copy(pctx->perm); result->block = block; @@ -356,7 +353,7 @@ ast_lambda(Token *pos, Array params, Ast_Expr *ret, Ast_Block function Ast_Lambda_Arg * ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Expr *typespec){ - AST_NEW(Lambda_Arg, LAMBDA_ARG, pos); + AST_NEW(Lambda_Arg, LAMBDA_ARG, pos, AST_EXPR); result->flags = AST_EXPR; result->name = name; result->typespec = typespec; @@ -366,7 +363,7 @@ ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Expr *typespec){ function Ast_Block * ast_block(Token *pos, Array stmts){ - AST_NEW(Block, BLOCK, pos); + AST_NEW(Block, BLOCK, pos, AST_STMT); result->stmts = stmts.tight_copy(pctx->perm); For(result->stmts) it[0]->parent = result; return result; @@ -374,15 +371,26 @@ ast_block(Token *pos, Array stmts){ function Ast_If * ast_if(Token *pos, Array ifs){ - AST_NEW(If, IF, pos); + AST_NEW(If, IF, pos, AST_STMT); result->ifs = ifs.tight_copy(pctx->perm); For(result->ifs) it[0]->parent = result; return result; } +function Ast_Return * +ast_return(Token *pos, Ast_Expr *expr){ + AST_NEW(Return, RETURN, pos, AST_STMT); + if(expr){ + assert(is_flag_set(expr->flags, AST_EXPR)); + result->expr = expr; + result->expr->parent = result; + } + return result; +} + function Ast_If_Node * ast_if_node(Token *pos, Ast_Init *init, Ast_Expr *expr, Ast_Block *block){ - AST_NEW(If_Node, IF_NODE, pos); + AST_NEW(If_Node, IF_NODE, pos, AST_STMT); result->block = block; result->expr = expr; result->init = init; @@ -394,7 +402,7 @@ ast_if_node(Token *pos, Ast_Init *init, Ast_Expr *expr, Ast_Block *block){ function Ast_Init * ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){ - AST_NEW(Init, INIT, pos); + AST_NEW(Init, INIT, pos, AST_STMT); result->op = op; result->ident = ident; result->expr = expr; @@ -405,7 +413,7 @@ ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){ function Ast_Array * ast_array(Token *pos, Ast_Expr *expr){ - AST_NEW(Array, ARRAY, pos); + AST_NEW(Array, ARRAY, pos, AST_EXPR); result->flags = AST_EXPR; result->expr = expr; result->expr->parent = result; @@ -414,7 +422,7 @@ ast_array(Token *pos, Ast_Expr *expr){ function Ast_Struct * ast_struct(Token *pos, Array members){ - AST_NEW(Struct, STRUCT, pos); + AST_NEW(Struct, STRUCT, pos, AST_AGGREGATE); result->members = members.tight_copy(pctx->perm); For(result->members) { assert(it[0]->kind == AST_VAR || it[0]->kind == AST_CONST || it[0]->kind == AST_STRUCT); @@ -428,7 +436,7 @@ ast_struct(Token *pos, Array members){ //----------------------------------------------------------------------------- function Ast_Var * ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){ - AST_NEW(Var, VAR, pos); + AST_NEW(Var, VAR, pos, AST_BINDING); result->expr = expr; result->typespec = typespec; result->name = name; @@ -438,8 +446,8 @@ ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){ } function Ast_Const * -ast_const(Token *pos, Intern_String name, Ast *value){ - AST_NEW(Const, CONST, pos); +ast_const(Token *pos, Intern_String name, Ast_Expr *value){ + AST_NEW(Const, CONST, pos, AST_BINDING); assert(value->kind == AST_STRUCT || is_flag_set(value->flags, AST_EXPR)); result->value = value; @@ -450,7 +458,7 @@ ast_const(Token *pos, Intern_String name, Ast *value){ function Ast_Package * ast_package(Token *pos, String name, Array decls){ - AST_NEW(Package, PACKAGE, pos); + AST_NEW(Package, PACKAGE, pos, 0); result->decls = decls.tight_copy(pctx->perm); result->ordered = array_make(pctx->perm, decls.len); result->name = intern_string(&pctx->interns, name); diff --git a/new_parse.cpp b/new_parse.cpp index df43d92..94856c3 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -204,9 +204,10 @@ parse_block(){ do{ Token *token = token_get(); if(token_match_keyword(keyword_return)){ - AST_NEW(Return, RETURN, token); - if(!token_is_scope()) result->expr = parse_expr(); - stmts.add(result); + Ast_Expr *expr = 0; + if(!token_is_scope()) expr = parse_expr(); + Ast_Return *return_stmt = ast_return(token, expr); + stmts.add(return_stmt); } else if(token_match_keyword(keyword_if)){ Array if_nodes = {scratch}; @@ -396,6 +397,7 @@ parse_struct(Token *pos){ Token *token = token_get(); Ast_Named *named = parse_named(false); if(!named) parsing_error(token, "Failed to parse struct member"); + members.add(named); }while(token_match(SAME_SCOPE)); token_expect(CLOSE_SCOPE); diff --git a/new_resolve.cpp b/new_resolve.cpp index d939ac8..999c6ab 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -171,7 +171,7 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){ return result; } -function Operand eval_decl(Ast *ast, Sym *sym = 0); +function Operand eval_binding(Ast *ast, Sym *sym = 0); function void eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ switch(ast->kind){ @@ -185,14 +185,14 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ } Ast_Begin(AST_VAR, Ast_Var){ - Operand op = eval_decl(node); + Operand op = eval_binding(node); Sym *sym = sym_new_resolved(SYM_VAR, node->name, op.type, op.value, node); sym_insert(sym); Ast_End(); } Ast_Begin(AST_CONST, Ast_Const){ - Operand op = eval_decl(node); + Operand op = eval_binding(node); Sym *sym = sym_new_resolved(SYM_CONST, node->name, op.type, op.value, node); sym_insert(sym); Ast_End(); @@ -484,6 +484,28 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple Ast_End(); } + Ast_Begin(AST_STRUCT, Ast_Struct){ + Scratch scratch; + Array members = {scratch}; + For(node->members){ + Operand op = eval_binding(it[0]); + + Intern_String name = {}; + if(is_flag_set(it[0]->flags, AST_BINDING)){ + Ast_Named *named = (Ast_Named *)it[0]; + name = named->name; + } + + sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]); + members.add({op.type, name}); + } + Ast_Resolved_Type *resolved = type_struct(members); + Operand result = {type_type, true}; result.type_val = resolved; + return result; + + Ast_End(); + } + invalid_default_case; } @@ -491,7 +513,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple } function Operand -eval_decl(Ast *ast, Sym *sym){ +eval_binding(Ast *ast, Sym *sym){ switch(ast->kind){ Ast_Begin(AST_VAR, Ast_Var){ @@ -538,7 +560,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, sym); + Operand op = eval_binding(sym->ast, sym); sym->type = op.type; if(sym->kind == SYM_CONST){ assert(op.is_const); diff --git a/new_type.cpp b/new_type.cpp index a38af7d..bebc8bd 100644 --- a/new_type.cpp +++ b/new_type.cpp @@ -32,6 +32,12 @@ const char *type_names[] = { "[Type]", }; +struct Ast_Resolved_Type_Field{ + Ast_Resolved_Type *type; + Intern_String name; + U64 offset; +}; + struct Ast_Resolved_Type{ Ast_Resolved_Type_Kind kind; SizeU size; @@ -42,6 +48,9 @@ struct Ast_Resolved_Type{ Ast_Resolved_Type *base; SizeU size; }arr; + struct{ + Array fields; + }agg; struct{ Ast_Resolved_Type *ret; Array args; @@ -135,6 +144,13 @@ type_lambda(Ast_Resolved_Type *ret, Array args){ return result; } +function Ast_Resolved_Type * +type_struct(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); + return result; +} + function void test_types(){ Scratch scratch; diff --git a/structs.kl b/structs.kl index e69de29..1d64196 100644 --- a/structs.kl +++ b/structs.kl @@ -0,0 +1,6 @@ + +Arena :: struct + data: *int + len : int + cap : int +