typedef struct {
Operator op;
m_str ret, lhs, rhs;
- Type (*ck)(Env, void*);
+ Type (*ck)(Env, void*, m_bool*);
m_bool (*em)(Emitter, void*);
m_bool mut;
} DL_Oper;
#define SFUN(a) ANN void a(const M_Object o NUSED, const m_bit* RETURN NUSED, const VM_Shred shred NUSED)
#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 OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED)
+#define OP_CHECK(a) ANN Type a(const Env env NUSED, void* data NUSED, m_bool* mut NUSED)
#define OP_EMIT(a) ANN m_bool a(const Emitter emit NUSED, void* data NUSED)
#ifdef GWION_BUILTIN
#define GWION_IMPORT(a) ANN m_bool import_##a(const Gwi gwi)
ANN m_int gwi_func_end(const Gwi gwi, const ae_flag flag);
ANN2(1) m_int gwi_oper_ini(const Gwi gwi, const m_str l, const m_str r, const m_str t);
-ANN m_int gwi_oper_add(const Gwi gwi, Type (*check)(Env, void*));
-ANN m_int gwi_oper_emi(const Gwi gwi, m_bool (*check)(Emitter, void*));
-ANN void gwi_oper_mut(const Gwi, const m_bool);
+ANN m_int gwi_oper_add(const Gwi gwi, opck);
+ANN m_int gwi_oper_emi(const Gwi gwi, opem);
ANN2(1) m_int gwi_oper_end(const Gwi gwi, const Operator op, const f_instr f);
ANN Type_Decl* str2decl(const Env, const m_str, m_uint* depth);
#define FREEARG(a) ANN void a(Instr instr NUSED, void *gwion NUSED)
typedef void (*f_freearg)(Instr, void*);
-ANN void register_freearg(const Gwi, const f_instr, void(*)(const Instr,void*));
+ANN void register_freearg(const Gwi, const f_instr, const f_freearg);
ANN void gwi_reserve(const Gwi, const m_str);
#endif
#define ERR_N(a, b, ...) { env_err(env, (a), (b), ## __VA_ARGS__); return t_null; }
-typedef Type (*opck)(const Env, void*);
+typedef Type (*opck)(const Env, void*, m_bool*);
typedef m_bool (*opem)(const Emitter, void*);
struct Op_Import {
uintptr_t data;
loc_t pos;
Operator op;
- m_bool mut;
};
struct Implicit {
#include "object.h"
#include "array.h"
#include "emit.h"
-#include "import.h"
#include "operator.h"
+#include "import.h"
#include "traverse.h"
#include "parse.h"
static OP_CHECK(opck_array_at) {
ARRAY_OPCK
- if(opck_const_rhs(env, data) == t_null)
+ if(opck_const_rhs(env, data, mut) == t_null)
return t_null;
if(bin->lhs->type->array_depth != bin->rhs->type->array_depth)
ERR_N(exp_self(bin)->pos, _("array depths do not match."))
#include "type.h"
#include "instr.h"
#include "object.h"
+#include "gwion.h"
+#include "operator.h"
#include "import.h"
#define describe(name, op) \
#include "nspc.h"
#include "type.h"
#include "object.h"
-#include "import.h"
-#include "gwi.h"
-#include "lang_private.h"
#include "emit.h"
#include "env.h"
#include "vm.h"
#include "gwion.h"
#include "operator.h"
+#include "import.h"
+#include "gwi.h"
#include "engine.h"
#include "parser.h"
+#include "lang_private.h"
static FREEARG(freearg_switchini) {
if(instr->m_val)
#include "type.h"
#include "instr.h"
#include "object.h"
+#include "operator.h"
#include "import.h"
static CTOR(event_ctor) {
#include "instr.h"
#include "emit.h"
#include "object.h"
-#include "import.h"
#include "nspc.h"
#include "operator.h"
+#include "import.h"
#include "traverse.h"
#include "template.h"
#include "parse.h"
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) ?: t_null;
}
GWION_IMPORT(func) {
CHECK_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@function", NULL))
CHECK_BB(gwi_oper_add(gwi, opck_func_call))
- gwi_oper_mut(gwi, 1);
CHECK_BB(gwi_oper_end(gwi, op_chuck, NULL))
CHECK_BB(gwi_oper_ini(gwi, "@function", "@func_ptr", NULL))
CHECK_BB(gwi_oper_add(gwi, opck_fptr_at))
#include "traverse.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
-#include "gwi.h"
#include "emit.h"
#include "func.h"
#include "nspc.h"
#include "gwion.h"
#include "operator.h"
+#include "import.h"
+#include "gwi.h"
#include "mpool.h"
#define GWI_ERR_B(a,...) { env_err(gwi->gwion->env, gwi->loc, (a), ## __VA_ARGS__); return GW_ERROR; }
const Type rhs = op->rhs ? get_type(env, op->rhs) : NULL;
const Type ret = get_type(env, op->ret);
const struct Op_Import opi = { lhs, rhs, ret,
- op->ck, op->em, (uintptr_t)f, gwi->loc, op->op, op->mut };
+ op->ck, op->em, (uintptr_t)f, gwi->loc, op->op };
return env_add_op(env, &opi);
}
return GW_OK;
}
-ANN m_int gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void*)) {
+ANN m_int gwi_oper_add(const Gwi gwi, Type (*ck)(Env, void*, m_bool*)) {
gwi->oper.ck = ck;
return GW_OK;
}
return GW_OK;
}
-ANN void gwi_oper_mut(const Gwi gwi, const m_bool mut) {
- gwi->oper.mut = mut;
-}
-
ANN m_int gwi_oper_end(const Gwi gwi, const Operator op, const f_instr f) {
gwi->oper.op = op;
const m_bool ret = import_op(gwi, &gwi->oper, f);
return t;
}
-ANN void register_freearg(const Gwi gwi, const f_instr _exec, void(*_free)(const Instr, void*)) {
+ANN void register_freearg(const Gwi gwi, const f_instr _exec, const f_freearg _free) {
map_set(&gwi->gwion->data->freearg, (vtype)_exec, (vtype)_free);
}
#include "type.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "func.h"
#include "array.h"
#include "nspc.h"
#include "shreduler_private.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
INSTR(DTOR_EOC) {
const M_Object o = *(M_Object*)MEM(0);
#include "type.h"
#include "instr.h"
#include "object.h"
+#include "operator.h"
#include "import.h"
#include "ugen.h"
#include "func.h"
#include "value.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "operator.h"
+#include "import.h"
ANN void exception(const VM_Shred shred, const m_str c) {
gw_err("%s: shred[id=%" UINT_F ":%s], PC=[%" UINT_F "]\n",
const Exp_Binary* bin = (Exp_Binary*)data;
const Type l = bin->lhs->type;
const Type r = bin->rhs->type;
- if(opck_rassign(env, data) == t_null)
+ if(opck_rassign(env, data, mut) == t_null)
return t_null;
if(bin->rhs->exp_type == ae_exp_decl)
SET_FLAG(bin->rhs->d.exp_decl.td, ref);
#include "value.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "emit.h"
#include "traverse.h"
#include "parse.h"
#include "operator.h"
+#include "import.h"
static inline m_str access(ae_Exp_Meta meta) {
return meta == ae_meta_value ? "non-mutable" : "protected";
OP_CHECK(opck_rassign) {
const Exp_Binary* bin = (Exp_Binary*)data;
- if(opck_const_rhs(env, data) == t_null)
+ if(opck_const_rhs(env, data, mut) == t_null)
return t_null;
bin->rhs->emit_var = 1;
return bin->rhs->type;
OP_CHECK(opck_unary_meta2_uniq) {
const Exp_Unary* unary = (Exp_Unary*)data;
- CHECK_OO(opck_unary_meta2(env, data))
+ CHECK_OO(opck_unary_meta2(env, data, mut))
if(unary->exp->next)
ERR_N(exp_self(unary)->pos,
_("'%s' must be applied to a unique expression"), op2str(unary->op))
#include "type.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
-#include "gwi.h"
#include "emit.h"
#include "operator.h"
+#include "import.h"
+#include "gwi.h"
#include "driver.h"
#include "traverse.h"
#include "parse.h"
#include "nspc.h"
#include "instr.h"
#include "object.h"
+#include "operator.h"
#include "import.h"
#include "emit.h"
-#include "operator.h"
static OP_CHECK(opck_ptr_assign) {
const Exp_Binary* bin = (Exp_Binary*)data;
#include "type.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "shreduler_private.h"
#include "gwion.h"
+#include "operator.h"
+#include "import.h"
static m_int o_fork_thread, o_shred_cancel, o_fork_done, o_fork_ev, o_fork_retsize, o_fork_retval,
o_fork_orig;
#include "type.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "gwion.h"
+#include "operator.h"
+#include "import.h"
ANN static void push_string(const VM_Shred shred, const M_Object obj, const m_str c) {
STRING(obj) = s_name(insert_symbol(shred->info->vm->gwion->st, c));
#include "type.h"
#include "instr.h"
#include "object.h"
+#include "operator.h"
#include "import.h"
#include "gwi.h"
#include "ugen.h"
#include "type.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "vararg.h"
#include "gwion.h"
+#include "operator.h"
+#include "import.h"
void free_vararg(MemPool p, struct Vararg_* arg) {
xfree(arg->d);
#include "type.h"
#include "instr.h"
#include "object.h"
+#include "gwion.h"
+#include "operator.h"
#include "import.h"
#include "driver.h"
#include "func.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "traverse.h"
#include "template.h"
#include "optim.h"
+#include "gwion.h"
+#include "operator.h"
+#include "import.h"
#include "parse.h"
#include "nspc.h"
-#include "operator.h"
#include "switch.h"
ANN static Type check_exp(const Env env, Exp exp);
Type lhs, rhs, ret;
f_instr instr;
Func func;
- Type (*ck)(Env, void*);
- m_bool (*em)(Emitter, void*);
- m_bool mut;
+ opck ck;
+ opem em;
} M_Operator;
ANN void free_op_map(Map map, struct Gwion_ *gwion) {
mo->instr = (f_instr)opi->data;
mo->ck = opi->ck;
mo->em = opi->em;
- mo->mut = opi->mut;
vector_add(v, (vtype)mo);
return GW_OK;
}
((Exp_Unary*)opi->data)->nspc = nspc;
}
-ANN static Type op_check_inner(const Env env, const Map map, struct Op_Import* opi) {
+ANN static Type op_check_inner(const Env env, const Map map, struct Op_Import* opi,
+ m_bool* mut) {
Type t, r = opi->rhs;
do {
const M_Operator* mo;
const Vector v = (Vector)map_get(map, (vtype)opi->op);
if(v && (mo = operator_find(v, opi->lhs, r))) {
- opi->mut = mo->mut;
- if((mo->ck && (t = mo->ck(env, (void*)opi->data))))
+ if((mo->ck && (t = mo->ck(env, (void*)opi->data, mut))))
return t;
else
return mo->ret;
if(nspc->info->op_map.ptr) {
Type l = opi->lhs;
do {
+ m_bool mut = 0;
struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data };
- ret = op_check_inner(env, &nspc->info->op_map, &opi2);
+ ret = op_check_inner(env, &nspc->info->op_map, &opi2, &mut);
if(ret) {
if(ret == t_null)
break;
- if(!opi2.mut)
+ if(!mut)
set_nspc(opi, nspc);
return ret;
}
#include "type.h"
#include "instr.h"
#include "object.h"
-#include "import.h"
#include "ugen.h"
#include "shreduler_private.h"
#include "emit.h"
#include "gwion.h"
+#include "operator.h"
+#include "import.h"
#include "map_private.h"
#include "value.h"
#include "array.h"
#include "memoize.h"
#include "gwion.h"
+#include "operator.h"
#include "import.h"
ANN /*static*/ void free_code_instr(const Vector v, const Gwion gwion) {