Work on order independent structs + cleanup
This commit is contained in:
12
ccodegen.cpp
12
ccodegen.cpp
@@ -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_Pointer:{gen_simple_decl_prefix(ast->base); gen("*");} break;
|
||||||
case TYPE_Array: gen_simple_decl_prefix(ast->base); break;
|
case TYPE_Array: gen_simple_decl_prefix(ast->base); break;
|
||||||
case TYPE_Lambda:break;
|
case TYPE_Lambda:break;
|
||||||
|
case TYPE_Struct: {
|
||||||
|
auto name = ast->sym->name;
|
||||||
|
gen("%s ", name.str);
|
||||||
|
}break;
|
||||||
invalid_default_case;
|
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_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_Array: gen("[%d]", (int)ast->arr.size); gen_simple_decl_postfix(ast->arr.base); break;
|
||||||
case TYPE_Lambda:break;
|
case TYPE_Lambda:break;
|
||||||
|
case TYPE_Struct:break;
|
||||||
invalid_default_case;
|
invalid_default_case;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -279,7 +284,8 @@ gen_ast(Ast *ast){
|
|||||||
}
|
}
|
||||||
else if(sym->type == type_type){
|
else if(sym->type == type_type){
|
||||||
if(sym->type_val->kind == TYPE_Struct){
|
if(sym->type_val->kind == TYPE_Struct){
|
||||||
Ast_Struct *agg = (Ast_Struct *)node->value;
|
Ast_Struct *agg = const_get_struct(sym->type_val->sym->ast);
|
||||||
|
if(node->value->kind == AST_STRUCT){
|
||||||
gen("struct %s{", node->name.str);
|
gen("struct %s{", node->name.str);
|
||||||
global_indent++;
|
global_indent++;
|
||||||
For(agg->members){
|
For(agg->members){
|
||||||
@@ -289,6 +295,10 @@ gen_ast(Ast *ast){
|
|||||||
global_indent--;
|
global_indent--;
|
||||||
genln("};");
|
genln("};");
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
// type alias
|
||||||
|
}
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
gen("// typedef ");
|
gen("// typedef ");
|
||||||
gen_simple_decl(sym->type_val, node->name);
|
gen_simple_decl(sym->type_val, node->name);
|
||||||
|
|||||||
4
main.cpp
4
main.cpp
@@ -48,8 +48,8 @@ int main(){
|
|||||||
test_intern_table();
|
test_intern_table();
|
||||||
lex_test();
|
lex_test();
|
||||||
|
|
||||||
// String result = compile_file("globals.kl"_s);
|
String result = compile_file("globals.kl"_s);
|
||||||
String result = compile_file("structs.kl"_s);
|
// String result = compile_file("structs.kl"_s);
|
||||||
// String result = compile_file("order_independent_globals.kl"_s);
|
// String result = compile_file("order_independent_globals.kl"_s);
|
||||||
printf("%s", result.str);
|
printf("%s", result.str);
|
||||||
|
|
||||||
|
|||||||
13
new_ast.cpp
13
new_ast.cpp
@@ -111,6 +111,7 @@ enum{
|
|||||||
AST_STMT = 2,
|
AST_STMT = 2,
|
||||||
AST_BINDING = 4,
|
AST_BINDING = 4,
|
||||||
AST_AGGREGATE = 8,
|
AST_AGGREGATE = 8,
|
||||||
|
AST_ATOM = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast{
|
struct Ast{
|
||||||
@@ -120,12 +121,6 @@ struct Ast{
|
|||||||
Ast_Kind kind;
|
Ast_Kind kind;
|
||||||
Ast *parent;
|
Ast *parent;
|
||||||
Ast_Flag flags;
|
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;
|
struct Ast_Resolved_Type;
|
||||||
@@ -252,21 +247,21 @@ struct Ast_Package:Ast{
|
|||||||
|
|
||||||
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,flags);
|
AST_NEW(Atom, STR, pos, AST_ATOM | 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,flags);
|
AST_NEW(Atom, IDENT, pos, AST_ATOM | 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 = 0){
|
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;
|
result->int_val = integer;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,19 @@ sym_insert_builtins(){
|
|||||||
function Sym *resolve_name(Token *pos, Intern_String name);
|
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);
|
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 *
|
function Ast_Resolved_Type *
|
||||||
resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){
|
resolve_type_pair(Token *pos, Ast_Resolved_Type *a, Ast_Resolved_Type *b){
|
||||||
Ast_Resolved_Type *result = 0;
|
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
|
function Operand
|
||||||
eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_complete){
|
eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_complete){
|
||||||
switch(ast->kind){
|
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");
|
if(!expected_type) parsing_error(node->pos, "Couldn't infer type of null");
|
||||||
result.type = expected_type;
|
result.type = expected_type;
|
||||||
result.is_const = true;
|
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){
|
else if(sym->kind == SYM_CONST || sym->kind == SYM_VAR){
|
||||||
result.type = sym->type;
|
result.type = sym->type;
|
||||||
result.is_const = sym->kind == SYM_CONST ? true : false;
|
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
|
// @note: first resolve type of lambda
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Ast_Resolved_Type *lambda_type = 0;
|
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};
|
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){
|
For(node->args){
|
||||||
Operand type = eval_expr(it[0]->typespec);
|
Operand type = eval_expr(it[0]->typespec);
|
||||||
if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]");
|
if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]");
|
||||||
args.add(type.type_val);
|
args.add(type.type_val);
|
||||||
}
|
}
|
||||||
lambda_type = type_lambda(ret_op.type_val, args);
|
lambda_type = type_lambda(ret_type, args);
|
||||||
{
|
{
|
||||||
assert(lambda_type);
|
assert(lambda_type);
|
||||||
Value val; val.type_val = 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);
|
sym_insert(arg_sym);
|
||||||
}
|
}
|
||||||
For(node->block->stmts){
|
For(node->block->stmts){
|
||||||
eval_stmt(it[0], ret_op.type_val);
|
eval_stmt(it[0], ret_type);
|
||||||
}
|
}
|
||||||
scope_close(scope_index);
|
scope_close(scope_index);
|
||||||
result.type = lambda_type;
|
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){
|
Ast_Begin(AST_CAST, Ast_Cast){
|
||||||
Operand expr = eval_expr(node->expr);
|
Operand expr = eval_expr(node->expr);
|
||||||
Operand typespec = eval_expr(node->typespec);
|
Ast_Resolved_Type *type = eval_typespec(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;
|
|
||||||
|
|
||||||
if(type == expr.type) return expr;
|
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();
|
Ast_End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo: add const prepass? expecting only structs, exprs, lambdas
|
||||||
Ast_Begin(AST_STRUCT, Ast_Struct){
|
Ast_Begin(AST_STRUCT, Ast_Struct){
|
||||||
|
assert(lambda_to_complete);
|
||||||
|
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<Ast_Resolved_Type_Field> members = {scratch};
|
Array<Ast_Resolved_Type_Field> members = {scratch};
|
||||||
For(node->members){
|
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]);
|
sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]);
|
||||||
members.add({op.type, name});
|
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;
|
Operand result = {type_type, true}; result.type_val = resolved;
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -517,10 +492,9 @@ eval_binding(Ast *ast, Sym *sym){
|
|||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
|
|
||||||
Ast_Begin(AST_VAR, Ast_Var){
|
Ast_Begin(AST_VAR, Ast_Var){
|
||||||
Operand type = node->typespec ? eval_expr(node->typespec) : Operand{};
|
Ast_Resolved_Type *type = eval_typespec(node->typespec, AST_CAN_BE_NULL);
|
||||||
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) : Operand{};
|
||||||
Operand expr = node->expr ? eval_expr(node->expr, type.type_val) : Operand{};
|
expr.type = resolve_type_pair(node->pos, type, expr.type);
|
||||||
expr.type = resolve_type_pair(node->pos, type.type_val, expr.type);
|
|
||||||
return expr;
|
return expr;
|
||||||
Ast_End();
|
Ast_End();
|
||||||
}
|
}
|
||||||
@@ -537,18 +511,12 @@ eval_binding(Ast *ast, Sym *sym){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Lambda *
|
function Ast_Struct *
|
||||||
ast_get_lambda(Ast *ast){
|
const_get_struct(Ast *ast){
|
||||||
if(ast->kind == AST_CONST){
|
assert(ast->kind == AST_CONST);
|
||||||
auto ast_const = (Ast_Const *)ast;
|
Ast_Const *constant = (Ast_Const *)ast;
|
||||||
if(ast_const->value){
|
assert(constant->value->kind == AST_STRUCT);
|
||||||
auto ast_expr = ast_const->value;
|
return (Ast_Struct *)constant->value;
|
||||||
if(ast_expr->kind == AST_LAMBDA){
|
|
||||||
return (Ast_Lambda *)ast_expr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
@@ -610,6 +578,13 @@ parse_file(){
|
|||||||
else invalid_codepath;
|
else invalid_codepath;
|
||||||
|
|
||||||
Sym *sym = sym_new(kind, decl->name, decl);
|
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);
|
sym_insert(sym);
|
||||||
|
|
||||||
decls.add(decl);
|
decls.add(decl);
|
||||||
|
|||||||
20
new_type.cpp
20
new_type.cpp
@@ -1,6 +1,7 @@
|
|||||||
enum Ast_Resolved_Type_Kind{
|
enum Ast_Resolved_Type_Kind{
|
||||||
TYPE_None,
|
TYPE_None,
|
||||||
TYPE_Null,
|
TYPE_Null,
|
||||||
|
TYPE_Incomplete,
|
||||||
TYPE_Int,
|
TYPE_Int,
|
||||||
TYPE_Bool,
|
TYPE_Bool,
|
||||||
TYPE_Unsigned,
|
TYPE_Unsigned,
|
||||||
@@ -18,6 +19,7 @@ enum Ast_Resolved_Type_Kind{
|
|||||||
const char *type_names[] = {
|
const char *type_names[] = {
|
||||||
"[Invalid Ast_Resolved_Type]",
|
"[Invalid Ast_Resolved_Type]",
|
||||||
"[Null]",
|
"[Null]",
|
||||||
|
"[Incomplete]",
|
||||||
"[Int]",
|
"[Int]",
|
||||||
"[Bool]",
|
"[Bool]",
|
||||||
"[Unsigned]",
|
"[Unsigned]",
|
||||||
@@ -42,6 +44,8 @@ struct Ast_Resolved_Type{
|
|||||||
Ast_Resolved_Type_Kind kind;
|
Ast_Resolved_Type_Kind kind;
|
||||||
SizeU size;
|
SizeU size;
|
||||||
SizeU align;
|
SizeU align;
|
||||||
|
|
||||||
|
Sym *sym;
|
||||||
union{
|
union{
|
||||||
Ast_Resolved_Type *base;
|
Ast_Resolved_Type *base;
|
||||||
struct{
|
struct{
|
||||||
@@ -145,9 +149,23 @@ type_lambda(Ast_Resolved_Type *ret, Array<Ast_Resolved_Type *> args){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Resolved_Type *
|
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
|
Ast_Resolved_Type *result = type_new(pctx->perm, TYPE_Struct, 0, 0); // @todo: align,size
|
||||||
result->agg.fields = fields.tight_copy(pctx->perm);
|
result->agg.fields = fields.tight_copy(pctx->perm);
|
||||||
|
result->sym = sym;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
structs.kl
16
structs.kl
@@ -1,6 +1,22 @@
|
|||||||
|
|
||||||
|
arena_pointer: *Arena = null
|
||||||
Arena :: struct
|
Arena :: struct
|
||||||
|
// next: *Arena
|
||||||
data: *int
|
data: *int
|
||||||
len : int
|
len : int
|
||||||
cap : 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
|
||||||
Reference in New Issue
Block a user