Complete rework, adding packages

This commit is contained in:
Krzosa Karol
2022-06-09 21:30:52 +02:00
parent 4edd2a4799
commit fbe911d267
11 changed files with 399 additions and 497 deletions

288
ast.cpp
View File

@@ -7,6 +7,7 @@ enum Ast_Kind: U32{
AST_PACKAGE,
AST_SCOPE,
AST_VALUE,
AST_CAST,
AST_IDENT,
@@ -16,6 +17,8 @@ enum Ast_Kind: U32{
AST_CALL_ITEM,
AST_CALL,
AST_VAR,
AST_CONST,
AST_POINTER,
AST_ARRAY,
AST_FOR,
@@ -29,8 +32,6 @@ enum Ast_Kind: U32{
AST_ENUM,
AST_ENUM_MEMBER,
AST_STRUCT,
AST_CONST,
AST_VAR,
};
typedef U32 Ast_Flag;
@@ -43,6 +44,7 @@ enum{
AST_ITEM_INCLUDED = bit_flag(6),
AST_ATOM = bit_flag(7),
AST_FOREIGN = bit_flag(8),
AST_DECL = bit_flag(9),
};
struct Ast{
@@ -161,16 +163,6 @@ struct Ast_Array: Ast_Expr{
Ast_Expr *expr;
};
struct Ast_Named:Ast{
Intern_String name;
};
enum Ast_Decl_State{
DECL_NOT_RESOLVED,
DECL_RESOLVED,
DECL_RESOLVING,
};
/*
How does current declaration order resolver works:
* First we put all the global declarations into the global scope (when parsing) all unresolved
@@ -188,81 +180,43 @@ How does current declaration order resolver works:
resolving, we got a circular dependency. That might happen when we have
that struct without pointer inside itself.
We need a new algorithm to process structs
we probably want default values so constants
can be evaluated first, also it's pretty weird that
only top scope gets special treatment
Idea 1
New algorithm, at some point in a constant we might
see the struct inside which is the constant. struct is
unresolved so we probably call resolve_name on struct
and struct continues resolving omitting already resolved and
declaration that requires the struct size. Problem is what happens
when we meet a member that references a constant and that constant
has reference to struct.
Idea 2
We resolve first members without default values, we add to queue dependencies
then we resolve constants. And at the end we resolve the queued values.
*/
struct Ast_Scope{
Array<Ast_Decl *> resolved;
Array<Ast *> children;
Array<Ast *> constants;
enum Ast_Decl_State{
DECL_NOT_RESOLVED,
DECL_RESOLVED,
DECL_RESOLVING,
};
struct Ast_Decl;
struct Ast_Scope: Ast{
Array<Ast_Decl *> resolved;
Array<Ast_Decl *> decls;
Array<Ast *> stmts;
};
struct Ast_Decl: Ast{
Ast_Decl_State state;
// kind:AST_CONST: subkind:AST_STRUCT, AST_ENUM, AST_EXPR(can be TYPE_TYPE), AST_LAMBDA
// kind:AST_VAR : subkind:AST_EXPR, AST_LAMBDA
// Kind: AST_STRUCT implied AST_DECL (should flag AST_CONST AST_DECL)
Intern_String name;
Ast_Kind sub_kind;
Ast_Scope *scope;
Ast_Resolved_Type *type;
};
struct Ast_Var: Ast_Named{
Ast_Expr *typespec;
Ast_Expr *expr;
};
struct Ast_Const;
struct Ast_Resolved_Type;
struct Ast_Struct: Ast{
// Required to be Ast_Struct or Ast_Var or Ast_Const
Array<Ast_Var *> members;
Array<Ast_Const *> const_members;
Ast_Resolved_Type *type;
};
struct Ast_Enum_Member: Ast{
Intern_String name;
Ast_Expr *value;
};
struct Ast_Enum: Ast{
Ast_Expr *typespec;
Array<Ast_Enum_Member *> members;
INLINE_VALUE_FIELDS;
};
struct Ast_Const: Ast_Named{
union{
Ast *ast;
Ast_Expr *value;
Ast_Struct *agg;
Ast_Enum *enu;
};
};
struct Ast_File{
String filename;
String filecontent;
struct Ast_Package:Ast{
Intern_String name;
Array<Ast_Named *> decls;
Array<Ast_Named *> ordered;
Array<Ast_Decl *> decls;
};
struct Ast_Package : Ast_Scope{
Intern_String name;
};
//-----------------------------------------------------------------------------
@@ -482,76 +436,72 @@ ast_array(Token *pos, Ast_Expr *expr){
return result;
}
function Ast_Enum_Member *
ast_enum_member(Token *pos, Intern_String name, Ast_Expr *default_value){
AST_NEW(Enum_Member, ENUM_MEMBER, pos, AST_AGGREGATE_CHILD);
result->name = name;
result->value = default_value;
if(result->value) result->value->parent = result;
function Ast_Scope *
ast_decl_scope(Token *pos, Array<Ast_Decl *> decls){
AST_NEW(Scope, SCOPE, pos, AST_DECL);
result->decls = decls.tight_copy(pctx->perm);
result->resolved = array_make<Ast_Decl *>(pctx->perm, result->decls.len);
For(result->decls){
it->parent = result;
}
return result;
}
function Ast_Enum *
ast_enum(Token *pos, Ast_Expr *typespec, Array<Ast_Enum_Member *> members){
AST_NEW(Enum, ENUM, pos, AST_AGGREGATE);
result->members = members.tight_copy(pctx->perm);
function Ast_Scope *
ast_stmt_scope(Token *pos, Array<Ast *> stmts){
AST_NEW(Scope, SCOPE, pos, AST_STMT);
result->stmts = stmts.tight_copy(pctx->perm);
For(result->stmts){
it->parent = result;
}
return result;
}
function Ast_Decl *
ast_struct(Token *pos, Array<Ast_Decl *> decls){
AST_NEW(Decl, STRUCT, pos, AST_DECL | AST_AGGREGATE);
result->scope = ast_decl_scope(pos, decls);
result->scope->parent = result;
return result;
}
function Ast_Decl *
ast_enum(Token *pos, Ast_Expr *typespec, Array<Ast_Decl *> decls){
AST_NEW(Decl, ENUM, pos, AST_DECL | AST_AGGREGATE);
result->scope = ast_decl_scope(pos, decls);
result->typespec = typespec;
result->scope->parent = result;
if(result->typespec) result->typespec->parent = result;
For(result->members){
it->parent = result;
}
return result;
}
function Ast_Struct *
ast_struct(Token *pos, Array<Ast_Var *> members, Array<Ast_Const *> const_members){
AST_NEW(Struct, STRUCT, pos, AST_AGGREGATE);
result->members = members.tight_copy(pctx->perm);
result->const_members = const_members.tight_copy(pctx->perm);
For(result->members) {
assert(is_flag_set(it->flags, AST_BINDING));
assert(it->kind == AST_VAR);
it->parent = result;
}
For(result->const_members) {
assert(is_flag_set(it->flags, AST_BINDING));
assert(it->kind == AST_CONST);
it->parent = result;
}
return result;
}
//-----------------------------------------------------------------------------
// Declarations
//-----------------------------------------------------------------------------
function Ast_Var *
function Ast_Decl *
ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr){
AST_NEW(Var, VAR, pos, AST_BINDING);
result->expr = expr;
result->typespec = typespec;
result->name = name;
if(result->expr) result->expr->parent = result;
if(result->typespec) result->typespec->parent = result;
return result;
}
function Ast_Const *
ast_const(Token *pos, Intern_String name, Ast_Expr *value){
assert(is_flag_set(value->flags, AST_AGGREGATE) || is_flag_set(value->flags, AST_EXPR) );
AST_NEW(Const, CONST, pos, AST_BINDING);
result->value = value;
AST_NEW(Decl, VAR, pos, AST_DECL);
result->name = name;
result->value->parent = result;
result->typespec = typespec;
result->expr = expr;
if(result->typespec) result->typespec->parent = result;
if(result->expr) result->expr->parent = result;
return result;
}
function Ast_Package *
ast_package(Token *pos, String name, Array<Ast_Named *> decls){
AST_NEW(Package, PACKAGE, pos, 0);
result->decls = decls.tight_copy(pctx->perm);
result->ordered = array_make<Ast_Named *>(pctx->perm, decls.len);
result->name = intern_string(&pctx->interns, name);
For(result->decls) it->parent = result;
function Ast_Decl *
ast_const(Token *pos, Intern_String name, Ast_Expr *expr){
AST_NEW(Decl, CONST, pos, AST_DECL);
result->expr = expr;
result->name = name;
if(result->expr) result->expr->parent = result;
return result;
}
function Ast_Package
ast_package(Allocator *allocator, Intern_String name, Array<Ast_Decl *> decls){
Ast_Package result = {};
result.kind = AST_PACKAGE;
result.decls = decls.copy(allocator);
result.resolved = {allocator};
result.name = name;
return result;
}
@@ -598,61 +548,6 @@ value_float(BigInt a){
return value;
}
//-----------------------------------------------------------------------------
// Utillities
//-----------------------------------------------------------------------------
function Ast_Struct *
const_try_getting_struct(Ast *ast){
assert(ast->kind == AST_CONST);
Ast_Const *constant = (Ast_Const *)ast;
if(constant->value->kind == AST_STRUCT){
return (Ast_Struct *)constant->value;
}
return 0;
}
function Ast_Struct *
const_get_struct(Ast *ast){
auto result = const_try_getting_struct(ast);
assert(result);
return result;
}
function Ast_Lambda *
const_try_getting_lambda(Ast *ast){
assert(ast->kind == AST_CONST);
Ast_Const *constant = (Ast_Const *)ast;
if(constant->value->kind == AST_LAMBDA){
return (Ast_Lambda *)constant->value;
}
return 0;
}
function Ast_Lambda *
const_get_lambda(Ast *ast){
auto result = const_try_getting_lambda(ast);
assert(result);
return result;
}
function Intern_String
ast_get_name(Ast *ast){
assert(is_flag_set(ast->flags, AST_BINDING));
auto constant = (Ast_Named *)ast;
return constant->name;
}
function B32
ast_is_struct(Ast *ast){
if(ast->kind == AST_CONST){
auto a = (Ast_Const *)ast;
B32 result = a->agg->kind == AST_STRUCT;
return result;
}
return false;
}
function B32
is_ident(Ast *ast){
B32 result = ast->kind == AST_IDENT;
@@ -670,28 +565,3 @@ is_atom(Ast *ast){
B32 result = is_flag_set(ast->flags, AST_ATOM);
return result;
}
function Ast *
query_struct(Ast_Struct *agg, Intern_String string){
For(agg->members){
if(it->name == string){
return it;
}
}
For(agg->const_members){
if(it->name == string){
return it;
}
}
return 0;
}
function Ast_Enum_Member *
query_enum(Ast_Enum *enu, Intern_String string){
For(enu->members){
if(it->name == string){
return it;
}
}
return 0;
}