unsigned ok : 1;
};
+struct Env_Scope_ {
+ struct Vector_ nspc_stack;
+ struct Vector_ class_stack;
+ struct Vector_ breaks;
+ struct Vector_ conts;
+ struct Vector_ known_ctx;
+ struct Scope_ swi;
+ size_t depth;
+ size_t type_xid;
+};
+
typedef struct Env_ * Env;
struct Env_ {
m_str name;
Type class_def;
Func func;
struct Gwion_ *gwion;
- struct Vector_ nspc_stack;
- struct Vector_ class_stack;
- struct Vector_ breaks;
- struct Vector_ conts;
- struct Vector_ known_ctx;
- struct Scope_ swi;
- size_t scope;
- size_t type_xid;
+ struct Env_Scope_* scope;
};
ANEW Env new_env();
#ifndef __PARSE
#define __PARSE
#define RET_NSPC(exp) \
-++env->scope; \
+++env->scope->depth; \
nspc_push_value(env->curr); \
const m_bool ret = exp; \
nspc_pop_value(env->curr); \
---env->scope; \
+--env->scope->depth; \
return ret;
#define SET_ACCESS(a,b) \
if(is_obj && (is_array || !is_ref)) {
const Instr assign = emit_add_instr(emit, ObjectAssign);
assign->m_val = (m_uint)emit_var;
- if(is_array && !emit->env->scope)
+ if(is_array && !emit->env->scope->depth)
ADD_REF(type)
}
return GW_OK;
if(is_obj && (is_array || !is_ref)) {
const Instr assign = emit_add_instr(emit, ObjectAssign);
assign->m_val = (m_uint)emit_var;
- if(is_array && !emit->env->scope)
+ if(is_array && !emit->env->scope->depth)
ADD_REF(type)
const Instr instr = emit_add_instr(emit, RegAddRef);
instr->m_val = emit_var;
}
static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
- ++emit->env->scope;
+ ++emit->env->scope->depth;
emit_push_scope(emit);
const m_bool pure = SAFE_FLAG(emit->env->func, pure);
if(!pure)
if(!pure)
emit_add_instr(emit, GcEnd);
emit_pop_scope(emit);
- --emit->env->scope;
+ --emit->env->scope->depth;
return GW_OK;
}
ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda) { GWDEBUG_EXE
if(lambda->def) {
const m_uint scope = !lambda->owner ?
- emit->env->scope : emit_push_type(emit, lambda->owner);
+ emit->env->scope->depth : emit_push_type(emit, lambda->owner);
CHECK_BB(emit_func_def(emit, lambda->def))
const Instr instr = emit_add_instr(emit, RegPushImm);
instr->m_val = (m_uint)lambda->def->func->code;
}
ANN static m_bool emit_stmt_code(const Emitter emit, const Stmt_Code stmt) { GWDEBUG_EXE
- ++emit->env->scope;
+ ++emit->env->scope->depth;
const m_bool ret = stmt->stmt_list ? emit_stmt_list(emit, stmt->stmt_list) : 1;
- --emit->env->scope;
+ --emit->env->scope->depth;
return ret;
}
ANN static m_bool emit_stmt_union(const Emitter emit, const Stmt_Union stmt) { GWDEBUG_EXE
Decl_List l = stmt->l;
- m_uint scope = emit->env->scope;
+ m_uint scope = emit->env->scope->depth;
const m_bool global = GET_FLAG(stmt, global);
if(stmt->xid) {
if(stmt->value->type->nspc->class_data_size && !stmt->value->type->nspc->class_data)
}
ANN static inline void emit_class_push(const Emitter emit, const Type type) { GWDEBUG_EXE
- vector_add(&emit->env->class_stack, (vtype)emit->env->class_def);
+ vector_add(&emit->env->scope->class_stack, (vtype)emit->env->class_def);
emit->env->class_def = type;
}
ANN static inline void emit_class_pop(const Emitter emit) { GWDEBUG_EXE
- emit->env->class_def = (Type)vector_pop(&emit->env->class_stack);
+ emit->env->class_def = (Type)vector_pop(&emit->env->scope->class_stack);
emit_pop_code(emit);
}
ANN2(1,3,4) m_bool check_lambda(const Env env, const Type owner,
Exp_Lambda *l, const Func_Def def) {
const m_uint scope = ((l->owner = owner)) ?
- env_push_type(env, owner) : env->scope;
+ env_push_type(env, owner) : env->scope->depth;
Arg_List base = def->arg_list, arg = l->arg;
while(base && arg) {
arg->td = base->td;
ANN void load_context(const Context context, const Env env) {
ADD_REF((env->context = context))
- vector_add(&env->nspc_stack, (vtype)env->curr);
+ vector_add(&env->scope->nspc_stack, (vtype)env->curr);
context->nspc->parent = env->curr;
env->curr = context->nspc;
}
map_release(&context->lbls);
}
REM_REF(context);
- env->curr = (Nspc)vector_pop(&env->nspc_stack);
+ env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
}
#include "mpool.h"
#include "switch.h"
+ANN static struct Env_Scope_ *new_scope(void) {
+ struct Env_Scope_ *a = mp_alloc(Env_Scope);
+ vector_init(&a->breaks);
+ vector_init(&a->conts);
+ vector_init(&a->class_stack);
+ vector_init(&a->nspc_stack);
+ vector_init(&a->known_ctx);
+ vector_init((Vector)&a->swi);
+ map_init(&a->swi.map);
+ return a;
+}
+
Env new_env() {
const Env env = (Env)xmalloc(sizeof(struct Env_));
env->global_nspc = new_nspc("global_nspc");
env->context = NULL;
- vector_init(&env->breaks);
- vector_init(&env->conts);
- vector_init(&env->class_stack);
- vector_init(&env->nspc_stack);
- vector_init(&env->known_ctx);
- env->type_xid = 0;
- vector_init((Vector)&env->swi);
- map_init(&env->swi.map);
-
+ env->scope = new_scope();
env_reset(env);
return env;
}
ANN void env_reset(const Env env) {
- vector_clear(&env->breaks);
- vector_clear(&env->conts);
- vector_clear(&env->nspc_stack);
- vector_add(&env->nspc_stack, (vtype)env->global_nspc);
- vector_clear(&env->class_stack);
- vector_add(&env->class_stack, (vtype)NULL);
+ vector_clear(&env->scope->breaks);
+ vector_clear(&env->scope->conts);
+ vector_clear(&env->scope->nspc_stack);
+ vector_add(&env->scope->nspc_stack, (vtype)env->global_nspc);
+ vector_clear(&env->scope->class_stack);
+ vector_add(&env->scope->class_stack, (vtype)NULL);
env->curr = env->global_nspc;
env->class_def = NULL;
env->func = NULL;
- env->scope = 0;
+ env->scope->depth = 0;
switch_reset(env);
}
-ANN void free_env(const Env a) {
+ANN static void free_env_scope(struct Env_Scope_ *a) {
const m_uint size = vector_size(&a->known_ctx);
for(m_uint i = size + 1; --i;)
REM_REF((Context)vector_at(&a->known_ctx, i - 1));
vector_release(&a->known_ctx);
- REM_REF(a->global_nspc);
vector_release(&a->nspc_stack);
vector_release(&a->class_stack);
vector_release(&a->breaks);
vector_release(&a->conts);
- switch_reset(a);
switch_release(&a->swi);
+ mp_free(Env_Scope, a);
+}
+
+ANN void free_env(const Env a) {
+ switch_reset(a);
+ free_env_scope(a->scope);
+ REM_REF(a->global_nspc);
free(a);
}
ANN2(1,3) m_uint env_push(const Env env, const Type type, const Nspc nspc) {
- const m_uint scope = env->scope;
- vector_add(&env->class_stack, (vtype)env->class_def);
+ const m_uint scope = env->scope->depth;
+ vector_add(&env->scope->class_stack, (vtype)env->class_def);
env->class_def = type;
- vector_add(&env->nspc_stack, (vtype)env->curr);
+ vector_add(&env->scope->nspc_stack, (vtype)env->curr);
env->curr = nspc;
- env->scope = 0;
+ env->scope->depth = 0;
return scope;
}
ANN void env_pop(const Env env, const m_uint scope) {
- env->class_def = (Type)vector_pop(&env->class_stack);
- env->curr = (Nspc)vector_pop(&env->nspc_stack);
- env->scope = scope;
+ env->class_def = (Type)vector_pop(&env->scope->class_stack);
+ env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
+ env->scope->depth = scope;
}
ANN void env_add_type(const Env env, const Type type) {
SET_FLAG(v, checked | ae_flag_const | ae_flag_global | ae_flag_builtin);
nspc_add_value(env->curr, insert_symbol(type->name), v);
type->owner = env->curr;
- type->xid = ++env->type_xid;
+ type->xid = ++env->scope->type_xid;
}
ANN m_bool type_engine_check_prog(const Env env, const Ast ast) {
const m_bool ret = traverse_ast(env, ast);
if(ret > 0) {
nspc_commit(env->curr);
- vector_add(&env->known_ctx, (vtype)ctx);
+ vector_add(&env->scope->known_ctx, (vtype)ctx);
} else //nspc_rollback(env->global_nspc);
REM_REF(ctx);
unload_context(ctx, env);
#define GET(a,b) ((a) & (b)) == (b)
ANN m_bool env_access(const Env env, const ae_flag flag) {
- if(env->scope) {
+ if(env->scope->depth) {
if(GET(flag, ae_flag_global))
ERR_B(0, "'global' can only be used at %s scope.",
GET(flag, ae_flag_global) && !env->class_def ?
"file" : "class")
}
if((GET(flag, ae_flag_static) || GET(flag, ae_flag_private) ||
- GET(flag, ae_flag_protect)) && (!env->class_def || env->scope))
+ GET(flag, ae_flag_protect)) && (!env->class_def || env->scope->depth))
ERR_B(0, "static/private/protect can only be used at class scope.")
return GW_OK;
}
info->t = env->class_def;
info->f = env->func;
const Switch sw = new_switch();
- map_set(&env->swi.map, (vtype)info, (vtype)sw);
+ map_set(&env->scope->swi.map, (vtype)info, (vtype)sw);
return sw;
}
}
ANN Switch swinfo_get(const Env env, const struct SwInfo_ *info) {
- for(m_uint i = 0; i < VLEN(&env->swi.map); ++i) {
- const struct SwInfo_ *key = (const struct SwInfo_*)VKEY(&env->swi.map, i);
+ for(m_uint i = 0; i < VLEN(&env->scope->swi.map); ++i) {
+ const struct SwInfo_ *key = (const struct SwInfo_*)VKEY(&env->scope->swi.map, i);
if(swinfo_cmp(key, info))
- return (Switch)VVAL(&env->swi.map, i);
+ return (Switch)VVAL(&env->scope->swi.map, i);
}
return NULL;
}
ANN m_bool switch_add(const Env env, const Stmt_Switch stmt) {
const struct SwInfo_ info = { stmt, env->class_def, env->func };
Switch sw = (Switch)swinfo_get(env, &info) ?: new_swinfo(env, stmt);
- vector_add((Vector)&env->swi, (vtype)sw);
+ vector_add((Vector)&env->scope->swi, (vtype)sw);
return GW_OK;
}
ANN void switch_get(const Env env, const Stmt_Switch stmt) {
const struct SwInfo_ info = { stmt, env->class_def, env->func };
const Switch sw = swinfo_get(env, &info);
- vector_add((Vector)&env->swi, (vtype)sw);
+ vector_add((Vector)&env->scope->swi, (vtype)sw);
}
void switch_reset(const Env env) {
- for(m_uint i = VLEN(&env->swi.map) + 1; --i;) {
- struct SwInfo_ *info = (struct SwInfo_ *)VKEY(&env->swi.map, i - 1);
+ for(m_uint i = VLEN(&env->scope->swi.map) + 1; --i;) {
+ struct SwInfo_ *info = (struct SwInfo_ *)VKEY(&env->scope->swi.map, i - 1);
mp_free(SwInfo, info);
- Switch sw = (Switch)VVAL(&env->swi.map, i - 1);
+ Switch sw = (Switch)VVAL(&env->scope->swi.map, i - 1);
free_map(sw->cases);
free_switch(sw);
}
- vector_clear((Vector)&env->swi);
- map_clear(&env->swi.map);
+ vector_clear((Vector)&env->scope->swi);
+ map_clear(&env->scope->swi.map);
}
ANN void switch_release(const Scope sw) {
}
ANN void switch_expset(const Env env, const Exp e) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
vector_add(&sw->exp, (vtype)e);
}
ANN Exp switch_expget(const Env env) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
return (Exp)vector_at(&sw->exp, sw->iter++);
}
ANN m_bool switch_inside(const Env env, const uint pos) {
- if(!VLEN(&env->swi))
+ if(!VLEN(&env->scope->swi))
ERR_B(pos, "case found outside switch statement.")
return GW_OK;
}
ANN m_bool switch_dup(const Env env, const m_int value, const uint pos) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
if(map_get(sw->cases, (vtype)value))
ERR_B(pos, "duplicated cases value %i", value)
return GW_OK;
}
ANN void switch_pc(const Env env, const m_uint pc) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
vector_add(sw->vec, pc);
}
ANN void switch_dynpc(const Env env, const m_int val, const m_uint pc) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
map_set(sw->cases, val, pc);
}
ANN m_bool switch_dyn(const Env env) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
return vector_size(&sw->exp);
}
ANN m_bool switch_default(const Env env, const m_uint pc, const uint pos) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
if(sw->default_case_index)
ERR_B(pos, "default case already defined")
sw->default_case_index = pc;
}
ANN Map switch_map(const Env env) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
return sw->cases;
}
ANN Vector switch_vec(const Env env) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
return vector_copy(sw->vec); // new_vector(); // dyn only
}
ANN m_uint switch_idx(const Env env) {
- const Switch sw = (Switch)vector_back((Vector)&env->swi);
+ const Switch sw = (Switch)vector_back((Vector)&env->scope->swi);
return sw->default_case_index;
}
ANN void switch_pop(const Env env) {
- vector_pop((Vector)&env->swi);
+ vector_pop((Vector)&env->scope->swi);
}
ANN void switch_end(const Env env) {
- const Switch sw = (Switch)vector_pop((Vector)&env->swi);
- const vtype index = VKEY(&env->swi.map, VLEN(&env->swi.map) - 1);
- map_remove(&env->swi.map, index);
+ const Switch sw = (Switch)vector_pop((Vector)&env->scope->swi);
+ const vtype index = VKEY(&env->scope->swi.map, VLEN(&env->scope->swi.map) - 1);
+ map_remove(&env->scope->swi.map, index);
free_switch(sw);
// return sw->ok = 1;
}
}
const Var_Decl var = list->self;
const Value v = var->value;
- if(env->class_def && !env->scope && env->class_def->parent)
+ if(env->class_def && !env->scope->depth && env->class_def->parent)
CHECK_BO(check_exp_decl_parent(env, var))
if(var->array && var->array->exp)
CHECK_BO(check_exp_array_subscripts(env, var->array->exp))
}
ANN static m_bool check_breaks(const Env env, const Stmt a, const Stmt b) { GWDEBUG_EXE
- vector_add(&env->breaks, (vtype)a);
+ vector_add(&env->scope->breaks, (vtype)a);
RET_NSPC(check_stmt(env, b))
- vector_pop(&env->breaks);
+ vector_pop(&env->scope->breaks);
return ret;
}
ANN static m_bool check_conts(const Env env, const Stmt a, const Stmt b) { GWDEBUG_EXE
- vector_add(&env->conts, (vtype)a);
+ vector_add(&env->scope->conts, (vtype)a);
CHECK_BB(check_breaks(env, a, b))
- vector_pop(&env->conts);
+ vector_pop(&env->scope->conts);
return GW_OK;
}
#define describe_check_stmt_stack(stack, name) \
ANN static m_bool check_stmt_##name(const Env env, const Stmt stmt) { GWDEBUG_EXE \
- if(!vector_size(&env->stack)) \
+ if(!vector_size(&env->scope->stack)) \
ERR_B(stmt->pos, "'"#name"' found outside of for/while/until...") \
return GW_OK; \
}
env_push_global(env);
const Func former = env->func;
env->func = func;
- ++env->scope;
+ ++env->scope->depth;
nspc_push_value(env->curr);
if((f->arg_list && (ret = check_func_args(env, f->arg_list)) > 0) || !f->arg_list) {
const Value variadic = GET_FLAG(f, variadic) ? set_variadic(env) : NULL;
operator_func(func);
}
nspc_pop_value(env->curr);
- --env->scope;
+ --env->scope->depth;
env->func = former;
if(GET_FLAG(f, global))
env_push_global(env);
CHECK_OB(base)
CHECK_BB(already_defined(env, stmt->xid, stmt->td->xid->pos)) // test for type ?
if(!stmt->td->types && (!stmt->td->array || !stmt->td->array->exp)) {
- const Type t = new_type(++env->type_xid, s_name(stmt->xid), base);
+ const Type t = new_type(++env->scope->type_xid, s_name(stmt->xid), base);
t->size = base->size;
const Nspc nspc = (!env->class_def && GET_FLAG(stmt->td, global)) ?
env->global_nspc : env->curr;
CHECK_BB(env_access(env, class_def->flag))
env_storage(env, &class_def->flag);
if(GET_FLAG(class_def, global)) {
- vector_add(&env->nspc_stack, (vtype)env->curr);
+ vector_add(&env->scope->nspc_stack, (vtype)env->curr);
env->curr = env->global_nspc;
}
CHECK_BB(already_defined(env, class_def->name->xid, class_def->name->pos)) // test for type ?
}
ANN static Type scan0_class_def_init(const Env env, const Class_Def class_def) { GWDEBUG_EXE
- const Type t = new_type(++env->type_xid, s_name(class_def->name->xid), t_object);
+ const Type t = new_type(++env->scope->type_xid, s_name(class_def->name->xid), t_object);
t->owner = env->curr;
t->nspc = new_nspc(t->name);
t->nspc->parent = GET_FLAG(class_def, global) ? env_nspc(env) : env->curr;
}
(void)mk_class(env, class_def->type);
if(GET_FLAG(class_def, global))
- env->curr = (Nspc)vector_pop(&env->nspc_stack);
+ env->curr = (Nspc)vector_pop(&env->scope->nspc_stack);
return GW_OK;
}
if(GET_FLAG(t, protect) && (!env->class_def || isa(t, env->class_def) < 0))
ERR_O(decl->self->pos, "can't use protected type %s", t->name)
if(env->class_def) {
- if(!env->scope) {
+ if(!env->scope->depth) {
if(!env->func && !GET_FLAG(decl->td, static))
SET_FLAG(decl->td, member);
if(!GET_FLAG(decl->td, ref) && t == env->class_def)
v->flag = decl->td->flag;
if(var->array && !var->array->exp)
SET_FLAG(v, ref);
- if(!env->func && !env->scope && !env->class_def)
+ if(!env->func && !env->scope->depth && !env->class_def)
SET_FLAG(v, global);
v->d.ptr = var->addr;
v->owner = !env->func ? env->curr : NULL;
- v->owner_class = env->scope ? NULL : env->class_def;
+ v->owner_class = env->scope->depth ? NULL : env->class_def;
} while((list = list->next));
decl->type = decl->list->self->value->type;
if(global)
return GW_OK;
const Func former = env->func;
env->func = FAKE_FUNC;
- ++env->scope;
+ ++env->scope->depth;
if(GET_FLAG(f, dtor) && !env->class_def)
ERR_B(f->td->xid->pos, "dtor must be in class def!!")
if(f->td)//lambda
if(GET_FLAG(f, op) && env->class_def)
SET_FLAG(f, static);
env->func = former;
- --env->scope;
+ --env->scope->depth;
return GW_OK;
}
ANN m_bool scan2_func_def(const Env env, const Func_Def f) { GWDEBUG_EXE
Value value = NULL;
f->stack_depth = 0;
- m_uint scope = env->scope;
+ m_uint scope = env->scope->depth;
if(GET_FLAG(f, global))
scope = env_push_global(env);
const Value overload = nspc_lookup_value0(env->curr, f->name);
const Type type = stmt->xid ? stmt->value->type : stmt->type_xid ?
stmt->type : NULL;
return type ? env_push_type(env, type) : GET_FLAG(stmt, global) ?
- env_push_global(env) : env->scope;
+ env_push_global(env) : env->scope->depth;
}
ANN void union_pop(const Env env, const Stmt_Union stmt, const m_uint scope) {