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_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,7 +284,8 @@ gen_ast(Ast *ast){
|
||||
}
|
||||
else if(sym->type == type_type){
|
||||
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);
|
||||
global_indent++;
|
||||
For(agg->members){
|
||||
@@ -289,6 +295,10 @@ gen_ast(Ast *ast){
|
||||
global_indent--;
|
||||
genln("};");
|
||||
}
|
||||
else{
|
||||
// type alias
|
||||
}
|
||||
}
|
||||
else{
|
||||
gen("// typedef ");
|
||||
gen_simple_decl(sym->type_val, node->name);
|
||||
|
||||
4
main.cpp
4
main.cpp
@@ -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);
|
||||
|
||||
|
||||
13
new_ast.cpp
13
new_ast.cpp
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
20
new_type.cpp
20
new_type.cpp
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
16
structs.kl
16
structs.kl
@@ -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
|
||||
Reference in New Issue
Block a user