Generating nested structs
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
4
main.cpp
4
main.cpp
@@ -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);
|
||||||
|
|
||||||
|
|||||||
35
new_type.cpp
35
new_type.cpp
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user