From 83641f12fbc884d42045c86bf7e3da925679271c Mon Sep 17 00:00:00 2001 From: fennecdjay Date: Sat, 30 Jul 2022 09:45:56 +0200 Subject: [PATCH] :art: handle arguments to decls --- src/emit/emit.c | 32 ++++++++++++++++++++++++++------ src/parse/check.c | 12 ++++++++++++ src/parse/scan1.c | 1 + src/parse/scan2.c | 1 + 4 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/emit/emit.c b/src/emit/emit.c index b73e635c..bd45e771 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -926,10 +926,26 @@ ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, return GW_OK; } +ANN static m_bool emit_instantiate_new(const Emitter emit, const Exp_Decl *decl) { + struct Exp_ e = { + .d = { .exp_unary = { + .op = insert_symbol("new"), + .ctor = { .td = decl->td, .exp = decl->args }, + .unary_type = unary_td + }}, + .exp_type = ae_exp_unary, + .pos = decl->td->pos + }; + CHECK_BB(traverse_exp(emit->env, &e)); + CHECK_BB(emit_exp(emit, &e)); + return GW_OK; +} + ANN static m_bool _decl_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl *var_decl, const uint is_ref) { const Value v = var_decl->value; - CHECK_BB(emit_instantiate_decl(emit, v->type, decl->td, is_ref)); + if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, v->type, decl->td, is_ref)); + else CHECK_BB(emit_instantiate_new(emit, decl)); CHECK_BB(emit_dot_static_data(emit, v, 1)); emit_add_instr(emit, Assign); // if(get_depth(var_decl->value->type) && !is_ref) @@ -1022,9 +1038,11 @@ ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Type type = v->type; const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0; const bool emit_addr = (!is_obj || is_ref) ? emit_var : true; - if (is_obj && !is_ref && !exp_self(decl)->ref) + if (is_obj && !is_ref && !exp_self(decl)->ref) { // if (is_obj && ((is_array && !exp_self(decl)->ref) || !is_ref)) - CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref)); + if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref)); + else CHECK_BB(emit_instantiate_new(emit, decl)); + } f_instr *exec = (f_instr *)allocmember; if (!emit->env->scope->depth) emit_debug(emit, v); if (!vflag(v, vflag_member)) { @@ -1064,8 +1082,10 @@ ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, const Type type = v->type; const bool is_obj = isa(type, emit->gwion->type[et_object]) > 0; const bool emit_addr = (!is_obj || is_ref) ? emit_var : true; - if (is_obj && !is_ref) - CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref)); + if (is_obj && !is_ref) { + if(!decl->args) CHECK_BB(emit_instantiate_decl(emit, type, decl->td, is_ref)); + else CHECK_BB(emit_instantiate_new(emit, decl)); + } const Instr instr = emit_dotstatic(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1); if (type->size > SZ_INT) //{ @@ -1118,7 +1138,7 @@ ANN static m_bool emit_decl(const Emitter emit, Exp_Decl *const decl) { CHECK_BB(op_emit(emit, &opi)); } set_late(decl, vd); - if (!exp_self(decl)->emit_var && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) && + if (!decl->args && !exp_self(decl)->emit_var && GET_FLAG(array_base_simple(v->type), abstract) && !GET_FLAG(decl->td, late) && GET_FLAG(v, late) && late_array(decl->td) && GET_FLAG(v->type, abstract)) { env_warn(emit->env, decl->td->pos, _("Type '%s' is abstract, use {+G}late{0} instead of {G+}%s{0}"), diff --git a/src/parse/check.c b/src/parse/check.c index 04ac3b0f..4e50f563 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -138,6 +138,18 @@ ANN static inline m_bool inferable(const Env env, const Type t, ANN Type check_exp_decl(const Env env, const Exp_Decl *decl) { if (decl->td->array && decl->td->array->exp) CHECK_OO(check_exp(env, decl->td->array->exp)); + if (decl->args) { + struct Exp_ e = { + .d = { .exp_unary = { + .op = insert_symbol("new"), + .ctor = { .td = decl->td, .exp = decl->args }, + .unary_type = unary_td + }}, + .exp_type = ae_exp_unary, + .pos = decl->td->pos + }; + CHECK_OO(check_exp(env, &e)); + } if (decl->td->xid == insert_symbol("auto")) { // should be better CHECK_BO(scan1_exp(env, exp_self(decl))); CHECK_BO(scan2_exp(env, exp_self(decl))); diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 2a9698b3..a6094ef3 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -155,6 +155,7 @@ ANN m_bool scan1_exp_decl(const Env env, Exp_Decl *const decl) { CHECK_BB(env_storage(env, decl->td->flag, exp_self(decl)->pos)); ((Exp_Decl *)decl)->type = scan1_exp_decl_type(env, (Exp_Decl *)decl); CHECK_OB(decl->type); + if(decl->args) CHECK_BB(scan1_exp(env, decl->args)); const bool global = GET_FLAG(decl->td, global); if (global) { if (env->context) env->context->global = true; diff --git a/src/parse/scan2.c b/src/parse/scan2.c index 943b50a3..876cc82d 100644 --- a/src/parse/scan2.c +++ b/src/parse/scan2.c @@ -36,6 +36,7 @@ ANN static m_bool scan2_decl(const Env env, const Exp_Decl *decl) { } ANN m_bool scan2_exp_decl(const Env env, const Exp_Decl *decl) { + if(decl->args) CHECK_BB(scan2_exp(env, decl->args)); const bool global = GET_FLAG(decl->td, global); const m_uint scope = !global ? env->scope->depth : env_push_global(env); const m_bool ret = scan2_decl(env, decl); -- 2.43.0