Iterator + start to add core to core codegen
This commit is contained in:
@@ -39,7 +39,7 @@ struct Array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dealloc() {
|
void dealloc() {
|
||||||
deallocate(allocator, data);
|
if (data) deallocate(allocator, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
S64 get_index(T *item) {
|
S64 get_index(T *item) {
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ ast_enum(Token *pos, Ast_Expr *typespec, Ast_Scope *scope) {
|
|||||||
AST_NEW(Decl, ENUM, pos, AST_DECL);
|
AST_NEW(Decl, ENUM, pos, AST_DECL);
|
||||||
result->scope = scope;
|
result->scope = scope;
|
||||||
result->typespec = typespec;
|
result->typespec = typespec;
|
||||||
|
if (typespec) set_flag(typespec->flags, AST_TYPESPEC);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +249,7 @@ ast_var(Token *pos, Ast_Expr *typespec, Intern_String name, Ast_Expr *expr) {
|
|||||||
AST_NEW(Decl, VAR, pos, AST_DECL);
|
AST_NEW(Decl, VAR, pos, AST_DECL);
|
||||||
result->name = name;
|
result->name = name;
|
||||||
result->typespec = typespec;
|
result->typespec = typespec;
|
||||||
|
if (typespec) set_flag(typespec->flags, AST_TYPESPEC);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,8 +83,9 @@ get_ctype_name_for_type(Ast_Type *type) {
|
|||||||
|
|
||||||
case TYPE_INCOMPLETE: {
|
case TYPE_INCOMPLETE: {
|
||||||
// This happens in case where we have a procedure in an away module.
|
// This happens in case where we have a procedure in an away module.
|
||||||
|
// Meaning that it's not resolved fully on purpose (treeshaking).
|
||||||
// And that procedure takes a pointer from a struct that is never
|
// And that procedure takes a pointer from a struct that is never
|
||||||
// use elsewhere. In that case this seems fine.
|
// used elsewhere. In that case this seems fine.
|
||||||
return "void";
|
return "void";
|
||||||
}
|
}
|
||||||
invalid_default_case;
|
invalid_default_case;
|
||||||
@@ -824,37 +825,144 @@ gen_ast(Ast *ast) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CORE_Static String
|
||||||
|
core_type_to_string(Ast_Type *type) {
|
||||||
|
switch (type->kind) {
|
||||||
|
case TYPE_NONE: return "<NONE>"_s; break;
|
||||||
|
case TYPE_S64: return "S64"_s; break;
|
||||||
|
case TYPE_S32: return "S32"_s; break;
|
||||||
|
case TYPE_S16: return "S16"_s; break;
|
||||||
|
case TYPE_S8: return "S8"_s; break;
|
||||||
|
case TYPE_INT: return "int"_s; break;
|
||||||
|
case TYPE_CHAR: return "char"_s; break;
|
||||||
|
case TYPE_U64: return "U64"_s; break;
|
||||||
|
case TYPE_U32: return "U32"_s; break;
|
||||||
|
case TYPE_U16: return "U16"_s; break;
|
||||||
|
case TYPE_U8: return "U8"_s; break;
|
||||||
|
case TYPE_F32: return "F32"_s; break;
|
||||||
|
case TYPE_F64: return "F64"_s; break;
|
||||||
|
case TYPE_BOOL: return "Bool"_s; break;
|
||||||
|
case TYPE_STRING: return "String"_s; break;
|
||||||
|
case TYPE_VOID: return "void"_s; break;
|
||||||
|
case TYPE_POINTER: {
|
||||||
|
String base = core_type_to_string(type->base);
|
||||||
|
return pctx->fmt("*%Q", base);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_LAMBDA: {
|
||||||
|
String_Builder *b = &pctx->helper_builder;
|
||||||
|
b->addf("(");
|
||||||
|
Array<Ast_Type *> &args = type->func.args;
|
||||||
|
For(args) {
|
||||||
|
String t = core_type_to_string(it);
|
||||||
|
b->addf("%Q", t);
|
||||||
|
if (!args.is_last(&it)) b->addf(", ");
|
||||||
|
}
|
||||||
|
b->addf(")");
|
||||||
|
if (type->func.ret) {
|
||||||
|
String t = core_type_to_string(type->func.ret);
|
||||||
|
b->addf("%Q", t);
|
||||||
|
}
|
||||||
|
String result = string_flatten(pctx->perm, b);
|
||||||
|
return result;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
case TYPE_UNION:
|
||||||
|
case TYPE_ENUM: {
|
||||||
|
// @fixme: we probably want a string on Ast_Type
|
||||||
|
// so that we don't have to reach into Ast_Decl
|
||||||
|
// for Structs Enums etc.
|
||||||
|
Ast_Decl *decl = (Ast_Decl *)type->ast;
|
||||||
|
return decl->name.s;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_ARRAY: {
|
||||||
|
String base = core_type_to_string(type->base);
|
||||||
|
return pctx->fmt("[%u]%Q", type->arr.size, base);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_SLICE: {
|
||||||
|
String base = core_type_to_string(type->base);
|
||||||
|
return pctx->fmt("[]%Q", base);
|
||||||
|
} break;
|
||||||
|
case TYPE_TUPLE: {
|
||||||
|
invalid_codepath;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TYPE_TYPE: return "Type"_s; break;
|
||||||
|
case TYPE_UNTYPED_BOOL: return "UntypedBool"_s; break;
|
||||||
|
case TYPE_UNTYPED_INT: return "UntypedInt"_s; break;
|
||||||
|
case TYPE_UNTYPED_FLOAT: return "UntypedFloat"_s; break;
|
||||||
|
case TYPE_UNTYPED_STRING: return "UntypedString"_s; break;
|
||||||
|
|
||||||
|
case TYPE_COMPLETING: invalid_codepath; break;
|
||||||
|
case TYPE_INCOMPLETE: invalid_codepath; break;
|
||||||
|
case TYPE_POLYMORPH:
|
||||||
|
invalid_codepath;
|
||||||
|
break;
|
||||||
|
|
||||||
|
invalid_default_case;
|
||||||
|
}
|
||||||
|
invalid_return;
|
||||||
|
}
|
||||||
|
|
||||||
CORE_Static String
|
CORE_Static String
|
||||||
compile_to_c_code() {
|
compile_to_c_code() {
|
||||||
pctx->time.code_generation = os_time();
|
pctx->time.code_generation = os_time();
|
||||||
|
|
||||||
|
int di = 0;
|
||||||
For(pctx->ordered_decls) {
|
For(pctx->ordered_decls) {
|
||||||
for (Ast_Iter iter = iterate_depth_first(pctx->heap, it); iter.ast; next(&iter)) {
|
for (Ast_Iter iter = iterate_depth_first(pctx->heap, it); iter.ast; next(&iter)) {
|
||||||
Ast_Decl *decl = (Ast_Decl *)iter.ast;
|
Ast_Decl *decl = (Ast_Decl *)iter.ast;
|
||||||
|
Ast *ast = iter.ast;
|
||||||
|
Ast_Atom *atom = (Ast_Atom *)iter.ast;
|
||||||
|
|
||||||
switch (iter.kind) {
|
switch (iter.kind) {
|
||||||
case AST_STRUCT: {
|
case AST_STRUCT: {
|
||||||
genln("(struct %s", decl->name.str);
|
genln("%Q :: struct", decl->name);
|
||||||
global_indent += 1;
|
global_indent += 1;
|
||||||
} break;
|
} break;
|
||||||
case AST_STRUCT + 128: {
|
case AST_STRUCT + AST_NODE_END: {
|
||||||
|
global_indent -= 1;
|
||||||
|
} break;
|
||||||
|
case AST_LAMBDA: {
|
||||||
|
Ast_Lambda *lambda = decl->lambda;
|
||||||
|
genln("%Q :: (", decl->name);
|
||||||
|
For(lambda->args) {
|
||||||
|
gen("%Q: %Q, ", it->name, core_type_to_string(it->type));
|
||||||
|
}
|
||||||
|
gen(")");
|
||||||
|
|
||||||
|
// @cleanup @refactor: return value shouldn't be a array of expressions.
|
||||||
|
// It should be a single expression. So probably need a special type
|
||||||
|
// for that.
|
||||||
|
if (lambda->args.len) {
|
||||||
|
gen(": ");
|
||||||
|
For(lambda->args) {
|
||||||
|
gen("%Q ", core_type_to_string(it->type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iter.skip_children = true;
|
||||||
|
iter.stack.add(decl);
|
||||||
|
if (lambda->scope) iter.stack.add(lambda->scope);
|
||||||
|
global_indent += 1;
|
||||||
|
} break;
|
||||||
|
case AST_LAMBDA + AST_NODE_END: {
|
||||||
global_indent -= 1;
|
global_indent -= 1;
|
||||||
genln(")");
|
|
||||||
} break;
|
} break;
|
||||||
case AST_VAR: {
|
case AST_VAR: {
|
||||||
genln("(var %s: ", decl->name.str);
|
genln("%Q: %Q", decl->name, core_type_to_string(decl->type));
|
||||||
auto typespec = (Ast_Atom *)decl->typespec;
|
|
||||||
Ast_Decl *type = typespec->resolved_decl;
|
|
||||||
assert(typespec);
|
|
||||||
gen("%s", type->name.str);
|
|
||||||
} break;
|
} break;
|
||||||
case AST_VAR + 128: {
|
case AST_VAR + AST_NODE_END: {
|
||||||
gen(")");
|
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String str = string_flatten(pctx->perm, &pctx->gen);
|
String str = string_flatten(pctx->perm, &pctx->gen);
|
||||||
printf("%s", str.str);
|
printf("%s\n", str.str);
|
||||||
pctx->gen.reset();
|
pctx->gen.reset();
|
||||||
|
di += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefixed_string_type = string_fmt(pctx->perm, "%QString", pctx->symbol_prefix);
|
prefixed_string_type = string_fmt(pctx->perm, "%QString", pctx->symbol_prefix);
|
||||||
|
|||||||
@@ -361,6 +361,8 @@ enum {
|
|||||||
AST_IDENT_POLYMORPH = 1 << 15,
|
AST_IDENT_POLYMORPH = 1 << 15,
|
||||||
AST_TYPE_POLYMORPH = 1 << 16,
|
AST_TYPE_POLYMORPH = 1 << 16,
|
||||||
AST_POLYMORPH = AST_IDENT_POLYMORPH | AST_TYPE_POLYMORPH,
|
AST_POLYMORPH = AST_IDENT_POLYMORPH | AST_TYPE_POLYMORPH,
|
||||||
|
|
||||||
|
AST_TYPESPEC = 1 << 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Ast {
|
struct Ast {
|
||||||
@@ -505,11 +507,11 @@ struct Ast_For : Ast {
|
|||||||
bool is_also_slice_traversal;
|
bool is_also_slice_traversal;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Ast_Lambda : Ast_Expr {
|
||||||
|
Array<Ast_Decl *> args;
|
||||||
// @cleanup @refactor: return value shouldn't be a array of expressions.
|
// @cleanup @refactor: return value shouldn't be a array of expressions.
|
||||||
// It should be a single expression. So probably need a special type
|
// It should be a single expression. So probably need a special type
|
||||||
// for that.
|
// for that.
|
||||||
struct Ast_Lambda : Ast_Expr {
|
|
||||||
Array<Ast_Decl *> args;
|
|
||||||
Array<Ast_Expr *> ret;
|
Array<Ast_Expr *> ret;
|
||||||
Ast_Scope *scope;
|
Ast_Scope *scope;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -266,7 +266,9 @@ parse_expr_call(Ast_Expr *left, Token_Kind close_kind) {
|
|||||||
CORE_Static Ast_Expr *
|
CORE_Static Ast_Expr *
|
||||||
parse_optional_type() {
|
parse_optional_type() {
|
||||||
Ast_Expr *result = 0;
|
Ast_Expr *result = 0;
|
||||||
if (token_match(TK_Colon)) result = parse_expr();
|
if (token_match(TK_Colon)) {
|
||||||
|
result = parse_expr();
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,6 +420,8 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
Ast_If *result_if = ast_if(token, if_nodes);
|
Ast_If *result_if = ast_if(token, if_nodes);
|
||||||
scope->stmts.add(result_if);
|
scope->stmts.add(result_if);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Var unpack
|
||||||
else if (token_is(TK_Identifier) && token_is(TK_Comma, 1)) {
|
else if (token_is(TK_Identifier) && token_is(TK_Comma, 1)) {
|
||||||
Array<Ast_Decl *> decls = {scratch.arena};
|
Array<Ast_Decl *> decls = {scratch.arena};
|
||||||
do {
|
do {
|
||||||
@@ -431,6 +435,8 @@ parse_stmt_scope(Ast_Scope *scope_defined_outside = 0) {
|
|||||||
Ast_Var_Unpack *vars = ast_var_unpack(token, decls, expr);
|
Ast_Var_Unpack *vars = ast_var_unpack(token, decls, expr);
|
||||||
scope->stmts.add(vars);
|
scope->stmts.add(vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Declaration or init stmt
|
||||||
else {
|
else {
|
||||||
Ast *result = parse_decl(false);
|
Ast *result = parse_decl(false);
|
||||||
if (result && result->kind != AST_VAR && result->kind != AST_CONST) {
|
if (result && result->kind != AST_VAR && result->kind != AST_CONST) {
|
||||||
@@ -470,6 +476,7 @@ parse_parameter_list(Arena *arena) {
|
|||||||
Ast_Decl *param = ast_new(Ast_Decl, AST_VAR, name, AST_DECL);
|
Ast_Decl *param = ast_new(Ast_Decl, AST_VAR, name, AST_DECL);
|
||||||
param->name = name->intern_val;
|
param->name = name->intern_val;
|
||||||
param->typespec = parse_expr();
|
param->typespec = parse_expr();
|
||||||
|
set_flag(param->typespec->flags, AST_TYPESPEC);
|
||||||
|
|
||||||
propagate_polymorphic(param, param->typespec);
|
propagate_polymorphic(param, param->typespec);
|
||||||
propagate_polymorphic(param, name);
|
propagate_polymorphic(param, name);
|
||||||
@@ -499,6 +506,7 @@ parse_lambda(Token *token) {
|
|||||||
if (token_match(TK_Colon)) {
|
if (token_match(TK_Colon)) {
|
||||||
do {
|
do {
|
||||||
Ast_Expr *typespec = parse_expr();
|
Ast_Expr *typespec = parse_expr();
|
||||||
|
set_flag(typespec->flags, AST_TYPESPEC);
|
||||||
ret.add(typespec);
|
ret.add(typespec);
|
||||||
} while (token_match(TK_Comma));
|
} while (token_match(TK_Comma));
|
||||||
}
|
}
|
||||||
@@ -595,7 +603,7 @@ parse_expr(S64 min_bp) {
|
|||||||
Token *token = token_next();
|
Token *token = token_next();
|
||||||
Binding_Power prefix_bp = binding_power(Binding_Prefix, token->kind);
|
Binding_Power prefix_bp = binding_power(Binding_Prefix, token->kind);
|
||||||
|
|
||||||
// @note: parse prefix expression
|
// parse prefix expression
|
||||||
switch (token->kind) {
|
switch (token->kind) {
|
||||||
case TK_StringLit: left = ast_str(token, token->intern_val); break;
|
case TK_StringLit: left = ast_str(token, token->intern_val); break;
|
||||||
case TK_Identifier: left = ast_ident(token, token->intern_val); break;
|
case TK_Identifier: left = ast_ident(token, token->intern_val); break;
|
||||||
@@ -611,14 +619,14 @@ parse_expr(S64 min_bp) {
|
|||||||
case TK_Decrement: left = ast_expr_unary(token, TK_Decrement, parse_expr(prefix_bp.right)); break;
|
case TK_Decrement: left = ast_expr_unary(token, TK_Decrement, parse_expr(prefix_bp.right)); break;
|
||||||
case TK_Dereference: left = ast_expr_unary(token, TK_Dereference, parse_expr(prefix_bp.right)); break;
|
case TK_Dereference: left = ast_expr_unary(token, TK_Dereference, parse_expr(prefix_bp.right)); break;
|
||||||
|
|
||||||
// Pointer typespec
|
// Pointer -> *int, Deref -> *var
|
||||||
case TK_Pointer: {
|
case TK_Pointer: {
|
||||||
left = ast_expr_unary(token, TK_Pointer, parse_expr(prefix_bp.right));
|
left = ast_expr_unary(token, TK_Pointer, parse_expr(prefix_bp.right));
|
||||||
auto unary = (Ast_Unary *)left;
|
auto unary = (Ast_Unary *)left;
|
||||||
propagate_polymorphic(unary, unary->expr);
|
propagate_polymorphic(unary, unary->expr);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Array typespec
|
// Array subscript -> [32]int
|
||||||
case TK_OpenBracket: {
|
case TK_OpenBracket: {
|
||||||
Ast_Expr *expr = 0;
|
Ast_Expr *expr = 0;
|
||||||
if (!token_is(TK_CloseBracket))
|
if (!token_is(TK_CloseBracket))
|
||||||
@@ -669,7 +677,7 @@ parse_expr(S64 min_bp) {
|
|||||||
Binding_Power postfix_bp = binding_power(Binding_Postfix, token->kind);
|
Binding_Power postfix_bp = binding_power(Binding_Postfix, token->kind);
|
||||||
Binding_Power infix_bp = binding_power(Binding_Infix, token->kind);
|
Binding_Power infix_bp = binding_power(Binding_Infix, token->kind);
|
||||||
|
|
||||||
// @note: parse postfix expression
|
// parse postfix expression
|
||||||
if (postfix_bp.left > min_bp) {
|
if (postfix_bp.left > min_bp) {
|
||||||
token_next();
|
token_next();
|
||||||
switch (token->kind) {
|
switch (token->kind) {
|
||||||
@@ -694,7 +702,7 @@ parse_expr(S64 min_bp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @note: parse infix expression
|
// parse infix expression
|
||||||
else if (infix_bp.left > min_bp) {
|
else if (infix_bp.left > min_bp) {
|
||||||
token = token_next();
|
token = token_next();
|
||||||
Ast_Expr *right = parse_expr(infix_bp.right);
|
Ast_Expr *right = parse_expr(infix_bp.right);
|
||||||
@@ -734,6 +742,8 @@ parse_struct(Token *pos, Ast_Kind kind) {
|
|||||||
token_expect(TK_Colon);
|
token_expect(TK_Colon);
|
||||||
|
|
||||||
Ast_Expr *typespec = parse_expr();
|
Ast_Expr *typespec = parse_expr();
|
||||||
|
set_flag(typespec->flags, AST_TYPESPEC);
|
||||||
|
|
||||||
Ast_Decl *decl = ast_var(token, typespec, token->intern_val, 0);
|
Ast_Decl *decl = ast_var(token, typespec, token->intern_val, 0);
|
||||||
set_flag(decl->flags, AST_AGGREGATE_CHILD);
|
set_flag(decl->flags, AST_AGGREGATE_CHILD);
|
||||||
add(pctx->perm, &scope->decls, decl);
|
add(pctx->perm, &scope->decls, decl);
|
||||||
@@ -953,8 +963,10 @@ parse_decl(B32 is_global) {
|
|||||||
result->kind = AST_LAMBDA;
|
result->kind = AST_LAMBDA;
|
||||||
result->flags = set_flag(result->flags, AST_OPERATOR_OVERLOAD);
|
result->flags = set_flag(result->flags, AST_OPERATOR_OVERLOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (token_match(TK_Identifier, TK_Colon)) {
|
else if (token_match(TK_Identifier, TK_Colon)) {
|
||||||
Ast_Expr *typespec = parse_expr();
|
Ast_Expr *typespec = parse_expr();
|
||||||
|
set_flag(typespec->flags, AST_TYPESPEC);
|
||||||
Ast_Expr *expr = parse_assign_expr();
|
Ast_Expr *expr = parse_assign_expr();
|
||||||
if (token_match_pound(pctx->intern_foreign))
|
if (token_match_pound(pctx->intern_foreign))
|
||||||
set_flag(flags, AST_FOREIGN);
|
set_flag(flags, AST_FOREIGN);
|
||||||
|
|||||||
@@ -4,64 +4,42 @@ Ast_Decl *get_or_instantiate_polymorph_type(Ast_Decl *poly, Array<Ast_Call_Item
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* @todo
|
const unsigned AST_NODE_END = 128;
|
||||||
for (Ast_Iter iter = iterate_depth_first(ast); iter.ast; next(&iter)) {
|
|
||||||
Ast *ast = iter.ast;
|
|
||||||
|
|
||||||
switch(ast->kind) {
|
|
||||||
case AST_CALL: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case AST_CALL_END: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct Ast_Iter {
|
struct Ast_Iter {
|
||||||
Array<Ast *> stack;
|
Array<Ast *> stack;
|
||||||
Ast *ast;
|
Ast *ast;
|
||||||
Ast_Kind kind;
|
Ast_Kind kind;
|
||||||
|
bool skip_children;
|
||||||
uint32_t visit_id;
|
uint32_t visit_id;
|
||||||
uint32_t di;
|
uint32_t di;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t Ast_Iter_VisitIDGen;
|
uint32_t Ast_Iter_VisitIDGen;
|
||||||
Ast_Iter iterate_depth_first(Allocator *a, Ast *ast) {
|
Ast_Iter iterate_depth_first(Allocator *a, Ast *ast) {
|
||||||
|
assert(ast);
|
||||||
Ast_Iter result = {};
|
Ast_Iter result = {};
|
||||||
result.stack = {a};
|
result.stack = {a};
|
||||||
result.stack.add(ast);
|
result.ast = ast;
|
||||||
|
result.kind = ast->kind;
|
||||||
result.visit_id = ++Ast_Iter_VisitIDGen;
|
result.visit_id = ++Ast_Iter_VisitIDGen;
|
||||||
void next(Ast_Iter * iter);
|
|
||||||
next(&result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void next(Ast_Iter *iter) {
|
void next(Ast_Iter *iter) {
|
||||||
if (iter->stack.len <= 0) {
|
Ast *ast = iter->ast;
|
||||||
iter->ast = 0;
|
|
||||||
iter->kind = AST_NONE;
|
|
||||||
iter->stack.dealloc();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ast *ast = iter->stack.pop();
|
|
||||||
assert(ast != 0);
|
|
||||||
iter->di += 1;
|
|
||||||
iter->ast = ast;
|
|
||||||
iter->kind = ast->kind;
|
|
||||||
if (ast->visit_id == iter->visit_id) {
|
|
||||||
iter->kind = (Ast_Kind)((unsigned)iter->kind + 128);
|
|
||||||
}
|
|
||||||
ast->visit_id = iter->visit_id;
|
ast->visit_id = iter->visit_id;
|
||||||
|
|
||||||
|
if (iter->skip_children) {
|
||||||
|
iter->skip_children = false;
|
||||||
|
goto end_of_switch;
|
||||||
|
}
|
||||||
|
|
||||||
switch (iter->kind) {
|
switch (iter->kind) {
|
||||||
case AST_SCOPE: {
|
case AST_SCOPE: {
|
||||||
Ast_Scope *node = (Ast_Scope *)ast;
|
Ast_Scope *node = (Ast_Scope *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
For(node->stmts) iter->stack.add(it);
|
For(node->stmts) iter->stack.add(it);
|
||||||
For(node->decls) iter->stack.add(it);
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_MODULE: invalid_codepath; break;
|
case AST_MODULE: invalid_codepath; break;
|
||||||
@@ -77,12 +55,15 @@ void next(Ast_Iter *iter) {
|
|||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->index);
|
iter->stack.add(node->index);
|
||||||
iter->stack.add(node->expr);
|
iter->stack.add(node->expr);
|
||||||
|
assert(node->index);
|
||||||
|
assert(node->expr);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_UNARY: {
|
case AST_UNARY: {
|
||||||
Ast_Unary *node = (Ast_Unary *)ast;
|
Ast_Unary *node = (Ast_Unary *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->expr);
|
iter->stack.add(node->expr);
|
||||||
|
assert(node->expr);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_BINARY: {
|
case AST_BINARY: {
|
||||||
@@ -90,14 +71,23 @@ void next(Ast_Iter *iter) {
|
|||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->right);
|
iter->stack.add(node->right);
|
||||||
iter->stack.add(node->left);
|
iter->stack.add(node->left);
|
||||||
|
assert(node->right);
|
||||||
|
assert(node->left);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_CALL_ITEM: {
|
case AST_CALL_ITEM: {
|
||||||
Ast_Call_Item *node = (Ast_Call_Item *)ast;
|
Ast_Call_Item *node = (Ast_Call_Item *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->item);
|
iter->stack.add(node->item);
|
||||||
if (node->call_flags & CALL_INDEX) iter->stack.add(node->index);
|
assert(node->item);
|
||||||
else if (node->call_flags & CALL_NAME) iter->stack.add(node->name);
|
if (node->call_flags & CALL_INDEX) {
|
||||||
|
iter->stack.add(node->index);
|
||||||
|
assert(node->index);
|
||||||
|
}
|
||||||
|
else if (node->call_flags & CALL_NAME) {
|
||||||
|
iter->stack.add(node->name);
|
||||||
|
assert(node->name);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_COMPOUND:
|
case AST_COMPOUND:
|
||||||
@@ -105,7 +95,7 @@ void next(Ast_Iter *iter) {
|
|||||||
Ast_Call *node = (Ast_Call *)ast;
|
Ast_Call *node = (Ast_Call *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
For(node->exprs) iter->stack.add(it);
|
For(node->exprs) iter->stack.add(it);
|
||||||
iter->stack.add(node->name);
|
if (node->name) iter->stack.add(node->name);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_TYPE_OF:
|
case AST_TYPE_OF:
|
||||||
@@ -117,20 +107,23 @@ void next(Ast_Iter *iter) {
|
|||||||
Ast_Builtin *node = (Ast_Builtin *)ast;
|
Ast_Builtin *node = (Ast_Builtin *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->expr);
|
iter->stack.add(node->expr);
|
||||||
|
assert(node->expr);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_SWITCH: {
|
case AST_SWITCH: {
|
||||||
Ast_Switch *node = (Ast_Switch *)ast;
|
Ast_Switch *node = (Ast_Switch *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->default_scope);
|
if (node->default_scope) iter->stack.add(node->default_scope);
|
||||||
For(node->cases) iter->stack.add(it);
|
For(node->cases) iter->stack.add(it);
|
||||||
iter->stack.add(node->value);
|
iter->stack.add(node->value);
|
||||||
|
assert(node->value);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_SWITCH_CASE: {
|
case AST_SWITCH_CASE: {
|
||||||
Ast_Switch_Case *node = (Ast_Switch_Case *)ast;
|
Ast_Switch_Case *node = (Ast_Switch_Case *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->scope);
|
iter->stack.add(node->scope);
|
||||||
|
assert(node->scope);
|
||||||
For(node->labels) iter->stack.add(it);
|
For(node->labels) iter->stack.add(it);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -138,6 +131,7 @@ void next(Ast_Iter *iter) {
|
|||||||
Ast_Var_Unpack *node = (Ast_Var_Unpack *)ast;
|
Ast_Var_Unpack *node = (Ast_Var_Unpack *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->expr);
|
iter->stack.add(node->expr);
|
||||||
|
assert(node->expr);
|
||||||
For(node->vars) iter->stack.add(it);
|
For(node->vars) iter->stack.add(it);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -168,13 +162,14 @@ void next(Ast_Iter *iter) {
|
|||||||
case AST_ARRAY: {
|
case AST_ARRAY: {
|
||||||
Ast_Array *node = (Ast_Array *)ast;
|
Ast_Array *node = (Ast_Array *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->expr);
|
if (node->expr) iter->stack.add(node->expr);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case AST_FOR: {
|
case AST_FOR: {
|
||||||
Ast_For *node = (Ast_For *)ast;
|
Ast_For *node = (Ast_For *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->scope);
|
iter->stack.add(node->scope);
|
||||||
|
assert(node->scope);
|
||||||
if (node->iter) iter->stack.add(node->iter);
|
if (node->iter) iter->stack.add(node->iter);
|
||||||
if (node->cond) iter->stack.add(node->cond);
|
if (node->cond) iter->stack.add(node->cond);
|
||||||
if (node->init) iter->stack.add(node->init);
|
if (node->init) iter->stack.add(node->init);
|
||||||
@@ -190,7 +185,8 @@ void next(Ast_Iter *iter) {
|
|||||||
Ast_If_Node *node = (Ast_If_Node *)ast;
|
Ast_If_Node *node = (Ast_If_Node *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->scope);
|
iter->stack.add(node->scope);
|
||||||
iter->stack.add(node->expr);
|
assert(node->scope);
|
||||||
|
if (node->expr) iter->stack.add(node->expr);
|
||||||
if (node->init) iter->stack.add(node->init);
|
if (node->init) iter->stack.add(node->init);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
@@ -204,10 +200,27 @@ void next(Ast_Iter *iter) {
|
|||||||
Ast_Lambda *node = (Ast_Lambda *)ast;
|
Ast_Lambda *node = (Ast_Lambda *)ast;
|
||||||
iter->stack.add(node);
|
iter->stack.add(node);
|
||||||
iter->stack.add(node->scope);
|
iter->stack.add(node->scope);
|
||||||
|
assert(node->scope);
|
||||||
For(node->ret) iter->stack.add(it);
|
For(node->ret) iter->stack.add(it);
|
||||||
For(node->args) iter->stack.add(it);
|
For(node->args) iter->stack.add(it);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
end_of_switch:
|
||||||
|
|
||||||
|
if (iter->stack.len <= 0) {
|
||||||
|
iter->ast = 0;
|
||||||
|
iter->kind = AST_NONE;
|
||||||
|
iter->stack.dealloc();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iter->ast = iter->stack.pop();
|
||||||
|
assert(iter->ast != 0);
|
||||||
|
iter->di += 1;
|
||||||
|
iter->kind = iter->ast->kind;
|
||||||
|
if (iter->ast->visit_id == iter->visit_id) {
|
||||||
|
iter->kind = (Ast_Kind)((unsigned)iter->kind + AST_NODE_END);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are not copying module and file Ast's
|
// We are not copying module and file Ast's
|
||||||
|
|||||||
Reference in New Issue
Block a user