Work on order independent structs + cleanup

This commit is contained in:
Krzosa Karol
2022-05-29 20:32:04 +02:00
parent ea1b74cda0
commit b6ea62fd67
6 changed files with 96 additions and 82 deletions

View File

@@ -28,6 +28,10 @@ gen_simple_decl_prefix(Ast_Resolved_Type *ast){
case TYPE_Pointer:{gen_simple_decl_prefix(ast->base); gen("*");} break;
case TYPE_Array: gen_simple_decl_prefix(ast->base); break;
case TYPE_Lambda:break;
case TYPE_Struct: {
auto name = ast->sym->name;
gen("%s ", name.str);
}break;
invalid_default_case;
}
}
@@ -43,6 +47,7 @@ gen_simple_decl_postfix(Ast_Resolved_Type *ast){
case TYPE_Pointer: gen_simple_decl_postfix(ast->base); break;
case TYPE_Array: gen("[%d]", (int)ast->arr.size); gen_simple_decl_postfix(ast->arr.base); break;
case TYPE_Lambda:break;
case TYPE_Struct:break;
invalid_default_case;
}
}
@@ -279,15 +284,20 @@ gen_ast(Ast *ast){
}
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]);
Ast_Struct *agg = const_get_struct(sym->type_val->sym->ast);
if(node->value->kind == AST_STRUCT){
gen("struct %s{", node->name.str);
global_indent++;
For(agg->members){
genln("");
gen_ast(it[0]);
}
global_indent--;
genln("};");
}
else{
// type alias
}
global_indent--;
genln("};");
}
else{
gen("// typedef ");

View File

@@ -48,8 +48,8 @@ int main(){
test_intern_table();
lex_test();
// String result = compile_file("globals.kl"_s);
String result = compile_file("structs.kl"_s);
String result = compile_file("globals.kl"_s);
// String result = compile_file("structs.kl"_s);
// String result = compile_file("order_independent_globals.kl"_s);
printf("%s", result.str);

View File

@@ -111,6 +111,7 @@ enum{
AST_STMT = 2,
AST_BINDING = 4,
AST_AGGREGATE = 8,
AST_ATOM = 16,
};
struct Ast{
@@ -120,12 +121,6 @@ struct Ast{
Ast_Kind kind;
Ast *parent;
Ast_Flag flags;
// @todo?
// bool is_atom: 1;
// bool is_stmt: 1;
// bool is_decl: 1;
// bool is_expr: 1;
// bool is_named: 1;
};
struct Ast_Resolved_Type;
@@ -252,21 +247,21 @@ struct Ast_Package:Ast{
function Ast_Atom *
ast_str(Token *pos, Intern_String string, Ast_Flag flags = 0){
AST_NEW(Atom, STR, pos,flags);
AST_NEW(Atom, STR, pos, AST_ATOM | 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,flags);
AST_NEW(Atom, IDENT, pos, AST_ATOM | flags);
result->intern_val = string;
return result;
}
function Ast_Atom *
ast_int(Token *pos, S64 integer, Ast_Flag flags = 0){
AST_NEW(Atom, INT, pos,flags);
AST_NEW(Atom, INT, pos, AST_ATOM | flags);
result->int_val = integer;
return result;
}

View File

@@ -153,6 +153,19 @@ sym_insert_builtins(){
function Sym *resolve_name(Token *pos, Intern_String name);
function Operand eval_expr(Ast_Expr *ast, Ast_Resolved_Type *compound_required_type = 0, Sym *lambda_to_complete = 0);
enum{
AST_CANT_BE_NULL = 0,
AST_CAN_BE_NULL = 1
};
function Ast_Resolved_Type *
eval_typespec(Ast_Expr *ast, B32 ast_can_be_null = AST_CANT_BE_NULL){
if(ast_can_be_null && ast == 0) return 0;
Operand resolved = eval_expr(ast);
if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", resolved.type->kind);
return resolved.type_val;
}
function Ast_Resolved_Type *
resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){
Ast_Resolved_Type *result = 0;
@@ -227,18 +240,6 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
}
}
enum{
AST_CAN_BE_NULL = 1
};
function Ast_Resolved_Type *
eval_typespec(Ast_Expr *ast, B32 ast_can_be_null){
if(ast_can_be_null && ast == 0) return 0;
Operand resolved = eval_expr(ast);
if(resolved.type != type_type) parsing_error(ast->pos, "Expected [Type] got instead %s", resolved.type->kind);
return resolved.type_val;
}
function Operand
eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_complete){
switch(ast->kind){
@@ -266,33 +267,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
if(!expected_type) parsing_error(node->pos, "Couldn't infer type of null");
result.type = expected_type;
result.is_const = true;
if(expected_type == type_int){
result.int_val = 0;
node->kind = AST_INT;
node->int_val = 0;
}
else if(expected_type->kind == TYPE_Pointer){
result.int_val = 0;
node->kind = AST_IDENT;
node->intern_val = pctx->intern("NULL_POINTER"_s);
}
else if(expected_type->kind == TYPE_Lambda){
result.int_val = 0;
node->kind = AST_IDENT;
node->intern_val = pctx->intern("NULL_LAMBDA"_s);
}
else if(expected_type == type_bool){
result.int_val = 0;
node->kind = AST_IDENT;
node->intern_val = pctx->intern("false"_s);
}
else if(expected_type == type_string){
result.intern_val = pctx->intern(""_s);
node->kind = AST_STR;
node->intern_val = result.intern_val;
}
}
else if(sym->kind == SYM_CONST || sym->kind == SYM_VAR){
result.type = sym->type;
result.is_const = sym->kind == SYM_CONST ? true : false;
@@ -322,15 +297,14 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
// @note: first resolve type of lambda
Scratch scratch;
Ast_Resolved_Type *lambda_type = 0;
Operand ret_op = eval_expr(node->ret);
Ast_Resolved_Type *ret_type = eval_typespec(node->ret);
Array<Ast_Resolved_Type *> args = {scratch};
if(ret_op.type != type_type) parsing_error(node->pos, "Return type of [Lambda] should be a [Type] not %s", ret_op.type);
For(node->args){
Operand type = eval_expr(it[0]->typespec);
if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]");
args.add(type.type_val);
}
lambda_type = type_lambda(ret_op.type_val, args);
lambda_type = type_lambda(ret_type, args);
{
assert(lambda_type);
Value val; val.type_val = lambda_type;
@@ -355,7 +329,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
sym_insert(arg_sym);
}
For(node->block->stmts){
eval_stmt(it[0], ret_op.type_val);
eval_stmt(it[0], ret_type);
}
scope_close(scope_index);
result.type = lambda_type;
@@ -410,9 +384,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
Ast_Begin(AST_CAST, Ast_Cast){
Operand expr = eval_expr(node->expr);
Operand typespec = eval_expr(node->typespec);
if(typespec.type != type_type) parsing_error(node->pos, "Expected type in left of cast got instead %s", type_names[typespec.type->kind]);
Ast_Resolved_Type *type = typespec.type_val;
Ast_Resolved_Type *type = eval_typespec(node->typespec);
if(type == expr.type) return expr;
@@ -484,7 +456,10 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
Ast_End();
}
// @todo: add const prepass? expecting only structs, exprs, lambdas
Ast_Begin(AST_STRUCT, Ast_Struct){
assert(lambda_to_complete);
Scratch scratch;
Array<Ast_Resolved_Type_Field> members = {scratch};
For(node->members){
@@ -499,7 +474,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_comple
sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]);
members.add({op.type, name});
}
Ast_Resolved_Type *resolved = type_struct(members);
Ast_Resolved_Type *resolved = type_struct(lambda_to_complete, members);
Operand result = {type_type, true}; result.type_val = resolved;
return result;
@@ -517,10 +492,9 @@ eval_binding(Ast *ast, Sym *sym){
switch(ast->kind){
Ast_Begin(AST_VAR, Ast_Var){
Operand type = node->typespec ? eval_expr(node->typespec) : Operand{};
if(type.type && (type.type != type_type)) parsing_error(node->typespec->pos, "Expected [Type] got instead %s", type_names[type.type->kind]);
Operand expr = node->expr ? eval_expr(node->expr, type.type_val) : Operand{};
expr.type = resolve_type_pair(node->pos, type.type_val, expr.type);
Ast_Resolved_Type *type = eval_typespec(node->typespec, AST_CAN_BE_NULL);
Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{};
expr.type = resolve_type_pair(node->pos, type, expr.type);
return expr;
Ast_End();
}
@@ -537,18 +511,12 @@ eval_binding(Ast *ast, Sym *sym){
}
}
function Ast_Lambda *
ast_get_lambda(Ast *ast){
if(ast->kind == AST_CONST){
auto ast_const = (Ast_Const *)ast;
if(ast_const->value){
auto ast_expr = ast_const->value;
if(ast_expr->kind == AST_LAMBDA){
return (Ast_Lambda *)ast_expr;
}
}
}
return 0;
function Ast_Struct *
const_get_struct(Ast *ast){
assert(ast->kind == AST_CONST);
Ast_Const *constant = (Ast_Const *)ast;
assert(constant->value->kind == AST_STRUCT);
return (Ast_Struct *)constant->value;
}
function void
@@ -610,6 +578,13 @@ parse_file(){
else invalid_codepath;
Sym *sym = sym_new(kind, decl->name, decl);
// if(kind == SYM_CONST){
// auto constant = (Ast_Const *)decl;
// if(constant->value->kind == AST_STRUCT) {
// sym->type = type_incomplete(sym);
// sym->state = SYM_RESOLVED;
// }
// }
sym_insert(sym);
decls.add(decl);

View File

@@ -1,6 +1,7 @@
enum Ast_Resolved_Type_Kind{
TYPE_None,
TYPE_Null,
TYPE_Incomplete,
TYPE_Int,
TYPE_Bool,
TYPE_Unsigned,
@@ -18,6 +19,7 @@ enum Ast_Resolved_Type_Kind{
const char *type_names[] = {
"[Invalid Ast_Resolved_Type]",
"[Null]",
"[Incomplete]",
"[Int]",
"[Bool]",
"[Unsigned]",
@@ -42,6 +44,8 @@ struct Ast_Resolved_Type{
Ast_Resolved_Type_Kind kind;
SizeU size;
SizeU align;
Sym *sym;
union{
Ast_Resolved_Type *base;
struct{
@@ -145,9 +149,23 @@ type_lambda(Ast_Resolved_Type *ret, Array<Ast_Resolved_Type *> args){
}
function Ast_Resolved_Type *
type_struct(Array<Ast_Resolved_Type_Field> fields){
type_incomplete(Sym *sym){
Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_Incomplete, 0, 0);
result->sym = sym;
return result;
}
function void
type_complete_struct(Ast_Resolved_Type *type, Array<Ast_Resolved_Type_Field> fields){
type->agg.fields = fields.tight_copy(pctx->perm);
type->kind = TYPE_Struct;
}
function Ast_Resolved_Type *
type_struct(Sym *sym, 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);
result->sym = sym;
return result;
}

View File

@@ -1,6 +1,22 @@
arena_pointer: *Arena = null
Arena :: struct
// next: *Arena
data: *int
len : int
cap : int
string16: Str16
String16 :: struct
data: *void
len : int
thing: Arena
no_type := thing
with_type: Arena = thing
pointer := &with_type
deref := *pointer
Str16 :: String16