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++; } }