-Subproject commit f6a44e51053e1e168322053cda0e6734911610f5
+Subproject commit 82cf57a4b02542e3a5528bd6fa362a47270ccb0f
ANN m_bool import_object_op(const Gwi gwi);
ANN m_bool import_values(const Gwi gwi);
ANN m_bool import_union(const Gwi gwi);
-ANN m_bool import_foreach(const Gwi gwi);
+ANN m_bool import_ref(const Gwi gwi);
#endif
}
if(vflag(v, vflag_builtin) || vflag(v, vflag_direct))
return emit_symbol_builtin(emit, data);
- if(!strncmp(v->type->name, "@Foreach:[", 10)) {
+ if(!strncmp(v->type->name, "Ref:[", 5)) {
if(exp_getvar(exp_self(prim_self(data)))) {
const Instr instr = emit_add_instr(emit, RegPushMem);
instr->m_val = v->from->offset;
GWI_BB(import_string(gwi))
GWI_BB(import_shred(gwi))
GWI_BB(import_modules(gwi))
- GWI_BB(import_foreach(gwi))
+ GWI_BB(import_ref(gwi))
GWI_BB(gwi_oper_ini(gwi, "@Class", "@Class", "int"))
GWI_BB(gwi_oper_end(gwi, "==", int_eq))
#include "gwi.h"
#include "tmpl_info.h"
+static m_bool ref_access(const Env env, const Exp e) {
+ const m_str access = exp_access(e);
+ if(!access)
+ return GW_OK;
+ ERR_B(e->pos, _("operand is %s"), access);
+}
+
+static OP_CHECK(opck_implicit_similar) {
+ const struct Implicit *imp = (struct Implicit*)data;
+ CHECK_BN(ref_access(env, imp->e))
+ exp_setvar(imp->e, 1);
+ return imp->t;
+}
+
+static OP_CHECK(opck_cast_similar) {
+ const Exp_Cast *cast = (Exp_Cast*)data;
+ return exp_self(cast)->type;
+}
+
+ANN static void base2ref(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, .ret=rhs, .rhs=rhs, .func=&opfunc, .data=eNoOp };
+ add_op(env->gwion, &opi);
+ opfunc.ck = opck_implicit_similar;
+ opi.op=insert_symbol("@implicit");
+ add_op(env->gwion, &opi);
+}
+
+ANN static void ref2base(Env env, const Type lhs, const Type rhs) {
+ struct Op_Import opi = { .op=insert_symbol("$"), .lhs=lhs, .ret=rhs, .rhs=rhs, /*.func=&opfunc,*/ .data=eNoOp };
+ add_op(env->gwion, &opi);
+ opi.op=insert_symbol("@implicit");
+ add_op(env->gwion, &opi);
+}
+
OP_CHECK(opck_foreach_scan) {
struct TemplateScan *ts = (struct TemplateScan*)data;
struct tmpl_info info = { .base=ts->t, .td=ts->td, .list=ts->t->info->cdef->base.tmpl->list };
return exists != env->gwion->type[et_error] ? exists : NULL;
const Type base = known_type(env, ts->td->types->td);
const Type t = new_type(env->gwion->mp, s_name(info.name), base);
+ SET_FLAG(t, abstract | ae_flag_final);
+ set_tflag(t, tflag_infer);
+ base2ref(env, base, t);
+ ref2base(env, t, base);
return t;
}
-GWION_IMPORT(foreach) {
- const Type t_foreach = gwi_struct_ini(gwi, "@Foreach:[A]");
+GWION_IMPORT(ref) {
+ const Type t_foreach = gwi_struct_ini(gwi, "Ref:[A]");
set_tflag(t_foreach, tflag_infer);
GWI_BB(gwi_item_ini(gwi, "@internal", "val"))
GWI_BB(gwi_item_end(gwi, ae_flag_none, num, 0))
GWI_BB(gwi_struct_end(gwi))
- GWI_BB(gwi_oper_ini(gwi, "@Foreach", NULL, NULL))
+ GWI_BB(gwi_oper_ini(gwi, "Ref", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_foreach_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
return GW_OK;
CHECK_BB(ensure_traverse(env, base))
const m_str basename = type2str(env->gwion, base, stmt->exp->pos);
char c[15 + strlen(basename)];
- sprintf(c, "@Foreach:[%s]", basename);
+ sprintf(c, "Ref:[%s]", basename);
const Type ret = str2type(env->gwion, c, stmt->exp->pos);
if(base->array_depth)
set_tflag(ret, tflag_typedef);
return exp_self(cast)->type;
}
-ANN static void scan0_implicit_similar(const Env env, const Type lhs, const Type rhs) {
+ANN /*static */void scan0_implicit_similar(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);
return ret;
}
+ANN static inline Type ref(const Env env, Type_Decl* td) {
+ struct Type_List_ tl = { .td=td };
+ td->ref = 0;
+ Type_Decl option_td = { .xid=insert_symbol("Ref"), .types=&tl, .pos=td->pos };
+ const Type t = known_type(env, &option_td);
+ td->ref = 1;
+ return t;
+}
+
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, _("type '%s' is invalid"), base->name)
- DECL_OO(const Type, t, = scan_type(env, base, td))
+ DECL_OO(const Type, type, = scan_type(env, base, td))
+ const Type t = !td->ref ? type : ref(env, td);
const Type ret = !td->option ? t : option(env, td);
return !td->array ? ret : array_type(env, ret, td->array->depth);
}