From b773ad1c17b15cbfcb57681c6c3bd7ea7bd0fa7b Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Thu, 26 May 2022 21:09:07 +0200 Subject: [PATCH] Trying to add order indendent decls --- cgenerate.cpp | 4 +- main.cpp | 1 + new_ast.cpp | 24 +++++----- new_parse.cpp | 26 +---------- new_resolve.cpp | 120 ++++++++++++++++++++++++++++++++++++++++++------ 5 files changed, 124 insertions(+), 51 deletions(-) diff --git a/cgenerate.cpp b/cgenerate.cpp index 63fde68..9565df7 100644 --- a/cgenerate.cpp +++ b/cgenerate.cpp @@ -298,13 +298,15 @@ compile_string(String filecontent, String filename = "default_name"_s){ lex_restream(&ctx, filecontent, filename); Ast_Package *result = parse_file(); sym_insert_builtins(); + pctx->resolving_package = result; gen(R"==(//------------------------------- #define NULL_POINTER 0 #define NULL_LAMBDA 0 //-------------------------------)=="); - eval_decl(result); + resolve_package(result); + // eval_decl(result); gen_ast(result); exp_destroy(&heap); diff --git a/main.cpp b/main.cpp index 9c0c779..db0c24f 100644 --- a/main.cpp +++ b/main.cpp @@ -19,6 +19,7 @@ int main(){ test_intern_table(); lex_test(); + // String result = compile_file("lambdas.kl"_s); String result = compile_file("order_independent_globals.kl"_s); printf("%s", result.str); diff --git a/new_ast.cpp b/new_ast.cpp index e832860..55410bb 100644 --- a/new_ast.cpp +++ b/new_ast.cpp @@ -19,6 +19,7 @@ Intern_String intern_int; Intern_String intern_str; Intern_String intern_unsigned; +struct Ast_Package; struct Sym; struct Parse_Ctx:Lexer{ Allocator *perm; // Stores: AST, tokens, interns @@ -27,6 +28,7 @@ struct Parse_Ctx:Lexer{ U64 unique_ids; Map type_map; + Ast_Package *resolving_package; Map resolved; Map syms; S32 scope; @@ -110,10 +112,11 @@ struct Ast{ Token *pos; Ast_Kind kind; - bool is_stmt: 1; - bool is_expr: 1; - bool is_decl: 1; - bool is_named: 1; + // @todo? + // bool is_stmt: 1; + // bool is_expr: 1; + // bool is_decl: 1; + // bool is_named: 1; }; struct Ast_Resolved_Type; @@ -128,8 +131,7 @@ struct Ast_Atom: Ast_Expr{ }; struct Ast_Compound_Item: Ast_Expr{ - // @todo: Ast_Expr to Ast_Atom - Ast_Expr *name; // index | name + Ast_Atom *name; // index | name Ast_Expr *index; Ast_Expr *item; }; @@ -215,19 +217,18 @@ struct Ast_Named:Ast{ }; struct Ast_Var: Ast_Named{ - Intern_String name; Ast_Typespec *typespec; Ast_Expr *expr; }; struct Ast_Const: Ast_Named{ - Intern_String name; Ast_Expr *expr; }; struct Ast_Package:Ast{ Intern_String name; Array decls; + Array ordered; }; function Ast_Typespec *ast_typespec_name(Token *pos, Intern_String name); @@ -279,7 +280,7 @@ ast_expr_compound(Token *pos, Ast_Typespec *typespec, Array } 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); result->name = name; result->index = index; @@ -425,7 +426,8 @@ ast_const(Token *pos, Intern_String name, Ast_Expr *expr){ function Ast_Package * ast_package(Token *pos, String name, Array decls){ AST_NEW(Package, AST_PACKAGE, pos); - result->decls = decls.tight_copy(pctx->perm); - result->name = intern_string(&pctx->interns, name); + result->decls = decls.tight_copy(pctx->perm); + result->ordered = array_make(pctx->perm, decls.len); + result->name = intern_string(&pctx->interns, name); return result; } diff --git a/new_parse.cpp b/new_parse.cpp index fbbf1a4..b150ae0 100644 --- a/new_parse.cpp +++ b/new_parse.cpp @@ -144,7 +144,7 @@ parse_expr_compound(){ while(!token_is(TK_CloseBrace)){ Token *token = token_get(); Ast_Expr *index = 0; - Ast_Expr *name = 0; + Ast_Atom *name = 0; if(token_match(TK_OpenBracket)){ index = parse_expr(); token_expect(TK_CloseBracket); @@ -452,28 +452,4 @@ parse_named(B32 is_global){ 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(); - Arraydecls = {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; -} - diff --git a/new_resolve.cpp b/new_resolve.cpp index 9b6b71f..b4ee603 100644 --- a/new_resolve.cpp +++ b/new_resolve.cpp @@ -2,16 +2,24 @@ #define Ast_End() } break enum Sym_Kind{ - SYM_None, - SYM_Type, - SYM_Const, - SYM_Var, + SYM_NONE, + SYM_TYPE, + SYM_CONST, + SYM_VAR, +}; + +enum Sym_State{ + SYM_NOT_RESOLVED, + SYM_RESOLVING, + SYM_RESOLVED, }; struct Sym{ Intern_String name; Sym_Kind kind; + Sym_State state; Ast *ast; + Ast_Resolved_Type *type; union{ S64 int_val; @@ -90,7 +98,7 @@ resolved_get(Ast *ast){ function void sym_insert_builtin_type(String name, Ast_Resolved_Type *type){ 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); } @@ -103,19 +111,19 @@ sym_insert_builtins(){ { 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); } { 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); } { 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); } } @@ -131,7 +139,7 @@ eval_typespec(Ast_Typespec *ast){ if(!type_sym){ 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"); } @@ -216,7 +224,7 @@ eval_stmt(Ast *ast, Ast_Resolved_Type *ret){ switch(node->op){ case TK_Comma:{ 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); }break; invalid_default_case; @@ -299,7 +307,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){ } else{ 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; } @@ -315,7 +323,7 @@ eval_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type){ S64 scope_index = scope_push(); For(node->args){ 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); } For(node->block->stmts){ @@ -459,7 +467,7 @@ eval_decl(Ast *ast){ Operand expr = node->expr ? eval_expr(node->expr, type) : Operand{}; 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); 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"); 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; else if(resolved_type == type_string) sym->intern_val = expr.intern_val; 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(); + Arraydecls = {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; +} +