]> Nishi Git Mirror - gwion.git/commitdiff
:art: handle arguments to decls
authorfennecdjay <fennecdjay@gmail.com>
Sat, 30 Jul 2022 07:45:56 +0000 (09:45 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Sat, 30 Jul 2022 07:45:56 +0000 (09:45 +0200)
src/emit/emit.c
src/parse/check.c
src/parse/scan1.c
src/parse/scan2.c

index b73e635c62a22b54063d68884c4dcef9e028b48e..bd45e771d9db084d779d68484955428b9f9dab0e 100644 (file)
@@ -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}"),
index 04ac3b0fe314581c1f71c90152f451fdd933cf95..4e50f563bfa0379d12ff648a43e5b51f028a923a 100644 (file)
@@ -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)));
index 2a9698b3c936b00e4dc5d0a92f17966991146d49..a6094ef3beec06e8ea48a3c4887b56ebd398f5d7 100644 (file)
@@ -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;
index 943b50a3d1ed02f3a98f5f8f8d78ec2c352952a3..876cc82d371bdeb4e4a48a8f03c2240c71ebd9cb 100644 (file)
@@ -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);