Generating nested structs
This commit is contained in:
@@ -379,10 +379,12 @@ compile_string(String filecontent, String filename = "default_name"_s){
|
||||
sym_insert_builtins();
|
||||
pctx->resolving_package = result;
|
||||
|
||||
gen(R"==(//-------------------------------
|
||||
gen(R"==(
|
||||
//-------------------------------
|
||||
#define NULL_POINTER 0
|
||||
#define NULL_LAMBDA 0
|
||||
//-------------------------------)==");
|
||||
//-------------------------------
|
||||
)==");
|
||||
|
||||
resolve_package(result);
|
||||
// eval_decl(result);
|
||||
|
||||
4
main.cpp
4
main.cpp
@@ -88,9 +88,13 @@ int main(){
|
||||
|
||||
String result = {};
|
||||
result = compile_file("globals.kl"_s);
|
||||
printf("%s", result.str);
|
||||
result = compile_file("enums.kl"_s);
|
||||
printf("%s", result.str);
|
||||
result = compile_file("lambdas.kl"_s);
|
||||
printf("%s", result.str);
|
||||
result = compile_file("order1.kl"_s);
|
||||
printf("%s", result.str);
|
||||
result = compile_file("order2.kl"_s);
|
||||
printf("%s", result.str);
|
||||
|
||||
|
||||
51
new_type.cpp
51
new_type.cpp
@@ -179,30 +179,19 @@ type_incomplete(Ast *ast){
|
||||
}
|
||||
|
||||
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(Ast_Resolved_Type *type, Ast_Struct *node){
|
||||
// @todo: compute size, alignement, offset !!!
|
||||
// @note: resolve all the struct members
|
||||
// @note: resolve all the struct members first
|
||||
type->kind = TYPE_COMPLETING;
|
||||
{
|
||||
Scratch scratch;
|
||||
Array<Ast_Resolved_Member> members = {scratch};
|
||||
For(node->members){
|
||||
Operand op = resolve_binding(it);
|
||||
Intern_String name = ast_get_name(it);
|
||||
sym_new_resolved(SYM_VAR, name, op.type, {}, it);
|
||||
members.add({op.type, name});
|
||||
}
|
||||
type->agg.members = members.tight_copy(pctx->perm);
|
||||
Scratch scratch;
|
||||
Array<Ast_Resolved_Member> members = {scratch};
|
||||
For(node->members){
|
||||
Operand op = resolve_binding(it);
|
||||
Intern_String name = ast_get_name(it);
|
||||
sym_new_resolved(SYM_VAR, name, op.type, {}, it);
|
||||
members.add({op.type, name});
|
||||
}
|
||||
|
||||
type->agg.members = members.tight_copy(pctx->perm);
|
||||
type->kind = TYPE_STRUCT;
|
||||
|
||||
// @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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ Arena :: struct
|
||||
len : int
|
||||
cap : int
|
||||
|
||||
Sub :: struct
|
||||
len: int
|
||||
|
||||
get_len :: (s: *Arena): int // @todo
|
||||
return s.next.len
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
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
|
||||
|
||||
switch(ast->kind){
|
||||
@@ -326,6 +326,7 @@ 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);
|
||||
|
||||
Operand result = {};
|
||||
// @note: check if null and rewrite the expression to match the expected type
|
||||
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){
|
||||
// @note: first resolve type of lambda
|
||||
// @note: first resolve type of lambda so recursive lambdas work
|
||||
Scratch scratch;
|
||||
Ast_Resolved_Type *lambda_type = 0;
|
||||
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);
|
||||
}
|
||||
lambda_type = type_lambda(node, ret_type, args);
|
||||
|
||||
{
|
||||
sym_type(node, lambda_type);
|
||||
if(const_sym){
|
||||
const_sym->type = lambda_type;
|
||||
const_sym->state = SYM_RESOLVED;
|
||||
if(lambda_to_resolve){
|
||||
lambda_to_resolve->type = lambda_type;
|
||||
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
|
||||
// @note: then try resolving the block of lambda
|
||||
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);
|
||||
if(i->name) parsing_error(i->pos, "Invalid indexing kind in a compound expression of type %s", type_names[type->kind]);
|
||||
if(i->index){
|
||||
Operand index_op = resolve_expr(i->index);
|
||||
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");
|
||||
Operand index_op = require_const_int(i->index, AST_CANT_BE_NULL);
|
||||
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);
|
||||
@@ -503,9 +501,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
}
|
||||
|
||||
// @note: cleanup, required?
|
||||
For(agg->members){
|
||||
it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED);
|
||||
}
|
||||
For(agg->members) it->flags = unset_flag(it->flags, AST_ITEM_INCLUDED);
|
||||
}
|
||||
else if(type->kind == TYPE_LAMBDA){
|
||||
Scratch scratch;
|
||||
@@ -580,12 +576,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
expr.type = type_bool;
|
||||
return expr;
|
||||
}
|
||||
|
||||
else if(expr.type == type_bool && type == type_int){
|
||||
expr.type = type_int;
|
||||
return expr;
|
||||
}
|
||||
|
||||
else if(expr.type == type_null){
|
||||
expr.type = type;
|
||||
return expr;
|
||||
@@ -726,6 +720,13 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
BREAK();
|
||||
}
|
||||
|
||||
CASE(STRUCT, Struct){
|
||||
Ast_Resolved_Type *type = type_struct(node);
|
||||
return operand_type(type);
|
||||
BREAK();
|
||||
}
|
||||
|
||||
|
||||
invalid_default_case;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user