示例#1
0
        private Instructions BuildInstructions(Stream source)
        {
            var instructions = new Instructions();
            var reader       = new CharReader(source);
            var jumpTable    = new Stack <int>();

            while (reader.HasCharacters())
            {
                if (IsSetToZero(reader))
                {
                    instructions.Add(new Instruction(InstructionType.SetZero));
                }

                var c = reader.GetChar();

                switch (c)
                {
                case '+':
                    instructions.AddRange(DeflateComboInstruction(GetComboInstruction(reader)));
                    break;

                case '-':
                    instructions.AddRange(DeflateComboInstruction(GetComboInstruction(reader)));
                    break;

                case '>':
                    instructions.AddRange(DeflateComboInstruction(GetComboInstruction(reader)));
                    break;

                case '<':
                    instructions.AddRange(DeflateComboInstruction(GetComboInstruction(reader)));
                    break;

                case '.':
                    instructions.Add(new Instruction(InstructionType.Print));
                    break;

                case ',':
                    instructions.Add(new Instruction(InstructionType.Read));
                    break;

                case '[':
                    instructions.Add(new Instruction(InstructionType.BeginLoop));
                    jumpTable.Push(instructions.Count - 1);
                    break;

                case ']':
                    var beginPosition    = jumpTable.Pop();
                    var beginInstruction = instructions[beginPosition];
                    instructions.Add(new Instruction(InstructionType.EndLoop, beginPosition));
                    beginInstruction.Parameter = instructions.Count - 1;
                    break;
                }

                reader.Forward();
            }

            return(instructions);
        }
示例#2
0
 private void PrefixIncrement()
 {
     if (TokenStream.Accept(TokenType.Delimiter, "++"))
     {
         TokenStream.PushPosition();
         GetReference();
         Instructions.Add(new Instruction(Opcode.Push, 1));
         Instructions.Add(new Instruction(Opcode.Add));
         TokenStream.PopPosition();
         TokenStream.PushPosition();
         SetReference();
         TokenStream.PopPosition();
         GetReference();
     }
     else if (TokenStream.Accept(TokenType.Delimiter, "--"))
     {
         TokenStream.PushPosition();
         GetReference();
         Instructions.Add(new Instruction(Opcode.Push, 1));
         Instructions.Add(new Instruction(Opcode.Subtract));
         TokenStream.PopPosition();
         TokenStream.PushPosition();
         SetReference();
         TokenStream.PopPosition();
         GetReference();
     }
 }
示例#3
0
 private void Unary()
 {
     if (Parser.IsAddOperation(TokenStream.Peek()))
     {
         UnarySign();
     }
     else if (TokenStream.Accept(TokenType.Delimiter, "!"))
     {
         Primary();
         Instructions.Add(new Instruction(Opcode.BitwiseNot));
     }
     else if (TokenStream.Accept(TokenType.Delimiter, "~"))
     {
         Primary();
         Instructions.Add(new Instruction(Opcode.BitwiseNegate));
     }
     else if (Parser.IsCastOperation(TokenStream.Peek()))
     {
         TypeCast();
     }
     else if (Parser.IsIncrementOperation(TokenStream.Peek()))
     {
         PrefixIncrement();
     }
     else
     {
         Primary();
     }
 }
示例#4
0
        private void Multiplicative()
        {
            Unary();

            while (Parser.IsMulOperation(TokenStream.Peek()))
            {
                if (TokenStream.Accept(TokenType.Delimiter, "*"))
                {
                    Unary();
                    Instructions.Add(new Instruction(Opcode.Multiply));
                }
                else if (TokenStream.Accept(TokenType.Delimiter, "/"))
                {
                    Unary();
                    Instructions.Add(new Instruction(Opcode.Divide));
                }
                else if (TokenStream.Accept(TokenType.Delimiter, "%"))
                {
                    if (TokenStream.Pass(TokenType.Delimiter, "["))
                    {
                        // Write hacks err day
                        Ternary();
                        Instructions.Add(new Instruction(Opcode.ClassCallStatic, "__str Format", 2));
                    }
                    else
                    {
                        Unary();
                        Instructions.Add(new Instruction(Opcode.Modulo));
                    }
                }
            }
        }
示例#5
0
        private void Ternary()
        {
            LogicalOr();

            while (TokenStream.Accept(TokenType.Delimiter, "?"))
            {
                Label labelElse = new Label(this);
                Label labelEnd  = new Label(this);

                Instructions.Add(new Instruction(Opcode.Push, 0));
                Instructions.Add(new Instruction(Opcode.CompareNotEqual));
                Instructions.Add(new Instruction(Opcode.IfFalse, 0));
                labelElse.PatchHere();

                LogicalOr();
                Instructions.Add(new Instruction(Opcode.Jump, 0));
                labelEnd.PatchHere();

                TokenStream.Expect(TokenType.Delimiter, ":");

                labelElse.Mark();
                LogicalOr();
                labelEnd.Mark();

                labelElse.Fix();
                labelEnd.Fix();
            }
        }
示例#6
0
        private bool BreakStatement()
        {
            if (!TokenStream.Accept(TokenType.Word, "break"))
            {
                return(false);
            }

            if (breakStack.Count == 0)
            {
                throw new CompilerException("Nothing to break from.");
            }

            if (TokenStream.Pass(TokenType.Number))
            {
                long count = TokenStream.ReadVariant().IntValue;
                if (breakStack.Count < count)
                {
                    throw new CompilerException("Cannot break from {0} scopes deep, because we are not {0} scopes deep at this time.", count);
                }

                Instructions.Add(new Instruction(Opcode.Jump, 0));
                Label[] labelArray = breakStack.ToArray();
                labelArray[count - 1].PatchHere();
            }
            else
            {
                Instructions.Add(new Instruction(Opcode.Jump, 0));
                breakStack.Peek().PatchHere();
            }

            TokenStream.Accept(TokenType.Delimiter, ";");

            return(true);
        }
示例#7
0
        private bool ReturnStatement()
        {
            if (!TokenStream.Accept(TokenType.Word, "return"))
            {
                return(false);
            }

            if (IsReference(TokenStream.Peek()) || TokenStream.Pass(TokenType.Number) || TokenStream.Pass(TokenType.String) ||
                (TokenStream.Pass(TokenType.Delimiter) && !TokenStream.Accept(TokenType.Delimiter, ";")))
            {
                if (currentMethod.Name == IdentConstructor)
                {
                    throw new CompilerException("Constructors must return a 'this' pointer.");
                }

                Ternary();
            }
            else if (currentMethod.Name == IdentConstructor)
            {
                Instructions.Add(new Instruction(Opcode.GetThis));
            }

            Instructions.Add(new Instruction(Opcode.Return));

            TokenStream.Accept(TokenType.Delimiter, ";");

            return(true);
        }
示例#8
0
 /// <summary>
 /// The function that will be called once the <see cref="AddInstructionCommand"/> is invoked
 /// </summary>
 public void AddInstructionCommandExecute()
 {
     //adds a new row
     Instructions.Add(new LoopUnrolInstructionModel {
         Order = ++Counter
     });
 }
示例#9
0
        public void Define(string action, params object[] parameters)
        {
            var ps = new List <string>();
            var i  = new Instruction {
                Action = action, Parameters = ps, Line = Count
            };

            foreach (var param in parameters)
            {
                if (param is string)
                {
                    ps.Add(param.ToString());
                }
                else if (param is Anchor)
                {
                    i.Anchor = (Anchor)param;
                }
                else if (param is int)
                {
                    ps.Add(param.ToString());
                }
            }

            if (ps.Count > 0)
            {
                i.Parameters = ps;
            }

            Instructions.Add(i);
            Count++;
        }
示例#10
0
            public void AddInstruction(string bytes, string completeInstruction)
            {
                Instruction instruction = new Instruction();

                Instruction lastInstruction = Instructions.Count > 0 ? Instructions[Instructions.Count - 1] : null;

                if (lastInstruction != null)
                {
                    instruction.Offset = lastInstruction.Offset + lastInstruction.Bytes.Length;
                }

                bytes = bytes.Replace(" ", string.Empty);
                Debug.Assert(bytes.Length % 2 == 0);
                instruction.Bytes = new byte[bytes.Length / 2];

                for (int i = 0; i < instruction.Bytes.Length; i++)
                {
                    instruction.Bytes[i] = byte.Parse(bytes.Substring(i * 2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture);
                }

                instruction.CompleteInstruction = completeInstruction;

                int firstSpace = completeInstruction.IndexOf(' ');

                if (firstSpace >= 0)
                {
                    instruction.Mnemonic = completeInstruction.Substring(0, firstSpace);
                }

                Instructions.Add(instruction);
            }
示例#11
0
        public void ReadXml(XmlReader reader)
        {
            string t;

            Name    = reader.ReadElementString("Name");
            Author  = reader.ReadElementString("Author");
            Date    = reader.ReadElementString("Date");
            Version = reader.ReadElementString("Version");
            t       = reader.ReadElementString("Pin");
            if (t != null)
            {
                Pin = Int32.Parse(t);
            }
            t = reader.ReadElementString("StartOffset");
            if (t != null)
            {
                StartOffset = Int32.Parse(t);
            }
            reader.ReadElementString("StartOffset");
            while (reader.NodeType != XmlNodeType.EndElement)
            {
                reader.ReadStartElement("Instruction");
                Instruction i = new Instruction();
                i.Operation = OperationHelper.Parse(reader.ReadElementString("Operation"));
                i.Modifier  = (Modifier)Enum.Parse(typeof(Modifier), reader.ReadElementString("Modifier"));
                i.ModeA     = ModeHelper.Parse(reader.ReadElementString("ModeA"));
                i.ValueA    = Int32.Parse(reader.ReadElementString("ValueA"));
                i.ModeB     = ModeHelper.Parse(reader.ReadElementString("ModeB"));
                i.ValueB    = Int32.Parse(reader.ReadElementString("ValueB"));
                Instructions.Add(i);
                reader.ReadEndElement();
                reader.MoveToContent();
            }
        }
示例#12
0
 public void MarkLabel(Label lb)
 {
     if (!Instructions.Contains(lb))
     {
         Instructions.Add(lb);
     }
 }
示例#13
0
 private void ProduceDebuggerInstructions <TNode>(TNode node, Action <TNode> visit)
     where TNode : RdlSyntaxNode
 {
     Instructions.Add(new DebuggerTrap(node, DebuggerTrap.ExpressionState.Before, (n, m) => { }, (n, m) => { }));
     visit?.Invoke(node);
     Instructions.Add(new DebuggerTrap(node, DebuggerTrap.ExpressionState.After, (n, m) => { }, (n, m) => { }));
 }
        public MethodInformation(MethodDefinition def, MetadataContext metadataContext)
        {
            this.definition      = def;
            this.MetadataContext = metadataContext;

            if (def.HasBody)
            {
                foreach (var Inst in def.Body.Instructions)
                {
                    Instructions.Add(new InstructionInformation(Inst));
                }
                if (def.Body.HasVariables)
                {
                    foreach (var localVar in def.Body.Variables)
                    {
                        LocalVariables.Add(new VariableInformation(localVar, metadataContext));
                    }
                }
                if (def.HasParameters)
                {
                    foreach (ParameterDefinition param in def.Parameters)
                    {
                        Parameters.Add(new ParameterInformation(param, metadataContext));
                    }
                }
            }
        }
示例#15
0
        private void ParseInstructions(string[] originalInstructions)
        {
            for (int i = 0; i < originalInstructions.Length; i++)
            {
                var splitValues    = originalInstructions[i].Split(' ', StringSplitOptions.RemoveEmptyEntries);
                var newInstruction = new Instruction();
                newInstruction.Value = Convert.ToInt32(splitValues[1]);
                switch (splitValues[0])
                {
                case "nop":
                    newInstruction.Command = CommandName.nop;
                    break;

                case "jmp":
                    newInstruction.Command = CommandName.jmp;
                    break;

                case "acc":
                    newInstruction.Command = CommandName.acc;
                    break;

                default:
                    break;
                }
                Instructions.Add(newInstruction);
            }
        }
示例#16
0
        public Script(string instructions)
        {
            var lines = instructions.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var line in lines)
            {
                var tokens = line.Split(null, 2).Select(t => t.Trim().ToLower()).Where(t => !string.IsNullOrEmpty(t)).ToList();
                if (!FieldScript.OpCodesReverse.Keys.Contains(tokens[0]))
                {
                    throw new Exception("unrecognised operation in fieldscript file (" + instructions + "): " + line);
                }
                var instruction = new FieldScriptInstruction(FieldScript.OpCodesReverse[tokens[0]]);

                if (tokens.Count > 1)
                {
                    if (!int.TryParse(tokens[1], out int param))
                    {
                        throw new Exception("invalid parameter in fieldscript file (" + instructions + "): " + line);
                    }
                    instruction.Param    = param;
                    instruction.HasParam = true;
                }

                Instructions.Add(instruction);
            }
        }
示例#17
0
        public MethodInformation(MethodDefinition def, MetadataContext metadataContext)
        {
            this.definition      = def;
            this.MetadataContext = metadataContext;

            if (def.HasBody)
            {
                foreach (var Inst in def.Body.Instructions)
                {
                    Instructions.Add(new InstructionInformation(Inst));
                }
                if (def.Body.HasVariables)
                {
                    foreach (var localVar in def.Body.Variables)
                    {
                        LocalVariables.Add(new VariableInformation(localVar, metadataContext));
                    }
                }
            }
            if (def.HasParameters)
            {
                foreach (ParameterDefinition param in def.Parameters)
                {
                    Parameters.Add(new ParameterInformation(param, metadataContext));
                }
            }
            if (def.HasGenericParameters)
            {
                genericParameterTypes = def.GenericParameters.Select(a => MetadataContext.GetTypeInformation(a)).ToArray();
            }
        }
示例#18
0
        private bool StaticField(Class parent)
        {
            // Make sure this is a static field
            string fieldIdent = TokenStream.Peek().Value;

            if (!IsStaticField(fieldIdent, parent) || !TokenStream.Pass(fieldIdent))
            {
                return(false);
            }

            TokenStream.ReadWord();

            // Check if it's a static field
            Field field = GetField(fieldIdent, parent);

            if (!field.Static)
            {
                throw new CompilerException("Field '{0}' is not a static member of class '{1}'.", fieldIdent, parent.Name);
            }

            // Check visibility
            if (field.Visibility != AccessVisibility.Public && parent != currentClass)
            {
                throw new CompilerException("'{0}.{1}' is not visible here.", parent.Name, fieldIdent);
            }

            // Evaluate get
            Instructions.Add(new Instruction(Opcode.ClassGetFieldStatic, parent.Name + " " + fieldIdent));

            return(true);
        }
示例#19
0
        private bool StaticProperty(Class parent)
        {
            // Make sure this is a static property
            string propertyIdent = TokenStream.Peek().Value;

            if (!IsStaticProperty(propertyIdent, parent) || !TokenStream.Pass(propertyIdent))
            {
                return(false);
            }

            TokenStream.ReadWord();

            Method method = GetMethod("__get_" + propertyIdent, parent);

            if (method == null)
            {
                throw new CompilerException("Property '{0}' has no get accessor.", propertyIdent);
            }

            if (!method.Static)
            {
                throw new CompilerException("Property '{0}' is not a static member of class '{1}'.", propertyIdent, parent.Name);
            }

            if (method.Visibility != AccessVisibility.Public && parent != currentClass)
            {
                throw new CompilerException("Property '{0}' is not visible here.", propertyIdent);
            }

            // Evaluate get
            Instructions.Add(new Instruction(Opcode.ClassCallStatic, parent.Name + " " + method.Name, 0));

            return(true);
        }
示例#20
0
        private bool ConstReference(Class parent)
        {
            // Make sure this is a constant
            string ident = TokenStream.Peek().Value;

            if (!IsConstant(ident, parent) || !TokenStream.Pass(ident))
            {
                return(false);
            }

            TokenStream.ReadWord();

            // Check visibility
            Field constant = parent.Constants.First(c => c.Name == ident);

            if (constant.Visibility != AccessVisibility.Public && parent != currentClass)
            {
                throw new CompilerException("'{0}.{1}' is not visible here.", parent.Name, ident);
            }

            // Evaluate constants inline
            Instructions.Add(new Instruction(Opcode.Push, constant.Value));

            return(true);
        }
示例#21
0
        private void MethodCall(Class parent, Instruction refGetter)
        {
            string methodIdent = TokenStream.ReadWord();

            // Parse arguments
            int argumentsPassed = ArgumentList();

            // Check visibility
            Method method = GetMethod(methodIdent, argumentsPassed, parent);

            if (GetMethod(methodIdent, parent) == null)
            {
                throw new CompilerException("Method '{0}' is not a member of class '{1}'.", methodIdent, parent.Name);
            }

            if (method == null)
            {
                throw new CompilerException("No overload of method '{0}' in class '{1}' accepts {2} arguments.",
                                            methodIdent, parent.Name, argumentsPassed);
            }

            if (method.Visibility != AccessVisibility.Public && parent != currentClass)
            {
                throw new CompilerException("'{0}.{1}' is not visible here.", parent.Name, methodIdent);
            }

            // Evaluate call
            Instructions.Add(refGetter);

            Instructions.Add(new Instruction(Opcode.ClassCall, methodIdent, argumentsPassed));
        }
示例#22
0
        private void PrimaryReference()
        {
            int refIndex = TokenStream.Position;

            GetReference();

            if (TokenStream.Accept(TokenType.Delimiter, "++"))
            {
                TokenStream.Position = refIndex;
                GetReference();
                Instructions.Add(new Instruction(Opcode.Push, 1));
                Instructions.Add(new Instruction(Opcode.Add));
                TokenStream.Position = refIndex;
                SetReference();

                TokenStream.Read();
            }
            else if (TokenStream.Accept(TokenType.Delimiter, "--"))
            {
                TokenStream.Position = refIndex;
                GetReference();
                Instructions.Add(new Instruction(Opcode.Push, 1));
                Instructions.Add(new Instruction(Opcode.Subtract));
                TokenStream.Position = refIndex;
                SetReference();

                TokenStream.Read();
            }
        }
示例#23
0
 public static void Join(this Instructions instructions, Instructions join, bool overwrite = false)
 {
     foreach (var key in join.AllKeys)
     {
         var hasKey = instructions.AllKeys.Any(k => k == key);
         if (overwrite && hasKey)
         {
             instructions.Remove(key);
             instructions.Add(key, join[key]);
         }
         else if (!hasKey)
         {
             instructions.Add(key, join[key]);
         }
     }
 }
示例#24
0
        void InventoryPage_draw()
        {
            var code = BeginCode();

            // var yoffset = yPositionOnScreen + borderWidth + spaceToClearTopBorder + Game1.tileSize
            var yoffset = generator.DeclareLocal(typeof(int));

            code.Prepend(
                Instructions.Ldarg_0(),
                Instructions.Ldfld(typeof(IClickableMenu), nameof(IClickableMenu.yPositionOnScreen)),
                Instructions.Ldsfld(typeof(IClickableMenu), nameof(IClickableMenu.borderWidth)),
                Instructions.Add(),
                Instructions.Ldsfld(typeof(IClickableMenu), nameof(IClickableMenu.spaceToClearTopBorder)),
                Instructions.Add(),
                Instructions.Ldc_I4_S(Game1.tileSize),
                Instructions.Add(),
                Instructions.Stloc_S(yoffset)
                );

            // Replace all remaining `yPositionOnScreen + borderWidth + spaceToClearTopBorder` by `yoffset`.
            for (var i = 0; i < 12; i++)
            {
                code = code.FindNext(
                    OpCodes.Ldarg_0,
                    Instructions.Ldfld(typeof(IClickableMenu), nameof(IClickableMenu.yPositionOnScreen)),
                    Instructions.Ldsfld(typeof(IClickableMenu), nameof(IClickableMenu.borderWidth)),
                    OpCodes.Add,
                    Instructions.Ldsfld(typeof(IClickableMenu), nameof(IClickableMenu.spaceToClearTopBorder)),
                    OpCodes.Add
                    );
                code.Replace(
                    Instructions.Ldloc_S(yoffset)
                    );
            }
        }
示例#25
0
 public ConsolePlayer(string[] instructions)
 {
     foreach (var instr in instructions)
     {
         var instruction = GetInstruction(instr);
         Instructions.Add(instruction);
     }
 }
示例#26
0
        /// <summary>
        /// Appends an instruction with the given parameters.
        /// If this block already has a defined exit, does nothing.
        /// </summary>
        public void AppendInstruction(Opcode opcode, ulong left, ushort right, ushort destination)
        {
            if (HasDefinedExitBehavior)
            {
                return;
            }

            Instructions.Add(new Instruction(opcode, left, right, destination));
        }
示例#27
0
        public MethodInformation(MethodDefinition def)
        {
            this.definition = def;

            foreach (var Inst in def.Body.Instructions)
            {
                Instructions.Add(new InstructionInformation(Inst));
            }
        }
示例#28
0
 public void ParseProgram(IEnumerable <string> rows)
 {
     Instructions.Clear();
     foreach (var row in rows)
     {
         var ins = Instruction.CreateCmd(row);
         Instructions.Add(ins);
     }
 }
示例#29
0
        private bool ForStatement()
        {
            if (!TokenStream.Accept(TokenType.Word, "for"))
            {
                return(false);
            }

            Label labelStart    = new Label(this);
            Label labelEnd      = new Label(this);
            Label labelContinue = new Label(this);

            continueStack.Push(labelContinue);
            breakStack.Push(labelEnd);

            TokenStream.Expect(TokenType.Delimiter, "(");
            if (!Variable())
            {
                Assignment();
            }

            TokenStream.Accept(TokenType.Delimiter, ";");

            labelStart.Mark();
            Assignment();
            Instructions.Add(new Instruction(Opcode.Push, 1));
            Instructions.Add(new Instruction(Opcode.CompareNotEqual));
            Instructions.Add(new Instruction(Opcode.IfTrue, 0));
            labelEnd.PatchHere();
            TokenStream.Accept(TokenType.Delimiter, ";");

            TokenStream.PushPosition();
            while (!TokenStream.Accept(TokenType.Delimiter, ")"))
            {
                TokenStream.Read();
            }

            Block();
            int endOfBlock = TokenStream.Position;

            TokenStream.PopPosition();
            labelContinue.Mark();
            Assignment();
            TokenStream.Position = endOfBlock;

            Instructions.Add(new Instruction(Opcode.Jump, 0));
            labelStart.PatchHere();
            labelEnd.Mark();

            labelContinue.Fix();
            labelStart.Fix();
            labelEnd.Fix();
            continueStack.Pop();
            breakStack.Pop();

            return(true);
        }
示例#30
0
 void ShopMenu_drawCurrency()
 {
     FindCode(
         Instructions.Ldc_I4_S(12),
         OpCodes.Sub
         ).Replace(
         Instructions.Ldc_I4_S(64 - 12),
         Instructions.Add()
         );
 }