eDotMember2,
eDotMember3,
eDotMember4,
- eUnionSet,
- eUnionCheck,
+ eUnionMember,
+ eUnionMember2,
+ eUnionMember3,
+ eUnionMember4,
eDotStatic,
eDotStatic2,
eDotStatic3,
#define DotMember2 (f_instr)eDotMember2
#define DotMember3 (f_instr)eDotMember3
#define DotMember4 (f_instr)eDotMember4
-#define UnionSet (f_instr)eUnionSet
-#define UnionCheck (f_instr)eUnionCheck
+#define UnionMember (f_instr)eUnionMember
+#define UnionMember2 (f_instr)eUnionMember2
+#define UnionMember3 (f_instr)eUnionMember3
+#define UnionMember4 (f_instr)eUnionMember4
#define DotStatic (f_instr)eDotStatic
#define DotStatic2 (f_instr)eDotStatic2
#define DotStatic3 (f_instr)eDotStatic3
DotMember2
DotMember3
DotMember4
-UnionSet
-UnionCheck
+UnionMember
+UnionMember2
+UnionMember3
+UnionMember4
DotStatic
DotStatic2
DotStatic3
ANN static m_bool emit_exp_binary(const Emitter emit, const Exp_Binary* bin) {
const Exp lhs = bin->lhs;
const Exp rhs = bin->rhs;
- struct Op_Import opi = { .op=bin->op, .lhs=lhs->info->type, .rhs=rhs->info->type,
- .pos=exp_self(bin)->pos, .data=(uintptr_t)bin, .op_type=op_binary };
CHECK_BB(emit_exp_pop_next(emit, lhs))
CHECK_BB(emit_exp_pop_next(emit, rhs))
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,
+ .pos=exp_self(bin)->pos, .data=(uintptr_t)bin, .op_type=op_binary };
return op_emit(emit, &opi);
}
}
static GWION_IMPORT(int_logical) {
- GWI_BB(gwi_oper_end(gwi, "&&", int_and))
- GWI_BB(gwi_oper_end(gwi, "||", int_or))
- GWI_BB(gwi_oper_end(gwi, "==", int_eq))
- GWI_BB(gwi_oper_end(gwi, "!=", int_neq))
+ GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
GWI_BB(gwi_oper_end(gwi, ">", int_gt))
GWI_BB(gwi_oper_end(gwi, ">=", int_ge))
GWI_BB(gwi_oper_end(gwi, "<", int_lt))
GWI_BB(gwi_oper_end(gwi, "<<", int_sl))
GWI_BB(gwi_oper_end(gwi, "&", int_sand))
GWI_BB(gwi_oper_end(gwi, "|", int_sor))
- return gwi_oper_end(gwi, "^", int_xor);
+ GWI_BB(gwi_oper_end(gwi, "^", int_xor))
+ GWI_BB(gwi_oper_ini(gwi, "int", "int", "bool"))
+ GWI_BB(gwi_oper_end(gwi, "&&", int_and))
+ GWI_BB(gwi_oper_end(gwi, "||", int_or))
+ GWI_BB(gwi_oper_end(gwi, "==", int_eq))
+ return gwi_oper_end(gwi, "!=", int_neq);
}
static GWION_IMPORT(int_r) {
+ GWI_BB(gwi_oper_ini(gwi, "int", "int", "int"))
CHECK_OP("=>", rassign, r_assign)
CHECK_OP("+=>", rassign, r_plus)
CHECK_OP("-=>", rassign, r_minus)
static GWION_IMPORT(intfloat) {
GWI_BB(gwi_oper_ini(gwi, "int", "float", "int"))
- GWI_BB(gwi_oper_end(gwi, "&&", int_float_and))
- GWI_BB(gwi_oper_end(gwi, "||", int_float_or))
- GWI_BB(gwi_oper_end(gwi, "==", int_float_eq))
- GWI_BB(gwi_oper_end(gwi, "!=", int_float_neq))
GWI_BB(gwi_oper_end(gwi, ">", int_float_gt))
GWI_BB(gwi_oper_end(gwi, ">=", int_float_ge))
GWI_BB(gwi_oper_end(gwi, "<", int_float_lt))
CHECK_IF("/=>", rassign, r_div)
_CHECK_OP("$", cast_i2f, CastI2F)
_CHECK_OP("@implicit", implicit_i2f, CastI2F)
+ GWI_BB(gwi_oper_ini(gwi, "int", "float", "bool"))
+ GWI_BB(gwi_oper_end(gwi, "&&", int_float_and))
+ GWI_BB(gwi_oper_end(gwi, "||", int_float_or))
+ GWI_BB(gwi_oper_end(gwi, "==", int_float_eq))
+ GWI_BB(gwi_oper_end(gwi, "!=", int_float_neq))
return GW_OK;
}
GWI_BB(gwi_oper_end(gwi, "*", float_int_mul))
GWI_BB(gwi_oper_end(gwi, "/", float_int_div))
GWI_BB(gwi_oper_ini(gwi, "float", "int", "int"))
- GWI_BB(gwi_oper_end(gwi, "&&", float_int_and))
- GWI_BB(gwi_oper_end(gwi, "||", float_int_or))
- GWI_BB(gwi_oper_end(gwi, "==", float_int_eq))
- GWI_BB(gwi_oper_end(gwi, "!=", float_int_neq))
GWI_BB(gwi_oper_end(gwi, ">", float_int_gt))
GWI_BB(gwi_oper_end(gwi, ">=", float_int_ge))
GWI_BB(gwi_oper_end(gwi, "<", float_int_lt))
CHECK_FI("/=>", rassign, r_div)
_CHECK_OP("$", cast_f2i, CastF2I)
_CHECK_OP("@implicit", implicit_f2i, CastF2I)
+ GWI_BB(gwi_oper_ini(gwi, "float", "int", "bool"))
+ GWI_BB(gwi_oper_end(gwi, "&&", float_int_and))
+ GWI_BB(gwi_oper_end(gwi, "||", float_int_or))
+ GWI_BB(gwi_oper_end(gwi, "==", float_int_eq))
+ GWI_BB(gwi_oper_end(gwi, "!=", float_int_neq))
return GW_OK;
}
CHECK_FF("-=>", rassign, r_minus)
CHECK_FF("*=>", rassign, r_mul)
CHECK_FF("/=>", rassign, r_div)
- GWI_BB(gwi_oper_ini(gwi, "float", "float", "int"))
+ GWI_BB(gwi_oper_ini(gwi, "float", "float", "bool"))
GWI_BB(gwi_oper_end(gwi, "&&", float_and))
GWI_BB(gwi_oper_end(gwi, "||", float_or))
GWI_BB(gwi_oper_end(gwi, "==", float_eq))
GWI_BB(gwi_oper_end(gwi, "!=", float_neq))
+ GWI_BB(gwi_oper_ini(gwi, "float", "float", "int"))
GWI_BB(gwi_oper_end(gwi, ">", float_gt))
GWI_BB(gwi_oper_end(gwi, ">=", float_ge))
GWI_BB(gwi_oper_end(gwi, "<", float_lt))
#include "gwi.h"
#include "specialid.h"
#include "gack.h"
+#include "traverse.h"
static GACK(gack_none) {
INTERP_PRINTF("None")
return GW_OK;
}
-static const f_instr dotmember[] = { DotMember, DotMember2, DotMember3, DotMember4 };
-
+static const f_instr unionmember[] = { UnionMember, UnionMember2, UnionMember3, UnionMember4 };
ANN Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]);
static OP_EMIT(opem_union_dot) {
instr->m_val = (m_uint)f->code;
return GW_OK;
}
+ if(!strcmp(s_name(member->xid), "@index")) {
+ emit_add_instr(emit, DotMember);
+ return GW_OK;
+ }
for(m_uint i = 0; i < map_size(map); ++i) {
if(VKEY(map, i) == (m_uint)member->xid) {
const Value v = (Value)VVAL(map, i);
const uint emit_addr = exp_getvar(exp_self(member));
- const Instr pre = emit_add_instr(emit,
- !emit_addr ? UnionCheck : UnionSet);
- pre->m_val = i + 1;
- const Instr instr = emit_kind(emit, v->type->size, emit_addr, dotmember);
- instr->m_val = SZ_INT;
+ const Instr instr = emit_kind(emit, v->type->size, emit_addr, unionmember);
+ instr->m_val = i + 1;
instr->m_val2 = v->type->size;
return GW_OK;
}
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)) {
- exp->d.prim.prim_type = ae_prim_num;
- exp->d.prim.d.num = i+1;
- return env->gwion->type[et_bool];
+ *mut = 1;
+ const Exp exp_func = call->func;
+ const Exp exp_base = call->func->d.exp_dot.base;
+ 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));
+ 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 env->gwion->type[et_error];
const Type t = actual_type(env->gwion, exp->func->info->type);
const Exp e = exp_self(exp);
struct Op_Import opi = { .op=insert_symbol("@func_check"),
- .rhs=t, .pos=exp_self(exp)->pos, .data=(uintptr_t)e, .op_type=op_exp };
+ .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] ?
GW_OK : GW_ERROR;
}
ANN Type check_exp_call1(const Env env, const Exp_Call *exp) {
- 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);
if(isa(t, env->gwion->type[et_function]) < 0) {
// use func flag?
ANN static Type check_exp_call(const Env env, Exp_Call* exp) {
if(exp->tmpl) {
- CHECK_BO(func_check(env, exp))
+// 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);
if(isa(t, env->gwion->type[et_function]) < 0)
return check_exp_call1(env, exp);
nspc_allocdata(env->gwion->mp, udef->type->nspc);
Union_List l = udef->l;
m_uint sz = 0;
+ const Value v = new_value(env->gwion->mp, env->gwion->type[et_int], "@index");
+ nspc_add_value_front(env->curr, insert_symbol("@index"), v);
+ valuefrom(env ,v->from);
do {
DECL_OB(const Type, t, = known_type(env, l->td))
if(nspc_lookup_value0(env->curr, l->xid))
ERR_B(l->pos, _("'%s' already declared in union"), s_name(l->xid))
const Value v = new_value(env->gwion->mp, t, s_name(l->xid));
- if(!tflag(t, tflag_scan1))
- tuple_contains(env, v);
+ if(!tflag(t, tflag_scan1)) // ???
+ tuple_contains(env, v); // ???
v->from->offset = SZ_INT;
valuefrom(env ,v->from);
nspc_add_value_front(env->curr, l->xid, v);
if(t->size > sz)
sz = t->size;
} while((l = l->next));
+udef->type->nspc->info->offset = SZ_INT +sz;
return GW_OK;
}
&&arrayappend, &&autoloop, &&autoloopptr, &&autoloopcount, &&arraytop, &&arrayaccess, &&arrayget, &&arrayaddr, &&arrayvalid,
&&newobj, &&addref, &&addrefaddr, &&objassign, &&assign, &&remref,
&&except, &&allocmemberaddr, &&dotmember, &&dotfloat, &&dotother, &&dotaddr,
- &&unionset, &&unioncheck,
+ &&unionint, &&unionfloat, &&unionother, &&unionaddr,
&&staticint, &&staticfloat, &&staticother,
&&upvalueint, &&upvaluefloat, &&upvalueother, &&upvalueaddr,
&&dotfunc, &&dotstaticfunc,
dotaddr:
*(m_bit**)(reg-SZ_INT) = ((*(M_Object*)(reg-SZ_INT))->data + VAL);
DISPATCH()
-unionset:
- *(m_uint*)(*(M_Object*)(reg-SZ_INT))->data = VAL;
- DISPATCH()
-unioncheck:
- if(*(m_uint*)(*(M_Object*)(reg-SZ_INT))->data != VAL) {
- exception(shred, "invalid union acces");
- continue;
+
+#define UNION_CHECK\
+ register const m_bit *data = (*(M_Object*)(reg-SZ_INT))->data;\
+ if(*(m_uint*)data != VAL) {\
+ exception(shred, "invalid union acces");\
+ continue;\
}
+
+unionint:
+{
+ UNION_CHECK
+ *(m_uint*)(reg-SZ_INT) = *(m_uint*)(data + SZ_INT);
+ DISPATCH()
+}
+unionfloat:
+{
+ UNION_CHECK
+ *(m_float*)(reg-SZ_INT) = *(m_float*)(data + SZ_INT);
+ reg += SZ_FLOAT - SZ_INT;
+ DISPATCH()
+}
+unionother:
+{
+ UNION_CHECK
+PRAGMA_PUSH()
+ for(m_uint i = 0; i <= VAL2; i += SZ_INT)
+ *(m_uint*)(reg+i-SZ_INT) = *(m_uint*)(data + SZ_INT + i);
+PRAGMA_POP()
+ reg += VAL2 - SZ_INT;
DISPATCH()
+}
+unionaddr:
+{
+ *(m_uint*)(*(M_Object*)(reg-SZ_INT))->data = VAL;
+ *(m_bit**)(reg - SZ_INT)= &*(m_bit*)((*(M_Object*)(reg-SZ_INT))->data + SZ_INT);
+ DISPATCH()
+}
staticint:
*(m_uint*)reg = *(m_uint*)VAL;
reg += SZ_INT;