Trying to add order indendent decls

This commit is contained in:
Krzosa Karol
2022-05-26 21:09:07 +02:00
parent 0e398c84b6
commit b773ad1c17
5 changed files with 124 additions and 51 deletions

View File

@@ -298,13 +298,15 @@ compile_string(String filecontent, String filename = "default_name"_s){
lex_restream(&ctx, filecontent, filename); lex_restream(&ctx, filecontent, filename);
Ast_Package *result = parse_file(); Ast_Package *result = parse_file();
sym_insert_builtins(); sym_insert_builtins();
pctx->resolving_package = result;
gen(R"==(//------------------------------- gen(R"==(//-------------------------------
#define NULL_POINTER 0 #define NULL_POINTER 0
#define NULL_LAMBDA 0 #define NULL_LAMBDA 0
//-------------------------------)=="); //-------------------------------)==");
eval_decl(result); resolve_package(result);
// eval_decl(result);
gen_ast(result); gen_ast(result);
exp_destroy(&heap); exp_destroy(&heap);

View File

@@ -19,6 +19,7 @@ int main(){
test_intern_table(); test_intern_table();
lex_test(); lex_test();
// String result = compile_file("lambdas.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);

View File

@@ -19,6 +19,7 @@ Intern_String intern_int;
Intern_String intern_str; Intern_String intern_str;
Intern_String intern_unsigned; Intern_String intern_unsigned;
struct Ast_Package;
struct Sym; struct Sym;
struct Parse_Ctx:Lexer{ struct Parse_Ctx:Lexer{
Allocator *perm; // Stores: AST, tokens, interns Allocator *perm; // Stores: AST, tokens, interns
@@ -27,6 +28,7 @@ struct Parse_Ctx:Lexer{
U64 unique_ids; U64 unique_ids;
Map type_map; Map type_map;
Ast_Package *resolving_package;
Map resolved; Map resolved;
Map syms; Map syms;
S32 scope; S32 scope;
@@ -110,10 +112,11 @@ struct Ast{
Token *pos; Token *pos;
Ast_Kind kind; Ast_Kind kind;
bool is_stmt: 1; // @todo?
bool is_expr: 1; // bool is_stmt: 1;
bool is_decl: 1; // bool is_expr: 1;
bool is_named: 1; // bool is_decl: 1;
// bool is_named: 1;
}; };
struct Ast_Resolved_Type; struct Ast_Resolved_Type;
@@ -128,8 +131,7 @@ struct Ast_Atom: Ast_Expr{
}; };
struct Ast_Compound_Item: Ast_Expr{ struct Ast_Compound_Item: Ast_Expr{
// @todo: Ast_Expr to Ast_Atom Ast_Atom *name; // index | name
Ast_Expr *name; // index | name
Ast_Expr *index; Ast_Expr *index;
Ast_Expr *item; Ast_Expr *item;
}; };
@@ -215,19 +217,18 @@ struct Ast_Named:Ast{
}; };
struct Ast_Var: Ast_Named{ struct Ast_Var: Ast_Named{
Intern_String name;
Ast_Typespec *typespec; Ast_Typespec *typespec;
Ast_Expr *expr; Ast_Expr *expr;
}; };
struct Ast_Const: Ast_Named{ struct Ast_Const: Ast_Named{
Intern_String name;
Ast_Expr *expr; Ast_Expr *expr;
}; };
struct Ast_Package:Ast{ struct Ast_Package:Ast{
Intern_String name; Intern_String name;
Array<Ast_Named *> decls; Array<Ast_Named *> decls;
Array<Ast_Named *> ordered;
}; };
function Ast_Typespec *ast_typespec_name(Token *pos, Intern_String name); function Ast_Typespec *ast_typespec_name(Token *pos, Intern_String name);
@@ -279,7 +280,7 @@ ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array<Ast_Compound_Item *>
} }
function Ast_Compound_Item * function Ast_Compound_Item *
ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Expr *name, Ast_Expr *item){ ast_expr_compound_item(Token *pos, Ast_Expr *index, Ast_Atom *name, Ast_Expr *item){
AST_NEW(Compound_Item, AST_COMPOUND_ITEM, pos); AST_NEW(Compound_Item, AST_COMPOUND_ITEM, pos);
result->name = name; result->name = name;
result->index = index; result->index = index;
@@ -425,7 +426,8 @@ ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
function Ast_Package * function Ast_Package *
ast_package(Token *pos, String name, Array<Ast_Named *> decls){ ast_package(Token *pos, String name, Array<Ast_Named *> decls){
AST_NEW(Package, AST_PACKAGE, pos); AST_NEW(Package, AST_PACKAGE, pos);
result->decls = decls.tight_copy(pctx->perm); result->decls = decls.tight_copy(pctx->perm);
result->name = intern_string(&pctx->interns, name); result->ordered = array_make<Ast_Named *>(pctx->perm, decls.len);
result->name = intern_string(&pctx->interns, name);
return result; return result;
} }

View File

@@ -144,7 +144,7 @@ parse_expr_compound(){
while(!token_is(TK_CloseBrace)){ while(!token_is(TK_CloseBrace)){
Token *token = token_get(); Token *token = token_get();
Ast_Expr *index = 0; Ast_Expr *index = 0;
Ast_Expr *name = 0; Ast_Atom *name = 0;
if(token_match(TK_OpenBracket)){ if(token_match(TK_OpenBracket)){
index = parse_expr(); index = parse_expr();
token_expect(TK_CloseBracket); token_expect(TK_CloseBracket);
@@ -452,28 +452,4 @@ parse_named(B32 is_global){
return result; return result;
} }
function Ast_Package *
parse_file(){
Scratch scratch;
//
// @note: pop the first token with token_next() / token_expect()
// which always should be an indentation token,
// it updates the indent info on the parser,
// making sure that indentation on
// the first line is properly updated
//
Token *token = token_get();
Array<Ast_Named *>decls = {scratch};
while(!token_is(TK_End)){
token_expect(SAME_SCOPE);
Ast_Named *decl = parse_named(true);
if(!decl) break;
decls.add(decl);
}
Ast_Package *result = ast_package(token, token->file, decls);
return result;
}

View File

@@ -2,16 +2,24 @@
#define Ast_End() } break #define Ast_End() } break
enum Sym_Kind{ enum Sym_Kind{
SYM_None, SYM_NONE,
SYM_Type, SYM_TYPE,
SYM_Const, SYM_CONST,
SYM_Var, SYM_VAR,
};
enum Sym_State{
SYM_NOT_RESOLVED,
SYM_RESOLVING,
SYM_RESOLVED,
}; };
struct Sym{ struct Sym{
Intern_String name; Intern_String name;
Sym_Kind kind; Sym_Kind kind;
Sym_State state;
Ast *ast; Ast *ast;
Ast_Resolved_Type *type; Ast_Resolved_Type *type;
union{ union{
S64 int_val; S64 int_val;
@@ -90,7 +98,7 @@ resolved_get(Ast *ast){
function void function void
sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ sym_insert_builtin_type(String name, Ast_Resolved_Type *type){
Intern_String string = intern_string(&pctx->interns, name); Intern_String string = intern_string(&pctx->interns, name);
Sym *sym = sym_new(SYM_Type, string, type, &empty_decl); Sym *sym = sym_new(SYM_TYPE, string, type, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
@@ -103,19 +111,19 @@ sym_insert_builtins(){
{ {
Intern_String string = intern_string(&pctx->interns, "true"_s); Intern_String string = intern_string(&pctx->interns, "true"_s);
Sym *sym = sym_new(SYM_Const, string, type_bool, &empty_decl); Sym *sym = sym_new(SYM_CONST, string, type_bool, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
{ {
Intern_String string = intern_string(&pctx->interns, "false"_s); Intern_String string = intern_string(&pctx->interns, "false"_s);
Sym *sym = sym_new(SYM_Const, string, type_bool, &empty_decl); Sym *sym = sym_new(SYM_CONST, string, type_bool, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
{ {
Intern_String string = intern_string(&pctx->interns, "null"_s); Intern_String string = intern_string(&pctx->interns, "null"_s);
Sym *sym = sym_new(SYM_Const, string, type_null, &empty_decl); Sym *sym = sym_new(SYM_CONST, string, type_null, &empty_decl);
sym_insert(sym); sym_insert(sym);
} }
} }
@@ -131,7 +139,7 @@ eval_typespec(Ast_Typespec *ast){
if(!type_sym){ if(!type_sym){
parsing_error(node->pos, "This type is not defined"); parsing_error(node->pos, "This type is not defined");
} }
if(type_sym->kind != SYM_Type){ if(type_sym->kind != SYM_TYPE){
parsing_error(node->pos, "This identifier is not a type"); parsing_error(node->pos, "This identifier is not a type");
} }
@@ -216,7 +224,7 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){
switch(node->op){ switch(node->op){
case TK_Comma:{ case TK_Comma:{
Operand op = eval_expr(node->expr); Operand op = eval_expr(node->expr);
Sym *sym = sym_new(SYM_Var, node->ident->intern_val, op.type, node); Sym *sym = sym_new(SYM_VAR, node->ident->intern_val, op.type, node);
sym_insert(sym); sym_insert(sym);
}break; }break;
invalid_default_case; invalid_default_case;
@@ -299,7 +307,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){
} }
else{ else{
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;
result.int_val = sym->int_val; result.int_val = sym->int_val;
} }
@@ -315,7 +323,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){
S64 scope_index = scope_push(); S64 scope_index = scope_push();
For(node->args){ For(node->args){
Ast_Resolved_Type *type = eval_typespec(it[0]->typespec); Ast_Resolved_Type *type = eval_typespec(it[0]->typespec);
Sym *arg_sym = sym_new(SYM_Var, it[0]->name, type, it[0]); Sym *arg_sym = sym_new(SYM_VAR, it[0]->name, type, it[0]);
sym_insert(arg_sym); sym_insert(arg_sym);
} }
For(node->block->stmts){ For(node->block->stmts){
@@ -459,7 +467,7 @@ eval_decl(Ast *ast){
Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{}; Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{};
Ast_Resolved_Type *resolved_type = resolve_type_pair(node->pos, type, expr.type); Ast_Resolved_Type *resolved_type = resolve_type_pair(node->pos, type, expr.type);
Sym *sym = sym_new(SYM_Var, node->name, resolved_type, node); Sym *sym = sym_new(SYM_VAR, node->name, resolved_type, node);
sym_insert(sym); sym_insert(sym);
Ast_End(); Ast_End();
} }
@@ -470,7 +478,7 @@ eval_decl(Ast *ast){
if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression"); if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression");
Ast_Resolved_Type *resolved_type = expr.type; Ast_Resolved_Type *resolved_type = expr.type;
Sym *sym = sym_new(SYM_Const, node->name, resolved_type, node); Sym *sym = sym_new(SYM_CONST, node->name, resolved_type, node);
if(resolved_type == type_int) sym->int_val = expr.int_val; if(resolved_type == type_int) sym->int_val = expr.int_val;
else if(resolved_type == type_string) sym->intern_val = expr.intern_val; else if(resolved_type == type_string) sym->intern_val = expr.intern_val;
sym_insert(sym); sym_insert(sym);
@@ -481,3 +489,87 @@ eval_decl(Ast *ast){
} }
} }
function void
resolve_sym(Sym *sym){
if(sym->state == SYM_RESOLVED) return;
else if(sym->state == SYM_RESOLVING){ parsing_error(sym->ast->pos, "Cyclic dependency"); return; }
assert(sym->state == SYM_NOT_RESOLVED);
sym->state = SYM_RESOLVING;
Ast_Named *ast = (Ast_Named *)sym->ast;
switch(ast->kind){
Ast_Begin(AST_VAR, Ast_Var){
Ast_Resolved_Type *type = eval_typespec(node->typespec);
Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{};
Ast_Resolved_Type *resolved_type = resolve_type_pair(node->pos, type, expr.type);
sym->type = resolved_type;
Ast_End();
}
Ast_Begin(AST_CONST, Ast_Const){
Operand expr = eval_expr(node->expr);
if(!expr.type) parsing_error(node->pos, "Constant value without expression");
if(!expr.is_const) parsing_error(node->pos, "Value of constant variable is not a constant expression");
Ast_Resolved_Type *resolved_type = expr.type;
sym->type = resolved_type;
if(resolved_type == type_int) sym->int_val = expr.int_val;
else if(resolved_type == type_string) sym->intern_val = expr.intern_val;
Ast_End();
}
invalid_default_case;
}
sym->state = SYM_RESOLVED;
pctx->resolving_package->ordered.add(ast);
}
function Sym *
resolve_name(Token *pos, Intern_String name){
Sym *sym = sym_get(name);
if(!sym) parsing_error(pos, "Unidentified name [%s]", name.str);
resolve_sym(sym);
return sym;
}
function void
resolve_package(Ast_Package *package){
For(package->decls){
resolve_name(it[0]->pos, it[0]->name);
}
}
function Ast_Package *
parse_file(){
Scratch scratch;
//
// @note: pop the first token with token_next() / token_expect()
// which always should be an indentation token,
// it updates the indent info on the parser,
// making sure that indentation on
// the first line is properly updated
//
Token *token = token_get();
Array<Ast_Named *>decls = {scratch};
while(!token_is(TK_End)){
token_expect(SAME_SCOPE);
Ast_Named *decl = parse_named(true);
if(!decl) break;
Sym_Kind kind = SYM_VAR;
if(decl->kind == AST_CONST) kind = SYM_CONST;
else if(decl->kind == AST_VAR) kind = SYM_VAR;
else invalid_codepath;
Sym *sym = sym_new(kind, decl->name, 0, decl);
sym_insert(sym);
decls.add(decl);
}
Ast_Package *result = ast_package(token, token->file, decls);
return result;
}