예제 #1
0
 public void EmitTryGetNonInheritedValue(CodeGen cg, Slot valueOut)
 {
     typeSlot.EmitGet(cg);
     cg.EmitCall(typeof(UserType), "GetNamespaceDictionary");
     cg.EmitInt(index);
     valueOut.EmitGetAddr(cg);
     cg.EmitCall(typeof(NamespaceDictionary), "TryGetNonInheritedValue");
 }
예제 #2
0
        public void EmitIndirectedSymbol(CodeGen cg, SymbolId id)
        {
            Slot value;

            if (!indirectSymbolIds.TryGetValue(id, out value))
            {
                // create field, emit fix-up...

                value = AddStaticField(typeof(int), "symbol_" + SymbolTable.IdToString(id));
                CodeGen init     = GetOrMakeInitializer();
                Slot    localTmp = init.GetLocalTmp(typeof(SymbolId));
                init.EmitString((string)SymbolTable.IdToString(id));
                init.EmitCall(typeof(SymbolTable), "StringToId");
                localTmp.EmitSet(init);
                localTmp.EmitGetAddr(init);
                init.EmitFieldGet(typeof(SymbolId), "Id");
                value.EmitSet(init);

                cg.FreeLocalTmp(localTmp);
                indirectSymbolIds[id] = value;
            }

            value.EmitGet(cg);
        }
예제 #3
0
        public override void EmitSet(CodeGen cg)
        {
            // Disallow "[] = l", "[], a = l, l", "[[]] = [l]", etc
            if (items.Length == 0)
            {
                cg.Context.AddError("can't assign to " + EmptySequenceString, this);
                return;
            }

            // int leftCount = items.Length;
            Slot leftCount = cg.GetLocalTmp(typeof(int));

            cg.EmitInt(items.Length);
            leftCount.EmitSet(cg);

            // object[] values = new object[leftCount];
            Slot values = cg.GetLocalTmp(typeof(object[]));

            leftCount.EmitGet(cg);
            cg.Emit(OpCodes.Newarr, typeof(object));
            values.EmitSet(cg);

            // ie = Ops.GetEnumerator(<value on stack>)
            Slot ie = cg.GetLocalTmp(typeof(IEnumerator));

            cg.EmitCall(typeof(Ops), "GetEnumerator");
            ie.EmitSet(cg);

            // int rightCount = Ops.GetEnumeratorValues(ie, ref values);
            Slot rightCount = cg.GetLocalTmp(typeof(int));

            ie.EmitGet(cg);
            values.EmitGetAddr(cg);
            cg.EmitCall(typeof(Ops), "GetEnumeratorValues");
            rightCount.EmitSet(cg);

            // if (leftCount != rightCount)
            //      throw Ops.ValueErrorForUnpackMismatch(leftCount, rightCount);
            Label equalSizes = cg.DefineLabel();

            leftCount.EmitGet(cg);
            rightCount.EmitGet(cg);
            cg.Emit(OpCodes.Ceq);
            cg.Emit(OpCodes.Brtrue_S, equalSizes);

            leftCount.EmitGet(cg);
            rightCount.EmitGet(cg);
            cg.EmitCall(typeof(Ops).GetMethod("ValueErrorForUnpackMismatch"));
            cg.Emit(OpCodes.Throw);

            cg.MarkLabel(equalSizes);

            // for (int i = 0; i < leftCount; i++)
            //     items[i].Assign(values[i], env);

            int i = 0;

            foreach (Expr expr in items)
            {
                values.EmitGet(cg);
                cg.EmitInt(i++);
                cg.Emit(OpCodes.Ldelem_Ref);
                expr.EmitSet(cg);
            }

            cg.FreeLocalTmp(leftCount);
            cg.FreeLocalTmp(rightCount);
            cg.FreeLocalTmp(values);
            cg.FreeLocalTmp(ie);
        }
예제 #4
0
 public override void EmitGetAddr(CodeGen cg)
 {
     attribute.EmitGetAddr(cg);
 }