Ejemplo n.º 1
0
        public Emit <Func <int> > EmitByteCode(CompilerContext context, Emit <Func <int> > emiter)
        {
            var loopLabel = emiter.DefineLabel();
            var outLabel  = emiter.DefineLabel();

            emiter.MarkLabel(loopLabel);
            Condition.EmitByteCode(context, emiter);
            emiter.BranchIfFalse(outLabel);
            BlockStmt.EmitByteCode(context, emiter);
            emiter.Branch(loopLabel);
            emiter.MarkLabel(outLabel);
            return(emiter);
        }
        public void EmitSerialize(Emit <Action <BinaryWriter, object> > emiter, Local value)
        {
            var write = emiter.DefineLabel(nameof(StringSerializer) + "Write" + Guid.NewGuid());

            // if (value != null) goto write
            emiter.LoadLocal(value);
            emiter.LoadNull();
            emiter.CompareEqual();
            emiter.BranchIfFalse(write);

            // value = string.Empty
            emiter.LoadField(typeof(string).GetField(nameof(string.Empty)));
            emiter.StoreLocal(value);

            // ProudNetBinaryWriterExtensions.WriteProudString(writer, value, false)
            emiter.MarkLabel(write);
            emiter.LoadArgument(1);
            emiter.LoadLocal(value);
            emiter.LoadConstant(false);
            emiter.Call(typeof(ProudNetBinaryWriterExtensions).GetMethod(nameof(ProudNetBinaryWriterExtensions.WriteProudString)));
        }
Ejemplo n.º 3
0
        private void GenerateFunctionInner(Emit<MuftecFunction> funcDef, Queue<MuftecStackItem> execStack, Local runtimeStack, MuftecStackItem lastItem = default(MuftecStackItem))
        {
            DebugMsg("- Call stack -> {0}", String.Join(", ", execStack.ToArray()));

            var stackPush = typeof (Stack<MuftecStackItem>).GetMethod("Push");

            while (execStack.Count > 0)
            {
                var currStackItem = execStack.Dequeue();
                DebugMsg("- Popping stack item: " + currStackItem.ToDebugString());

                switch (currStackItem.Type)
                {
                    // Run a user defined function
                    case MuftecType.Function:
                        // Find the function and create an IL call
                        var funcName = currStackItem.Item.ToString();
                        DebugMsg(" -- Call function {0}", funcName);
                        var func = _funcCache[funcName];
                        funcDef.LoadArgument(0); // Load OpCodeData into stack
                        funcDef.Call(func);
                        break;

                    // Execute a library opcode
                    case MuftecType.OpCode:
                        // Translate opcode into direct call
                        var opCodeName = currStackItem.Item.ToString();
                        DebugMsg(" >> Call opcode {0}", opCodeName);
                        var opCode = _system.FindOpCode(opCodeName);

                        // If this is an internal opcode, we need to handle it at this level
                        if (opCode.Attribute.Extern)
                        {
                            switch (opCode.Attribute.OpCodeName)
                            {
                                case "!":
                                case "@":
                                    throw new MuftecCompilerException("Variables not supported in the fabricator at line " + currStackItem.LineNumber);
                                case "loadlibdll":
                                    funcDef.LoadLocal(runtimeStack);
                                    funcDef.Call(typeof (Shared).GetMethod("PopStr"));
                                    _system.AddLibrary(lastItem.ToString());
                                    break;
                            }
                        }
                        else
                        {
                            funcDef.LoadArgument(0); // Load OpCodeData into the stack
                            funcDef.Call(opCode.Pointer.Method); // Call OpCode function
                        }

                        // Handle post-execution magic
                        var magic = opCode.Attribute.Magic;
                        switch (magic)
                        {
                            case MagicOpcodes.Abort:
                                // End exeuction
                                DebugMsg(" ---- Abort");
                                funcDef.LoadConstant(0);
                                funcDef.Call(typeof (Environment).GetMethod("Exit"));
                                return;
                            case MagicOpcodes.Exit:
                                DebugMsg(" ---- Exit");
                                // Exit out of this loop
                                return;
                        }
                        break;

                    // Handle a conditional container
                    case MuftecType.Conditional:
                        var container = currStackItem.Item as ConditionalContainer;
                        if (container == null)
                            throw new MuftecCompilerException("Unable to process conditional statement at line " + currStackItem.LineNumber);

                        DebugMsg(" -- Container");
                        var ltLabel = funcDef.DefineLabel();
                        var endLabel = funcDef.DefineLabel();
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.Call(typeof (Shared).GetMethod("PopInt")); // Call PopInt on RuntimeStack
                        funcDef.BranchIfFalse(ltLabel);

                        // GT operations
                        DebugMsg(" -- Starting true condition");
                        GenerateFunctionInner(funcDef, container.TrueQueue, runtimeStack, lastItem);
                        funcDef.Branch(endLabel);

                        // LT operations
                        funcDef.MarkLabel(ltLabel);
                        DebugMsg(" -- Starting false condition");
                        GenerateFunctionInner(funcDef, container.FalseQueue, runtimeStack, lastItem);

                        funcDef.MarkLabel(endLabel);
                        DebugMsg(" -- Conditions done");
                        break;

                    // Add item to the runtime stack
                    case MuftecType.Integer:
                        DebugMsg(" -- Pushing int {0} to RS", currStackItem.ToString());
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.LoadConstant((int)currStackItem.Item);
                        funcDef.LoadConstant(currStackItem.LineNumber);
                        funcDef.NewObject<MuftecStackItem, int, int>();
                        funcDef.Call(stackPush);
                        break;
                    case MuftecType.Float:
                        DebugMsg(" -- Pushing float {0} to RS", currStackItem.ToString());
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.LoadConstant((double)currStackItem.Item);
                        funcDef.LoadConstant(currStackItem.LineNumber);
                        funcDef.NewObject<MuftecStackItem, double, int>();
                        funcDef.Call(stackPush);
                        break;
                    case MuftecType.String:
                        DebugMsg(" -- Pushing string {0} to RS", currStackItem.ToString());
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStackp =
                        funcDef.LoadConstant((string)currStackItem.Item);
                        funcDef.LoadConstant(currStackItem.LineNumber);
                        funcDef.NewObject<MuftecStackItem, string, int>();
                        funcDef.Call(stackPush);
                        break;
                    case MuftecType.ArrayMarker:
                        DebugMsg(" -- Pushing array marker to RS");
                        funcDef.LoadLocal(runtimeStack); // Get the RuntimeStack
                        funcDef.LoadConstant((int)currStackItem.Item);
                        funcDef.Call(typeof(MuftecStackItem).GetMethod("CreateArrayMarker"));
                        funcDef.Call(stackPush);
                        break;
                }

                lastItem = currStackItem;
            }
        }
Ejemplo n.º 4
0
 public override void Emit <T>(Emit <T> emitter)
 {
     emitter.BranchIfFalse(_label);
 }