From b2fcae904f6efa46b027cd1d55a43e3e819aec9f Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Wed, 26 Oct 2022 01:47:36 +0200 Subject: [PATCH] :art: Struct constructors --- include/emit.h | 2 +- include/parse.h | 2 + src/emit/emit.c | 136 +++++++++++++------- src/lib/object_op.c | 5 +- src/lib/opfunc.c | 6 +- src/parse/check.c | 56 ++++---- src/parse/default_arg.c | 2 +- src/parse/scan2.c | 2 +- tests/struct_ctor/struct_ctor_assign_get.gw | 12 ++ tests/struct_ctor/struct_ctor_assign_set.gw | 11 ++ tests/struct_ctor/struct_ctor_decl_get.gw | 12 ++ tests/struct_ctor/struct_ctor_decl_set.gw | 12 ++ tests/struct_ctor/struct_ctor_new_get.gw | 11 ++ tests/struct_ctor/struct_ctor_new_set.gw | 11 ++ tests/struct_ctor/struct_ctor_simple_get.gw | 11 ++ tests/struct_ctor/struct_ctor_simple_set.gw | 11 ++ 16 files changed, 220 insertions(+), 82 deletions(-) create mode 100644 tests/struct_ctor/struct_ctor_assign_get.gw create mode 100644 tests/struct_ctor/struct_ctor_assign_set.gw create mode 100644 tests/struct_ctor/struct_ctor_decl_get.gw create mode 100644 tests/struct_ctor/struct_ctor_decl_set.gw create mode 100644 tests/struct_ctor/struct_ctor_new_get.gw create mode 100644 tests/struct_ctor/struct_ctor_new_set.gw create mode 100644 tests/struct_ctor/struct_ctor_simple_get.gw create mode 100644 tests/struct_ctor/struct_ctor_simple_set.gw diff --git a/include/emit.h b/include/emit.h index 3f798001..89bc1ecc 100644 --- a/include/emit.h +++ b/include/emit.h @@ -80,7 +80,7 @@ ANN m_uint emit_code_offset(const Emitter emit); ANN m_uint emit_local(const Emitter emit, const Type t); ANN m_uint emit_localn(const Emitter emit, const Type t); ANN void* emit_localx(const Emitter emit, const Type t); -ANN void emit_local_exp(const Emitter emit, const Exp); +ANN m_uint emit_local_exp(const Emitter emit, const Exp); ANN m_bool emit_exp_spork(const Emitter, const Exp_Unary *); ANN m_bool emit_exp(const Emitter, const Exp); diff --git a/include/parse.h b/include/parse.h index 1041c265..f2c96926 100644 --- a/include/parse.h +++ b/include/parse.h @@ -133,4 +133,6 @@ ANN static inline bool is_static_call(const Gwion gwion, const Exp e) { is_class(gwion, member->base->type) || member->base->exp_type == ae_exp_cast; } + +#define is_new(a) !strcmp(s_name((a)->base->xid), "new") #endif diff --git a/src/emit/emit.c b/src/emit/emit.c index dc978ff2..41b55be4 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -320,10 +320,11 @@ ANN void* emit_localx(const Emitter emit, const Type t) { return l; } -ANN void emit_local_exp(const Emitter emit, const Exp e) { +ANN m_uint emit_local_exp(const Emitter emit, const Exp e) { Local *const l = emit_localx(emit, e->type); if(e->ref) e->ref->data = l; + return l->offset; } ANN m_uint emit_localn(const Emitter emit, const Type t) { @@ -962,12 +963,31 @@ ANN static void decl_expand(const Emitter emit, const Type t) { emit_regmove(emit, t->size - SZ_INT); } -ANN static void emit_struct_decl_finish(const Emitter emit, const Type t, - const bool emit_addr) { - emit->code->frame->curr_offset += t->size + SZ_INT; - emit_ext_ctor(emit, t); - if (!emit_addr) decl_expand(emit, t); - emit->code->frame->curr_offset -= t->size + SZ_INT; +ANN static m_uint decl_non_static_offset(const Emitter emit, const Exp_Decl *decl, const Type t) { + if(!exp_self(decl)->data) + return emit_local(emit, t); + const Local *l = exp_self(decl)->data; + exp_self(decl)->data = (void*)-1; + return l->offset; +} + +ANN static m_bool struct_finish(const Emitter emit, const Exp_Decl *decl) { + const Type t = decl->type; + const bool emit_addr = exp_getvar(exp_self(decl)); + if (decl->args) { + const Instr instr = (Instr)vector_back(&emit->code->instr); + CHECK_BB(emit_exp(emit, decl->args)); + if (emit_addr) { + emit_regmove(emit, -t->size); + vector_add(&emit->code->instr, (m_uint)instr); + } + return GW_OK; + } + if(tflag(t, tflag_ctor)) { + emit_ext_ctor(emit, t); + if (!emit_addr) decl_expand(emit, t); + } + return GW_OK; } ANN static m_bool emit_exp_decl_static(const Emitter emit, const Exp_Decl *decl, @@ -978,7 +998,7 @@ ANN static m_bool emit_exp_decl_static(const Emitter emit, const Exp_Decl *decl, if (isa(v->type, emit->gwion->type[et_object]) > 0 && !is_ref) CHECK_BB(decl_static(emit, decl, var_decl, 0)); CHECK_BB(emit_dot_static_data(emit, v, !struct_ctor(v) ? emit_addr : 1)); - if (struct_ctor(v)) emit_struct_decl_finish(emit, v->type, emit_addr); + if (tflag(v->type, tflag_struct)) CHECK_BB(struct_finish(emit, decl)); if (isa(v->type, emit->gwion->type[et_object]) > 0 && !is_ref) if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global)) emit_object_addref(emit, 0, emit_addr); @@ -1011,14 +1031,6 @@ ANN void unset_local(const Emitter emit, Local *const l) { } } -ANN static m_uint decl_non_static_offset(const Emitter emit, const Exp_Decl *decl, const Type t) { - if(!exp_self(decl)->data) - return emit_local(emit, t); - const Local *l = exp_self(decl)->data; - exp_self(decl)->data = (void*)-1; - return l->offset; -} - ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl *var_decl, @@ -1060,8 +1072,11 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, } if(safe_tflag(emit->env->class_def, tflag_struct) && GET_FLAG(emit->env->class_def, global)) emit_object_addref(emit, 0, emit_addr); - } else if (struct_ctor(v)) - emit_struct_decl_finish(emit, v->type, emit_addr); + } else if (tflag(v->type, tflag_struct)) { +// if (!emit_var) +// decl->vd.value->from->offset = decl_non_static_offset(emit, decl, type); + CHECK_BB(struct_finish(emit, decl)); + } return GW_OK; } @@ -1087,8 +1102,8 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, const Instr assign = emit_add_instr(emit, Assign); assign->m_val = emit_var; (void)emit_object_addref(emit, -SZ_INT, emit_var); - } else if (struct_ctor(v)) { - emit_struct_decl_finish(emit, v->type, emit_addr); + } else if (tflag(v->type, tflag_struct)) { + struct_finish(emit, decl); (void)emit_struct_addref(emit, v->type, -v->type->size, emit_addr); } return GW_OK; @@ -1137,7 +1152,7 @@ ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) { const Vector vec = &v->type->nspc->vtable; for(m_uint i = 0; i < vector_size(vec); i++) { const Func f = (Func)vector_at(vec, i); - if(!strcmp(s_name(f->def->base->xid), "new")) { + if(is_new(f->def)) { gw_err(_("maybe use a constructor?\n")); break; } @@ -1311,38 +1326,66 @@ ANN static inline m_bool emit_inline(const Emitter emit, const Func f, } #endif -ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call *exp_call) { + +ANN static inline bool is_new_struct(const Func f, const Type t) { + return is_new(f->def) && tflag(t, tflag_struct); +} + +ANN static m_bool emit_new_struct(const Emitter emit,const Exp_Call *call) { + const Exp self = exp_self(call); + const Type t = self->type; + const m_int offset = self->ref ? emit->code->frame->curr_offset - t->size: emit_local(emit, t); + const Instr back = self->ref ? (Instr)vector_pop(&emit->code->instr) : NULL; + CHECK_BB(emit_func_args(emit, call)); + if(back) + vector_add(&emit->code->instr, (m_uint)back); + else if(tflag(t, tflag_ctor)) { + const Instr instr = emit_add_instr(emit, RegPushMem4); + instr->m_val = offset; + } + if(tflag(t, tflag_ctor)) emit_ext_ctor(emit, t); + else if(!back) { + emit_regmove(emit, -SZ_INT + t->size); + const Instr instr = emit_add_instr(emit, RegPushMem4); + instr->m_val = offset; + } + emit_add_instr(emit, NoOp); + return GW_OK; +} + +ANN static m_bool _emit_exp_call(const Emitter emit, const Exp_Call *call) { #ifdef GWION_INLINE - const Func _f = is_inlinable(emit, exp_call); + const Func _f = is_inlinable(emit, call); if(_f) { const Func base = emit->env->func; emit->env->func = _f; const m_uint scope = emit_push(emit, _f->value_ref->from->owner_class, _f->value_ref->from->owner); - const m_bool ret = emit_inline(emit, _f, exp_call); + const m_bool ret = emit_inline(emit, _f, call); emit_pop(emit, scope); emit->env->func = base; return ret; } #endif - // skip when recursing - const Type t = actual_type(emit->gwion, exp_call->func->type); - const Func f = t->info->func; - if (strstr(emit->code->name, "ork~") || - (f != emit->env->func || (f && f->value_ref->from->owner_class))) - CHECK_BB(prepare_call(emit, exp_call)); - else - CHECK_BB(emit_func_args(emit, exp_call)); - if (is_func(emit->gwion, t)) // is_callable needs type - CHECK_BB(emit_exp_call1(emit, t->info->func, - is_static_call(emit->gwion, exp_call->func))); - else { + const Type t = call->func->type; + + if(unlikely(!is_func(emit->gwion, t))) { + const Type t = actual_type(emit->gwion, call->func->type); struct Op_Import opi = {.op = insert_symbol("@ctor"), .rhs = t, - .data = (uintptr_t)exp_call, - .pos = exp_self(exp_call)->pos}; + .data = (uintptr_t)call, + .pos = exp_self(call)->pos}; CHECK_BB(op_emit(emit, &opi)); } + + const Func f = t->info->func; + if(unlikely(is_new_struct(f, exp_self(call)->type))) + emit_new_struct(emit, call); + else if (strstr(emit->code->name, "ork~") || // skip when recursing + (f != emit->env->func || (f && f->value_ref->from->owner_class))) + CHECK_BB(prepare_call(emit, call)); + else CHECK_BB(emit_func_args(emit, call)); + CHECK_BB(emit_exp_call1(emit, f, is_static_call(emit->gwion, call->func))); return GW_OK; } @@ -1362,8 +1405,6 @@ ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call *exp_call) { tflag(e->type, tflag_struct)) emit_regmove(emit, -SZ_INT); } -// if(isa(e->type, emit->gwion->type[et_object]) > 0) -// emit_local_exp(emit, e); return GW_OK; } @@ -1632,7 +1673,7 @@ ANN static void emit_fptr_call(const Emitter emit, const Func f) { ANN static void call_finish(const Emitter emit, const Func f, const bool is_static) { const m_uint offset = emit_code_offset(emit); - if (f != emit->env->func || !is_static || strcmp(s_name(f->def->base->xid), "new")) + if (f != emit->env->func || !is_static || !is_new(f->def)) emit_setimm(emit, offset, 0); const Instr instr = emit_call(emit, f, is_static); instr->m_val = f->def->base->ret_type->size; @@ -2712,8 +2753,15 @@ ANN static VM_Code emit_internal(const Emitter emit, const Func f) { ANN static inline VM_Code _emit_func_def_code(const Emitter emit, const Func func) { - if(!strcmp(s_name(func->def->base->xid), "new")) - emit_add_instr(emit, RegPushMem); + if(is_new(func->def)) { + const Type t = func->value_ref->from->owner_class; + if(!tflag(t, tflag_struct)) + emit_add_instr(emit, RegPushMem); + else { + const Instr instr = emit_add_instr(emit, RegPushMemDeref); + instr->m_val2 = t->size; + } + } return !fbflag(func->def->base, fbflag_internal) ? finalyze(emit, FuncReturn) : emit_internal(emit, func); } @@ -2843,7 +2891,7 @@ ANN static m_bool _emit_func_def(const Emitter emit, const Func_Def f) { return GW_OK; } if ((vflag(func->value_ref, vflag_builtin) && - safe_tflag(emit->env->class_def, tflag_tmpl)) || (fdef->base->tmpl && !strcmp(s_name(f->base->xid), "new"))) { + safe_tflag(emit->env->class_def, tflag_tmpl)) || (fdef->base->tmpl && is_new(f))) { const Func base = nspc_lookup_func1(func->value_ref->from->owner, f->base->xid); builtin_func(emit->gwion, func, (f_xfun)base->code->native_func); diff --git a/src/lib/object_op.c b/src/lib/object_op.c index 9a9ba746..a91886d6 100644 --- a/src/lib/object_op.c +++ b/src/lib/object_op.c @@ -130,7 +130,7 @@ ANN static void emit_dottmpl(const Emitter emit, const Func f) { ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) { const Func f = exp_self(member)->type->info->func; - if(!strcmp(s_name(f->def->base->xid), "new")) { + if(is_new(f->def)) { if(f != emit->env->func) emit_pushfunc(emit, f); return; } @@ -143,7 +143,7 @@ ANN static void emit_member_func(const Emitter emit, const Exp_Dot *member) { return; } } else if (is_static_call(emit->gwion, exp_self(member))) { - if (member->is_call && f == emit->env->func && strcmp(s_name(f->def->base->xid), "new")) return; + if (member->is_call && f == emit->env->func && !is_new(f->def)) return; return emit_pushfunc(emit, f); } else { if (tflag(member->base->type, tflag_struct)) @@ -171,6 +171,7 @@ ANN static inline void emit_struct_data(const Emitter emit, const Value v, const bool emit_addr) { const Instr instr = emit_structmember(emit, v->type->size, emit_addr); instr->m_val = v->from->offset; + instr->m_val2 = 3; if (!emit_addr) emit_regmove(emit, v->type->size - SZ_INT); } diff --git a/src/lib/opfunc.c b/src/lib/opfunc.c index ab43adcd..98181263 100644 --- a/src/lib/opfunc.c +++ b/src/lib/opfunc.c @@ -140,9 +140,6 @@ OP_CHECK(opck_new) { self->d.exp_call.tmpl = NULL; self->exp_type = ae_exp_call; CHECK_BN(traverse_exp(env, self)); -// const Type tbase = func->type->info->value->from->owner_class; -// if(!tflag(base->type, tflag_union) && tbase != base->type) -// ERR_N(base->pos, "'%s' has no matching constructor", base->type->name); return self->type; } if (GET_FLAG(t, abstract) && @@ -156,7 +153,8 @@ OP_CHECK(opck_new) { OP_EMIT(opem_new) { const Exp_Unary *unary = (Exp_Unary *)data; - CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type, + if(!tflag(exp_self(unary)->type, tflag_struct)) + CHECK_BB(emit_instantiate_object(emit, exp_self(unary)->type, unary->ctor.td->array, 0)); if(!unary->ctor.exp) emit_local_exp(emit, exp_self(unary)); diff --git a/src/parse/check.c b/src/parse/check.c index 2117b113..9d3ee8d8 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -148,11 +148,11 @@ ANN static inline m_bool inferable(const Env env, const Type t, ANN Type check_exp_decl(const Env env, Exp_Decl *const decl) { if (decl->td->array && decl->td->array->exp) CHECK_OO(check_exp(env, decl->td->array->exp)); -// if (decl->args && !decl->args->type) { // for some reason this can be parsed twice if (decl->args) { const Exp e = new_exp_unary2(env->gwion->mp, insert_symbol("new"), cpy_type_decl(env->gwion->mp, decl->td), decl->args, decl->td->pos); CHECK_OO(check_exp(env, e)); decl->args = e; + e->ref = exp_self(decl); } if (decl->td->xid == insert_symbol("auto")) { // should be better CHECK_BO(scan1_exp(env, exp_self(decl))); @@ -894,11 +894,15 @@ ANN void call_add_effect(const Env env, const Func func, const loc_t pos) { } ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) { - /* const */Type t = exp->func->type; + Type t = exp->func->type; if (!is_func(env->gwion, t)) { // use func flag? if(isa(exp->func->type, env->gwion->type[et_closure]) > 0) t = closure_def(t)->base->func->value_ref->type; - else { + else if(is_class(env->gwion, t) && tflag(t->info->base_type, tflag_struct)) { + const Value v = nspc_lookup_value0(t->info->base_type->nspc, insert_symbol("new")); + if(v) t = exp->func->type = v->type; + else return NULL; + } else { struct Op_Import opi = {.op = insert_symbol("@ctor"), .rhs = actual_type(env->gwion, exp->func->type), .data = (uintptr_t)exp, @@ -910,13 +914,6 @@ ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) { if (t == env->gwion->type[et_op]) return check_op_call(env, exp); if (!t->info->func) // TODO: effects? return check_lambda_call(env, exp); -/* - if (fflag(t->info->func, fflag_ftmpl)) { - const Value value = t->info->func->value_ref; - if (value->from->owner_class) - CHECK_BO(ensure_traverse(env, value->from->owner_class)); - } -*/ if (exp->args) { CHECK_OO(check_exp(env, exp->args)); Exp e = exp->args; @@ -927,23 +924,13 @@ ANN Type _check_exp_call1(const Env env, Exp_Call *const exp) { return check_exp_call_template(env, (Exp_Call *)exp); // TODO: effects? const Func func = find_func_match(env, t->info->func, exp); if (func) { -/* - if (func != env->func && func->def && !fflag(func, fflag_valid)) { - if(func->value_ref->from->owner_class) - CHECK_BO(ensure_check(env, func->value_ref->from->owner_class)); - else { - const m_uint scope = env_push(env, NULL, func->value_ref->from->owner); - const m_bool ret = check_func_def(env, func->def); - env_pop(env, scope); - CHECK_BO(ret); - } - } -*/ exp->func->type = func->value_ref->type; call_add_effect(env, func, exp->func->pos); -// used in new. why??? - return func->def->base->ret_type != env->gwion->type[et_auto] ? - func->def->base->ret_type : exp->func->d.exp_dot.base->type; + if(func->def->base->ret_type != env->gwion->type[et_auto]) + return func->def->base->ret_type; + if(tflag(func->value_ref->from->owner_class, tflag_struct)) + return func->value_ref->from->owner_class; + return exp->func->d.exp_dot.base->type; } if(exp->func->exp_type == ae_exp_lambda) { const Type tt = partial_type(env, exp); @@ -968,7 +955,8 @@ ANN static Type check_static(const Env env, const Exp e) { ANN Type check_exp_call1(const Env env, Exp_Call *const exp) { DECL_BO(const m_bool, ret, = func_check(env, exp)); if (!ret) return exp_self(exp)->type; - const Type t = exp->func->type; +// const Type t = actual_type(env->gwion, exp->func->type); +/* const */Type t = exp->func->type; CHECK_OO(check_static(env, exp->func)); const Type _ret = _check_exp_call1(env, exp); if(_ret) return _ret; @@ -982,7 +970,17 @@ ANN Type check_exp_call1(const Env env, Exp_Call *const exp) { if(t) return t; } } - function_alternative(env, t, exp->args, exp->func->pos); +//puts(t->name); +// if(!is_func(env->gwion, t)) { +// if(is_class(env->gwion, t)) { +// const Value v = nspc_lookup_value0(t->info->base_type->nspc, insert_symbol("new")); +// if(v) t = v->type; +// } +// else +// } +//exit(3); + if(is_func(env->gwion, exp->func->type)) + function_alternative(env, exp->func->type, exp->args, exp->func->pos); return NULL; } @@ -1131,7 +1129,7 @@ ANN static Type check_exp_call(const Env env, Exp_Call *exp) { } // check for closure and b ring it back if (!is_func(env->gwion, t)) return check_exp_call1(env, exp); - if(strcmp("new", s_name(t->info->func->def->base->xid))) + if(!is_new(t->info->func->def)) return check_exp_call_tmpl(env, exp, t); } return check_exp_call1(env, exp); @@ -1409,7 +1407,7 @@ stmt_func_xxx(loop, Stmt_Loop, env_inline_mult(env, 1.5); check_idx(env, stmt->i stmt_func_xxx(each, Stmt_Each, env_inline_mult(env, 1.5), do_stmt_each(env, stmt)) ANN static m_bool check_stmt_return(const Env env, const Stmt_Exp stmt) { - if (!strcmp(s_name(env->func->def->base->xid), "new")) { + if (is_new(env->func->def)) { if(stmt->val) ERR_B(stmt_self(stmt)->pos, _("'return' statement inside constructor function should have no expression")) diff --git a/src/parse/default_arg.c b/src/parse/default_arg.c index 3d973831..eb0231c3 100644 --- a/src/parse/default_arg.c +++ b/src/parse/default_arg.c @@ -64,7 +64,7 @@ ANN void default_args(const Env env, const Section *s, Ast *acc) { Arg *arg = mp_vector_at(args, Arg, args->len); if(!arg->exp) break; Func_Base *const base = cpy_func_base(p, base_fdef->base); - Stmt_List code = strcmp("new", s_name(base->xid)) + Stmt_List code = strcmp(s_name(base->xid), "new") ? std_code(env->gwion->mp, base, args, len) : new_code(env, base, args, len); // const Stmt body = new_stmt_code(p, slist, base->pos); diff --git a/src/parse/scan2.c b/src/parse/scan2.c index c7aefd8f..48742541 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -552,7 +552,7 @@ static inline int is_cpy(const Func_Def fdef) { ANN m_bool _scan2_func_def(const Env env, const Func_Def fdef) { if (tmpl_base(fdef->base->tmpl) && fbflag(fdef->base, fbflag_op)) return GW_OK; - if(!strcmp(s_name(fdef->base->xid), "new")) { + if(is_new(fdef)) { if(!env->class_def) ERR_B(fdef->base->pos, _("{G+}new{0} operator must be set inside {C+}class{0}")); SET_FLAG(env->class_def, abstract); diff --git a/tests/struct_ctor/struct_ctor_assign_get.gw b/tests/struct_ctor/struct_ctor_assign_get.gw new file mode 100644 index 00000000..72a69801 --- /dev/null +++ b/tests/struct_ctor/struct_ctor_assign_get.gw @@ -0,0 +1,12 @@ +#! [contains] 42 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +S(21,21) :=> var auto s; +<<< s.i >>>; diff --git a/tests/struct_ctor/struct_ctor_assign_set.gw b/tests/struct_ctor/struct_ctor_assign_set.gw new file mode 100644 index 00000000..e845d721 --- /dev/null +++ b/tests/struct_ctor/struct_ctor_assign_set.gw @@ -0,0 +1,11 @@ +#! [contains] 42 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +<<< 12 :=> (S(21,21) :=> var auto s).i >>>; diff --git a/tests/struct_ctor/struct_ctor_decl_get.gw b/tests/struct_ctor/struct_ctor_decl_get.gw new file mode 100644 index 00000000..99a01685 --- /dev/null +++ b/tests/struct_ctor/struct_ctor_decl_get.gw @@ -0,0 +1,12 @@ +#! [contains] 42 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +var S(21,21) w; +<<< w.i >>>; diff --git a/tests/struct_ctor/struct_ctor_decl_set.gw b/tests/struct_ctor/struct_ctor_decl_set.gw new file mode 100644 index 00000000..1af53acc --- /dev/null +++ b/tests/struct_ctor/struct_ctor_decl_set.gw @@ -0,0 +1,12 @@ +#! [contains] 42 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +12 :=> (var S(21,21) w).i; +<<< w.i >>>; diff --git a/tests/struct_ctor/struct_ctor_new_get.gw b/tests/struct_ctor/struct_ctor_new_get.gw new file mode 100644 index 00000000..ece50c87 --- /dev/null +++ b/tests/struct_ctor/struct_ctor_new_get.gw @@ -0,0 +1,11 @@ +#! [contains] 42 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +(new S(21,21)).i; diff --git a/tests/struct_ctor/struct_ctor_new_set.gw b/tests/struct_ctor/struct_ctor_new_set.gw new file mode 100644 index 00000000..e6b10522 --- /dev/null +++ b/tests/struct_ctor/struct_ctor_new_set.gw @@ -0,0 +1,11 @@ +#! [contains] 13 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +<<< 13 :=> (new S(21,21)).i >>>; diff --git a/tests/struct_ctor/struct_ctor_simple_get.gw b/tests/struct_ctor/struct_ctor_simple_get.gw new file mode 100644 index 00000000..d4ebecb7 --- /dev/null +++ b/tests/struct_ctor/struct_ctor_simple_get.gw @@ -0,0 +1,11 @@ +#! [contains] 42 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +<<< (S(21,21)).i >>>; diff --git a/tests/struct_ctor/struct_ctor_simple_set.gw b/tests/struct_ctor/struct_ctor_simple_set.gw new file mode 100644 index 00000000..4e8c3f41 --- /dev/null +++ b/tests/struct_ctor/struct_ctor_simple_set.gw @@ -0,0 +1,11 @@ +#! [contains] 13 + +struct S { + 12 :=> var int i; + var float f; + operator new(int i, int j) { + <<< i + j :=> this.i >>>; + } +} + +<<< 13 :=> (S(21,21)).i >>>; -- 2.43.0