-Subproject commit 2183d0dd09928316960494532af8b57911341061
+Subproject commit 1f57eb48c6eb8b0379b3d232cb7f3fe1ccf90d67
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);
#endif
struct Vector_ size;
uint8_t index;
};
+
+ANN Type tmpl_exists(const Env env, struct tmpl_info *const info);
#endif
return emit_symbol_owned(emit, data);
if(vflag(v, vflag_builtin) || vflag(v, vflag_direct) || vflag(v, vflag_enum))
return emit_symbol_builtin(emit, data);
+ if(!strncmp(v->type->name, "@Foreach:[", 10)) {
+ if(exp_getvar(exp_self(prim_self(data)))) {
+ const Instr instr = emit_add_instr(emit, RegPushMem);
+ instr->m_val = v->from->offset;
+ instr->m_val2 = SZ_INT;
+ } else {
+ const Instr instr = emit_add_instr(emit, RegPushMemDeref);
+ instr->m_val = v->from->offset;
+ instr->m_val2 = v->type->size;
+ }
+ return GW_OK;
+ }
const m_uint size = v->type->size;
const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !vflag(v, vflag_fglobal) ? regpushmem : regpushbase);
instr->m_val = v->from->offset;
ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, m_uint *end_pc) {
const Instr s1 = emit_add_instr(emit, MemSetImm);
- Instr cpy = stmt->is_ptr ? emit_add_instr(emit, MemSetImm) : NULL;
+ Instr cpy = emit_add_instr(emit, MemSetImm);
emit_local(emit, emit->gwion->type[et_int]);
const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
emit_local(emit, emit->gwion->type[et_int]);
stmt->v->from->offset = offset + SZ_INT;
const m_uint ini_pc = emit_code_size(emit);
- const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop);
+ const Instr loop = emit_add_instr(emit, AutoLoopPtr);
const Instr end = emit_add_instr(emit, BranchEqInt);
const m_bool ret = scoped_stmt(emit, stmt->body, 1);
*end_pc = emit_code_size(emit);
- if(stmt->is_ptr) {
- loop->m_val2 = (m_uint)stmt->v->type;
- cpy->m_val = stmt->v->from->offset;
- }
+ loop->m_val2 = (m_uint)stmt->v->type;
+ cpy->m_val = stmt->v->from->offset;
const Instr tgt = emit_add_instr(emit, Goto);
end->m_val = emit_code_size(emit);
tgt->m_val = ini_pc;
GWI_BB(import_shred(gwi))
GWI_BB(import_modules(gwi))
GWI_BB(import_union(gwi))
+ GWI_BB(import_foreach(gwi))
GWI_BB(gwi_oper_ini(gwi, "@Class", "@Class", "int"))
GWI_BB(gwi_oper_end(gwi, "==", int_eq))
--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+#include "gwion_util.h"
+#include "gwion_ast.h"
+#include "gwion_env.h"
+#include "vm.h"
+#include "gwion.h"
+#include "instr.h"
+#include "object.h"
+#include "operator.h"
+#include "import.h"
+#include "emit.h"
+#include "traverse.h"
+#include "template.h"
+#include "parse.h"
+#include "specialid.h"
+#include "gwi.h"
+#include "tmpl_info.h"
+
+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 };
+ const Type exists = tmpl_exists(env, &info);
+ if(exists)
+ 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);
+ return t;
+}
+
+GWION_IMPORT(foreach) {
+ const Type t_foreach = gwi_struct_ini(gwi, "@Foreach:[A]");
+ set_tflag(t_foreach, tflag_ntmpl);
+ GWI_BB(gwi_item_ini(gwi, "@internal", "val"))
+ GWI_BB(gwi_item_end(gwi, ae_flag_none, NULL))
+ GWI_BB(gwi_struct_end(gwi))
+ GWI_BB(gwi_oper_ini(gwi, "@Foreach", NULL, NULL))
+ GWI_BB(gwi_oper_add(gwi, opck_foreach_scan))
+ GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
+ return GW_OK;
+}
-#include <stdlib.h>
-#include <string.h>
#include "gwion_util.h"
#include "gwion_ast.h"
#include "gwion_env.h"
#include "traverse.h"
#include "template.h"
#include "parse.h"
-#include "specialid.h"
#include "gwi.h"
#include "tmpl_info.h"
SET_FLAG(udef, global);
const m_bool ret = scan0_union_def(env, udef);
if(udef->type) {
-/*
- if(!strcmp(info->base->name, "Option")) {
- const Type base = known_type(env, info->td->types->td);
- const m_uint scope = env_push(env, udef->type->info->parent->info->owner_class, udef->type->info->parent->info->owner);
- const struct Op_Func opfunc0 = { .ck=opck_option_get, .em=opem_option_get };
- struct Op_Import opi0 = { .lhs=udef->type, .rhs=base, .ret=base,
- .op=insert_symbol(env->gwion->st, "?=>"), .pos=info->td->pos, .func=&opfunc0 };
- CHECK_BB(add_op(env->gwion, &opi0))
- const struct Op_Func opfunc1 = { .ck=opck_option_set, .em=opem_option_set };
- struct Op_Import opi1 = { .lhs=base, .rhs=udef->type, .ret=udef->type, .func=&opfunc1,
- .op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
- CHECK_BB(add_op(env->gwion, &opi1))
- const struct Op_Func opfunc2 = { .ck=opck_option_setn, .em=opem_option_setn };
- struct Op_Import opi2 = { .lhs=env->gwion->type[et_error], .rhs=udef->type, .ret=udef->type, .func=&opfunc2,
- .op=insert_symbol(env->gwion->st, "@=>"), .pos=info->td->pos };
- CHECK_BB(add_op(env->gwion, &opi2))
- const struct Op_Func opfunc3 = { .em=opem_option_not };
- struct Op_Import opi3 = { .rhs=udef->type, .ret=env->gwion->type[et_bool], .func=&opfunc3,
- .op=insert_symbol(env->gwion->st, "!"), .pos=info->td->pos };
- CHECK_BB(add_op(env->gwion, &opi3))
- const struct Op_Func opfunc4 = { .em=opem_option_cond };
- struct Op_Import opi4 = { .rhs=udef->type, .ret=env->gwion->type[et_bool], .func=&opfunc4,
- .op=insert_symbol(env->gwion->st, "@conditionnal"), .pos=info->td->pos };
- CHECK_BB(add_op(env->gwion, &opi4))
- const struct Op_Func opfunc5 = { .em=opem_option_uncond };
- struct Op_Import opi5 = { .rhs=udef->type, .ret=env->gwion->type[et_bool], .func=&opfunc5,
- .op=insert_symbol(env->gwion->st, "@unconditionnal"), .pos=info->td->pos };
- CHECK_BB(add_op(env->gwion, &opi5))
- env_pop(env, scope);
- }
-*/
udef->type->info->udef = udef;// mark as udef
info->ret = udef->type;
set_tflag(info->ret, tflag_udef);
-// set_tflag(info->ret, tflag_tmpl);
} else
free_union_def(env->gwion->mp, udef);
return ret;
ANN Type tmpl_exists(const Env env, struct tmpl_info *const info);
ANN Type scan_class(const Env env, const Type t, const Type_Decl *td) {
+puts("here");
struct tmpl_info info = { .base=t, .td=td, .list=t->info->cdef->base.tmpl->list };
const Type exists = tmpl_exists(env, &info);
if(exists)
GWI_BB(gwi_oper_ini(gwi, "@Compound", NULL, NULL))
GWI_BB(gwi_oper_add(gwi, opck_struct_scan))
GWI_BB(gwi_oper_end(gwi, "@scan", NULL))
+
return GW_OK;
}
return GW_OK;
}
+ANN static inline Type foreach_type(const Env env, const Exp exp) {
+ DECL_OO(Type, et, = check_exp(env, exp))
+ if(isa(et, env->gwion->type[et_array]) < 0)
+ ERR_O(exp->pos, _("type '%s' is not array.\n"
+ " This is not allowed in foreach loop"), et->name)
+ DECL_OO(Type, base, = typedef_base(et))
+ DECL_OO(const Type, t, = array_base(base))
+ const m_uint depth = base->array_depth - 1;
+ return depth ? array_type(env, t, depth) : t;
+
+}
+
ANN static m_bool do_stmt_each(const Env env, const Stmt_Each stmt) {
- DECL_OB(Type, t, = check_exp(env, stmt->exp))
- while(tflag(t, tflag_typedef))
- t = t->info->parent;
- Type ptr = array_base(t);
- const m_uint depth = t->array_depth - 1;
- if(!ptr || isa(t, env->gwion->type[et_array]) < 0)
- ERR_B(stmt_self(stmt)->pos, _("type '%s' is not array.\n"
- " This is not allowed in foreach loop"), stmt->exp->info->type->name)
- if(stmt->is_ptr) {
- if(depth)
- ptr = array_type(env, ptr, depth);
- char c[15 + strlen(ptr->name)];
- sprintf(c, "Ptr:[%s]", ptr->name);
- ptr = str2type(env->gwion, c, stmt->exp->pos);
- const Type base = get_type(ptr);
- CHECK_BB(ensure_traverse(env, base))
- }
- t = (!stmt->is_ptr && depth) ? array_type(env, ptr, depth) : ptr;
- stmt->v = new_value(env->gwion->mp, t, s_name(stmt->sym));
+ DECL_OB(const Type, ptr, = foreach_type(env, stmt->exp))
+ const Type base = get_type(ptr);
+ CHECK_BB(ensure_traverse(env, base))
+ char c[15 + strlen(ptr->name)];
+ sprintf(c, "@Foreach:[%s]", ptr->name);
+ const Type ret = str2type(env->gwion, c, stmt->exp->pos);
+ stmt->v = new_value(env->gwion->mp, ret, s_name(stmt->sym));
set_vflag(stmt->v, vflag_valid);
nspc_add_value(env->curr, stmt->sym, stmt->v);
return check_conts(env, stmt_self(stmt), stmt->body);
var int i[2][2];
-foreach(ref a : i)
+foreach(a : i)
<<< a >>>;
<<< i >>>;
var C i[2];
-foreach(ref a : i)
+foreach(a : i)
<<< a >>>;
-var Ptr:[int] ptr;
var int i[4];
-foreach(ref a : i)
- <<< *a >>>;
-<<< ptr >>>;
+foreach(a : i)
+ <<< 1 => a >>>;
+foreach(a : i)
+ <<< a >>>;