Beispiel #1
0
		public JumpCommand(AsmInterpreter interpreter, string[] lineParts)
			: base(interpreter, lineParts)
		{
			string comparisonName = lineParts[0];
			string labelName;
			if (comparisonName == "jmp")
			{
				comp = GetComparisonDelegation(comparisonName);
				labelName = lineParts[1];
			}
			else
			{
				string operandLeftName = lineParts[1];
				string operandRightName = lineParts[2];
				labelName = lineParts[3];

				ComparisonDelegation delegation = GetComparisonDelegation(comparisonName);
				if (delegation == null)
					throw new InvalidOperationException("Invalid comparison operator.");
				comp = delegation;

				ValueStorage vs = null;
				vs = parent.GetVariableByName(operandLeftName);
				if (vs == null)
				{
					vs = parent.GetRegisterByName(operandLeftName);
					if (vs == null)
					{
						vs = parent.GetStackValueFromTop(operandLeftName);
						if (vs == null)
						{
							float number = 0.0f;
							if (float.TryParse(operandLeftName, out number))
							{
								vs = new ValueStorage();
								vs.SetValue(number);
								parent.m_constants.Add(vs);
							}
						}
					}
				}
				if (vs == null)
					throw new InvalidOperationException("Invalid comparison left operand.");
				operandLeft = vs;

				vs = null;
				vs = parent.GetVariableByName(operandRightName);
				if (vs == null)
				{
					vs = parent.GetRegisterByName(operandRightName);
					if (vs == null)
					{
						vs = parent.GetStackValueFromTop(operandRightName);
						if (vs == null)
						{
							float number = 0.0f;
							if (float.TryParse(operandRightName, out number))
							{
								vs = new ValueStorage();
								vs.SetValue(number);
								parent.m_constants.Add(vs);
							}
						}
					}
				}
				if (vs == null)
					throw new InvalidOperationException("Invalid comparison right operand.");
				operandRight = vs;
			}

			JumpLabel label = parent.GetJumpLabelByName(labelName);
			if (label == null)
				throw new InvalidOperationException("Invalid jump target.");
			target = label;
		}
        public void LoadString(string codeStr)
        {
            Clear();
            string[] lines = codeStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

            // First remove all comments.
            bool inCommentBody = false;
            for(int i = 0; i < lines.Length; i++)
            {
                if (inCommentBody == false)
                {
                    int commentStartIdx = lines[i].IndexOf("/*");
                    int commentLineIdx = lines[i].IndexOf("//");
                    if (commentStartIdx >= 0 && commentLineIdx >= 0)
                    {
                        if (commentStartIdx > commentLineIdx)
                        {
                            // The line is commented.
                            lines[i] = lines[i].Substring(0, commentLineIdx);
                        }
                        else
                        {
                            // The comment body starts.
                            lines[i] = lines[i].Substring(0, commentStartIdx);
                            inCommentBody = true;
                            i--;
                        }
                    }
                    else
                    {
                        if (commentStartIdx >= 0)
                        {
                            // The comment body start exists.
                            lines[i] = lines[i].Substring(0, commentStartIdx);
                            inCommentBody = true;
                            i--;
                        }
                        else if (commentLineIdx >= 0)
                        {
                            // The comment line exists.
                            lines[i] = lines[i].Substring(0, commentLineIdx);
                        }
                    }
                }
                else
                {
                    // In comment body. Only focus on comment end.
                    if (lines[i].Contains("*/"))
                    {
                        lines[i] = lines[i].Substring(lines[i].IndexOf("*/") + 2);
                        inCommentBody = false;
                        i--;
                    }
                    else
                    {
                        lines[i] = "";
                    }
                }
            }

            // Second pick all labels.
            int lineIndex = 0;
            List<string> codeLines = new List<string>();
            foreach (string line in lines)
            {
                if (line.EndsWith(":"))
                {
                    JumpLabel newLabel = new JumpLabel();
                    newLabel.instructionIndexOfNextLine = lineIndex;
                    newLabel.labelName = line.Substring(0, line.Length - 1).TrimStart(' ', '\t');
                    m_labels.Add(newLabel);
                }
                else
                {
                    if (line.Trim() == "")
                        continue;

                    lineIndex++;
                    codeLines.Add(line.TrimStart(' ', '\t').TrimEnd(' ', '\t'));
                }
            }

            // Now analyze all code lines.
            lineIndex = 0;
            foreach(string codeLine in codeLines)
            {
                string[] lineParts = codeLine.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries);
                if (lineParts[0].Equals("var", StringComparison.CurrentCultureIgnoreCase))
                {
                    string name = lineParts[1];
                    if (m_namedVariables.Exists((NamedValueStorage nvs) => { return nvs.name == name; }) == false)
                    {
                        float value = 0.0f;
                        if (lineParts.Length == 4 && lineParts[2] == "=")
                        {
                            value = Convert.ToSingle(lineParts[3]);
                        }
                        NamedValueStorage newNamedValueStorage = new NamedValueStorage(name, value);
                        m_namedVariables.Add(newNamedValueStorage);
                    }

                    NoOperationCommand newCmd = new NoOperationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if(lineParts[0].Equals("mov", StringComparison.CurrentCultureIgnoreCase))
                {
                    AssignmentCommand newCmd = new AssignmentCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts.Length == 3 && lineParts[1].Equals("=", StringComparison.CurrentCultureIgnoreCase))
                {
                    AssignmentCommand newCmd = new AssignmentCommand(this, new string[] { "mov", lineParts[0], lineParts[2] });
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("add", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts.Length == 3 && lineParts[1].Equals("+=", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, new string[] { "add", lineParts[0], lineParts[2] });
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("sub", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts.Length == 3 && lineParts[1].Equals("-=", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, new string[] { "sub", lineParts[0], lineParts[2] });
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("mul", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts.Length == 3 && lineParts[1].Equals("*=", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, new string[] { "mul", lineParts[0], lineParts[2] });
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("div", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts.Length == 3 && lineParts[1].Equals("/=", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, new string[] { "div", lineParts[0], lineParts[2] });
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("mod", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts.Length == 3 && lineParts[1].Equals("%=", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, new string[] { "mod", lineParts[0], lineParts[2] });
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("pow", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts.Length == 3 && lineParts[1].Equals("^=", StringComparison.CurrentCultureIgnoreCase))
                {
                    CalculationCommand newCmd = new CalculationCommand(this, new string[] { "pow", lineParts[0], lineParts[2] });
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("jmp", StringComparison.CurrentCultureIgnoreCase))
                {
                    JumpCommand newCmd = new JumpCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("je", StringComparison.CurrentCultureIgnoreCase))
                {
                    JumpCommand newCmd = new JumpCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("jne", StringComparison.CurrentCultureIgnoreCase))
                {
                    JumpCommand newCmd = new JumpCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("jb", StringComparison.CurrentCultureIgnoreCase))
                {
                    JumpCommand newCmd = new JumpCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("jl", StringComparison.CurrentCultureIgnoreCase))
                {
                    JumpCommand newCmd = new JumpCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("jbe", StringComparison.CurrentCultureIgnoreCase))
                {
                    JumpCommand newCmd = new JumpCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("jle", StringComparison.CurrentCultureIgnoreCase))
                {
                    JumpCommand newCmd = new JumpCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("if", StringComparison.CurrentCultureIgnoreCase))
                {
                    int correspondingNode = FindCorrespondingEndNode(codeLines, lineIndex);
                    if (correspondingNode == -1)
                        throw new InvalidOperationException("Invalid if block.");
                    IfCommand newCmd = new IfCommand(this, lineParts);
                    newCmd.targetInstructionIndex = correspondingNode;
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("else", StringComparison.CurrentCultureIgnoreCase))
                {
                    NoOperationCommand newCmd = new NoOperationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("while", StringComparison.CurrentCultureIgnoreCase))
                {
                    int correspondingNode = FindCorrespondingEndNode(codeLines, lineIndex);
                    if (correspondingNode == -1)
                        throw new InvalidOperationException("Invalid while block.");
                    IfCommand newCmd = new IfCommand(this, lineParts);
                    newCmd.targetInstructionIndex = correspondingNode + 1;
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("end", StringComparison.CurrentCultureIgnoreCase))
                {
                    string startNodeType = "";
                    int correspondingNode = FindCorrespondingStartNode(codeLines, lineIndex, out startNodeType);
                    if (correspondingNode == -1)
                        throw new InvalidOperationException("Invalid end block.");
                    if (startNodeType == "if")
                    {
                        EndCommand newCmd = new EndCommand(this, lineParts);
                        m_commands.Add(newCmd);
                    }
                    else if (startNodeType == "while")
                    {
                        EndCommand newCmd = new EndCommand(this, lineParts);
                        newCmd.loopInstructionIndex = correspondingNode;
                        m_commands.Add(newCmd);
                    }
                }
                else if (lineParts[0].Equals("push", StringComparison.CurrentCultureIgnoreCase))
                {
                    PushCommand newCmd = new PushCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("pop", StringComparison.CurrentCultureIgnoreCase))
                {
                    PopCommand newCmd = new PopCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("yield", StringComparison.CurrentCultureIgnoreCase))
                {
                    YieldCommand newCmd = new YieldCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                else if (lineParts[0].Equals("nop", StringComparison.CurrentCultureIgnoreCase))
                {
                    NoOperationCommand newCmd = new NoOperationCommand(this, lineParts);
                    m_commands.Add(newCmd);
                }
                //else if (lineParts[0].Equals("trig", StringComparison.CurrentCultureIgnoreCase))
                //{
                //    // Need to implement this later.
                //    NoOperationCommand newCmd = new NoOperationCommand(this, lineParts);
                //    m_commands.Add(newCmd);
                //}
                else
                {
                    if (UserCommandModuleHandler.HandleUserCommand(this, codeLines, lineIndex, lineParts) == false)
                    {
                        throw new InvalidOperationException("Unknown command.");
                    }
                }

                lineIndex++;
            }
        }