Commits

KS Sreeram  committed 7bfb5e7

oldclay: add support for indexAssign, fieldRefAssign, staticIndexAssign.

  • Participants
  • Parent commits 5c4c886

Comments (0)

Files changed (4)

File compiler/src/codegen.cpp

                           CodegenContextPtr ctx);
 EnvPtr codegenBinding(BindingPtr x, EnvPtr env, CodegenContextPtr ctx);
 
+void codegenExprAssign(ExprPtr left,
+                       CValuePtr cvRight,
+                       PValuePtr pvRight,
+                       EnvPtr env,
+                       CodegenContextPtr ctx);
+
+void codegenMultiExprAssign(ExprListPtr left,
+                            MultiCValuePtr mcvRight,
+                            MultiPValuePtr mpvRight,
+                            EnvPtr env,
+                            CodegenContextPtr ctx);
+
 void codegenPrimOp(PrimOpPtr x,
                    MultiCValuePtr args,
                    CodegenContextPtr ctx,
         }
         int tempMarker = markTemps(ctx);
         int marker = cgMarkStack(ctx);
-        if (mpvLeft->size() == 1) {
-            MultiCValuePtr mcvRight = codegenMultiAsRef(x->right, env, ctx);
-            MultiCValuePtr mcvLeft = codegenMultiAsRef(x->left, env, ctx);
-            CValuePtr cvRight = mcvRight->values[0];
-            CValuePtr cvLeft = mcvLeft->values[0];
-            if (mpvRight->values[0]->isTemp)
-                codegenValueMoveAssign(cvLeft, cvRight, ctx);
-            else
-                codegenValueAssign(cvLeft, cvRight, ctx);
+
+        MultiPValuePtr mpvRight2;
+        MultiCValuePtr mcvRight;
+        if (mpvRight->size() == 1) {
+            mcvRight = codegenMultiAsRef(x->right, env, ctx);
+            mpvRight2 = mpvRight;
         }
         else {
-            MultiCValuePtr mcvRight = new MultiCValue();
+            mpvRight2 = new MultiPValue();
+            mcvRight = new MultiCValue();
             for (unsigned i = 0; i < mpvRight->size(); ++i) {
                 PValuePtr pv = mpvRight->values[i];
+                PValuePtr pv2 = new PValue(pv->type, true);
+                mpvRight2->add(pv2);
                 CValuePtr cv = codegenAllocValue(pv->type, ctx);
                 mcvRight->add(cv);
             }
             codegenMultiInto(x->right, env, ctx, mcvRight);
             for (unsigned i = 0; i < mcvRight->size(); ++i)
                 cgPushStack(mcvRight->values[i], ctx);
-            MultiCValuePtr mcvLeft = codegenMultiAsRef(x->left, env, ctx);
-            assert(mcvLeft->size() == mcvRight->size());
-            for (unsigned i = 0; i < mcvLeft->size(); ++i) {
-                CValuePtr cvLeft = mcvLeft->values[i];
-                CValuePtr cvRight = mcvRight->values[i];
-                codegenValueMoveAssign(cvLeft, cvRight, ctx);
+        }
+        unsigned j = 0;
+        for (unsigned i = 0; i < x->left->size(); ++i) {
+            ExprPtr leftExpr = x->left->exprs[i];
+            if (leftExpr->exprKind == UNPACK) {
+                ExprListPtr leftExprList = new ExprList();
+                leftExprList->add(leftExpr);
+                MultiPValuePtr mpvLeftI = safeAnalyzeMulti(leftExprList, env);
+                MultiPValuePtr mpvRightI = new MultiPValue();
+                MultiCValuePtr mcvRightI = new MultiCValue();
+                for (unsigned k = 0; k < mpvLeftI->size(); ++k) {
+                    mpvRightI->add(mpvRight2->values[j + k]);
+                    mcvRightI->add(mcvRight->values[j + k]);
+                }
+                codegenMultiExprAssign(
+                    leftExprList, mcvRightI, mpvRightI, env, ctx
+                );
+                j += mpvLeftI->size();
+            }
+            else {
+                codegenExprAssign(
+                    leftExpr, mcvRight->values[j], mpvRight2->values[j],
+                    env, ctx
+                );
+                j += 1;
             }
         }
+        assert(j == mpvRight2->size());
+
         cgDestroyAndPopStack(marker, ctx);
         clearTemps(tempMarker, ctx);
         return false;
 
 
 //
+// codegenExprAssign, codegenMultiExprAssign
+//
+
+void codegenExprAssign(ExprPtr left,
+                       CValuePtr cvRight,
+                       PValuePtr pvRight,
+                       EnvPtr env,
+                       CodegenContextPtr ctx)
+{
+    if (left->exprKind == INDEXING) {
+        Indexing *x = (Indexing *)left.ptr();
+        ExprPtr indexable = x->expr;
+        ExprListPtr args = x->args;
+        PValuePtr pvIndexable = safeAnalyzeOne(indexable, env);
+        if (pvIndexable->type->typeKind != STATIC_TYPE) {
+            MultiPValuePtr pvArgs = new MultiPValue(pvIndexable);
+            pvArgs->add(safeAnalyzeMulti(args, env));
+            pvArgs->add(pvRight);
+            CValuePtr cvIndexable = codegenOneAsRef(indexable, env, ctx);
+            MultiCValuePtr cvArgs = new MultiCValue(cvIndexable);
+            cvArgs->add(codegenMultiAsRef(args, env, ctx));
+            cvArgs->add(cvRight);
+            codegenCallValue(
+                staticCValue(prelude_indexAssign(), ctx),
+                cvArgs, pvArgs, ctx,
+                new MultiCValue()
+            );
+            return;
+        }
+    }
+    else if (left->exprKind == STATIC_INDEXING) {
+        StaticIndexing *x = (StaticIndexing *)left.ptr();
+        ValueHolderPtr vh = sizeTToValueHolder(x->index);
+        CValuePtr cvIndex = staticCValue(vh.ptr(), ctx);
+        MultiPValuePtr pvArgs = new MultiPValue(safeAnalyzeOne(x->expr, env));
+        pvArgs->add(new PValue(cvIndex->type, true));
+        pvArgs->add(pvRight);
+        MultiCValuePtr cvArgs = new MultiCValue(codegenOneAsRef(x->expr, env, ctx));
+        cvArgs->add(cvIndex);
+        cvArgs->add(cvRight);
+        codegenCallValue(
+            staticCValue(prelude_staticIndexAssign(), ctx),
+            cvArgs, pvArgs, ctx,
+            new MultiCValue()
+        );
+        return;
+    }
+    else if (left->exprKind == FIELD_REF) {
+        FieldRef *x = (FieldRef *)left.ptr();
+        ExprPtr base = x->expr;
+        PValuePtr pvBase = safeAnalyzeOne(base, env);
+        if (pvBase->type->typeKind != STATIC_TYPE) {
+            CValuePtr cvName = staticCValue(x->name.ptr(), ctx);
+            MultiPValuePtr pvArgs = new MultiPValue(pvBase);
+            pvArgs->add(new PValue(cvName->type, true));
+            pvArgs->add(pvRight);
+            MultiCValuePtr cvArgs = new MultiCValue(codegenOneAsRef(base, env, ctx));
+            cvArgs->add(cvName);
+            cvArgs->add(cvRight);
+            codegenCallValue(
+                staticCValue(prelude_fieldRefAssign(), ctx),
+                cvArgs, pvArgs, ctx,
+                new MultiCValue()
+            );
+            return;
+        }
+    }
+    CValuePtr cvLeft = codegenOneAsRef(left, env, ctx);
+    if (pvRight->isTemp)
+        codegenValueMoveAssign(cvLeft, cvRight, ctx);
+    else
+        codegenValueAssign(cvLeft, cvRight, ctx);
+}
+
+void codegenMultiExprAssign(ExprListPtr left,
+                            MultiCValuePtr mcvRight,
+                            MultiPValuePtr mpvRight,
+                            EnvPtr env,
+                            CodegenContextPtr ctx)
+{
+    MultiCValuePtr mcvLeft = codegenMultiAsRef(left, env, ctx);
+    assert(mcvLeft->size() == mcvRight->size());
+    for (unsigned i = 0; i < mcvLeft->size(); ++i) {
+        CValuePtr cvLeft = mcvLeft->values[i];
+        CValuePtr cvRight = mcvRight->values[i];
+        if (mpvRight->values[i]->isTemp)
+            codegenValueMoveAssign(cvLeft, cvRight, ctx);
+        else
+            codegenValueAssign(cvLeft, cvRight, ctx);
+    }
+}
+
+
+
+//
 // valueToStatic, valueToStaticSizeTOrInt
 // valueToType, valueToNumericType, valueToIntegerType,
 // valueToPointerLikeType, valueToTupleType, valueToRecordType,

File compiler/src/libclaynames.hpp

 ObjectPtr prelude_move();
 ObjectPtr prelude_assign();
 ObjectPtr prelude_updateAssign();
+ObjectPtr prelude_indexAssign();
+ObjectPtr prelude_fieldRefAssign();
+ObjectPtr prelude_staticIndexAssign();
 ObjectPtr prelude_ByRef();
 ObjectPtr prelude_setArgcArgv();
 ObjectPtr prelude_callMain();
 ExprPtr prelude_expr_move();
 ExprPtr prelude_expr_assign();
 ExprPtr prelude_expr_updateAssign();
+ExprPtr prelude_expr_indexAssign();
+ExprPtr prelude_expr_fieldRefAssign();
+ExprPtr prelude_expr_staticIndexAssign();
 ExprPtr prelude_expr_ByRef();
 ExprPtr prelude_expr_setArgcArgv();
 ExprPtr prelude_expr_callMain();

File compiler/src/loader.cpp

 DEFINE_PRELUDE_ACCESSOR(move)
 DEFINE_PRELUDE_ACCESSOR(assign)
 DEFINE_PRELUDE_ACCESSOR(updateAssign)
+DEFINE_PRELUDE_ACCESSOR(indexAssign)
+DEFINE_PRELUDE_ACCESSOR(fieldRefAssign)
+DEFINE_PRELUDE_ACCESSOR(staticIndexAssign)
 DEFINE_PRELUDE_ACCESSOR(ByRef)
 DEFINE_PRELUDE_ACCESSOR(setArgcArgv)
 DEFINE_PRELUDE_ACCESSOR(callMain)

File lib-clay/operators/operators.clay

 procedure fieldRef;
 procedure staticIndex;
 
+procedure fieldRefAssign;
+procedure staticIndexAssign;
+procedure indexAssign;
 
 
 //
 inline overload bitwiseXor(a, b, c, ...rest) =
     bitwiseXor(bitwiseXor(a,b), c, ...rest);
 
+[FIELD]
+inline overload fieldRefAssign(dest, static FIELD, forward src) {
+    assign(fieldRef(dest, static FIELD), src);
+}
+
+[i]
+inline overload staticIndexAssign(dest, static i, forward src) {
+    assign(staticIndex(dest, static i), src);
+}
+
+[...T | countValues(...T) >= 2]
+inline overload indexAssign(dest, forward ...indicesAndSrc:T) {
+    assign(
+        index(dest, ...withoutNthValue(
+            static countValues(...T)-1,
+            ...indicesAndSrc
+        )),
+        lastValue(...indicesAndSrc),
+    );
+}
+
 
 
 //