]> Nishi Git Mirror - gwion.git/commitdiff
:art: new and decl shenanigans
authorfennecdjay <fennecdjay@gmail.com>
Sat, 30 Jul 2022 19:56:31 +0000 (21:56 +0200)
committerfennecdjay <fennecdjay@gmail.com>
Sat, 30 Jul 2022 19:56:31 +0000 (21:56 +0200)
src/lib/object_op.c
src/parse/check.c

index bf6f3c3c881dbc712f8728bc221a27abe8403a8f..30c44658c81106cfd13b3401fa92436f53ef3f92 100644 (file)
@@ -40,6 +40,26 @@ static OP_CHECK(opck_object_at) {
   return bin->rhs->type;
 }
 
+static OP_CHECK(opck_object_instance) {
+  Exp_Binary *bin = (Exp_Binary*)data;
+  Exp rhs = bin->rhs;
+  if (rhs->exp_type != ae_exp_decl)
+    return NULL;
+  if (rhs->d.exp_decl.td->array)
+    return NULL;
+  Exp lhs = bin->lhs;
+  Exp e = exp_self(bin);
+  Exp_Decl *const decl = &e->d.exp_decl;
+  e->exp_type = ae_exp_decl;
+  decl->td = cpy_type_decl(env->gwion->mp, rhs->d.exp_decl.td);
+  decl->vd = rhs->d.exp_decl.vd;
+  decl->type = rhs->type;
+  decl->args = lhs;
+  free_exp(env->gwion->mp, rhs);
+  CHECK_ON(check_exp(env, e));
+  return e->type;
+}
+
 ANN void unset_local(const Emitter emit, void *const l);
 static OP_EMIT(opem_object_at) {
   const Exp_Binary *bin = (Exp_Binary *)data;
@@ -439,6 +459,9 @@ GWION_IMPORT(object_op) {
   GWI_BB(gwi_oper_add(gwi, opck_object_at))
   GWI_BB(gwi_oper_emi(gwi, opem_object_at))
   GWI_BB(gwi_oper_end(gwi, ":=>", NULL))
+  GWI_BB(gwi_oper_ini(gwi, (m_str)OP_ANY_TYPE, "@Compound", NULL))
+  GWI_BB(gwi_oper_add(gwi, opck_object_instance))
+  GWI_BB(gwi_oper_end(gwi, "=>", NULL))
   GWI_BB(gwi_oper_ini(gwi, "Object", "Object", "bool"))
   GWI_BB(gwi_oper_end(gwi, "==", EqObject))
   GWI_BB(gwi_oper_end(gwi, "!=", NeqObject))
index 2fcea6a95c1555cf06da1aa5d48e5e349b10a6fe..f61233d068c22d3b5273e3b6a42ae3d6b188db52 100644 (file)
@@ -919,6 +919,23 @@ ANN static Type check_exp_binary(const Env env, const Exp_Binary *bin) {
                          bin->rhs->exp_type == ae_exp_decl &&
                          bin->rhs->d.exp_decl.type == env->gwion->type[et_auto];
   if (is_auto) bin->rhs->d.exp_decl.type = bin->lhs->type;
+  // allow foo => new C to mean new C(foo)
+  if(bin->op == insert_symbol("=>") &&
+     bin->rhs->exp_type == ae_exp_unary && bin->rhs->d.exp_unary.unary_type == unary_td &&
+     !bin->rhs->d.exp_unary.ctor.td->array &&
+     !bin->rhs->d.exp_unary.ctor.exp) {
+   Exp lhs = bin->lhs;
+   Exp rhs = bin->rhs;
+   Exp e = exp_self(bin);
+   Exp_Unary *const unary = &e->d.exp_unary;
+   e->exp_type = ae_exp_unary;
+   unary->unary_type = unary_td;
+   unary->op = insert_symbol("new");
+   unary->ctor.td = cpy_type_decl(env->gwion->mp, bin->rhs->d.exp_unary.ctor.td);
+   unary->ctor.exp = lhs;
+   free_exp(env->gwion->mp, rhs);
+   return check_exp(env, e);
+  }
   CHECK_OO(check_exp(env, bin->rhs));
   if (is_auto) {
     assert(bin->rhs->type == bin->lhs->type);