Adding struts

This commit is contained in:
Krzosa Karol
2022-05-29 12:30:02 +02:00
parent 07b793aacc
commit ea1b74cda0
7 changed files with 112 additions and 44 deletions

View File

@@ -278,10 +278,23 @@ gen_ast(Ast *ast){
gen("String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str); gen("String %s = LIT(\"%s\");", node->name.str, sym->intern_val.str);
} }
else if(sym->type == type_type){ 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]);
}
global_indent--;
genln("};");
}
else{
gen("// typedef "); gen("// typedef ");
gen_simple_decl(sym->type_val, node->name); gen_simple_decl(sym->type_val, node->name);
gen(";"); gen(";");
} }
}
else{ else{
parsing_error(node->pos, "C_Codegen: Unhandled type of constant expression"); parsing_error(node->pos, "C_Codegen: Unhandled type of constant expression");
} }

View File

@@ -27,6 +27,7 @@
/// @todo /// @todo
/// [x] - Typespecs should probably be expressions so stuff like would be possible :: *[32]int /// [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/ /// [ ] - Add single line lambda expressions/
/// [ ] - Think about compound expressions, unify with calls - maybe Thing(a=1) instead of Thing{a=1} /// [ ] - Think about compound expressions, unify with calls - maybe Thing(a=1) instead of Thing{a=1}
/// [ ] - Structs /// [ ] - Structs

View File

@@ -76,7 +76,7 @@ thread_local Parse_Ctx *pctx;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// AST // AST
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
enum Ast_Kind{ enum Ast_Kind: U32{
AST_NONE, AST_NONE,
AST_PACKAGE, AST_PACKAGE,
@@ -108,6 +108,9 @@ enum Ast_Kind{
typedef U32 Ast_Flag; typedef U32 Ast_Flag;
enum{ enum{
AST_EXPR = 1, AST_EXPR = 1,
AST_STMT = 2,
AST_BINDING = 4,
AST_AGGREGATE = 8,
}; };
struct Ast{ struct Ast{
@@ -213,10 +216,9 @@ struct Ast_Array: Ast_Expr{
Ast_Expr *expr; Ast_Expr *expr;
}; };
struct Ast_Struct: Ast{ struct Ast_Struct: Ast_Expr{
// Required to be Ast_Struct or Ast_Var or Ast_Const // Required to be Ast_Struct or Ast_Var or Ast_Const
Array<Ast *> members; Array<Ast *> members;
}; };
struct Ast_Named:Ast{ struct Ast_Named:Ast{
@@ -229,7 +231,7 @@ struct Ast_Var: Ast_Named{
}; };
struct Ast_Const: Ast_Named{ struct Ast_Const: Ast_Named{
Ast *value; Ast_Expr *value;
}; };
struct Ast_Package:Ast{ struct Ast_Package:Ast{
@@ -241,40 +243,37 @@ struct Ast_Package:Ast{
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// AST Constructors beginning with expressions // 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);\ Ast_##T *result = exp_alloc_type(pctx->perm, Ast_##T, AF_ZeroMemory);\
result->flags = iflags; \
result->kind = AST_##ikind; \ result->kind = AST_##ikind; \
result->pos = ipos; \ result->pos = ipos; \
result->id = ++pctx->unique_ids result->id = ++pctx->unique_ids
function Ast_Atom * function Ast_Atom *
ast_str(Token *pos, Intern_String string, Ast_Flag flags = 0){ ast_str(Token *pos, Intern_String string, Ast_Flag flags = 0){
AST_NEW(Atom, STR, pos); AST_NEW(Atom, STR, pos,flags);
result->flags = flags;
result->intern_val = string; result->intern_val = string;
return result; return result;
} }
function Ast_Atom * function Ast_Atom *
ast_ident(Token *pos, Intern_String string, Ast_Flag flags = 0){ ast_ident(Token *pos, Intern_String string, Ast_Flag flags = 0){
AST_NEW(Atom, IDENT, pos); AST_NEW(Atom, IDENT, pos,flags);
result->flags = flags;
result->intern_val = string; result->intern_val = string;
return result; return result;
} }
function Ast_Atom * function Ast_Atom *
ast_int(Token *pos, S64 integer, Ast_Flag flags){ ast_int(Token *pos, S64 integer, Ast_Flag flags = 0){
AST_NEW(Atom, INT, pos); AST_NEW(Atom, INT, pos,flags);
result->flags = flags;
result->int_val = integer; result->int_val = integer;
return result; return result;
} }
function Ast_Expr * function Ast_Expr *
ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
AST_NEW(Binary, BINARY, op); AST_NEW(Binary, BINARY, op, AST_EXPR);
result->flags = AST_EXPR;
result->op = op->kind; result->op = op->kind;
result->left = left; result->left = left;
result->right = right; result->right = right;
@@ -285,8 +284,7 @@ ast_expr_binary(Ast_Expr *left, Ast_Expr *right, Token *op){
function Ast_Compound * function Ast_Compound *
ast_expr_compound(Token *pos, Ast_Expr *typespec, Array<Ast_Compound_Item *> exprs){ ast_expr_compound(Token *pos, Ast_Expr *typespec, Array<Ast_Compound_Item *> exprs){
AST_NEW(Compound, COMPOUND, pos); AST_NEW(Compound, COMPOUND, pos, AST_EXPR);
result->flags = AST_EXPR;
result->typespec = typespec; result->typespec = typespec;
result->exprs = exprs.tight_copy(pctx->perm); result->exprs = exprs.tight_copy(pctx->perm);
if(result->typespec) result->typespec->parent = result; if(result->typespec) result->typespec->parent = result;
@@ -296,8 +294,7 @@ ast_expr_compound(Token *pos, Ast_Expr *typespec, Array<Ast_Compound_Item *> exp
function Ast_Compound_Item * function Ast_Compound_Item *
ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){
AST_NEW(Compound_Item, COMPOUND_ITEM, pos); AST_NEW(Compound_Item, COMPOUND_ITEM, pos, AST_EXPR);
result->flags = AST_EXPR;
result->name = name; result->name = name;
result->index = index; result->index = index;
result->item = item; 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 * function Ast_Expr *
ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){ 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->flags = AST_EXPR;
result->expr = expr; result->expr = expr;
result->typespec = typespec; result->typespec = typespec;
@@ -320,7 +317,7 @@ ast_expr_cast(Token *pos, Ast_Expr *expr, Ast_Expr *typespec){
function Ast_Expr * function Ast_Expr *
ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *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->flags = AST_EXPR;
result->expr = expr; result->expr = expr;
result->op = op; result->op = op;
@@ -330,7 +327,7 @@ ast_expr_unary(Token *pos, Token_Kind op, Ast_Expr *expr){
function Ast_Expr * function Ast_Expr *
ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){ 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->flags = AST_EXPR;
result->expr = expr; result->expr = expr;
result->index = index; result->index = index;
@@ -341,7 +338,7 @@ ast_expr_index(Token *pos, Ast_Expr *expr, Ast_Expr *index){
function Ast_Lambda * function Ast_Lambda *
ast_lambda(Token *pos, Array<Ast_Lambda_Arg *> params, Ast_Expr *ret, Ast_Block *block){ ast_lambda(Token *pos, Array<Ast_Lambda_Arg *> params, Ast_Expr *ret, Ast_Block *block){
AST_NEW(Lambda, LAMBDA, pos); AST_NEW(Lambda, LAMBDA, pos, AST_EXPR);
result->flags = AST_EXPR; result->flags = AST_EXPR;
result->args = params.tight_copy(pctx->perm); result->args = params.tight_copy(pctx->perm);
result->block = block; result->block = block;
@@ -356,7 +353,7 @@ ast_lambda(Token *pos, Array<Ast_Lambda_Arg *> params, Ast_Expr *ret, Ast_Block
function Ast_Lambda_Arg * function Ast_Lambda_Arg *
ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Expr *typespec){ 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->flags = AST_EXPR;
result->name = name; result->name = name;
result->typespec = typespec; result->typespec = typespec;
@@ -366,7 +363,7 @@ ast_expr_lambda_arg(Token *pos, Intern_String name, Ast_Expr *typespec){
function Ast_Block * function Ast_Block *
ast_block(Token *pos, Array<Ast *> stmts){ ast_block(Token *pos, Array<Ast *> stmts){
AST_NEW(Block, BLOCK, pos); AST_NEW(Block, BLOCK, pos, AST_STMT);
result->stmts = stmts.tight_copy(pctx->perm); result->stmts = stmts.tight_copy(pctx->perm);
For(result->stmts) it[0]->parent = result; For(result->stmts) it[0]->parent = result;
return result; return result;
@@ -374,15 +371,26 @@ ast_block(Token *pos, Array<Ast *> stmts){
function Ast_If * function Ast_If *
ast_if(Token *pos, Array<Ast_If_Node *> ifs){ ast_if(Token *pos, Array<Ast_If_Node *> ifs){
AST_NEW(If, IF, pos); AST_NEW(If, IF, pos, AST_STMT);
result->ifs = ifs.tight_copy(pctx->perm); result->ifs = ifs.tight_copy(pctx->perm);
For(result->ifs) it[0]->parent = result; For(result->ifs) it[0]->parent = result;
return 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 * function Ast_If_Node *
ast_if_node(Token *pos, Ast_Init *init, Ast_Expr *expr, Ast_Block *block){ 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->block = block;
result->expr = expr; result->expr = expr;
result->init = init; result->init = init;
@@ -394,7 +402,7 @@ ast_if_node(Token *pos, Ast_Init *init, Ast_Expr *expr, Ast_Block *block){
function Ast_Init * function Ast_Init *
ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){ 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->op = op;
result->ident = ident; result->ident = ident;
result->expr = expr; result->expr = expr;
@@ -405,7 +413,7 @@ ast_init(Token *pos, Token_Kind op, Ast_Atom *ident, Ast_Expr *expr){
function Ast_Array * function Ast_Array *
ast_array(Token *pos, Ast_Expr *expr){ ast_array(Token *pos, Ast_Expr *expr){
AST_NEW(Array, ARRAY, pos); AST_NEW(Array, ARRAY, pos, AST_EXPR);
result->flags = AST_EXPR; result->flags = AST_EXPR;
result->expr = expr; result->expr = expr;
result->expr->parent = result; result->expr->parent = result;
@@ -414,7 +422,7 @@ ast_array(Token *pos, Ast_Expr *expr){
function Ast_Struct * function Ast_Struct *
ast_struct(Token *pos, Array<Ast *> members){ ast_struct(Token *pos, Array<Ast *> members){
AST_NEW(Struct, STRUCT, pos); AST_NEW(Struct, STRUCT, pos, AST_AGGREGATE);
result->members = members.tight_copy(pctx->perm); result->members = members.tight_copy(pctx->perm);
For(result->members) { For(result->members) {
assert(it[0]->kind == AST_VAR || it[0]->kind == AST_CONST || it[0]->kind == AST_STRUCT); 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<Ast *> members){
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
function Ast_Var * function Ast_Var *
ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){ 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->expr = expr;
result->typespec = typespec; result->typespec = typespec;
result->name = name; result->name = name;
@@ -438,8 +446,8 @@ ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){
} }
function Ast_Const * function Ast_Const *
ast_const(Token *pos, Intern_String name, Ast *value){ ast_const(Token *pos, Intern_String name, Ast_Expr *value){
AST_NEW(Const, CONST, pos); AST_NEW(Const, CONST, pos, AST_BINDING);
assert(value->kind == AST_STRUCT || is_flag_set(value->flags, AST_EXPR)); assert(value->kind == AST_STRUCT || is_flag_set(value->flags, AST_EXPR));
result->value = value; result->value = value;
@@ -450,7 +458,7 @@ ast_const(Token *pos, Intern_String name, Ast *value){
function Ast_Package * function Ast_Package *
ast_package(Token *pos, String name, Array<Ast_Named *> decls){ ast_package(Token *pos, String name, Array<Ast_Named *> decls){
AST_NEW(Package, PACKAGE, pos); AST_NEW(Package, PACKAGE, pos, 0);
result->decls = decls.tight_copy(pctx->perm); result->decls = decls.tight_copy(pctx->perm);
result->ordered = array_make<Ast_Named *>(pctx->perm, decls.len); result->ordered = array_make<Ast_Named *>(pctx->perm, decls.len);
result->name = intern_string(&pctx->interns, name); result->name = intern_string(&pctx->interns, name);

View File

@@ -204,9 +204,10 @@ parse_block(){
do{ do{
Token *token = token_get(); Token *token = token_get();
if(token_match_keyword(keyword_return)){ if(token_match_keyword(keyword_return)){
AST_NEW(Return, RETURN, token); Ast_Expr *expr = 0;
if(!token_is_scope()) result->expr = parse_expr(); if(!token_is_scope()) expr = parse_expr();
stmts.add(result); Ast_Return *return_stmt = ast_return(token, expr);
stmts.add(return_stmt);
} }
else if(token_match_keyword(keyword_if)){ else if(token_match_keyword(keyword_if)){
Array<Ast_If_Node *> if_nodes = {scratch}; Array<Ast_If_Node *> if_nodes = {scratch};
@@ -396,6 +397,7 @@ parse_struct(Token *pos){
Token *token = token_get(); Token *token = token_get();
Ast_Named *named = parse_named(false); Ast_Named *named = parse_named(false);
if(!named) parsing_error(token, "Failed to parse struct member"); if(!named) parsing_error(token, "Failed to parse struct member");
members.add(named);
}while(token_match(SAME_SCOPE)); }while(token_match(SAME_SCOPE));
token_expect(CLOSE_SCOPE); token_expect(CLOSE_SCOPE);

View File

@@ -171,7 +171,7 @@ resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){
return result; return result;
} }
function Operand eval_decl(Ast *ast, Sym *sym = 0); function Operand eval_binding(Ast *ast, Sym *sym = 0);
function void function void
eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
switch(ast->kind){ switch(ast->kind){
@@ -185,14 +185,14 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
} }
Ast_Begin(AST_VAR, Ast_Var){ 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 *sym = sym_new_resolved(SYM_VAR, node->name, op.type, op.value, node);
sym_insert(sym); sym_insert(sym);
Ast_End(); Ast_End();
} }
Ast_Begin(AST_CONST, Ast_Const){ 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 *sym = sym_new_resolved(SYM_CONST, node->name, op.type, op.value, node);
sym_insert(sym); sym_insert(sym);
Ast_End(); Ast_End();
@@ -484,6 +484,28 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
Ast_End(); Ast_End();
} }
Ast_Begin(AST_STRUCT, Ast_Struct){
Scratch scratch;
Array<Ast_Resolved_Type_Field> 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; invalid_default_case;
} }
@@ -491,7 +513,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
} }
function Operand function Operand
eval_decl(Ast *ast, Sym *sym){ eval_binding(Ast *ast, Sym *sym){
switch(ast->kind){ switch(ast->kind){
Ast_Begin(AST_VAR, Ast_Var){ 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); assert(sym->ast->kind == AST_VAR || sym->ast->kind == AST_CONST);
sym->state = SYM_RESOLVING; sym->state = SYM_RESOLVING;
Operand op = eval_decl(sym->ast, sym); Operand op = eval_binding(sym->ast, sym);
sym->type = op.type; sym->type = op.type;
if(sym->kind == SYM_CONST){ if(sym->kind == SYM_CONST){
assert(op.is_const); assert(op.is_const);

View File

@@ -32,6 +32,12 @@ const char *type_names[] = {
"[Type]", "[Type]",
}; };
struct Ast_Resolved_Type_Field{
Ast_Resolved_Type *type;
Intern_String name;
U64 offset;
};
struct Ast_Resolved_Type{ struct Ast_Resolved_Type{
Ast_Resolved_Type_Kind kind; Ast_Resolved_Type_Kind kind;
SizeU size; SizeU size;
@@ -42,6 +48,9 @@ struct Ast_Resolved_Type{
Ast_Resolved_Type *base; Ast_Resolved_Type *base;
SizeU size; SizeU size;
}arr; }arr;
struct{
Array<Ast_Resolved_Type_Field> fields;
}agg;
struct{ struct{
Ast_Resolved_Type *ret; Ast_Resolved_Type *ret;
Array<Ast_Resolved_Type*> args; Array<Ast_Resolved_Type*> args;
@@ -135,6 +144,13 @@ type_lambda(Ast_Resolved_Type *ret, Array<Ast_Resolved_Type *> args){
return result; return result;
} }
function Ast_Resolved_Type *
type_struct(Array<Ast_Resolved_Type_Field> 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 function void
test_types(){ test_types(){
Scratch scratch; Scratch scratch;

View File

@@ -0,0 +1,6 @@
Arena :: struct
data: *int
len : int
cap : int