Generating nested structs

This commit is contained in:
Krzosa Karol
2022-05-31 16:12:18 +02:00
parent ef9c2f4ee5
commit 7dfc4c7b36
5 changed files with 58 additions and 39 deletions

View File

@@ -379,10 +379,12 @@ compile_string(String filecontent, String filename = "default_name"_s){
sym_insert_builtins(); sym_insert_builtins();
pctx->resolving_package = result; pctx->resolving_package = result;
gen(R"==(//------------------------------- gen(R"==(
//-------------------------------
#define NULL_POINTER 0 #define NULL_POINTER 0
#define NULL_LAMBDA 0 #define NULL_LAMBDA 0
//-------------------------------)=="); //-------------------------------
)==");
resolve_package(result); resolve_package(result);
// eval_decl(result); // eval_decl(result);

View File

@@ -88,9 +88,13 @@ int main(){
String result = {}; String result = {};
result = compile_file("globals.kl"_s); result = compile_file("globals.kl"_s);
printf("%s", result.str);
result = compile_file("enums.kl"_s); result = compile_file("enums.kl"_s);
printf("%s", result.str);
result = compile_file("lambdas.kl"_s); result = compile_file("lambdas.kl"_s);
printf("%s", result.str);
result = compile_file("order1.kl"_s); result = compile_file("order1.kl"_s);
printf("%s", result.str);
result = compile_file("order2.kl"_s); result = compile_file("order2.kl"_s);
printf("%s", result.str); printf("%s", result.str);

View File

@@ -179,19 +179,10 @@ type_incomplete(Ast *ast){
} }
function void function void
type_complete(Ast_Resolved_Type *type){ type_struct_complete(Ast_Resolved_Type *type, Ast_Struct *node){
if(type->kind == TYPE_COMPLETING){
parsing_error(type->ast->pos, "Cyclic type dependency");
}
else if(type->kind != TYPE_INCOMPLETE){
return;
}
Ast_Struct *node = (Ast_Struct *)type->ast;
// @todo: compute size, alignement, offset !!! // @todo: compute size, alignement, offset !!!
// @note: resolve all the struct members // @note: resolve all the struct members first
type->kind = TYPE_COMPLETING; type->kind = TYPE_COMPLETING;
{
Scratch scratch; Scratch scratch;
Array<Ast_Resolved_Member> members = {scratch}; Array<Ast_Resolved_Member> members = {scratch};
For(node->members){ For(node->members){
@@ -201,8 +192,6 @@ type_complete(Ast_Resolved_Type *type){
members.add({op.type, name}); members.add({op.type, name});
} }
type->agg.members = members.tight_copy(pctx->perm); type->agg.members = members.tight_copy(pctx->perm);
}
type->kind = TYPE_STRUCT; type->kind = TYPE_STRUCT;
// @note: resolve constant members after the struct got resolved // @note: resolve constant members after the struct got resolved
@@ -215,7 +204,27 @@ type_complete(Ast_Resolved_Type *type){
Intern_String name = ast_get_name(it); Intern_String name = ast_get_name(it);
sym_new_resolved(SYM_CONST, name, op.type, op.value, it); sym_new_resolved(SYM_CONST, name, op.type, op.value, it);
} }
}
function Ast_Resolved_Type *
type_struct(Ast_Struct *agg){
Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_STRUCT, 0, 0);
result->ast = agg;
type_struct_complete(result, agg);
return result;
}
function void
type_complete(Ast_Resolved_Type *type){
if(type->kind == TYPE_COMPLETING){
parsing_error(type->ast->pos, "Cyclic type dependency");
}
else if(type->kind != TYPE_INCOMPLETE){
return;
}
Ast_Struct *node = (Ast_Struct *)type->ast;
type_struct_complete(type, node);
pctx->resolving_package->ordered.add((Ast_Named *)node->parent); pctx->resolving_package->ordered.add((Ast_Named *)node->parent);
} }

View File

@@ -21,6 +21,9 @@ Arena :: struct
len : int len : int
cap : int cap : int
Sub :: struct
len: int
get_len :: (s: *Arena): int // @todo get_len :: (s: *Arena): int // @todo
return s.next.len return s.next.len

View File

@@ -306,7 +306,7 @@ _rewrite_into_const(Ast *node, U64 ast_size, Sym *sym){
#define rewrite_into_const(ast,T,sym) _rewrite_into_const(ast,sizeof(T),sym) #define rewrite_into_const(ast,T,sym) _rewrite_into_const(ast,sizeof(T),sym)
function Operand function Operand
resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_resolve){
if(!ast) return {}; // @todo: add option for better error prevention if(!ast) return {}; // @todo: add option for better error prevention
switch(ast->kind){ switch(ast->kind){
@@ -326,6 +326,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
CASE(IDENT, Atom){ CASE(IDENT, Atom){
Sym *sym = resolve_name(node->pos, node->intern_val); Sym *sym = resolve_name(node->pos, node->intern_val);
Operand result = {}; Operand result = {};
// @note: check if null and rewrite the expression to match the expected type // @note: check if null and rewrite the expression to match the expected type
if(sym->type->kind == TYPE_NULL){ if(sym->type->kind == TYPE_NULL){
@@ -382,7 +383,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
} }
CASE(LAMBDA, Lambda){ CASE(LAMBDA, Lambda){
// @note: first resolve type of lambda // @note: first resolve type of lambda so recursive lambdas work
Scratch scratch; Scratch scratch;
Ast_Resolved_Type *lambda_type = 0; Ast_Resolved_Type *lambda_type = 0;
Ast_Resolved_Type *ret_type = resolve_typespec(node->ret); Ast_Resolved_Type *ret_type = resolve_typespec(node->ret);
@@ -395,17 +396,16 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
args.add(type.type_val); args.add(type.type_val);
} }
lambda_type = type_lambda(node, ret_type, args); lambda_type = type_lambda(node, ret_type, args);
{ {
sym_type(node, lambda_type); sym_type(node, lambda_type);
if(const_sym){ if(lambda_to_resolve){
const_sym->type = lambda_type; lambda_to_resolve->type = lambda_type;
const_sym->state = SYM_RESOLVED; lambda_to_resolve->state = SYM_RESOLVED;
} }
} }
Operand result = {type_type, true};
result.type_val = lambda_type; Operand result = operand_type(lambda_type);
// @todo: We also need to make sure there is a return value when ret type is not void // @todo: We also need to make sure there is a return value when ret type is not void
// @note: then try resolving the block of lambda // @note: then try resolving the block of lambda
if(node->block){ if(node->block){
@@ -455,9 +455,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
assert(i->kind == AST_CALL_ITEM); assert(i->kind == AST_CALL_ITEM);
if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]); if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]);
if(i->index){ if(i->index){
Operand index_op = resolve_expr(i->index); Operand index_op = require_const_int(i->index, AST_CANT_BE_NULL);
if(!index_op.is_const) parsing_error(i->pos, "Index in a compound expression is not a constant");
if(index_op.type != type_int) parsing_error(i->pos, "Index should be of type int");
if(index_op.int_val > (type->arr.size - 1)) parsing_error(i->pos, "Invalid index in compound expression, larger then type can store"); if(index_op.int_val > (type->arr.size - 1)) parsing_error(i->pos, "Invalid index in compound expression, larger then type can store");
} }
Operand expr = resolve_expr(i->item, item_type); Operand expr = resolve_expr(i->item, item_type);
@@ -503,9 +501,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
} }
// @note: cleanup, required? // @note: cleanup, required?
For(agg->members){ For(agg->members) it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED);
it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED);
}
} }
else if(type->kind == TYPE_LAMBDA){ else if(type->kind == TYPE_LAMBDA){
Scratch scratch; Scratch scratch;
@@ -580,12 +576,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
expr.type = type_bool; expr.type = type_bool;
return expr; return expr;
} }
else if(expr.type == type_bool && type == type_int){ else if(expr.type == type_bool && type == type_int){
expr.type = type_int; expr.type = type_int;
return expr; return expr;
} }
else if(expr.type == type_null){ else if(expr.type == type_null){
expr.type = type; expr.type = type;
return expr; return expr;
@@ -726,6 +720,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
BREAK(); BREAK();
} }
CASE(STRUCT, Struct){
Ast_Resolved_Type *type = type_struct(node);
return operand_type(type);
BREAK();
}
invalid_default_case; invalid_default_case;
} }