コード例 #1
0
ファイル: UnaryOperatorBase.cs プロジェクト: SealedSun/prx
 public void Implement(CompilerState state, Instruction ins, CompileTimeValue[] staticArgv,
     int dynamicArgc)
 {
     if (dynamicArgc >= 1)
     {
         state.EmitIgnoreArguments(dynamicArgc - 1);
     }
     else
     {
         staticArgv[0].EmitLoadAsPValue(state);
     }
     state.EmitLoadLocal(state.SctxLocal);
     state.Il.EmitCall(OpCodes.Call, OperationMethod, null);
 }
コード例 #2
0
ファイル: UnaryOperatorBase.cs プロジェクト: SealedSun/prx
 public bool ValidateArguments(CompileTimeValue[] staticArgv, int dynamicArgc)
 {
     return staticArgv.Length + dynamicArgc >= 1;
 }
コード例 #3
0
ファイル: ConsolePrintLine.cs プロジェクト: SealedSun/prx
 /// <summary>
 ///     Checks whether the static arguments and number of dynamic arguments are valid for the CIL extension. 
 /// 
 ///     <para>Returning false means that the CIL extension cannot provide a CIL implementation for the set of arguments at hand. In that case the CIL compiler will fall back to  <see
 ///       cref = "ICilCompilerAware" /> and finally the built-in mechanisms.</para>
 ///     <para>Returning true means that the CIL extension can provide a CIL implementation for the set of arguments at hand. In that case the CIL compiler may subsequently call <see
 ///      cref = "ICilExtension.Implement" /> with the same set of arguments.</para>
 /// </summary>
 /// <param name = "staticArgv">The suffix of compile-time constant arguments, starting after the last dynamic (not compile-time constant) argument. An empty array means that there were no compile-time constant arguments at the end.</param>
 /// <param name = "dynamicArgc">The number of dynamic arguments preceding the supplied static arguments. The total number of arguments is determined by <code>(staticArgv.Length + dynamicArgc)</code></param>
 /// <returns>true if the extension can provide a CIL implementation for the set of arguments; false otherwise</returns>
 public bool ValidateArguments(CompileTimeValue[] staticArgv, int dynamicArgc)
 {
     return dynamicArgc <= 0 && staticArgv.All(ctv => !ctv.IsReference);
 }
コード例 #4
0
ファイル: ConsolePrintLine.cs プロジェクト: SealedSun/prx
        /// <summary>
        ///     Implements the CIL extension in CIL for the supplied arguments. The CIL compiler guarantees to always first call <see
        ///      cref = "ICilExtension.ValidateArguments" /> in order to establish whether the extension can actually implement a particular call.
        ///     Thus, this method does not have to verify <paramref name = "staticArgv" /> and <paramref name = "dynamicArgc" />.
        /// </summary>
        /// <param name = "state">The CIL compiler state. This object is used to emit instructions.</param>
        /// <param name = "ins">The instruction that "calls" the CIL extension. Usually a command call.</param>
        /// <param name = "staticArgv">The suffix of compile-time constant arguments, starting after the last dynamic (not compile-time constant) argument. An empty array means that there were no compile-time constant arguments at the end.</param>
        /// <param name = "dynamicArgc">The number of dynamic arguments preceding the supplied static arguments. The total number of arguments is determined by <code>(staticArgv.Length + dynamicArgc)</code></param>
        public void Implement(CompilerState state, Instruction ins, CompileTimeValue[] staticArgv,
            int dynamicArgc)
        {
            var text = String.Concat(staticArgv.Select(StaticPrint._ToString));

            state.Il.Emit(OpCodes.Ldstr, text);
            if (!ins.JustEffect)
            {
                state.Il.Emit(OpCodes.Dup);
            }
            state.EmitCall(consoleWriteLineMethod_String);
            if (!ins.JustEffect)
            {
                state.EmitWrapString();
            }
        }
コード例 #5
0
 bool ICilExtension.ValidateArguments(CompileTimeValue[] staticArgv, int dynamicArgc)
 {
     return true;
 }
コード例 #6
0
 void ICilExtension.Implement(CompilerState state, Instruction ins,
     CompileTimeValue[] staticArgv, int dynamicArgc)
 {
     FlippedFunctionalPartialCallCommand._ImplementCtorCall(state, ins, staticArgv, dynamicArgc, _functionPartialCallCtor);
 }
コード例 #7
0
ファイル: Char.cs プロジェクト: SealedSun/prx
 bool ICilExtension.ValidateArguments(CompileTimeValue[] staticArgv, int dynamicArgc)
 {
     string literal;
     int code;
     return dynamicArgc == 0 && staticArgv.Length == 1 &&
         (staticArgv[0].TryGetString(out literal) && literal.Length > 0 ||
             staticArgv[0].TryGetInt(out code) && code >= 0);
 }
コード例 #8
0
ファイル: Char.cs プロジェクト: SealedSun/prx
        void ICilExtension.Implement(CompilerState state, Instruction ins,
            CompileTimeValue[] staticArgv, int dynamicArgc)
        {
            if (ins.JustEffect)
                return; // Usually for commands without side-effects you have to at least
            //  pop dynamic arguments from the stack.
            // ValidateArguments proved that there are no arguments on the stack.
            string literal;
            int code;
            if (staticArgv[0].TryGetString(out literal))
                code = literal[0];
            else if (!staticArgv[0].TryGetInt(out code))
                throw new ArgumentException(
                    "char command requires one argument that is either a string or a 32-bit integer with the most significant bit cleared.");

            state.EmitLdcI4(code);
            state.EmitWrapChar();
        }
コード例 #9
0
ファイル: Operators.cs プロジェクト: SealedSun/prx
		public override void Implement(CompilerState state, Instruction ins, CompileTimeValue[] staticArgv, int dynamicArgc)
		{
			if(dynamicArgc >= 2)
			{
				state.EmitIgnoreArguments(dynamicArgc-2);
			}
			else if(dynamicArgc == 1)
			{
				staticArgv[0].EmitLoadAsPValue(state);
			}
			else
			{
				staticArgv[0].EmitLoadAsPValue(state);
				staticArgv[1].EmitLoadAsPValue(state);
			}
			state.EmitLoadLocal(state.SctxLocal);
            state.Il.EmitCall(System.Reflection.Emit.OpCodes.Call, OperationMethod, null);
		}
コード例 #10
0
ファイル: BinaryOperatorBase.cs プロジェクト: SealedSun/prx
        public virtual void Implement(CompilerState state, Instruction ins,
            CompileTimeValue[] staticArgv, int dynamicArgc)
        {
            if (dynamicArgc >= 2)
            {
                state.EmitIgnoreArguments(dynamicArgc - 2);
                state.EmitStoreLocal(state.PrimaryTempLocal);
                state.EmitLoadLocal(state.SctxLocal);
                state.EmitLoadLocal(state.PrimaryTempLocal);
            }
            else if (dynamicArgc == 1)
            {
                //we can load the second static arg just where we need it
                state.EmitLoadLocal(state.SctxLocal);
                staticArgv[0].EmitLoadAsPValue(state);
            }
            else
            {
                PValue left;
                PValue right;

                if (staticArgv[0].TryGetConstant(out left)
                    && staticArgv[1].TryGetConstant(out right))
                {
                    //Both operands are constants (remember: static args can also be references)
                    //=> Apply the operator at compile time.
                    var result = Run(state, new[] {left, right});
                    switch (result.Type.ToBuiltIn())
                    {
                        case PType.BuiltIn.Real:
                            state.EmitLoadRealAsPValue((double) result.Value);
                            break;
                        case PType.BuiltIn.Int:
                            state.EmitLoadIntAsPValue((int) result.Value);
                            break;
                        case PType.BuiltIn.String:
                            state.EmitLoadStringAsPValue((string) result.Value);
                            break;
                        case PType.BuiltIn.Null:
                            state.EmitLoadNullAsPValue();
                            break;
                        case PType.BuiltIn.Bool:
                            state.EmitLoadBoolAsPValue((bool) result.Value);
                            break;
                        default:
                            throw new PrexoniteException(
                                string.Format(
                                    "The operation {0} is no implemented correctly. Given {1} and {2} it results in the non-constant {3}",
                                    GetType().FullName, left, right, result));
                    }
                    return; //We've already emitted the result. 
                }
                else
                {
                    //Load the first operand now, then proceed like for just one static arg
                    staticArgv[0].EmitLoadAsPValue(state);
                    state.EmitLoadLocal(state.SctxLocal);
                    staticArgv[1].EmitLoadAsPValue(state);
                }
            }

            state.Il.EmitCall(OpCodes.Call, OperationMethod, null);
        }
コード例 #11
0
        internal static void _ImplementCtorCall(CompilerState state, Instruction ins, CompileTimeValue[] staticArgv,
            int dynamicArgc, ConstructorInfo partialCallCtor)
        {
//the call subject is not part of argv
            var argc = staticArgv.Length + dynamicArgc - 1;

            if (argc == 0)
            {
                //there is no subject, just load null
                state.EmitLoadNullAsPValue();
                return;
            }

            //We don't actually need static arguments, just emit the corresponding opcodes
            foreach (var compileTimeValue in staticArgv)
                compileTimeValue.EmitLoadAsPValue(state);

            //pack arguments (including static ones) into the argv array, but exclude subject (the first argument)
            state.FillArgv(argc);
            state.ReadArgv(argc);

            //call constructor of FunctionalPartialCall

            state.Il.Emit(OpCodes.Newobj, partialCallCtor);

            //wrap in PValue
            if (ins.JustEffect)
            {
                state.Il.Emit(OpCodes.Pop);
            }
            else
            {
                state.EmitStoreTemp(0);
                state.EmitLoadLocal(state.SctxLocal);
                state.EmitLoadTemp(0);
                state.EmitVirtualCall(Compiler.Cil.Compiler.CreateNativePValue);
            }
        }
コード例 #12
0
ファイル: StaticPrintLine.cs プロジェクト: SealedSun/prx
        public void Implement(CompilerState state, Instruction ins, CompileTimeValue[] staticArgv,
            int dynamicArgc)
        {
            var text = String.Concat(staticArgv.Select(StaticPrint._ToString));

            state.EmitCall(StaticPrint._StaticPrintTextWriterGetMethod);
            state.Il.Emit(OpCodes.Ldstr, text);
            if (!ins.JustEffect)
            {
                state.Il.Emit(OpCodes.Dup);
                state.EmitStoreTemp(0);
            }
            state.EmitVirtualCall(_textWriterWriteLineMethod);
            if (!ins.JustEffect)
            {
                state.EmitLoadTemp(0);
                state.EmitWrapString();
            }
        }
コード例 #13
0
ファイル: StaticPrint.cs プロジェクト: SealedSun/prx
 internal static String _ToString(CompileTimeValue value)
 {
     switch (value.Interpretation)
     {
         case CompileTimeInterpretation.Null:
             return "";
         case CompileTimeInterpretation.String:
             string str;
             if (!value.TryGetString(out str))
                 goto default;
             return str;
         case CompileTimeInterpretation.Int:
             int integer;
             if (!value.TryGetInt(out integer))
                 goto default;
             return integer.ToString();
         case CompileTimeInterpretation.Bool:
             bool boolean;
             if (!value.TryGetBool(out boolean))
                 goto default;
             return boolean.ToString();
         default:
             throw new ArgumentOutOfRangeException();
     }
 }
コード例 #14
0
ファイル: Unbind.cs プロジェクト: SealedSun/prx
        void ICilExtension.Implement(CompilerState state, Instruction ins,
            CompileTimeValue[] staticArgv, int dynamicArgc)
        {
            foreach (var compileTimeValue in staticArgv)
            {
                EntityRef.Variable.Local local;
                if (!compileTimeValue.TryGetLocalVariableReference(out local))
                    throw new ArgumentException(
                        "CIL implementation of Core.Unbind command only accepts local variable references.",
                        "staticArgv");

                CilSymbol cilSymbol;
                if (!state.Symbols.TryGetValue(local.Id, out cilSymbol) ||
                    cilSymbol.Kind != SymbolKind.LocalRef)
                    throw new PrexoniteException(
                        string.Format("CIL implementation of {1} cannot find local explicit variable {0}", local.Id, GetType().FullName));

                //Create new PVariable
                state.Il.Emit(OpCodes.Newobj, Compiler.Cil.Compiler.NewPVariableCtor);
                state.Il.Emit(OpCodes.Dup);

                //Copy old value
                state.EmitLoadPValue(cilSymbol);
                state.EmitCall(Compiler.Cil.Compiler.SetValueMethod);

                //Override variable slot
                state.EmitStoreLocal(cilSymbol.Local);
            }

            if (!ins.JustEffect)
                state.EmitLoadNullAsPValue();
        }
コード例 #15
0
ファイル: Unbind.cs プロジェクト: SealedSun/prx
 bool ICilExtension.ValidateArguments(CompileTimeValue[] staticArgv, int dynamicArgc)
 {
     return dynamicArgc == 0
         &&
         staticArgv.All(
             arg => arg.Interpretation == CompileTimeInterpretation.LocalVariableReference);
 }