Complete rework, adding packages
This commit is contained in:
288
ast.cpp
288
ast.cpp
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user