-Subproject commit b6efc8376c611d9c86e662ad4c348b64baebd523
+Subproject commit df2bc1f376c00d733304f1ea7f3c5ed6f76b84de
struct EmitterInfo_ {
struct Vector_ pure;
char *escape;
- f_instr finalyzer;
VM_Code (*emit_code)(const Emitter);
VM_Code code;
m_bool memoize;
ANN void env_add_type(const Env, const Type);
ANN Type find_type(const Env, Type_Decl*);
ANN m_bool already_defined(const Env env, const Symbol s, const loc_t pos);
-ANN m_bool type_engine_check_prog(const Env, const Ast);
-ANN m_bool type_engine_clean_prog(const Env, m_bool*);
ANN m_bool traverse_func_template(const Env, const Func_Def);
ANN2(1,3) void env_err(const Env, const loc_t pos, const m_str fmt, ...);
ANN Value global_string(const Env env, const m_str str);
#ifndef __GWI
#define __GWI
-#define loc(gwi) loc_cpy(gwi->gwion->mp, gwi->loc)
-
struct Gwi_ {
struct Gwion_ *const gwion;
Ast body;
#define CTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
#define DTOR(a) ANN void a(const M_Object o NUSED, const m_bit* _ NUSED, const VM_Shred shred NUSED)
#define GACK(a) ANN2(2) void a(const Type t NUSED, const m_bit* VALUE NUSED, const VM_Shred shred NUSED)
-#define OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED, m_bool* mut NUSED)
+#define OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED)
#define OP_EMIT(a) ANN m_bool a(const Emitter emit NUSED, void* data NUSED)
#ifdef GWION_BUILTIN
#define GWI_BB(a) { gwi_set_loc(gwi, __FILE__, __LINE__); (void)(a); }
ANN2(1,3) static inline M_Object new_object_str(const Gwion gwion, const VM_Shred shred, const m_str str) {
struct loc_t_ loc = {};
- DECL_OO(const Type, t, = str2type(gwion, str, &loc))
+ DECL_OO(const Type, t, = str2type(gwion, str, loc))
return new_object(gwion->mp, shred, t);
}
#endif
typedef struct OperCK { // name_checker ?
m_str ret;
Symbol sym;
- Type (*ck)(Env, void*, m_bool*); // oper
+ Type (*ck)(Env, void*); // oper
m_bool (*em)(Emitter, void*); // oper
m_str lhs;// oper
m_str rhs;// oper
#define FREEARG(a) ANN void a(Instr instr NUSED, void *gwion NUSED)
typedef void (*f_freearg)(Instr, void*);
ANN void gwi_register_freearg(const Gwi, const f_instr, const f_freearg);
-ANN void gwi_register_pass(const Gwi, const m_str, const compilation_pass[2]);
+ANN void gwi_register_pass(const Gwi, const m_str, const compilation_pass);
ANN void gwi_reserve(const Gwi, const m_str);
typedef struct SpecialId_* SpecialId;
ANN void gwi_specialid(const Gwi gwi, const m_str id, const SpecialId);
#define CHECK_BN(f) { if(f < 0) return env->gwion->type[et_error]; }
#define CHECK_NN(f) { if(f == env->gwion->type[et_error]) return env->gwion->type[et_error]; }
-typedef Type (*opck)(const Env, void*, m_bool*);
+typedef Type (*opck)(const Env, void*);
typedef m_bool (*opem)(const Emitter, void*);
struct Op_Func {
ANEW ANN struct Passes_* new_passes(MemPool mp);
ANN void free_passes(MemPool mp, struct Passes_*);
-ANN void pass_register(const Gwion, const m_str, const compilation_pass[2]);
+ANN void pass_register(const Gwion, const m_str, const compilation_pass);
ANN void pass_default(const Gwion);
ANN m_bool pass_set(const Gwion, const Vector);
#endif
ANN static inline Type specialid_type(const Env env,
struct SpecialId_ *spid, const Exp_Primary* prim) {
- exp_self(prim)->info->type = spid->type;
+ exp_self(prim)->type = spid->type;
if(spid->is_const)
exp_setmeta(exp_self(prim), 1);
return spid->ck ? spid->ck(env, prim) : spid->type;
}
ANN static void clean_exp_unary(Clean *a, Exp_Unary *b) {
- if(b->exp)
+ switch(b->unary_type) {
+ case unary_exp:
clean_exp(a, b->exp);
- if(b->td)
+ break;
+ case unary_td:
clean_type_decl(a, b->td);
- if(b->code)
+ break;
+ case unary_code:
clean_stmt(a, b->code);
+ break;
+ }
}
ANN static void clean_exp_cast(Clean *a, Exp_Cast *b) {
return GW_OK;
}
+ANN static inline m_bool _passes(struct Gwion_* gwion, struct Compiler* c) {
+ for(m_uint i = 0; i < vector_size(&gwion->data->passes->vec); ++i) {
+ const compilation_pass pass = (compilation_pass)vector_at(&gwion->data->passes->vec, i);
+ CHECK_BB(pass(gwion->env, c->ast))
+ }
+ return GW_OK;
+}
+
+
+ANN static inline m_bool passes(struct Gwion_* gwion, struct Compiler* c) {
+ const Env env = gwion->env;
+ const Context ctx = new_context(env->gwion->mp, c->ast, env->name);
+ env_reset(env);
+ load_context(ctx, env);
+ const m_bool ret = _passes(gwion, c);
+ if(ret > 0) //{
+ nspc_commit(env->curr);
+ if(ret > 0 || env->context->global)
+ vector_add(&env->scope->known_ctx, (vtype)ctx);
+ else //nspc_rollback(env->global_nspc);
+ context_remref(ctx, env->gwion);
+ unload_context(ctx, env);
+ return ret;
+}
+
ANN static inline m_bool _check(struct Gwion_* gwion, struct Compiler* c) {
struct AstGetter_ arg = { c->name, c->file, gwion->st, .ppa=gwion->ppa };
CHECK_OB((c->ast = parse(&arg)))
gwion->env->name = c->name;
- for(m_uint i = 0; i < vector_size(&gwion->data->passes->vec); ++i) {
- const compilation_pass *pass = (compilation_pass*)vector_at(&gwion->data->passes->vec, i);
- m_bool ret = pass[0](gwion->env, c->ast);
- if(ret < 0)
- ast_cleaner(gwion, c->ast);
- if(pass[1])
- CHECK_BB(pass[1](gwion->env, &ret))
- CHECK_BB(ret)
- }
+ const m_bool ret = passes(gwion, c);
if(!arg.global)
ast_cleaner(gwion, c->ast);
- return GW_OK;
+ return ret;
}
ANN static m_uint _compile(struct Gwion_* gwion, struct Compiler* c) {
ANN static inline m_uint exp_size(const Exp e) {
if(exp_getvar(e))
return SZ_INT;
- const Type type = e->info->cast_to ?: e->info->type;
+ const Type type = e->cast_to ?: e->type;
return type->size;
}
}
ANN2(1) static void emit_exp_addref1(const Emitter emit, /* const */Exp exp, m_int size) {
- if(isa(exp->info->type, emit->gwion->type[et_object]) > 0 &&
- (exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
+ if(isa(exp->type, emit->gwion->type[et_object]) > 0 &&
+ (exp->cast_to ? isa(exp->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
if(exp->exp_type == ae_exp_decl && GET_FLAG(exp->d.exp_decl.td, late) && !exp_getvar(exp)) {
const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
instr->m_val = size;
}
const Instr instr = emit_addref(emit, exp_getvar(exp));
instr->m_val = size;
- } else if(tflag(exp->info->type, tflag_struct)) // check cast_to ?
- struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
+ } else if(tflag(exp->type, tflag_struct)) // check cast_to ?
+ struct_addref(emit, exp->type, size, 0, exp_getvar(exp));
}
ANN2(1) static void emit_exp_addref(const Emitter emit, /* const */Exp exp, m_int size) {
CHECK_BB(emit_range(emit, range))
const Exp e = range->start ?: range->end;
const Symbol sym = insert_symbol("@range");
- struct Op_Import opi = { .op=sym, .rhs=e->info->type,
+ struct Op_Import opi = { .op=sym, .rhs=e->type,
.pos=e->pos, .data=(uintptr_t)prim_exp(data), .op_type=op_exp };
CHECK_BB(op_emit(emit, &opi))
emit_gc(emit, -SZ_INT);
return emit_array_access(emit, info);
}
// look mum no pos
- struct Op_Import opi = { .op=insert_symbol("@array"), .lhs=info->array.exp->info->type, .rhs=info->array.type,
+ struct Op_Import opi = { .op=insert_symbol("@array"), .lhs=info->array.exp->type, .rhs=info->array.type,
.data=(uintptr_t)info, .op_type=op_array };
if(!info->is_var && (GET_FLAG(info->array.type, abstract) || type_ref(info->array.type))) {
const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) {
CHECK_BB(emit_exp(emit, array->base))
const Exp e = exp_self(array);
- struct ArrayAccessInfo info = { *array->array, e->info->type, exp_getvar(e) };
+ struct ArrayAccessInfo info = { *array->array, e->type, exp_getvar(e) };
return emit_array_access(emit, &info);
}
CHECK_BB(emit_range(emit, range->range))
const Symbol sym = insert_symbol("@slice");
const Exp e = range->range->start ?: range->range->end;
- struct Op_Import opi = { .op=sym, .lhs=e->info->type, .rhs=range->base->info->type,
+ struct Op_Import opi = { .op=sym, .lhs=e->type, .rhs=range->base->type,
.pos=e->pos, .data=(uintptr_t)exp_self(range), .op_type=op_exp };
return op_emit(emit, &opi);
}
ANN static m_bool emit_prim_typeof(const Emitter emit, const Exp *exp) {
const Exp e = *exp;
- if(!e->info->type->array_depth)
- regpushi(emit, (m_uint)(actual_type(emit->gwion, e->info->type)));
+ if(!e->type->array_depth)
+ regpushi(emit, (m_uint)(actual_type(emit->gwion, e->type)));
else
- regpushi(emit, (m_uint)e->info->type);
+ regpushi(emit, (m_uint)e->type);
return GW_OK;
}
}
if(e->exp_type == ae_exp_decl) // why only objects?
interp_multi(emit, e);
- regseti(emit, (m_uint)e->info->type);
- interp_size(emit, e->info->type);
- const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
+ regseti(emit, (m_uint)e->type);
+ interp_size(emit, e->type);
+ const m_bool isobj = isa(e->type, emit->gwion->type[et_object]) > 0;
if(isobj && e->exp_type != ae_exp_cast)
emit_add_instr(emit, GackType);
const Instr instr = emit_add_instr(emit, Gack);
return ret;
}
-ANN static m_uint vararg_size(const Exp_Call* exp_call, const Vector kinds) {
+ANN static m_uint vararg_size(const Gwion gwion, const Exp_Call* exp_call, const Vector kinds) {
Exp e = exp_call->args;
- Arg_List l = exp_call->m_func->def->base->args;
+ const Type t = actual_type(gwion, exp_call->func->type);
+ Arg_List l = t->info->func->def->base->args;
m_uint size = 0;
while(e) {
if(!l) {
- size += e->info->type->size;
- vector_add(kinds, (vtype)e->info->type); // ->size
+ size += e->type->size;
+ vector_add(kinds, (vtype)e->type); // ->size
} else
l = l->next;
e = e->next;
ANN static void emit_func_arg_vararg(const Emitter emit, const Exp_Call* exp_call) {
const Instr instr = emit_add_instr(emit, VarargIni);
const Vector kinds = new_vector(emit->gwion->mp);
- if((instr->m_val = vararg_size(exp_call, kinds)))
+ if((instr->m_val = vararg_size(emit->gwion, exp_call, kinds)))
instr->m_val2 = (m_uint)kinds;
else
free_vector(emit->gwion->mp, kinds);
CHECK_BB(emit_exp(emit, exp_call->args))
emit_exp_addref(emit, exp_call->args, -exp_totalsize(exp_call->args));
}
- if(exp_call->m_func && fbflag(exp_call->m_func->def->base, fbflag_variadic))
+ const Type t = actual_type(emit->gwion, exp_call->func->type);
+ if(isa(t, emit->gwion->type[et_function]) > 0 &&
+ fbflag(t->info->func->def->base, fbflag_variadic))
emit_func_arg_vararg(emit, exp_call);
return GW_OK;
}
ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
CHECK_BB(prepare_call(emit, exp_call))
- if(exp_call->m_func)
- CHECK_BB(emit_exp_call1(emit, exp_call->m_func))
+ const Type t = actual_type(emit->gwion, exp_call->func->type);
+ if(isa(t, emit->gwion->type[et_function]) > 0)
+ CHECK_BB(emit_exp_call1(emit, t->info->func))
else {
- struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=exp_call->func->info->type->info->base_type,
+ struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=t,
.data=(uintptr_t)exp_call, .pos=exp_self(exp_call)->pos, .op_type=op_exp };
CHECK_BB(op_emit(emit, &opi))
}
const Exp e = exp_self(exp_call);
if(exp_getvar(e)) {
- regpop(emit, exp_self(exp_call)->info->type->size - SZ_INT);
+ regpop(emit, exp_self(exp_call)->type->size - SZ_INT);
const Instr instr = emit_add_instr(emit, Reg2RegAddr);
instr->m_val = -SZ_INT;
instr->m_val2 = -SZ_INT;
- } else if(!exp_call->m_func && tflag(e->info->type, tflag_struct))
+ } else if(isa(exp_call->func->type, emit->gwion->type[et_function]) < 0 &&
+ tflag(e->type, tflag_struct))
regpop(emit, SZ_INT);
return GW_OK;
}
m_uint size = 0;
do { // account for emit_var ?
size += (e->exp_type == ae_exp_decl ?
- get_decl_size(e->d.exp_decl.list, emit_addr) : e->info->type->size);
+ get_decl_size(e->d.exp_decl.list, emit_addr) : e->type->size);
} while((e = e->next));
return size;
}
const m_int size = exp_size(rhs);
emit_exp_addref1(emit, lhs, -exp_size(lhs) - size);
emit_exp_addref1(emit, rhs, -size);
- struct Op_Import opi = { .op=bin->op, .lhs=lhs->info->type, .rhs=rhs->info->type,
+ struct Op_Import opi = { .op=bin->op, .lhs=lhs->type, .rhs=rhs->type,
.pos=exp_self(bin)->pos, .data=(uintptr_t)bin, .op_type=op_binary };
return op_emit(emit, &opi);
}
ANN static m_bool emit_exp_cast(const Emitter emit, const Exp_Cast* cast) {
// no pos ?
- struct Op_Import opi = { .op=insert_symbol("$"), .lhs=cast->exp->info->type, .rhs=exp_self(cast)->info->type,
+ struct Op_Import opi = { .op=insert_symbol("$"), .lhs=cast->exp->type, .rhs=exp_self(cast)->type,
.data=(uintptr_t)cast, .op_type=op_cast};
CHECK_BB(emit_exp(emit, cast->exp))
(void)op_emit(emit, &opi);
ANN static m_bool emit_exp_post(const Emitter emit, const Exp_Postfix* post) {
// no pos ?
- struct Op_Import opi = { .op=post->op, .lhs=post->exp->info->type,
+ struct Op_Import opi = { .op=post->op, .lhs=post->exp->type,
.data=(uintptr_t)post, .op_type=op_postfix };
CHECK_BB(emit_exp(emit, post->exp))
emit_exp_addref(emit, post->exp, -exp_totalsize(post->exp));
static m_bool me_cmp(MemoizeEmitter *me, const Arg_List arg) {
const Emitter emit = me->emit;
const Symbol sym = insert_symbol("==");
- struct ExpInfo_ info = { .nspc=me->fdef->base->func->value_ref->from->owner };
- struct Exp_ exp = { .info=&info };
+ struct Exp_ exp = {};
struct Op_Import opi = { .op=sym, .lhs=arg->type, .rhs=arg->type,
.pos=me->fdef->pos, .data=(uintptr_t)&exp.d, .op_type=op_binary };
CHECK_BB(op_emit(emit, &opi))
#define FORK_CODE_PREFIX "fork~code:%i"
static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t pos) {
- char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos->first.line) + 1];
- sprintf(c, prefix, pos->first.line);
+ char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos.first.line) + 1];
+ sprintf(c, prefix, pos.first.line);
emit_push_code(emit, c);
}
ANN static m_bool spork_prepare_func(const Emitter emit, const struct Sporker *sp) {
push_spork_code(emit, sp->is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, sp->exp->pos);
- return emit_exp_call1(emit, sp->exp->d.exp_call.m_func);
+ const Type t = actual_type(emit->gwion, sp->exp->d.exp_call.func->type);
+ return emit_exp_call1(emit, t->info->func);
}
ANN static VM_Code spork_prepare(const Emitter emit, const struct Sporker *sp) {
}
ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
- const Func f = sp->exp->d.exp_call.m_func;
+ const Func f = actual_type(emit->gwion, sp->exp->d.exp_call.func->type)->info->func;
if(vflag(f->value_ref, vflag_member) && is_fptr(emit->gwion, f->value_ref->type)) {
regpush(emit, SZ_INT*2);
// (re-)emit owner
ANN m_bool emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
struct Sporker sporker = {
- .exp=unary->exp,
- .code=unary->code,
- .type=exp_self(unary)->info->type,
+ .exp= unary->unary_type == unary_exp ? unary->exp : NULL,
+ .code= unary->unary_type == unary_code ? unary->code : NULL,
+ .type=exp_self(unary)->type,
.is_spork=(unary->op == insert_symbol("spork")),
.emit_var=exp_getvar(exp_self(unary))
};
CHECK_OB((sporker.vm_code = spork_prepare(emit, &sporker)))
spork_ini(emit, &sporker);
- (unary->code ? spork_code : spork_func)(emit, &sporker);
+ (unary->unary_type == unary_code ? spork_code : spork_func)(emit, &sporker);
return GW_OK;
}
ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
- const Type t = exp_self(unary)->info->type;
+ const Type t = exp_self(unary)->type;
const Type base = get_type(actual_type(emit->gwion, t));
CHECK_BB(ensure_emit(emit, base))
// no pos ?
struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
- if(unary->op != insert_symbol("spork") && unary->op != insert_symbol("fork") && unary->exp) {
+ if(unary->unary_type == unary_exp && unary->op != insert_symbol("spork") && unary->op != insert_symbol("fork")) {
CHECK_BB(emit_exp_pop_next(emit, unary->exp))
emit_exp_addref1(emit, unary->exp, -exp_size(unary->exp));
- opi.rhs = unary->exp->info->type;
+ opi.rhs = unary->exp->type;
}
return op_emit(emit, &opi);
}
const restrict Exp from, const restrict Type to) {
const struct Implicit imp = { from, to, from->pos };
// no pos
- struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=from->info->type, .rhs=to,
+ struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=from->type, .rhs=to,
.data=(m_uint)&imp, .op_type=op_implicit };
return op_emit(emit, &opi);
}
CHECK_BO(emit_exp_pop_next(emit, e))
emit_exp_addref1(emit, e, -exp_size(e));
struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
- .rhs=e->info->type, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
+ .rhs=e->type, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
CHECK_BO(op_emit(emit, &opi))
return (Instr)vector_back(&emit->code->instr);
}
}
ANN static m_bool emit_exp_td(const Emitter emit, Type_Decl* td) {
- regpushi(emit, (m_uint)exp_self(td)->info->type->info->base_type);
+ regpushi(emit, (m_uint)exp_self(td)->type->info->base_type);
return GW_OK;
}
Exp exp = e;
do {
CHECK_BB(emit_exp_func[exp->exp_type](emit, &exp->d))
- if(exp->info->cast_to)
- CHECK_BB(emit_implicit_cast(emit, exp, exp->info->cast_to))
+ if(exp->cast_to)
+ CHECK_BB(emit_implicit_cast(emit, exp, exp->cast_to))
} while((exp = exp->next));
return GW_OK;
}
ANN static m_bool optimize_taill_call(const Emitter emit, const Exp_Call* e) {
if(e->args) {
emit_func_args(emit, e);
- regpop(emit, e->m_func->def->stack_depth);
- emit_args(emit, e->m_func);
+ const Func f = e->func->type->info->func;
+ regpop(emit, f->def->stack_depth);
+ emit_args(emit, f);
}
emit_add_instr(emit, Goto);
return GW_OK;
ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) {
if(stmt->val) {
- if(stmt->val->exp_type == ae_exp_call && emit->env->func == stmt->val->d.exp_call.m_func)
- return optimize_taill_call(emit, &stmt->val->d.exp_call);
+ if(stmt->val->exp_type == ae_exp_call) {
+ const Func f = stmt->val->d.exp_call.func->type->info->func;
+ if(stmt->val->exp_type == ae_exp_call && emit->env->func == f)
+ return optimize_taill_call(emit, &stmt->val->d.exp_call);
+ }
CHECK_BB(emit_exp_pop_next(emit, stmt->val))
}
vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
emit_exp_addref(emit, base, -exp_totalsize(base) + size);
emit_exp_addref1(emit, e, size);
const Exp_Binary bin = { .lhs=base, .rhs=e, .op=op };
- struct ExpInfo_ info = { .nspc=e->info->nspc };
- struct Exp_ ebin = { .d={.exp_binary=bin}, .info=&info };
- struct Op_Import opi = { .op=op, .lhs=base->info->type, .rhs=e->info->type,
+ struct Exp_ ebin = { .d={.exp_binary=bin}, };
+ struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type,
.data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos, .op_type=op_binary };
CHECK_BB(op_emit(emit, &opi))
const Instr instr = emit_add_instr(emit, BranchEqInt);
ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
const Value v = e->d.prim.value;
- v->from->offset = emit_local(emit, base->info->type);
+ v->from->offset = emit_local(emit, base->type);
CHECK_BB(emit_exp(emit, base))
emit_exp_addref(emit, base, -exp_totalsize(base));
- regpop(emit, base->info->type->size);
+ regpop(emit, base->type->size);
const Instr instr = emit_add_instr(emit, Reg2Mem4);
instr->m_val = v->from->offset;
- instr->m_val2 = base->info->type->size;
+ instr->m_val2 = base->type->size;
return GW_OK;
}
}
ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) {
- struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->base->info->type,
- .rhs=exp_self(member)->info->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos, .op_type=op_dot };
+ struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->base->type,
+ .rhs=exp_self(member)->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos, .op_type=op_dot };
return op_emit(emit, &opi);
}
const m_bool ret = emit_ast_inner(emit, ast);
emit_pop_scope(emit);
if(ret > 0)
- emit->info->code = finalyze(emit, emit->info->finalyzer);
+ emit->info->code = finalyze(emit, EOC);
else
emit_free_stack(emit);
return ret;
vector_init(&emit->info->pure);
emit->info->escape = escape_table(p);
emit->info->emit_code = emit_code;
- emit->info->finalyzer = EOC;
return emit;
}
set_vflag(v, vflag_builtin);
set_tflag(type, tflag_scan0 | tflag_scan1 | tflag_scan2 | tflag_check | tflag_emit);
}
-
-ANN m_bool type_engine_check_prog(const Env env, const Ast ast) {
- const Context ctx = new_context(env->gwion->mp, ast, env->name);
- env_reset(env);
- load_context(ctx, env);
- return traverse_ast(env, ast);
-}
-
-ANN m_bool type_engine_clean_prog(const Env env, m_bool *r) {
- const m_bool ret = (m_bool)*r;
- const Context ctx = env->context;
- if(ret > 0) //{
- nspc_commit(env->curr);
- if(ret > 0 || env->context->global)
- vector_add(&env->scope->known_ctx, (vtype)ctx);
- else //nspc_rollback(env->global_nspc);
- context_remref(ctx, env->gwion);
- unload_context(ctx, env);
- return ret;
-}
nspc_pop_type(gwi->gwion->mp, gwi->gwion->env->curr);
CHECK_OO(p)
const Type t = new_type(gwi->gwion->mp, s_name(ck.sym), p);
- t->info->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, loc(gwi));
+ t->info->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, td, NULL, gwi->loc);
t->info->cdef->base.tmpl = tmpl;
t->info->cdef->base.type = t;
t->info->tuple = new_tupleform(gwi->gwion->mp, p);
if(!ck.tmpl)
gwi_type_flag(t);
else {
- t->info->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, NULL, NULL, loc(gwi));
+ t->info->cdef = new_class_def(gwi->gwion->mp, 0, ck.sym, NULL, NULL, gwi->loc);
t->info->cdef->base.type = t;
t->info->cdef->base.tmpl = new_tmpl_base(gwi->gwion->mp, ck.tmpl);
t->info->tuple = new_tupleform(gwi->gwion->mp, NULL);
CHECK_BO(ac_run(gwion, &ac))
const Array_Sub array = ac.depth ?
mk_array(gwion->mp, &ac) : NULL;
- return new_var_decl(gwion->mp, sym, array, loc_cpy(gwion->mp, pos));
+ return new_var_decl(gwion->mp, sym, array, pos);
}
// only in udef.c
return NULL;
}
}
- Type_Decl *td = new_type_decl(gwion->mp, sym, loc_cpy(gwion->mp, tdc->pos));
+ Type_Decl *td = new_type_decl(gwion->mp, sym, tdc->pos);
td->next = next;
td->types = tl;
if(ac.depth)
if(str != ac->str) {
CHECK_BB(ac_num(gwion, ac, num))
CHECK_BB(ac_exp(gwion, ac))
- const Exp exp = new_prim_int(gwion->mp, num, loc_cpy(gwion->mp, ac->pos));
+ const Exp exp = new_prim_int(gwion->mp, num, ac->pos);
ac_add_exp(ac, exp);
} else
CHECK_BB(ac_noexp(gwion, ac))
GWI_ERR_O("Enum is empty");
const Gwion gwion = gwi->gwion;
const Enum_Def edef = new_enum_def(gwion->mp, gwi->ck->tmpl,
- gwi->ck->xid, loc(gwi));
+ gwi->ck->xid, gwi->loc);
gwi->ck->tmpl = NULL;
const m_bool ret = traverse_enum_def(gwion->env, edef);
import_enum_end(gwi, &edef->values);
ANEW ANN static Func_Def import_fdef(const Gwi gwi, ImportCK *ck) {
Func_Base* base = gwi_func_base(gwi, ck);
- const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, loc(gwi));
+ const Func_Def fdef = new_func_def(gwi->gwion->mp, base, NULL, gwi->loc);
return fdef;
}
ANN m_bool gwi_run(const Gwion gwion, m_bool (*f)(const Gwi)) {
const m_str name = gwion->env->name;
- struct loc_t_ loc = {};
OperCK oper = {};
- struct Gwi_ gwi = { .gwion=gwion, .loc=&loc, .oper=&oper };
+ struct Gwi_ gwi = { .gwion=gwion, .oper=&oper };
const m_bool ret = f(&gwi);
if(ret < 0)
gwi_reset(&gwi);
ANN static m_int gwi_item_tmpl(const Gwi gwi) {
const MemPool mp = gwi->gwion->mp;
- const Stmt stmt = new_stmt_exp(mp, ae_stmt_exp, gwi->ck->exp, loc(gwi));
+ const Stmt stmt = new_stmt_exp(mp, ae_stmt_exp, gwi->ck->exp, gwi->loc);
const Stmt_List slist = new_stmt_list(mp, stmt, NULL);
Section* section = new_section_stmt_list(mp, slist);
const Ast body = new_ast(mp, section, NULL);
return GW_OK;
}
-ANN m_int gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void*, m_bool*)) {
+ANN m_int gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void*)) {
gwi->oper->ck = ck;
return GW_OK;
}
map_set(&gwi->gwion->data->freearg, (vtype)_exec, (vtype)_free);
}
-ANN void gwi_register_pass(const Gwi gwi, const m_str name, const compilation_pass pass[2]) {
+ANN void gwi_register_pass(const Gwi gwi, const m_str name, const compilation_pass pass) {
pass_register(gwi->gwion, name, pass);
}
}
ANN void gwi_set_loc(const Gwi gwi, const m_str file, const uint line) {
- gwi->loc->first.line = gwi->loc->last.line = line;
+ gwi->loc.first.line = gwi->loc.last.line = line;
gwi->gwion->env->name = file;
}
DECL_OO(Type_Decl*, td, = gwi_str2td(gwi, type))
const Var_Decl_List vlist = gwi_str2varlist(gwi, name);
if(vlist)
- return new_exp_decl(gwi->gwion->mp, td, vlist, loc(gwi));
+ return new_exp_decl(gwi->gwion->mp, td, vlist, gwi->loc);
free_type_decl(gwi->gwion->mp, td);
return NULL;
}
CHECK_BB(ck_ok(gwi, ck_udef))
DECL_OB(Type_Decl*, td, = str2td(gwi->gwion, type, gwi->loc))
DECL_OB(const Symbol, xid, = str2sym(gwi->gwion, name, gwi->loc))
- const Union_List l = new_union_list(gwi->gwion->mp, td, xid, loc(gwi));
+ const Union_List l = new_union_list(gwi->gwion->mp, td, xid, gwi->loc);
l->next = gwi->ck->list;
gwi->ck->list = l;
return GW_OK;
CHECK_BO(ck_ok(gwi, ck_udef))
if(!gwi->ck->list)
GWI_ERR_O(_("union is empty"));
- const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->list, loc(gwi));
+ const Union_Def udef = new_union_def(gwi->gwion->mp, gwi->ck->list, gwi->loc);
gwi->ck->list = NULL;
udef->flag = flag;
udef->xid = gwi->ck->sym;
return t;
}
-#define ARRAY_OPCK(a, b, pos) \
- const Type l = get_array_type(a->info->type); \
- const Type r = get_array_type(b->info->type); \
- if(isa(l, r) < 0) \
+#define ARRAY_OPCK(a, b, pos) \
+ const Type l = get_array_type(a->type); \
+ const Type r = get_array_type(b->type); \
+ if(isa(l, r) < 0) \
ERR_N(pos, _("array types do not match."))
static OP_CHECK(opck_array_at) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(opck_const_rhs(env, data, mut) == env->gwion->type[et_error])
+ if(opck_const_rhs(env, data) == env->gwion->type[et_error])
return env->gwion->type[et_error];
- if(bin->lhs->info->type != env->gwion->type[et_error]) {
+ if(bin->lhs->type != env->gwion->type[et_error]) {
ARRAY_OPCK(bin->lhs, bin->rhs, exp_self(bin)->pos)
- if(bin->lhs->info->type->array_depth != bin->rhs->info->type->array_depth)
+ if(bin->lhs->type->array_depth != bin->rhs->type->array_depth)
ERR_N(exp_self(bin)->pos, _("array depths do not match."))
}
if(bin->rhs->exp_type == ae_exp_decl) {
ERR_N(exp_self(bin)->pos, _("do not provide array for 'xxx @=> declaration'."))
}
exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
ANN static Type check_array_shift(const Env env,
const Exp a, const Exp b, const m_str str, const loc_t pos) {
- if(a->info->type == env->gwion->type[et_error] &&
- b->info->type->array_depth > 1)
- return a->info->type;
+ if(a->type == env->gwion->type[et_error] &&
+ b->type->array_depth > 1)
+ return a->type;
ARRAY_OPCK(a, b, pos)
- if(a->info->type->array_depth == b->info->type->array_depth + 1)
- return a->info->type;
- else if(a->info->type->array_depth == b->info->type->array_depth)
- return a->info->type;
+ if(a->type->array_depth == b->type->array_depth + 1)
+ return a->type;
+ else if(a->type->array_depth == b->type->array_depth)
+ return a->type;
ERR_N(pos, "array depths do not match for '%s'.", str);
}
static OP_EMIT(opem_array_sr) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(bin->rhs->info->type->array_depth == bin->lhs->info->type->array_depth)
+ if(bin->rhs->type->array_depth == bin->lhs->type->array_depth)
return emit_array_shift(emit, ArrayConcatRight);
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = SZ_INT;
static OP_EMIT(opem_array_sl) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(bin->lhs->info->type->array_depth == bin->rhs->info->type->array_depth)
+ if(bin->lhs->type->array_depth == bin->rhs->type->array_depth)
return emit_array_shift(emit, ArrayConcatLeft);
const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = bin->rhs->info->type->size;
+ pop->m_val = bin->rhs->type->size;
emit_gc(emit, -SZ_INT);
emit_add_instr(emit, ArrayAppend);
return GW_OK;
// check me. use common ancestor maybe
static OP_CHECK(opck_array_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
- Type l = cast->exp->info->type;
- Type r = exp_self(cast)->info->type;
- while(!l->info->base_type)
- l = l->info->parent;
- while(!r->info->base_type)
- r = r->info->parent;
- if(get_depth(cast->exp->info->type) == get_depth(exp_self(cast)->info->type) && isa(l->info->base_type, r->info->base_type) > 0)
+ Type l = array_base(cast->exp->type);
+ Type r = array_base(exp_self(cast)->type);
+ if(get_depth(cast->exp->type) == get_depth(exp_self(cast)->type) && isa(l->info->base_type, r->info->base_type) > 0)
return l;
return NULL;
}
static OP_CHECK(opck_array_slice) {
const Exp e = (Exp)data;
exp_setmeta(exp_self(e), 1);
- return e->d.exp_slice.base->info->type;
+ return e->d.exp_slice.base->type;
}
static inline m_bool bounds(const M_Vector v, const m_int i) {
const Emitter emit = shred->info->vm->gwion->emit;
emit->env->name = "runtime";
struct loc_t_ pos = {};
- m_str tmpl_name = tl2str(emit->gwion, dt->tl, &pos);
+ m_str tmpl_name = tl2str(emit->gwion, dt->tl, pos);
for(m_uint i = 0 ; i <= f->value_ref->from->offset; ++i) {
const Symbol sym = func_symbol(emit->env, f->value_ref->from->owner->name,
name, tmpl_name, i);
Exp e = exp_self(bin);
e->exp_type = ae_exp_call;
memcpy(&e->d.exp_call, &call, sizeof(Exp_Call));
- ++*mut;
return check_exp_call1(env, &e->d.exp_call) ?: env->gwion->type[et_error];
}
static OP_EMIT(opem_func_assign) {
Exp_Binary* bin = (Exp_Binary*)data;
- if(bin->rhs->info->type->info->func->def->base->tmpl)
- fptr_instr(emit, bin->lhs->info->type->info->func, 2);
+ if(bin->rhs->type->info->func->def->base->tmpl)
+ fptr_instr(emit, bin->lhs->type->info->func, 2);
(void)emit_add_instr(emit, int_r_assign);
- if(!is_fptr(emit->gwion, bin->lhs->info->type) && vflag(bin->rhs->info->type->info->func->value_ref, vflag_member)) {
+ if(!is_fptr(emit->gwion, bin->lhs->type) && vflag(bin->rhs->type->info->func->value_ref, vflag_member)) {
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = SZ_INT;
const Instr cpy = emit_add_instr(emit, Reg2Reg);
const Func_Def fdef = t->info->func->def;
l->owner = t->info->owner_class;
CHECK_BB(_check_lambda(env, l, fdef))
- exp_self(l)->info->type = l->def->base->func->value_ref->type;
+ exp_self(l)->type = l->def->base->func->value_ref->type;
return GW_OK;
}
ANN static m_bool fptr_do(const Env env, struct FptrInfo *info) {
- if(isa(info->exp->info->type, env->gwion->type[et_lambda]) < 0) {
+ if(isa(info->exp->type, env->gwion->type[et_lambda]) < 0) {
CHECK_BB(fptr_check(env, info))
- CHECK_OB((info->exp->info->type = fptr_type(env, info)))
+ CHECK_OB((info->exp->type = fptr_type(env, info)))
return GW_OK;
}
Exp_Lambda *l = &info->exp->d.exp_lambda;
return env->gwion->type[et_error];
// create a matching signature
// TODO: we could check first if there a matching existing one
- Func_Base *const fbase = cpy_func_base(env->gwion->mp, bin->lhs->info->type->info->func->def->base);
+ Func_Base *const fbase = cpy_func_base(env->gwion->mp, bin->lhs->type->info->func->def->base);
const Fptr_Def fptr_def = new_fptr_def(env->gwion->mp, fbase);
char name[13 + strlen(env->curr->name) +
- num_digit(bin->rhs->pos->first.line) + num_digit(bin->rhs->pos->first.column)];
- sprintf(name, "generated@%s@%u:%u", env->curr->name, bin->rhs->pos->first.line, bin->rhs->pos->first.column);
+ num_digit(bin->rhs->pos.first.line) + num_digit(bin->rhs->pos.first.column)];
+ sprintf(name, "generated@%s@%u:%u", env->curr->name, bin->rhs->pos.first.line, bin->rhs->pos.first.column);
fptr_def->base->xid = insert_symbol(name);
const m_bool ret = traverse_fptr_def(env, fptr_def);
const Type t = fptr_def->type;
free_fptr_def(env->gwion->mp, fptr_def);
type_remref(t, env->gwion);
- bin->rhs->d.exp_decl.list->self->value->type = bin->rhs->info->type = bin->rhs->d.exp_decl.type = t;
+ bin->rhs->d.exp_decl.list->self->value->type = bin->rhs->type = bin->rhs->d.exp_decl.type = t;
exp_setvar(bin->rhs, 1);
return ret > 0 ? t : env->gwion->type[et_error];
}
Exp_Binary* bin = (Exp_Binary*)data;
if(bin->rhs->exp_type == ae_exp_decl)
UNSET_FLAG(bin->rhs->d.exp_decl.list->self->value, late);
- if(bin->rhs->info->type->info->func->def->base->tmpl &&
- bin->rhs->info->type->info->func->def->base->tmpl->call) {
- struct FptrInfo info = { bin->lhs->info->type->info->func, bin->rhs->info->type->info->parent->info->func,
+ if(bin->rhs->type->info->func->def->base->tmpl &&
+ bin->rhs->type->info->func->def->base->tmpl->call) {
+ struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->parent->info->func,
bin->lhs, exp_self(bin)->pos };
CHECK_BO(fptr_do(env, &info))
exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
- struct FptrInfo info = { bin->lhs->info->type->info->func, bin->rhs->info->type->info->func,
+ struct FptrInfo info = { bin->lhs->type->info->func, bin->rhs->type->info->func,
bin->lhs, exp_self(bin)->pos };
CHECK_BO(fptr_do(env, &info))
exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
static OP_CHECK(opck_fptr_cast) {
Exp_Cast* cast = (Exp_Cast*)data;
- const Type t = exp_self(cast)->info->type;
- struct FptrInfo info = { cast->exp->info->type->info->func, t->info->func,
+ const Type t = exp_self(cast)->type;
+ struct FptrInfo info = { cast->exp->type->info->func, t->info->func,
cast->exp, exp_self(cast)->pos };
CHECK_BO(fptr_do(env, &info))
return t;
static OP_EMIT(opem_fptr_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
- if(exp_self(cast)->info->type->info->func->def->base->tmpl)
- fptr_instr(emit, cast->exp->info->type->info->func, 1);
- if(is_member(cast->exp->info->type))
+ if(exp_self(cast)->type->info->func->def->base->tmpl)
+ fptr_instr(emit, cast->exp->type->info->func, 1);
+ if(is_member(cast->exp->type))
member_fptr(emit);
return GW_OK;
}
static OP_CHECK(opck_fptr_impl) {
struct Implicit *impl = (struct Implicit*)data;
- struct FptrInfo info = { impl->e->info->type->info->func, impl->t->info->func,
+ struct FptrInfo info = { impl->e->type->info->func, impl->t->info->func,
impl->e, impl->e->pos };
CHECK_BO(fptr_do(env, &info))
return impl->t;
static OP_EMIT(opem_fptr_impl) {
struct Implicit *impl = (struct Implicit*)data;
- if(is_member(impl->e->info->type))
+ if(is_member(impl->e->type))
member_fptr(emit);
if(impl->t->info->func->def->base->tmpl)
- fptr_instr(emit, ((Exp)impl->e)->info->type->info->func, 1);
+ fptr_instr(emit, ((Exp)impl->e)->type->info->func, 1);
return GW_OK;
}
ANN Type check_exp_unary_spork(const Env env, const Stmt code);
ANN static void fork_exp(const Env env, const Exp_Unary* unary) {
- const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, unary->exp,
- loc_cpy(env->gwion->mp, unary->exp->pos));
+ const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, unary->exp, unary->exp->pos);
const Stmt_List list = new_stmt_list(env->gwion->mp, stmt, NULL);
- const Stmt code = new_stmt_code(env->gwion->mp, list,
- loc_cpy(env->gwion->mp, unary->exp->pos));
+ const Stmt code = new_stmt_code(env->gwion->mp, list, unary->exp->pos);
((Exp_Unary*)unary)->exp = NULL;
((Exp_Unary*)unary)->code = code;
+ ((Exp_Unary*)unary)->unary_type = unary_code;
}
ANN static Type fork_type(const Env env, const Exp_Unary* unary) {
- const Type t = unary->exp->info->type;
+ const Type t = unary->exp->type;
fork_exp(env, unary);
if(t == env->gwion->type[et_void])
return env->gwion->type[et_fork];
static OP_CHECK(opck_spork) {
const Exp_Unary* unary = (Exp_Unary*)data;
- if(unary->exp && unary->exp->exp_type == ae_exp_call) {
+ if(unary->unary_type == unary_exp && unary->exp->exp_type == ae_exp_call) {
const m_bool is_spork = unary->op == insert_symbol("spork");
return is_spork ? env->gwion->type[et_shred] : fork_type(env, unary);
}
- if(unary->code) {
+ if(unary->unary_type == unary_code) {
++env->scope->depth;
nspc_push_value(env->gwion->mp, env->curr);
const m_bool ret = check_stmt(env, unary->code);
static OP_CHECK(opck_usrugen) {
Exp_Binary *bin = (Exp_Binary*)data;
- const Arg_List arg = bin->lhs->info->type->info->func->def->base->args;
+ const Arg_List arg = bin->lhs->type->info->func->def->base->args;
if(!arg || arg->next)
ERR_N(exp_self(bin)->pos, _("Tick function take one and only one argument"))
if(isa(arg->type, env->gwion->type[et_float]) < 0)
ERR_N(exp_self(bin)->pos, _("Tick functions argument must be of type float"))
- if(isa(bin->lhs->info->type->info->func->def->base->ret_type, env->gwion->type[et_float]) < 0)
+ if(isa(bin->lhs->type->info->func->def->base->ret_type, env->gwion->type[et_float]) < 0)
ERR_N(exp_self(bin)->pos, _("Tick function must return float"))
- if(bin->lhs->info->type->info->func->value_ref->from->owner_class)
- CHECK_BN(isa(bin->lhs->info->type->info->func->value_ref->from->owner_class,
- bin->rhs->info->type))
- return bin->rhs->info->type;
+ if(bin->lhs->type->info->func->value_ref->from->owner_class)
+ CHECK_BN(isa(bin->lhs->type->info->func->value_ref->from->owner_class,
+ bin->rhs->type))
+ return bin->rhs->type;
}
static INSTR(UURet) {
static OP_EMIT(opem_usrugen) {
Exp_Binary *bin = (Exp_Binary*)data;
const Instr instr = emit_add_instr(emit, UsrUGenTick);
- instr->m_val = !!bin->lhs->info->type->info->func->value_ref->from->owner_class;
+ instr->m_val = !!bin->lhs->type->info->func->value_ref->from->owner_class;
return GW_OK;
}
}
static ID_EMIT(opem_this) {
- if(!exp_getvar(exp_self(prim)) && tflag(exp_self(prim)->info->type, tflag_struct)) {
+ if(!exp_getvar(exp_self(prim)) && tflag(exp_self(prim)->type, tflag_struct)) {
const Instr instr = emit_add_instr(emit, RegPushMemDeref);
instr->m_val2 = emit->env->class_def->size;
return (Instr)GW_OK;
static OP_CHECK(at_object) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(opck_rassign(env, data, mut) == env->gwion->type[et_error])
+ if(opck_rassign(env, data) == env->gwion->type[et_error])
return env->gwion->type[et_error];
if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, late); // ???
exp_setvar(bin->rhs, 1);
- CHECK_BO(isa(bin->lhs->info->type , bin->rhs->info->type))
- return bin->rhs->info->type;
+ CHECK_BO(isa(bin->lhs->type , bin->rhs->type))
+ return bin->rhs->type;
}
static OP_CHECK(opck_object_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
const Type to = known_type(env, cast->td);
- if(isa(cast->exp->info->type, to) < 0) {
- if(isa(to, cast->exp->info->type) > 0)
- ERR_N(exp_self(cast)->pos, _("can't upcast '%s' to '%s'"), cast->exp->info->type->name, to->name)
- ERR_N(exp_self(cast)->pos, _("can't cast '%s' to '%s'"), cast->exp->info->type->name, to->name)
+ if(isa(cast->exp->type, to) < 0) {
+ if(isa(to, cast->exp->type) > 0)
+ ERR_N(exp_self(cast)->pos, _("can't upcast '%s' to '%s'"), cast->exp->type->name, to->name)
+ ERR_N(exp_self(cast)->pos, _("can't cast '%s' to '%s'"), cast->exp->type->name, to->name)
}
- return exp_self(cast)->info->type;
+ return exp_self(cast)->type;
}
static OP_CHECK(opck_implicit_null2obj) {
static Type opck_object_scan(const Env env, const struct TemplateScan *ts) {
if(ts->td->types)
return scan_class(env, ts->t, ts->td) ?: env->gwion->type[et_error];
- ERR_N(td_pos(ts->td), _("you must provide template types for type '%s'"), ts->t->name)
+ Type_Decl *td = (Type_Decl*)ts->td;
+ ERR_N(td->pos, _("you must provide template types for type '%s'"), ts->t->name)
}
static OP_CHECK(opck_struct_scan) {
static const f_instr dotmember[] = { DotMember, DotMember2, DotMember3, DotMember4 };
ANN static void emit_member_func(const Emitter emit, const Exp_Dot* member) {
- const Func f = exp_self(member)->info->type->info->func;
+ const Func f = exp_self(member)->type->info->func;
if(f->def->base->tmpl)
emit_add_instr(emit, DotTmplVal);
else
- if(is_class(emit->gwion, member->base->info->type) || member->base->exp_type == ae_exp_cast) {
+ if(is_class(emit->gwion, member->base->type) || member->base->exp_type == ae_exp_cast) {
const Instr func_i = emit_add_instr(emit, f->code ? RegPushImm : SetFunc);
func_i->m_val = (m_uint)f->code ?: (m_uint)f;
return;
// if(f->def->base->tmpl)
// emit_add_instr(emit, DotTmplVal);
else {
- if(tflag(member->base->info->type, tflag_struct)) {
+ if(tflag(member->base->type, tflag_struct)) {
if(!GET_FLAG(f->def->base, static)) {
exp_setvar(member->base, 1);
emit_exp(emit, member->base);
OP_CHECK(opck_object_dot) {
const Exp_Dot *member = (Exp_Dot*)data;
const m_str str = s_name(member->xid);
- const m_bool base_static = is_class(env->gwion, member->base->info->type);
- const Type the_base = base_static ? member->base->info->type->info->base_type : member->base->info->type;
+ const m_bool base_static = is_class(env->gwion, member->base->type);
+ const Type the_base = base_static ? member->base->type->info->base_type : member->base->type;
// if(!the_base->nspc)
-// ERR_N(member->base->pos,
+// ERR_N(&member->base->pos,
// _("type '%s' does not have members - invalid use in dot expression of %s"),
// the_base->name, str)
if(member->xid == insert_symbol(env->gwion->st, "this") && base_static)
if(!value) {
env_err(env, exp_self(member)->pos,
_("class '%s' has no member '%s'"), the_base->name, str);
- if(member->base->info->type->nspc)
+ if(member->base->type->nspc)
did_you_mean_type(the_base, str);
return env->gwion->type[et_error];
}
OP_EMIT(opem_object_dot) {
const Exp_Dot *member = (Exp_Dot*)data;
- const Type t_base = actual_type(emit->gwion, member->base->info->type);
+ const Type t_base = actual_type(emit->gwion, member->base->type);
const Value value = find_value(t_base, member->xid);
- if(!is_class(emit->gwion, member->base->info->type) && (vflag(value, vflag_member) ||
- (isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 &&
- !is_fptr(emit->gwion, exp_self(member)->info->type)))) {
+ if(!is_class(emit->gwion, member->base->type) && (vflag(value, vflag_member) ||
+ (isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 &&
+ !is_fptr(emit->gwion, exp_self(member)->type)))) {
if(!tflag(t_base, tflag_struct))
CHECK_BB(emit_exp(emit, member->base))
}
- if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->info->type))
+ if(isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0 && !is_fptr(emit->gwion, exp_self(member)->type))
emit_member_func(emit, member);
else if(vflag(value, vflag_member)) {
if(!tflag(t_base, tflag_struct))
ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
const Class_Def c = info->base->info->cdef;
const Class_Def cdef = new_class_def(env->gwion->mp, c->flag, info->name, c->base.ext ? cpy_type_decl(env->gwion->mp, c->base.ext) : NULL,
- c->body ?cpy_ast(env->gwion->mp, c->body) : NULL,
- loc_cpy(env->gwion->mp, c->pos));
+ c->body ?cpy_ast(env->gwion->mp, c->body) : NULL, c->pos);
cdef->cflag = c->cflag;
cdef->base.tmpl = mk_tmpl(env, c->base.tmpl, info->td->types);
const m_bool ret = scan0_class_def(env, cdef);
ANN static m_bool scantmpl_union_def(const Env env, struct tmpl_info *info) {
const Union_Def u = info->base->info->udef;
- const Union_Def udef = new_union_def(env->gwion->mp, cpy_union_list(env->gwion->mp, u->l),
- loc_cpy(env->gwion->mp, u->pos));
+ const Union_Def udef = new_union_def(env->gwion->mp, cpy_union_list(env->gwion->mp, u->l), u->pos);
udef->xid = info->name;
udef->tmpl = mk_tmpl(env, u->tmpl, info->td->types);
if(GET_FLAG(info->base, global))
OP_CHECK(opck_basic_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
- return isa(cast->exp->info->type, exp_self(cast)->info->type) > 0 ?
- exp_self(cast)->info->type : env->gwion->type[et_error];
+ return isa(cast->exp->type, exp_self(cast)->type) > 0 ?
+ exp_self(cast)->type : env->gwion->type[et_error];
}
OP_CHECK(opck_usr_implicit) {
if(access)
ERR_N(bin->rhs->pos, _("cannot assign '%s' on types '%s' and '%s'.\n"
" ... (reason: --- right-side operand is %s.)"),
- s_name(bin->op), bin->lhs->info->type->name, bin->rhs->info->type->name,
+ s_name(bin->op), bin->lhs->type->name, bin->rhs->type->name,
access)
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
OP_CHECK(opck_rassign) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(opck_const_rhs(env, data, mut) == env->gwion->type[et_error])
+ if(opck_const_rhs(env, data) == env->gwion->type[et_error])
return env->gwion->type[et_error];
exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
OP_CHECK(opck_unary_meta) {
const Exp_Unary* unary = (Exp_Unary*)data;
exp_setmeta(exp_self(unary), 1);
- return unary->exp->info->type;
+ return unary->exp->type;
}
OP_CHECK(opck_unary_meta2) {
_("unary operator '%s' cannot be used on %s data-types."),
s_name(unary->op), access);
exp_setvar(unary->exp, 1);
- return unary->exp->info->type;
+ return unary->exp->type;
}
OP_CHECK(opck_post) {
ERR_N(post->exp->pos, _("post operator '%s' cannot be used on %s data-type."),
s_name(post->op), access)
exp_setvar(post->exp, 1);
- return post->exp->info->type;
+ return post->exp->type;
}
ANN Type check_td(const Env env, Type_Decl *td);
if(isa(t, env->gwion->type[et_object]) < 0)
ERR_N(exp_self(unary)->pos, _("can't use 'new' on non-object types...\n"))
if(type_ref(t))
- ERR_N(td_pos(unary->td), _("can't use 'new' on ref type '%s'\n"), t->name)
+ ERR_N(unary->td->pos, _("can't use 'new' on ref type '%s'\n"), t->name)
if(GET_FLAG(t, abstract))
- ERR_N(td_pos(unary->td), _("can't use 'new' on abstract type '%s'\n"), t->name)
+ ERR_N(unary->td->pos, _("can't use 'new' on abstract type '%s'\n"), t->name)
if(unary->td->array)
CHECK_BN(check_subscripts(env, unary->td->array, 1))
return t;
OP_EMIT(opem_new) {
const Exp_Unary* unary = (Exp_Unary*)data;
- CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->info->type,
+ CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type,
unary->td->array, 0))
emit_gc(emit, -SZ_INT);
return GW_OK;
const Exp exp = (Exp)data;
const Range *range = exp->d.prim.d.range;
const Exp e = range->start ?: range->end;
- return array_type(env, e->info->type, 1);
+ return array_type(env, e->type, 1);
}
static OP_EMIT(opem_int_range) {
const Exp exp = (Exp)data;
const Instr instr = emit_add_instr(emit, IntRange);
- instr->m_val = (m_uint)exp->info->type;
+ instr->m_val = (m_uint)exp->type;
return GW_OK;
}
static OP_CHECK(opck_now) {
const Exp_Binary* bin = (Exp_Binary*)data;
if(!is_now(env, bin->rhs))
- CHECK_NN(opck_const_rhs(env, data, mut))
+ CHECK_NN(opck_const_rhs(env, data))
exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
static GWION_IMPORT(time) {
CHECK_BO(ptr_access(env, bin->rhs))
exp_setvar(bin->lhs, 1);
exp_setvar(bin->rhs, 1);
- Type t = bin->lhs->info->type;
+ Type t = bin->lhs->type;
do {
- Type u = bin->rhs->info->type;
+ Type u = bin->rhs->type;
do {
const Type base = ptr_base(env, u);
if(isa(t, base) > 0)
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = SZ_INT;
const Exp_Binary* bin = (Exp_Binary*)data;
- if(isa(bin->lhs->info->type, emit->gwion->type[et_object]) > 0) {
+ if(isa(bin->lhs->type, emit->gwion->type[et_object]) > 0) {
const Instr instr = emit_add_instr(emit, RegAddRefAddr);
instr->m_val = -SZ_INT;
emit_add_instr(emit, instr_ptr_assign_obj);
static OP_CHECK(opck_ptr_deref) {
const Exp_Unary* unary = (Exp_Unary*)data;
- return ptr_base(env, unary->exp->info->type);
+ return ptr_base(env, unary->exp->type);
}
static OP_CHECK(opck_ptr_cast) {
CHECK_BN(ensure_traverse(env, _t))
const Type to = known_type(env, cast->td->types->td);
exp_setvar(cast->exp, 1);
- if(isa(cast->exp->info->type, to) > 0)
+ if(isa(cast->exp->type, to) > 0)
return t;
ERR_N(exp_self(cast)->pos, "invalid pointer cast")
}
const struct Implicit* imp = (struct Implicit*)data;
const Exp e = imp->e;
const Type base = ptr_base(env, imp->t);
- if(isa(e->info->type, base) > 0) {
+ if(isa(e->type, base) > 0) {
const m_str access = exp_access(e);
if(access)
ERR_N(e->pos, _("can't cast %s value to Ptr"), access);
static OP_EMIT(opem_ptr_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
const Instr instr = emit_add_instr(emit, Cast2Ptr);
- instr->m_val = (m_uint)exp_self(cast)->info->type;
+ instr->m_val = (m_uint)exp_self(cast)->type;
return GW_OK;
}
static OP_EMIT(opem_ptr_deref) {
const Exp_Unary* unary = (Exp_Unary*)data;
const Instr instr = emit_add_instr(emit, instr_ptr_deref);
- instr->m_val = exp_self(unary)->info->type->size;
+ instr->m_val = exp_self(unary)->type->size;
instr->m_val2 = exp_getvar(exp_self(unary));
return GW_OK;
}
static OP_CHECK(opck_ptr_ref) {
const Exp_Binary* bin = (Exp_Binary*)data;
exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
static GACK(gack_ptr) {
static OP_CHECK(opck_chuck_ugen) {
const Exp_Binary* bin = (Exp_Binary*)data;
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
GWION_IMPORT(ugen) {
static OP_CHECK(opck_none) {
Exp_Binary *bin = (Exp_Binary*)data;
- CHECK_NN(opck_rassign(env, data, mut))
+ CHECK_NN(opck_rassign(env, data))
exp_setvar(bin->rhs, 1);
- return bin->rhs->info->type;
+ return bin->rhs->type;
}
static OP_EMIT(opem_none) {
static OP_EMIT(opem_union_dot) {
const Exp_Dot *member = (Exp_Dot*)data;
- const Map map = &member->base->info->type->nspc->info->value->map;
+ const Map map = &member->base->type->nspc->info->value->map;
CHECK_BB(emit_exp(emit, member->base))
- if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0) {
+ if(isa(exp_self(member)->type, emit->gwion->type[et_function]) > 0) {
const Instr instr = emit_add_instr(emit, RegPushImm);
- const Func f = (Func)vector_front(&member->base->info->type->info->parent->nspc->info->vtable);
+ const Func f = (Func)vector_front(&member->base->type->info->parent->nspc->info->vtable);
instr->m_val = (m_uint)f->code;
return GW_OK;
}
const Exp exp = call->args;
if(exp->exp_type != ae_exp_primary && exp->d.prim.prim_type != ae_prim_id)
ERR_N(exp->pos, "Union.is() argument must be of form id");
- const Type t = call->func->d.exp_dot.base->info->type;
+ const Type t = call->func->d.exp_dot.base->type;
const Value v = find_value(t, exp->d.prim.d.var);
if(!v)
ERR_N(exp->pos, "'%s' has no member '%s'", t->name, s_name(exp->d.prim.d.var));
for(m_uint i = 0; i < map_size(map); ++i) {
const Value v = (Value)VVAL(map, i);
if(!strcmp(s_name(exp->d.prim.d.var), v->name)) {
- *mut = 1;
const Exp exp_func = call->func;
const Exp exp_args = call->args;
e->exp_type = ae_exp_binary;
e->d.exp_binary.lhs = cpy_exp(env->gwion->mp, exp_func);
e->d.exp_binary.lhs->d.exp_dot.xid = insert_symbol(env->gwion->st, "@index");
- e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i+1, loc_cpy(env->gwion->mp, e->pos));
+ e->d.exp_binary.rhs = new_prim_int(env->gwion->mp, i+1, e->pos);
free_exp(env->gwion->mp, exp_func);
free_exp(env->gwion->mp, exp_args);
e->d.exp_binary.op = insert_symbol(env->gwion->st, "==");
CHECK_OO(check_exp(env, e))
- return e->info->type;
+ return e->type;
}
}
return env->gwion->type[et_error];
static OP_EMIT(opem_vararg_cast) {
const Exp_Cast* cast = (Exp_Cast*)data;
const Instr instr = emit_add_instr(emit, VarargCast);
- instr->m_val = (m_uint)exp_self(cast)->info->type;
+ instr->m_val = (m_uint)exp_self(cast)->type;
const Instr push = emit_add_instr(emit, RegPush);
- push->m_val = exp_self(cast)->info->type->size - SZ_INT;
+ push->m_val = exp_self(cast)->type->size - SZ_INT;
return GW_OK;
}
static ID_CHECK(idck_vararg) {
if(env->func && fbflag(env->func->def->base, fbflag_variadic))
- return exp_self(prim)->info->type;
+ return exp_self(prim)->type;
ERR_O(exp_self(prim)->pos, _("'vararg' must be used inside variadic function"))
}
ANN static Type check_internal(const Env env, const Symbol sym,
const Exp e, const Type t) {
struct Implicit imp = { .e=e, .t=t, .pos=e->pos };
- struct Op_Import opi = { .op=sym, .lhs=e->info->type,
+ struct Op_Import opi = { .op=sym, .lhs=e->type,
.rhs=t, .data=(uintptr_t)&imp, .pos=e->pos, .op_type=op_implicit };
return op_check(env, &opi);
}
ANN m_bool check_implicit(const Env env, const Exp e, const Type t) {
- if(e->info->type == t)
+ if(e->type == t)
return GW_OK;
const Symbol sym = insert_symbol("@implicit");
- return (e->info->cast_to = check_internal(env, sym, e, t)) ? GW_OK : GW_ERROR;
+ return (e->cast_to = check_internal(env, sym, e, t)) ? GW_OK : GW_ERROR;
}
ANN m_bool check_subscripts(Env env, const Array_Sub array, const m_bool is_decl) {
ANN Type check_td(const Env env, Type_Decl *td) {
CHECK_BO(check_td_exp(env, td))
- const Type t = actual_type(env->gwion, td->exp->info->type);
+ const Type t = actual_type(env->gwion, td->exp->type);
td->xid = insert_symbol("auto");
return t;
}
CHECK_BO(scan2_exp(env, exp_self(decl)))
}
if(!decl->type)
- ERR_O(td_pos(decl->td), _("can't find type"));
+ ERR_O(decl->td->pos, _("can't find type"));
{
const Type t = get_type(decl->type);
- CHECK_BO(inferable(env, t, td_pos(decl->td)))
+ CHECK_BO(inferable(env, t, decl->td->pos))
CHECK_BO(ensure_check(env, t))
}
const m_bool global = GET_FLAG(decl->td, global);
return ret > 0 ? decl->list->self->value->type : NULL;
}
-
-ANN static inline void set_cast(const Env env, Type type, const Exp e) {
- e->info->cast_to = type;
- e->info->nspc = env->curr;
-}
-
ANN static m_bool prim_array_inner(const Env env, Type type, const Exp e) {
- const Type common = find_common_anc(e->info->type, type);
+ const Type common = find_common_anc(e->type, type);
if(common)
return GW_OK;
if(check_implicit(env, e, type) < 0)
ERR_B(e->pos, _("array init [...] contains incompatible types ..."))
- set_cast(env, type, e); // ???
return GW_OK;
}
ANN static inline Type prim_array_match(const Env env, Exp e) {
- const Type type = e->info->type;
+ const Type type = e->type;
do CHECK_BO(prim_array_inner(env, type, e))
while((e = e->next));
return array_type(env, array_base(type), type->array_depth + 1);
if(range->end)
CHECK_OB(check_exp(env, range->end))
if(range->start && range->end) {
- if(isa(range->end->info->type, range->start->info->type) < 0)
+ if(isa(range->end->type, range->start->type) < 0)
ERR_B(range->start->pos, _("range types do not match"))
}
return GW_OK;
CHECK_BO(check_range(env, range))
const Exp e = range->start ?: range->end;
const Symbol sym = insert_symbol("@range");
- struct Op_Import opi = { .op=sym, .rhs=e->info->type, .pos=e->pos, .data=(uintptr_t)prim_exp(data), .op_type=op_exp };
+ struct Op_Import opi = { .op=sym, .rhs=e->type, .pos=e->pos, .data=(uintptr_t)prim_exp(data), .op_type=op_exp };
return op_check(env, &opi);
}
}
ANN static Type check_dot(const Env env, const Exp_Dot *member) {
- struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->base->info->type, .data=(uintptr_t)member,
+ struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->base->type, .data=(uintptr_t)member,
.pos=exp_self(member)->pos, .op_type=op_dot };
return op_check(env, &opi);
}
const Exp exp = exp_self(prim_exp(data));
const Value v = exp->d.prim.value;
const m_str name = !GET_FLAG(v, static) ? "this" : v->from->owner_class->name;
- const Exp base = new_prim_id(env->gwion->mp, insert_symbol(name), loc_cpy(env->gwion->mp, prim_pos(data)));
+ const Exp base = new_prim_id(env->gwion->mp, insert_symbol(name), prim_pos(data));
exp->exp_type = ae_exp_dot;
exp->d.exp_dot.base = base;
exp->d.exp_dot.xid = *data;
DECL_PRIM_FUNC(check, Type, Env);
ANN static Type check_prim(const Env env, Exp_Primary *prim) {
- return exp_self(prim)->info->type = check_prim_func[prim->prim_type](env, &prim->d);
+ return exp_self(prim)->type = check_prim_func[prim->prim_type](env, &prim->d);
}
ANN Type check_array_access(const Env env, const Array_Sub array) {
const Symbol sym = insert_symbol("@array");
- struct Op_Import opi = { .op=sym, .lhs=array->exp->info->type, .rhs=array->type,
+ struct Op_Import opi = { .op=sym, .lhs=array->exp->type, .rhs=array->type,
.pos=array->exp->pos, .data=(uintptr_t)array, .op_type=op_array };
return op_check(env, &opi);
}
CHECK_BO(check_range(env, range->range))
const Symbol sym = insert_symbol("@slice");
const Exp e = range->range->start ?: range->range->end;
- struct Op_Import opi = { .op=sym, .lhs=e->info->type, .rhs=range->base->info->type,
+ struct Op_Import opi = { .op=sym, .lhs=e->type, .rhs=range->base->type,
.pos=e->pos, .data=(uintptr_t)exp_self(range), .op_type=op_exp };
return op_check(env, &opi);
}
-ANN2(1,2,4) static Type_Decl* prepend_type_decl(MemPool mp, const Symbol xid, Type_Decl* td, const loc_t pos) {
- Type_Decl *a = new_type_decl(mp, xid, loc_cpy(mp, pos));
+ANN2(1,2) static Type_Decl* prepend_type_decl(MemPool mp, const Symbol xid, Type_Decl* td, const struct loc_t_ pos) {
+ Type_Decl *a = new_type_decl(mp, xid, pos);
a->next = td;
return a;
}
ANN static m_bool func_match_inner(const Env env, const Exp e, const Type t,
const m_bool implicit, const m_bool specific) {
- const m_bool match = (specific ? e->info->type == t : isa(e->info->type, t) > 0);
+ const m_bool match = (specific ? e->type == t : isa(e->type, t) > 0);
if(!match) {
- if(e->info->type == env->gwion->type[et_lambda] && is_fptr(env->gwion, t)) {
+ if(e->type == env->gwion->type[et_lambda] && is_fptr(env->gwion, t)) {
exp_setvar(e, 1);
return check_lambda(env, t, &e->d.exp_lambda);
}
nspc_pop_type(env->gwion->mp, env->curr);
CHECK_OO(e1->type)
}
- if(!func->def->base->tmpl && func->next)
- env->context->error = 1;
+// if(!func->def->base->tmpl && func->next)
+// env->context->error = 1;
const m_bool ret = func_match_inner(env, e, e1->type, implicit, specific);
- if(func->next)
- env->context->error = ret < 0;
+// if(func->next)
+// env->context->error = ret < 0;
if(ret < 0)
break;
e = e->next;
ANN2(1, 2) Func find_func_match(const Env env, const Func up, const Exp exp) {
Func func;
- const Exp args = (exp && isa(exp->info->type, env->gwion->type[et_void]) < 0) ? exp : NULL;
+ const Exp args = (exp && isa(exp->type, env->gwion->type[et_void]) < 0) ? exp : NULL;
if((func = find_func_match_actual(env, up, args, 0, 1)) ||
(func = find_func_match_actual(env, up, args, 1, 1)) ||
(func = find_func_match_actual(env, up, args, 0, 0)) ||
ANN static void print_current_args(Exp e) {
gw_err(_("and not\n "));
- do gw_err(" \033[32m%s\033[0m", e->info->type->name);
+ do gw_err(" \033[32m%s\033[0m", e->type->name);
while((e = next_arg_Exp(e)));
gw_err("\n");
}
if(f) {
// copy that tmpl->call?
Tmpl* tmpl = new_tmpl_call(env->gwion->mp, func->tmpl->call);
- tmpl->list = v->d.func_ref ? v->d.func_ref->def->base->tmpl->list : func->func->info->type->info->func->def->base->tmpl->list;
+ tmpl->list = v->d.func_ref ? v->d.func_ref->def->base->tmpl->list : func->func->type->info->func->def->base->tmpl->list;
((Exp_Call*)func)->tmpl = tmpl;
- return ((Exp_Call*)func)->m_func = f;
+ func->func->type = f->value_ref->type;
+ return f;
}
((Exp_Call*)func)->tmpl = NULL;
assert(exp_self(func));
envset_pop(&es, v->from->owner_class);
CHECK_BO(ret)
}
- exp->m_func = func;
+ exp->func->type = func->value_ref->type;
return func->def->base->ret_type;
}
Exp template_arg = exp->args;
while(arg && template_arg) {
if(list->xid == arg->td->xid) {
- tl[args_number] = mk_type_list(env, template_arg->info->type, fdef->pos);
+ tl[args_number] = mk_type_list(env, template_arg->type, fdef->pos);
if(args_number)
tl[args_number - 1]->next = tl[args_number];
++args_number;
}
ANN static Type check_exp_call_template(const Env env, Exp_Call *exp) {
- const Type t = exp->func->info->type;
+ const Type t = exp->func->type;
DECL_OO(const Value, value, = type_value(env->gwion, t))
const Func_Def fdef = value->d.func_ref ? value->d.func_ref->def : t->info->func->def;
Tmpl *tm = fdef->base->tmpl;
Arg_List arg = l->def->base->args;
Exp e = exp->args;
while(arg && e) {
- arg->type = e->info->type;
+ arg->type = e->type;
arg = arg->next;
e = e->next;
}
if(env->class_def)
set_vflag(l->def->base->func->value_ref, vflag_member);
}
- ((Exp_Call*)exp)->m_func = l->def->base->func;
+ exp->func->type = l->def->base->func->value_ref->type;
if(!l->def->base->ret_type)
l->def->base->ret_type = env->gwion->type[et_void];
return ret > 0 ? l->def->base->ret_type : NULL;
CHECK_OB(check_exp(env, exp->func))
if(exp->func->exp_type == ae_exp_decl)
ERR_B(exp->func->pos, _("Can't call late function pointer at declaration site"))
- const Type t = actual_type(env->gwion, exp->func->info->type);
+ const Type t = actual_type(env->gwion, exp->func->type);
const Exp e = exp_self(exp);
struct Op_Import opi = { .op=insert_symbol("@func_check"),
.rhs=t, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
CHECK_NB(op_check(env, &opi)) // doesn't really return NULL
if(e->exp_type != ae_exp_call)
return 0;
- return e->info->type != env->gwion->type[et_error] ?
+ return e->type != env->gwion->type[et_error] ?
GW_OK : GW_ERROR;
}
ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
DECL_BO(const m_bool, ret, = func_check(env, exp))
if(!ret)
- return exp_self(exp)->info->type;
- const Type t = actual_type(env->gwion, exp->func->info->type);
+ return exp_self(exp)->type;
+ const Type t = actual_type(env->gwion, exp->func->type);
if(isa(t, env->gwion->type[et_function]) < 0) {
// use func flag?
- struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=actual_type(env->gwion, exp->func->info->type),
+ struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=actual_type(env->gwion, exp->func->type),
.data=(uintptr_t)exp, .pos=exp_self(exp)->pos, .op_type=op_exp };
const Type t = op_check(env, &opi);
- exp_self(exp)->info->nspc = t ? t->info->owner : NULL;
+// exp_self(exp)->info->nspc = t ? t->info->owner : NULL;
return t;
}
if(t == env->gwion->type[et_lambda])
if(tflag(t, tflag_ftmpl))
return check_exp_call_template(env, (Exp_Call*)exp);
const Func func = find_func_match(env, t->info->func, exp->args);
- if((exp_self(exp)->d.exp_call.m_func = func)) {
- exp->func->info->type = func->value_ref->type;
+ if(func) {
+ exp->func->type = func->value_ref->type;
return func->def->base->ret_type;
}
- function_alternative(env, exp->func->info->type, exp->args, exp_self(exp)->pos);
+ function_alternative(env, exp->func->type, exp->args, exp_self(exp)->pos);
return NULL;
}
CHECK_OO(check_exp(env, bin->lhs))
const m_bool is_auto = bin->rhs->exp_type == ae_exp_decl && bin->rhs->d.exp_decl.type == env->gwion->type[et_auto];
if(is_auto)
- bin->rhs->d.exp_decl.type = bin->lhs->info->type;
+ bin->rhs->d.exp_decl.type = bin->lhs->type;
CHECK_OO(check_exp(env, bin->rhs))
if(is_auto)
- bin->rhs->info->type = bin->lhs->info->type;
- struct Op_Import opi = { .op=bin->op, .lhs=bin->lhs->info->type,
- .rhs=bin->rhs->info->type, .data=(uintptr_t)bin, .pos=exp_self(bin)->pos, .op_type=op_binary };
+ bin->rhs->type = bin->lhs->type;
+ struct Op_Import opi = { .op=bin->op, .lhs=bin->lhs->type,
+ .rhs=bin->rhs->type, .data=(uintptr_t)bin, .pos=exp_self(bin)->pos, .op_type=op_binary };
const Type ret = op_check(env, &opi);
if(!ret && is_auto && exp_self(bin)->exp_type == ae_exp_binary)
bin->rhs->d.exp_decl.list->self->value->type = env->gwion->type[et_auto];
ANN static Type check_exp_cast(const Env env, const Exp_Cast* cast) {
DECL_OO(const Type, t, = check_exp(env, cast->exp))
- CHECK_OO((exp_self(cast)->info->type = cast->td->xid ? known_type(env, cast->td) : check_td(env, cast->td)))
- struct Op_Import opi = { .op=insert_symbol("$"), .lhs=t, .rhs=exp_self(cast)->info->type,
+ CHECK_OO((exp_self(cast)->type = cast->td->xid ? known_type(env, cast->td) : check_td(env, cast->td)))
+ struct Op_Import opi = { .op=insert_symbol("$"), .lhs=t, .rhs=exp_self(cast)->type,
.data=(uintptr_t)cast, .pos=exp_self(cast)->pos, .op_type=op_cast };
return op_check(env, &opi);
}
// CHECK_BO(func_check(env, exp))
DECL_BO(const m_bool, ret, = func_check(env, exp))
if(!ret)
- return exp_self(exp)->info->type;
- const Type t = actual_type(env->gwion, exp->func->info->type);
+ return exp_self(exp)->type;
+ const Type t = actual_type(env->gwion, exp->func->type);
if(isa(t, env->gwion->type[et_function]) < 0)
return check_exp_call1(env, exp);
if(exp->args)
ERR_O(exp_self(exp)->pos, _("template call of non-template function."))
if(t->info->func->def->base->tmpl->call) {
if(env->func == t->info->func) {
- exp->m_func = env->func;
+ exp->func->type = env->func->value_ref->type;
return env->func->def->base->ret_type;
- } else
- CHECK_BO(predefined_call(env, t, exp_self(exp)->pos))
+ } else
+ CHECK_BO(predefined_call(env, t, exp_self(exp)->pos))
}
const Value v = type_value(env->gwion, t);
- CHECK_OO((exp->m_func = find_template_match(env, v, exp)))
- return exp->m_func->def->base->ret_type;
+ DECL_OO(const Func, f, = find_template_match(env, v, exp))
+ exp->func->type = f->value_ref->type;
+ return f->def->base->ret_type;
}
return check_exp_call1(env, exp);
}
ANN static Type check_exp_unary(const Env env, const Exp_Unary* unary) {
- struct Op_Import opi = { .op=unary->op, .rhs=unary->exp ? check_exp(env, unary->exp) : NULL,
+ const Type rhs = unary->unary_type == unary_exp ? check_exp(env, unary->exp) : NULL;
+ if(unary->unary_type == unary_exp)
+ CHECK_OO(rhs)
+ struct Op_Import opi = { .op=unary->op, .rhs=rhs,
.data=(uintptr_t)unary, .pos=exp_self(unary)->pos, .op_type=op_unary };
- if(unary->exp && !opi.rhs)
- return NULL;
DECL_OO(const Type, ret, = op_check(env, &opi))
const Type t = get_type(actual_type(env->gwion, ret));
CHECK_BO(ensure_traverse(env, t))
ERR_O(exp_self(exp_if)->pos,
_("incompatible types '%s' and '%s' in if expression..."),
if_exp->name, else_exp->name)
- if(!exp_if->if_exp && isa(exp_if->cond->info->type, else_exp) < 0)
+ if(!exp_if->if_exp && isa(exp_if->cond->type, else_exp) < 0)
ERR_O(exp_self(exp_if)->pos,
_("condition type '%s' does not match '%s'"),
cond->name, ret->name)
ANN Type check_exp(const Env env, const Exp exp) {
Exp curr = exp;
do {
- CHECK_OO((curr->info->type = check_exp_func[curr->exp_type](env, &curr->d)))
- if(env->func && isa(curr->info->type, env->gwion->type[et_lambda]) < 0 && isa(curr->info->type, env->gwion->type[et_function]) > 0 &&
- !fflag(curr->info->type->info->func, fflag_pure))
+ CHECK_OO((curr->type = check_exp_func[curr->exp_type](env, &curr->d)))
+ if(env->func && isa(curr->type, env->gwion->type[et_lambda]) < 0 && isa(curr->type, env->gwion->type[et_function]) > 0 &&
+ !fflag(curr->type->info->func, fflag_pure))
unset_fflag(env->func, fflag_pure);
} while((curr = curr->next));
- return exp->info->type;
+ return exp->type;
}
ANN m_bool check_enum_def(const Env env, const Enum_Def edef) {
ANN static m_bool check_stmt_varloop(const Env env, const Stmt_VarLoop stmt) {
CHECK_OB(check_exp(env, stmt->exp))
- if(isa(stmt->exp->info->type, env->gwion->type[et_vararg]) < 0)
+ if(isa(stmt->exp->type, env->gwion->type[et_vararg]) < 0)
ERR_B(stmt->exp->pos, "varloop expression type must be '%s', not '%s'",
- env->gwion->type[et_vararg]->name, stmt->exp->info->type->name)
+ env->gwion->type[et_vararg]->name, stmt->exp->type->name)
return check_stmt(env, stmt->body);
}
ANN static Value match_value(const Env env, const Exp_Primary* prim, const m_uint i) {
const Symbol sym = prim->d.var;
const Value v = new_value(env->gwion->mp,
- ((Exp)VKEY(&env->scope->match->map, i))->info->type, s_name(sym));
+ ((Exp)VKEY(&env->scope->match->map, i))->type, s_name(sym));
set_vflag(v, vflag_valid);
nspc_add_value(env->curr, sym, v);
VVAL(&env->scope->match->map, i) = (vtype)v;
const Exp base = (Exp)VKEY(&env->scope->match->map, i);
CHECK_OB(check_exp(env, e))
Exp_Binary bin = { .lhs=base, .rhs=e, .op=op };
- struct ExpInfo_ info = { .nspc=env->curr };
- struct Exp_ ebin = { .d={.exp_binary=bin}, .info=&info };
- struct Op_Import opi = { .op=op, .lhs=base->info->type, .rhs=e->info->type,
+ struct Exp_ ebin = { .d={.exp_binary=bin} };
+ struct Op_Import opi = { .op=op, .lhs=base->type, .rhs=e->type,
.data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos, .op_type=op_binary };
CHECK_OB(op_check(env, &opi))
- e->info->nspc= info.nspc;
+// e->info->nspc= info.nspc;
return GW_OK;
}
}
ANN static m_bool check_signature_match(const Env env, const Func_Def fdef, const Func parent) {
if(GET_FLAG(parent->def->base, final))
- ERR_B(td_pos(fdef->base->td), _("can't override final function '%s'\n"), parent->name)
+ ERR_B(fdef->base->td->pos, _("can't override final function '%s'\n"), parent->name)
if(GET_FLAG(parent->def->base, static) != GET_FLAG(fdef->base, static)) {
const m_str c_name = fdef->base->func->value_ref->from->owner_class->name;
const m_str p_name = parent->value_ref->from->owner_class->name;
const m_str f_name = s_name(fdef->base->xid);
- ERR_B(td_pos(fdef->base->td),
+ ERR_B(fdef->base->td->pos,
_("function '%s.%s' ressembles '%s.%s' but cannot override...\n"
" ...(reason: '%s.%s' is declared as 'static')"),
c_name, f_name, p_name, c_name,
for(m_uint j = i + 1; f1 && j <= v->from->offset; ++j) {
const Func f2 = get_overload(env, fdef, j);
if(f2 && compat_func(f1->def, f2->def) > 0)
- ERR_B(td_pos(f2->def->base->td), _("global function '%s' already defined"
+ ERR_B(f2->def->base->td->pos, _("global function '%s' already defined"
" for those arguments"), s_name(fdef->base->xid))
}
}
#include "operator.h"
#include "import.h"
#include "parse.h"
-#include "match.h"
#include "emit.h"
#include "specialid.h"
#include "tmp_resolve.h"
const Type exists = nspc_lookup_type0(v->from->owner, sym);
if(exists)
return exists->info->func;
- const Func_Def base = v->d.func_ref ? v->d.func_ref->def : ra->e->func->info->type->info->func->def;
+ const Func_Def base = v->d.func_ref ? v->d.func_ref->def : ra->e->func->type->info->func->def;
const Tmpl tmpl = { .list=base->base->tmpl->list, .call=ra->types };
CHECK_BO(template_push_types(env, &tmpl));
Func_Base *const fbase = cpy_func_base(env->gwion->mp, base->base);
const Env env;
const Map map;
const struct Op_Import* opi;
- m_bool mut;
};
__attribute__((returns_nonnull))
ANN m_bool add_op(const Gwion gwion, const struct Op_Import* opi) {
Nspc n = gwion->env->curr;
do {
- struct OpChecker ock = { gwion->env, &n->info->op_map, opi, 0 };
+ struct OpChecker ock = { gwion->env, &n->info->op_map, opi };
CHECK_BB(op_exist(&ock, n))
} while((n = n->parent));
if(!gwion->env->curr->info->op_map.ptr)
map_init(&gwion->env->curr->info->op_map);
- struct OpChecker ock = { gwion->env, &gwion->env->curr->info->op_map, opi, 0 };
+ struct OpChecker ock = { gwion->env, &gwion->env->curr->info->op_map, opi };
const Vector v = op_vector(gwion->mp, &ock);
const M_Operator* mo = new_mo(gwion->mp, opi);
vector_add(v, (vtype)mo);
return GW_OK;
}
-ANN static void set_nspc(struct Op_Import *opi, const Nspc nspc) {
- if(opi->op_type == op_implicit) {
- struct Implicit* imp = (struct Implicit*)opi->data;
- imp->e->info->nspc = nspc;
- return;
- }
- if(opi->op_type == op_array) {
- Array_Sub array = (Array_Sub)opi->data;
- array->exp->info->nspc = nspc;
- return;
- }
- if(opi->op_type == op_exp) {
- ((Exp)opi->data)->info->nspc = nspc;
- return;
- }
- if(opi->op_type != op_scan)
- exp_self((union exp_data*)opi->data)->info->nspc = nspc;
-}
-
ANN static Type op_check_inner(struct OpChecker* ock) {
Type t, r = ock->opi->rhs;
do {
const M_Operator* mo;
const Vector v = (Vector)map_get(ock->map, (vtype)ock->opi->op);
if(v && (mo = operator_find(v, ock->opi->lhs, r))) {
- if((mo->ck && (t = mo->ck(ock->env, (void*)ock->opi->data, &ock->mut))))
+ if((mo->ck && (t = mo->ck(ock->env, (void*)ock->opi->data))))
return t;
else
return mo->ret;
Type l = opi->lhs;
do {
struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data, .op_type=opi->op_type };
- struct OpChecker ock = { env, &nspc->info->op_map, &opi2, 0 };
+ struct OpChecker ock = { env, &nspc->info->op_map, &opi2 };
const Type ret = op_check_inner(&ock);
if(ret) {
if(ret == env->gwion->type[et_error])
return NULL;
- if(!ock.mut)
- set_nspc(&opi2, nspc);
return ret;
}
} while(l && (l = l->info->parent));
return GW_OK;
}
-ANN static Nspc get_nspc(const struct Op_Import* opi) {
- if(opi->op_type == op_implicit) {
- struct Implicit* imp = (struct Implicit*)opi->data;
- return imp->e->info->nspc;
- }
- if(opi->op_type == op_array) {
- struct ArrayAccessInfo *info = (struct ArrayAccessInfo*)opi->data;
- return info->array.exp->info->nspc;
- }
- if(opi->op_type == op_exp)
- return ((Exp)opi->data)->info->nspc;
- return exp_self((union exp_data*)opi->data)->info->nspc;
-}
-
-ANN static inline Nspc ensure_nspc(const struct Op_Import* opi) {
- DECL_OO(Nspc, nspc, = get_nspc(opi))
- while(!nspc->info->op_map.ptr)
- nspc = nspc->parent;
- return nspc;
-}
-
ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
- DECL_OB(Nspc, nspc, = ensure_nspc(opi))
- Type l = opi->lhs;
+ Nspc nspc = emit->env->class_def ? emit->env->curr : emit->env->context->nspc;
do {
- Type r = opi->rhs;
+ if(!nspc->info->op_map.ptr)continue;
+ Type l = opi->lhs;
do {
- const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
- if(!v)
- continue;
- const M_Operator* mo = operator_find(v, l, r);
- if(mo) {
- if(mo->em) {
- const m_bool ret = mo->em(emit, (void*)opi->data);
- if(ret)
- return ret;
- } else if(mo->func || mo->instr)
- return handle_instr(emit, mo);
- }
- } while(r && (r = r->info->parent));
- } while(l && (l = l->info->parent));
+ Type r = opi->rhs;
+ do {
+ const Vector v = (Vector)map_get(&nspc->info->op_map, (vtype)opi->op);
+ if(!v)
+ continue;
+ const M_Operator* mo = operator_find(v, l, r);
+ if(mo) {
+ if(mo->em) {
+ const m_bool ret = mo->em(emit, (void*)opi->data);
+ if(ret)
+ return ret;
+ } else if(mo->func || mo->instr)
+ return handle_instr(emit, mo);
+ }
+ } while(r && (r = r->info->parent));
+ } while(l && (l = l->info->parent));
+ } while((nspc = nspc->parent));
return GW_ERROR;
}
static void fptr_def(const Env env, const Fptr_Def fptr) {
const Func_Def def = new_func_def(env->gwion->mp,
cpy_func_base(env->gwion->mp, fptr->base),
- NULL, loc_cpy(env->gwion->mp, td_pos(fptr->base->td)));
+ NULL, fptr->base->td->pos);
fptr->base->func = new_func(env->gwion->mp, s_name(fptr->base->xid), def);
fptr->value->d.func_ref = fptr->base->func;
fptr->base->func->value_ref = fptr->value;
}
ANN m_bool scan0_fptr_def(const Env env, const Fptr_Def fptr) {
- CHECK_BB(env_access(env, fptr->base->flag, td_pos(fptr->base->td)))
- CHECK_BB(scan0_defined(env, fptr->base->xid, td_pos(fptr->base->td)));
+ CHECK_BB(env_access(env, fptr->base->flag, fptr->base->td->pos))
+ CHECK_BB(scan0_defined(env, fptr->base->xid, fptr->base->td->pos));
const m_str name = s_name(fptr->base->xid);
const Type t = scan0_type(env, name, env->gwion->type[et_fptr]);
t->info->owner = !(!env->class_def && GET_FLAG(fptr->base, global)) ?
static OP_CHECK(opck_implicit_similar) {
const struct Implicit *imp = (struct Implicit*)data;
- return imp->e->info->type;
+ return imp->e->type;
}
static OP_CHECK(opck_cast_similar) {
const Exp_Cast *cast = (Exp_Cast*)data;
- return exp_self(cast)->info->type;
+ return exp_self(cast)->type;
}
ANN static void scan0_implicit_similar(const Env env, const Type lhs, const Type rhs) {
ANN static m_bool typedef_complex(const Env env, const Type_Def tdef, const Type base) {
const ae_flag flag = base->info->cdef ? base->info->cdef->flag : 0;
const Class_Def cdef = new_class_def(env->gwion->mp, flag, tdef->xid,
- cpy_type_decl(env->gwion->mp, tdef->ext), NULL,
- loc_cpy(env->gwion->mp, td_pos(tdef->ext)));
+ cpy_type_decl(env->gwion->mp, tdef->ext), NULL, tdef->ext->pos);
CHECK_BB(scan0_class_def(env, cdef))
tdef->type = cdef->base.type;
cdef->base.tmpl = tdef->tmpl;// check cpy
}
ANN m_bool scan0_type_def(const Env env, const Type_Def tdef) {
- CHECK_BB(env_access(env, tdef->ext->flag, td_pos(tdef->ext)))
+ CHECK_BB(env_access(env, tdef->ext->flag, tdef->ext->pos))
DECL_OB(const Type, base, = tdef->tmpl ? find_type(env, tdef->ext) : known_type(env, tdef->ext))
- CHECK_BB(scan0_defined(env, tdef->xid, td_pos(tdef->ext)))
+ CHECK_BB(scan0_defined(env, tdef->xid, tdef->ext->pos))
if(isa(base, env->gwion->type[et_function]) < 0) {
if(!tdef->ext->types && (!tdef->ext->array || !tdef->ext->array->exp))
typedef_simple(env, tdef, base);
}
ANN static Symbol scan0_sym(const Env env, const m_str name, const loc_t pos) {
- const size_t line_len = num_digit(pos->first.line);
- const size_t col_len = num_digit(pos->first.column);
+ const size_t line_len = num_digit(pos.first.line);
+ const size_t col_len = num_digit(pos.first.column);
char c[strlen(env->curr->name) + strlen(env->name) + line_len + col_len + strlen(name) + 6];
sprintf(c, "@%s:%s:%s:%u:%u", name, env->name, env->curr->name,
- pos->first.line, pos->first.column);
+ pos.first.line, pos.first.column);
return insert_symbol(c);
}
Type owner = env->class_def;
while(owner) {
if(t == owner)
- ERR_O(td_pos(td), _("'%s' as parent inside itself\n."), owner->name);
+ ERR_O(td->pos, _("'%s' as parent inside itself\n."), owner->name);
owner = owner->info->owner_class;
}
return t;
DECL_OO(const Type, t, = known_type(env, td))
if(!GET_FLAG(t, final))
return t;
- ERR_O(td_pos(td), _("can't inherit from final parent class '%s'\n."), t->name);
+ ERR_O(td->pos, _("can't inherit from final parent class '%s'\n."), t->name);
}
ANN static Type get_parent(const Env env, const Class_Def cdef) {
Type parent = t;
while(parent) {
if(parent == owner)
- ERR_B(td_pos(td), _("%s declared inside %s"), t->name, owner->name);
+ ERR_B(td->pos, _("%s declared inside %s"), t->name, owner->name);
parent = parent->info->parent;
}
} while((owner = owner->info->owner_class));
DECL_OO(const Type, type, = scan1_type(env, td))
if(type->size)
return type;
- ERR_O(td_pos(td), _("cannot declare variables of size '0' (i.e. 'void')..."))
+ ERR_O(td->pos, _("cannot declare variables of size '0' (i.e. 'void')..."))
}
ANN static Type scan1_exp_decl_type(const Env env, Exp_Decl* decl) {
ANN static inline Exp sym2func(const Env env, const Symbol sym, const loc_t pos) {
MemPool mp = env->gwion->mp;
const m_str name = s_name(sym);
- return new_prim_id(mp, insert_symbol(name + 1), loc_cpy(mp, pos));
+ return new_prim_id(mp, insert_symbol(name + 1), pos);
}
ANN static void binary_args(const Exp_Binary* bin) {
e->exp_type = ae_exp_call;
e->d.exp_call.func = sym2func(env, sym, e->pos);
e->d.exp_call.args = args;
+ e->d.exp_call.tmpl = NULL;
return scan1_exp(env, e);
}
}
ANN static inline m_bool scan1_exp_unary(const restrict Env env, const Exp_Unary *unary) {
- if((unary->op == insert_symbol("spork") || unary->op == insert_symbol("fork")) && unary->code)
+ if(unary->unary_type == unary_code)
{ RET_NSPC(scan1_stmt(env, unary->code)) }
else if(opiscall(unary->op)) {
return exp2call(env, exp_self(unary), unary->op, unary->exp);
}
- return unary->exp ? scan1_exp(env, unary->exp) : GW_OK;
+ return unary->unary_type == unary_exp ? scan1_exp(env, unary->exp) : GW_OK;
}
#define scan1_exp_lambda dummy_func
ANN static m_bool class_internal(const Env env, const Func_Base *base) {
if(!env->class_def)
- ERR_B(td_pos(base->td), _("'%s' must be in class def!!"), s_name(base->xid))
+ ERR_B(base->td->pos, _("'%s' must be in class def!!"), s_name(base->xid))
if(base->args)
- ERR_B(td_pos(base->td), _("'%s' must not have args"), s_name(base->xid))
+ ERR_B(base->td->pos, _("'%s' must not have args"), s_name(base->xid))
if(base->ret_type != env->gwion->type[et_void])
- ERR_B(td_pos(base->td), _("'%s' must return 'void'"), s_name(base->xid))
+ ERR_B(base->td->pos, _("'%s' must return 'void'"), s_name(base->xid))
return GW_OK;
}
ANN static inline m_bool scan_internal_arg(const Env env, const Func_Base *base) {
if(base->args && !base->args->next)
return GW_OK;
- ERR_B(td_pos(base->td), _("'%s' must have one (and only one) argument"), s_name(base->xid))
+ ERR_B(base->td->pos, _("'%s' must have one (and only one) argument"), s_name(base->xid))
}
ANN static inline m_bool scan_internal_int(const Env env, const Func_Base *base) {
CHECK_BB(scan_internal_arg(env, base))
if(isa(base->ret_type, env->gwion->type[et_int]) > 0)
return GW_OK;
- ERR_B(td_pos(base->td), _("'%s' must return 'int'"), s_name(base->xid))
+ ERR_B(base->td->pos, _("'%s' must return 'int'"), s_name(base->xid))
}
ANN static m_bool scan_internal(const Env env, const Func_Base *base) {
const uint global = GET_FLAG(fdef->base, global);
const m_uint scope = !global ? env->scope->depth : env_push_global(env);
if(fdef->base->td)
- CHECK_BB(env_storage(env, fdef->base->flag, td_pos(fdef->base->td)))
+ CHECK_BB(env_storage(env, fdef->base->flag, fdef->base->td->pos))
CHECK_BB(scan1_fdef_defined(env, fdef))
if(tmpl_base(fdef->base->tmpl))
return scan1_fdef_base_tmpl(env, fdef->base);
CHECK_OO((tdef->type->info->parent = parent));
Type t = parent;
do if(tdef->type == t)
- ERR_O(td_pos(tdef->ext), _("recursive (%s <= %s) class declaration."), tdef->type->name, t->name)
+ ERR_O(tdef->ext->pos, _("recursive (%s <= %s) class declaration."), tdef->type->name, t->name)
while((t = t->info->parent));
return parent;
}
ANN static m_bool scan1_parent(const Env env, const Class_Def cdef) {
- const loc_t pos = td_pos(cdef->base.ext);
+ const loc_t pos = cdef->base.ext->pos;
if(cdef->base.ext->array)
CHECK_BB(scan1_exp(env, cdef->base.ext->array->exp))
DECL_OB(const Type , parent, = scan1_get_parent(env, &cdef->base))
}
ANN static m_bool scan2_exp_unary(const Env env, const Exp_Unary * unary) {
- if((unary->op == insert_symbol("spork") || unary->op == insert_symbol("fork")) && unary->code) {
+ if(unary->unary_type == unary_code) {
RET_NSPC(scan2_stmt(env, unary->code))
- } else if(unary->exp)
+ } else if(unary->unary_type == unary_exp)
return scan2_exp(env, unary->exp);
return GW_OK;
}
if(tflag(t, tflag_ctmpl) || (tflag(t, tflag_ntmpl) && !td->types))
return t;
struct TemplateScan ts = { .t=t, .td=td };
- struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td_pos(td), .op_type=op_scan };
+ struct Op_Import opi = { .op=insert_symbol("@scan"), .lhs=t, .data=(uintptr_t)&ts, .pos=td->pos, .op_type=op_scan };
return op_check(env, &opi);
} else if(td->types)
return maybe_func(env, t, td);
td->next = next;
CHECK_OO(owner)
if(!owner->nspc)
- ERR_O(td_pos(td), "type '%s' has no namespace", owner->name)
+ ERR_O(td->pos, "type '%s' has no namespace", owner->name)
struct EnvSet es = { .env=env, .data=env,
.scope=env->scope->depth, .flag=tflag_none };
envset_push(&es, owner, owner->nspc);
ANN static Type resolve(const Env env, Type_Decl* td) {
DECL_OO(const Type, base, = find_type(env, td))
if(base->info->ctx && base->info->ctx->error)
- ERR_O(td_pos(td), _("type '%s' is invalid"), base->name)
+ ERR_O(td->pos, _("type '%s' is invalid"), base->name)
DECL_OO(const Type, t, = scan_type(env, base, td))
const Type ret = !td->option ? t : option(env, td);
return !td->array ? ret : array_type(env, ret, td->array->depth);
#include "emit.h"
#include "gwion.h"
#include "pass.h"
+#include "traverse.h"
static const m_str default_passes_name[] = { "check", "emit" };
-static const compilation_pass default_passes[][2] = { { type_engine_check_prog, type_engine_clean_prog }, { emit_ast, NULL } };
+static const compilation_pass default_passes[] = { traverse_ast, emit_ast };
#define NPASS sizeof(default_passes)/sizeof(default_passes[0])
-ANN void pass_register(const Gwion gwion, const m_str name, const compilation_pass pass[2]) {
- compilation_pass *passes = mp_malloc2(gwion->mp, sizeof(compilation_pass)*2);
- passes[0] = pass[0];
- passes[1] = pass[1];
+ANN void pass_register(const Gwion gwion, const m_str name, const compilation_pass pass) {
const Symbol sym = insert_symbol(gwion->st, name);
map_set(&gwion->data->passes->map, (vtype)sym, (vtype)pass);
- map_set(&gwion->data->passes->map, (vtype)sym, (vtype)passes);
}
ANN m_bool pass_set(const Gwion gwion, const Vector passes) {
ANN void free_passes(const MemPool mp, struct Passes_ *a) {
map_release(&a->map);
- for(m_uint i = 0; i < vector_size(&a->vec); ++i) {
- compilation_pass *passes = (compilation_pass *)vector_at(&a->vec, i);
- mp_free2(mp, sizeof(compilation_pass)*2, passes);
- }
vector_release(&a->vec);
+ mp_free(mp, Passes, a);
}
#define ADISPATCH() { ADVANCE(); SDISPATCH(); }
-#define PC ((*(unsigned short*)(byte + 2)) + 1)
+#define PC ((*(unsigned*)(byte + 1)) + 1)
#define OP(t, sz, op, ...) \
reg -= sz;\
*(Instr*)(ptr + (i*BYTECODE_SZ) + SZ_INT) = instr;
*(f_instr*)(ptr + (i*BYTECODE_SZ) + SZ_INT*2) = instr->execute;
}
- *(unsigned short*)(ptr + (i*BYTECODE_SZ) + 2) = i;
+ *(unsigned*)(ptr + (i*BYTECODE_SZ) + 1) = i;
}
return ptr;
}
return GW_OK;
}
-static compilation_pass passes[2] = { pass, NULL };
GWION_IMPORT(array_test) {
-
- gwi_register_pass(gwi, "dummy", passes);
+ gwi_register_pass(gwi, "dummy", pass);
return GW_OK;
}
typedef int[2] test;
-var test vv;
+var test v;
<<< int >>>;
<<< test >>>;
<<< v >>>;
-Subproject commit 1d6d54e532d7be45374ec7a94a2884886457ea20
+Subproject commit f7c62c03f5981a91a3910f6e4998747c3837f0d1