#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_EMIT(a) ANN Instr a(const Emitter emit 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); }
#define GWI_OB(a) { gwi_set_loc(gwi, __FILE__, __LINE__); (void)(a); }
#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 struct Instr_* (*opem)(const Emitter, void*);
+typedef Type (*opck)(const Env, void*, m_bool*);
+typedef m_bool (*opem)(const Emitter, void*);
struct Op_Func {
opck ck;
ANN m_bool add_op(const Gwion gwion, const struct Op_Import*);
ANN Type op_check(const Env, struct Op_Import*);
-ANN struct Instr_* op_emit(const Emitter, const struct Op_Import*);
+ANN m_bool op_emit(const Emitter, const struct Op_Import*);
ANN m_bool operator_set_func(const struct Op_Import*);
ANN void free_op_map(Map map, struct Gwion_* gwion);
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 };
- CHECK_OB(op_emit(emit, &opi))
+ CHECK_BB(op_emit(emit, &opi))
emit_gc(emit, -SZ_INT);
return GW_OK;
}
// look mum no pos
struct Op_Import opi = { .op=insert_symbol("@array"), .lhs=info->array.exp->info->type, .rhs=info->array.type,
.data=(uintptr_t)info, .op_type=op_array };
- return op_emit(emit, &opi) != (Instr)GW_ERROR ? GW_OK : GW_ERROR;
+ return op_emit(emit, &opi);
}
ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) {
const Exp e = range->range->start ?: range->range->end;
struct Op_Import opi = { .op=sym, .lhs=e->info->type, .rhs=range->base->info->type,
.pos=e->pos, .data=(uintptr_t)exp_self(range), .op_type=op_exp };
- CHECK_OB(op_emit(emit, &opi))
- return GW_OK;
+ return op_emit(emit, &opi);
}
ANN static inline Instr specialid_instr(const Emitter emit,
else {
struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=exp_call->func->info->type->info->base_type,
.data=(uintptr_t)exp_call, .pos=exp_self(exp_call)->pos, .op_type=op_exp };
- CHECK_OB(op_emit(emit, &opi))
+ CHECK_BB(op_emit(emit, &opi))
}
const Exp e = exp_self(exp_call);
if(exp_getvar(e)) {
return GW_OK;
}
-ANN static inline m_bool op_emit_bool(const Emitter emit, const struct Op_Import* opi) {
- DECL_OB(const Instr, instr, = op_emit(emit, opi))
- return GW_OK;
-}
-
ANN static m_bool emit_exp_binary(const Emitter emit, const Exp_Binary* bin) {
const Exp lhs = bin->lhs;
const Exp rhs = bin->rhs;
const m_int size = exp_size(rhs);
emit_exp_addref1(emit, lhs, -exp_size(lhs) - size);
emit_exp_addref1(emit, rhs, -size);
- return op_emit_bool(emit, &opi);
+ return op_emit(emit, &opi);
}
ANN static m_bool emit_exp_cast(const Emitter emit, const Exp_Cast* cast) {
.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));
- return op_emit_bool(emit, &opi);
+ return op_emit(emit, &opi);
}
ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_Def fdef) {
struct Exp_ exp = { .info=&info };
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_bool(emit, &opi))
+ CHECK_BB(op_emit(emit, &opi))
const Instr instr = emit_add_instr(emit, BranchEqInt);
vector_add(&me->branch, (vtype)instr);
return GW_OK;
emit_exp_addref1(emit, unary->exp, -exp_size(unary->exp));
opi.rhs = unary->exp->info->type;
}
- return op_emit_bool(emit, &opi);
+ return op_emit(emit, &opi);
}
ANN static m_bool emit_implicit_cast(const Emitter emit,
// no pos
struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=from->info->type, .rhs=to,
.data=(m_uint)&imp, .op_type=op_implicit };
- return op_emit_bool(emit, &opi);
+ return op_emit(emit, &opi);
}
ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
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 };
- return op_emit(emit, &opi);
+ CHECK_BO(op_emit(emit, &opi))
+ return (Instr)vector_back(&emit->code->instr);
}
#define emit_flow(emit,b) _flow(emit, b, 1)
struct Exp_ ebin = { .d={.exp_binary=bin}, .info=&info };
struct Op_Import opi = { .op=op, .lhs=base->info->type, .rhs=e->info->type,
.data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos, .op_type=op_binary };
- CHECK_BB(op_emit_bool(emit, &opi))
+ CHECK_BB(op_emit(emit, &opi))
const Instr instr = emit_add_instr(emit, BranchEqInt);
vector_add(v, (vtype)instr);
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->t_base,
.rhs=exp_self(member)->info->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos, .op_type=op_dot };
- return op_emit_bool(emit, &opi);
+ return op_emit(emit, &opi);
}
ANN static inline void emit_func_def_fglobal(const Emitter emit, const Value value) {
return check_array_shift(env, bin->rhs, bin->lhs, ">>", exp_self(bin)->pos);
}
-ANN static Instr emit_array_shift(const Emitter emit, const f_instr exec) {
+ANN static inline m_bool emit_array_shift(const Emitter emit, const f_instr exec) {
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = SZ_INT;
- return emit_add_instr(emit, exec);
+ (void)emit_add_instr(emit, exec);
+ return GW_OK;
}
static INSTR(ArrayAppendFront) {
return emit_array_shift(emit, ArrayConcatRight);
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = SZ_INT;
- (void)emit_gc(emit, 0);
- return emit_add_instr(emit, ArrayAppendFront);
+ emit_gc(emit, 0);
+ (void)emit_add_instr(emit, ArrayAppendFront);
+ return GW_OK;
}
static OP_EMIT(opem_array_sl) {
return emit_array_shift(emit, ArrayConcatLeft);
const Instr pop = emit_add_instr(emit, RegPop);
pop->m_val = bin->rhs->info->type->size;
- (void)emit_gc(emit, -SZ_INT);
- return emit_add_instr(emit, ArrayAppend);
+ emit_gc(emit, -SZ_INT);
+ emit_add_instr(emit, ArrayAppend);
+ return GW_OK;
}
// check me. use common ancestor maybe
static OP_EMIT(opem_array_slice) {
emit_add_instr(emit, ArraySlice);
- return emit_gc(emit, -SZ_INT);
+ emit_gc(emit, -SZ_INT);
+ return GW_OK;
}
static FREEARG(freearg_array) {
struct ArrayAccessInfo *const info = (struct ArrayAccessInfo*)data;
if(info->array.type->array_depth >= info->array.depth) {
struct Array_Sub_ next = { .exp=info->array.exp, .type=info->type, .depth=info->array.depth };
- return (Instr)(m_uint)array_do(emit, &next, info->is_var);
+ return array_do(emit, &next, info->is_var);
}
struct Array_Sub_ partial = { info->array.exp, info->array.type, info->array.type->array_depth };
struct Array_Sub_ next = { info->array.exp, array_base(info->array.type), info->array.depth - info->array.type->array_depth };
const Exp exp = emit_n_exp(emit, info);
next.exp = exp;
info->array = next;
- return (Instr)(m_uint)(exp ? emit_array_access(emit, info) : GW_ERROR);
+ return exp ? emit_array_access(emit, info) : GW_ERROR;
}
GWION_IMPORT(array) {
const Instr cpy = emit_add_instr(emit, Reg2Reg);
cpy->m_val = -SZ_INT;
}
- return instr;
+ return GW_OK;
}
struct FptrInfo {
fptr_instr(emit, cast->exp->info->type->info->func, 1);
if(is_member(cast->exp->info->type))
member_fptr(emit);
- return (Instr)GW_OK;
+ return GW_OK;
}
static OP_CHECK(opck_fptr_impl) {
member_fptr(emit);
if(impl->t->info->func->def->base->tmpl)
fptr_instr(emit, ((Exp)impl->e)->info->type->info->func, 1);
- return (Instr)GW_OK;
+ return GW_OK;
}
ANN Type check_exp_unary_spork(const Env env, const Stmt code);
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;
- return instr;
+ return GW_OK;
}
static GWION_IMPORT(usrugen) {
}
static OP_EMIT(opem_implicit_null2obj) {
- return (Instr)GW_OK;
+ return GW_OK;
}
ANN /*static*/ Type scan_class(const Env env, const Type t, const Type_Decl * td);
(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0 &&
!is_fptr(emit->gwion, exp_self(member)->info->type)))) {
if(!tflag(t_base, tflag_struct))
- CHECK_BO(emit_exp(emit, member->base))
+ 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))
emit_member_func(emit, member);
emit_member(emit, value, exp_getvar(exp_self(member)));
else {
exp_setvar(member->base, 1);
- CHECK_BO(emit_exp(emit, member->base))
+ CHECK_BB(emit_exp(emit, member->base))
emit_struct_data(emit, value, exp_getvar(exp_self(member)));
}
} else if(GET_FLAG(value, static))
const Instr instr = emit_add_instr(emit, GWOP_EXCEPT);
instr->m_val = -SZ_INT;
}
- return (Instr)GW_OK;
+ return GW_OK;
}
ANN static m_bool scantmpl_class_def(const Env env, struct tmpl_info *info) {
const Exp_Unary* unary = (Exp_Unary*)data;
CHECK_BO(emit_instantiate_object(emit, exp_self(unary)->info->type,
unary->td->array, 0))
- return emit_gc(emit, -SZ_INT);
+ emit_gc(emit, -SZ_INT);
+ return GW_OK;
}
const Exp exp = (Exp)data;
const Instr instr = emit_add_instr(emit, IntRange);
instr->m_val = (m_uint)exp->info->type;
- return instr;
+ return GW_OK;
}
static GWION_IMPORT(int_unary) {
emit_add_instr(emit, instr_ptr_assign_obj);
} else
emit_add_instr(emit, instr_ptr_assign);
- return pop;
+ return GW_OK;
}
static OP_CHECK(opck_ptr_deref) {
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;
- return instr;
+ return GW_OK;
}
static OP_EMIT(opem_ptr_implicit) {
const struct Implicit* imp = (struct Implicit*)data;
const Instr instr = emit_add_instr(emit, Cast2Ptr);
instr->m_val = (m_uint)imp->t;
- return instr;
+ return GW_OK;
}
static OP_EMIT(opem_ptr_deref) {
const Instr instr = emit_add_instr(emit, instr_ptr_deref);
instr->m_val = exp_self(unary)->info->type->size;
instr->m_val2 = exp_getvar(exp_self(unary));
- return instr;
+ return GW_OK;
}
ANN Type scan_class(const Env env, const Type t, const Type_Decl* td);
exp_setvar(bin->rhs, 1);
return bin->rhs->info->type;
}
-/*
-static OP_EMIT(opem_ptr_ref) {
- const Exp_Binary* bin = (Exp_Binary*)data;
- const Instr instr = emit_add_instr(emit, Reg2Reg);
- instr->m_val = -SZ_INT;
- instr->m_val2 = -SZ_INT*2;
- const Instr pop = emit_add_instr(emit, RegPop);
- pop->m_val = SZ_INT;
- return instr;
-}
-*/
+
static GACK(gack_ptr) {
INTERP_PRINTF("%p", *(m_str*)VALUE);
}
static OP_EMIT(opem_union_dot) {
const Exp_Dot *member = (Exp_Dot*)data;
const Map map = &member->t_base->nspc->info->value->map;
- CHECK_BO(emit_exp(emit, member->base))
+ CHECK_BB(emit_exp(emit, member->base))
if(isa(exp_self(member)->info->type, emit->gwion->type[et_function]) > 0) {
const Instr instr = emit_add_instr(emit, RegPushImm);
const Func f = (Func)vector_front(&member->t_base->info->parent->nspc->info->vtable);
instr->m_val = (m_uint)f->code;
- return instr;
+ return GW_OK;
}
for(m_uint i = 0; i < map_size(map); ++i) {
if(VKEY(map, i) == (m_uint)member->xid) {
const Instr instr = emit_kind(emit, v->type->size, emit_addr, dotmember);
instr->m_val = SZ_INT;
instr->m_val2 = v->type->size;
- return instr;
+ return GW_OK;
}
}
- return NULL;
+ return GW_ERROR;
}
static DTOR(UnionDtor) {
instr->m_val = (m_uint)exp_self(cast)->info->type;
const Instr push = emit_add_instr(emit, RegPush);
push->m_val = exp_self(cast)->info->type->size - SZ_INT;
- return instr;
+ return GW_OK;
}
static FREEARG(freearg_vararg) {
return GW_OK;
}
-ANN static Instr handle_instr(const Emitter emit, const M_Operator* mo) {
+ANN static m_bool handle_instr(const Emitter emit, const M_Operator* mo) {
if(mo->func) {
const Instr push = emit_add_instr(emit, mo->func->code ? RegPushImm : SetFunc);
push->m_val = ((m_uint)mo->func->code ?:(m_uint)mo->func);
- CHECK_BO(emit_exp_call1(emit, mo->func))
+ CHECK_BB(emit_exp_call1(emit, mo->func))
if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@conditionnal"))
- return emit_add_instr(emit, BranchEqInt);
- if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditionnal"))
- return emit_add_instr(emit, BranchNeqInt);
- return push;
+ emit_add_instr(emit, BranchEqInt);
+ else if(mo->func->def->base->xid == insert_symbol(emit->gwion->st, "@unconditionnal"))
+ emit_add_instr(emit, BranchNeqInt);
+ return GW_OK;
}
- return emit_add_instr(emit, mo->instr);
+ (void)emit_add_instr(emit, mo->instr);
+ return GW_OK;
}
ANN static Nspc get_nspc(const struct Op_Import* opi) {
return nspc;
}
-ANN Instr op_emit(const Emitter emit, const struct Op_Import* opi) {
- DECL_OO(Nspc, nspc, = ensure_nspc(opi))
+ANN m_bool op_emit(const Emitter emit, const struct Op_Import* opi) {
+ DECL_OB(Nspc, nspc, = ensure_nspc(opi))
Type l = opi->lhs;
do {
Type r = opi->rhs;
const M_Operator* mo = operator_find(v, l, r);
if(mo) {
if(mo->em) {
- const Instr ret = mo->em(emit, (void*)opi->data);
+ const m_bool ret = mo->em(emit, (void*)opi->data);
if(ret)
return ret;
}
}
} while(r && (r = op_parent(emit->env, r)));
} while(l && (l = op_parent(emit->env, l)));
- return NULL;
+ return GW_ERROR;
}