const Type_Decl *td;
};
+ANN void op_cpy(const Env env, const struct Op_Import* opi);
ANN m_bool add_op(const Gwion gwion, const struct Op_Import*);
ANN Type op_check(const Env, struct Op_Import*);
ANN m_bool op_emit(const Emitter, const struct Op_Import*);
ERR_N(exp_self(call)->pos, _("can't call a non-callable value"));
}
+static ID_CHECK(idck_predicate) {
+ set_fflag(env->func, fflag_return);
+ return exp_self(prim)->type;
+}
+
static INSTR(PredicateCheck) {
if(!*(m_uint*)REG(-SZ_INT))
- handle(shred, "predicate failed");
+ handle(shred, "PredicateFail");
}
ANN static m_bool import_core_libs(const Gwi gwi) {
gwi_specialid(gwi, "now", &spid);
gwidoc(gwi, "internal predicate representation.");
- struct SpecialId_ predicate = { .type=t_void, .exec=PredicateCheck, .is_const=1 };
+ struct SpecialId_ predicate = { .type=t_void, .ck=idck_predicate, .exec=PredicateCheck, .is_const=1 };
gwi_specialid(gwi, "@predicate", &predicate);
gwidoc(gwi, "internal base of all objects and structures.");
const Exp when = cpy_exp(env->gwion->mp, tdef->when);
when->next = helper;
const Stmt stmt = new_stmt_exp(env->gwion->mp, ae_stmt_exp, when, when->pos);
+// const Stmt stmt_return = new_stmt_exp(env->gwion->mp, ae_stmt_return, new_prim_id(env->gwion->mp, insert_symbol("self"), when->pos), when->pos);
+// const Stmt_List ret_list = new_stmt_list(env->gwion->mp, stmt_return, NULL);//ret_list);
const Stmt_List body = new_stmt_list(env->gwion->mp, stmt, NULL);//ret_list);
const Stmt code = new_stmt_code(env->gwion->mp, body, when->pos);
const Func_Def fdef = new_func_def(env->gwion->mp, fb, code);
ret_id->type = tdef->type;
body->next = ret_list;
tdef->when_def = fdef;
+
}
return (!is_fptr(env->gwion, tdef->type) && tdef->type->info->cdef) ?
check_class_def(env, tdef->type->info->cdef) : GW_OK;
array_type(env, array_base(t)->info->parent, depth);
}
-ANN static Type op_check_inner(struct OpChecker* ock, const uint i) {
+ANN static Type op_check_inner(const Env env, struct OpChecker* ock, const uint i) {
Type t, r = ock->opi->rhs;
do {
const M_Operator* mo;
} else
return mo->ret;
}
- } while(r && (r = r->info->parent));
+ } while(r && (r = op_parent(env, r)));
return NULL;
}
do {
struct Op_Import opi2 = { .op=opi->op, .lhs=l, .rhs=opi->rhs, .data=opi->data };
struct OpChecker ock = { .env=env, .map=&nspc->info->op_map, .opi=&opi2 };
- const Type ret = op_check_inner(&ock, i);
+ const Type ret = op_check_inner(env, &ock, i);
if(ret) {
if(ret == env->gwion->type[et_error])
return NULL;
}
return GW_ERROR;
}
+
+#define CONVERT(t) t != from ? t : to
+ANN static M_Operator* cpy_mo(MemPool p, M_Operator *const base,
+ const Type from, const Type to) {
+ M_Operator* mo = mp_calloc(p, M_Operator);
+ mo->lhs = CONVERT(base->lhs);
+ mo->rhs = CONVERT(base->rhs);
+ mo->ret = CONVERT(base->ret);
+ mo->instr = base->instr;
+ mo->func = base->func;
+ mo->ck = base->ck;
+ mo->em = base->em;
+ if(base->effect.ptr) {
+ vector_init(&mo->effect);
+ vector_copy2(&base->effect, &mo->effect);
+ }
+ return mo;
+}
+#undef CONVERT
+
+ANN static inline Map ensure_map(const Nspc nspc) {
+ const Map map = &nspc->info->op_map;
+ if(!map->ptr)
+ map_init(map);
+ return map;
+}
+
+ANN static inline Vector ensure_vec(const MemPool mp, const Map map, const m_uint key) {
+ const Vector exists = (Vector)map_get(map, key);
+ if(exists)
+ return exists;
+ const Vector vec = new_vector(mp);
+ map_set(map, key, (m_uint)vec);
+ return vec;
+}
+
+ANN static void op_visit(const MemPool mp, const Nspc nspc, const struct Op_Import* opi, const Vector visited) {
+ if(vector_find(visited, (m_uint)nspc) != -1)
+ return;
+ vector_add(visited, (m_uint)nspc);
+ if(nspc->info->op_map.ptr) {
+ const Map map = &nspc->info->op_map;
+ const Map base_map = ensure_map(opi->rhs->info->value->from->owner);
+ for(m_uint i = 0; i < map_size(map); i++) {
+ const Vector v = (Vector)map_at(map, i);
+ const m_uint sz = vector_size(v);
+ for(m_uint j = 0; j < sz; j++) {
+ M_Operator *const mo = (M_Operator*)vector_at(v, j);
+ if(opi->lhs == mo->lhs || opi->lhs == mo->rhs || opi->lhs == mo->ret) {
+ const M_Operator* tmp = cpy_mo(mp, mo, opi->lhs, opi->rhs);
+ const Vector target = ensure_vec(mp, base_map, VKEY(map, i));
+ vector_add(target, (vtype)tmp);
+ }
+ }
+ }
+ }
+ if(nspc->parent)
+ op_visit(mp, nspc->parent, opi, visited);
+}
+
+ANN void op_cpy(const Env env, const struct Op_Import* opi) {
+ struct Vector_ visited;
+ vector_init(&visited);
+ op_visit(env->gwion->mp, opi->rhs->info->value->from->owner, opi, &visited);
+ op_visit(env->gwion->mp, opi->lhs->info->value->from->owner, opi, &visited);
+ op_visit(env->gwion->mp, env->curr, opi, &visited);
+ vector_release(&visited);
+}
add_op(env->gwion, &opi);
}
+ANN static void scan0_explicit_distinct(const Env env, const Type lhs, const Type rhs) {
+ struct Op_Func opfunc = { .ck=opck_cast_similar };
+ struct Op_Import opi = { .op=insert_symbol("$"), .lhs=lhs, .rhs=rhs, .func=&opfunc };
+ add_op(env->gwion, &opi);
+}
+
ANN static void typedef_simple(const Env env, const Type_Def tdef, const Type base) {
const Type t = scan0_type(env, s_name(tdef->xid), base);
t->size = base->size;
} else
typedef_fptr(env, tdef, base);
if(!tdef->distinct && !tdef->when)
- scan0_implicit_similar(env, tdef->type, base);
- if(tdef->distinct)
+ scan0_implicit_similar(env, base, tdef->type);
+ if(tdef->distinct) {
+ tdef->type->info->parent = base->info->parent;
+ if(base->info->gack)
+ vmcode_addref(tdef->type->info->gack = base->info->gack);
set_tflag(tdef->type, tflag_distinct);
+ struct Op_Import opi = { .lhs=base, .rhs=tdef->type };
+ op_cpy(env, &opi);
+ scan0_explicit_distinct(env, base, tdef->type);
+// type_addref(tdef->type); // maybe because of scope_iter in nspc_free_values
+ } else
+ set_tflag(tdef->type, tflag_typedef);
if(global)
env_pop(env, 0);
- set_tflag(tdef->type, tflag_typedef);
return GW_OK;
}
fun int recursive_fib(int n) {
if (n < 2)
return n;
- else
- return recursive_fib(n - 2) + recursive_fib(n - 1);
+ return recursive_fib(n - 2) + recursive_fib(n - 1);
}
<<< 6 => recursive_fib >>>;
<<< 6 => recursive_fib >>>;