Trying to add order indendent decls
This commit is contained in:
@@ -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);
|
||||||
|
|
||||||
|
|||||||
1
main.cpp
1
main.cpp
@@ -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);
|
||||||
|
|
||||||
|
|||||||
20
new_ast.cpp
20
new_ast.cpp
@@ -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;
|
||||||
@@ -426,6 +427,7 @@ 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->ordered = array_make<Ast_Named *>(pctx->perm, decls.len);
|
||||||
result->name = intern_string(&pctx->interns, name);
|
result->name = intern_string(&pctx->interns, name);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
120
new_resolve.cpp
120
new_resolve.cpp
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user