public override PsudoInstruction CopyTo(PsudoMethod newMethod) { CallMethodInstruction clone = new CallMethodInstruction(this.Line, newMethod, this.methodName); clone.Arguments = this.Arguments; return(clone); }
public CreateLocalVariable(int lineNumber, PsudoMethod method, string type, string name, string defaultValue) : base(lineNumber, method) { this.type = type; this.name = name; this.defaultValue = defaultValue; }
public override PsudoInstruction Run() { PsudoMethod method = this.Method.GetMethod(this.methodName); method.Program = this.Method.Program; this.Method.Program.callStack.Push(method); if (Arguments.Count != method.ArgumentNames.Count) { this.Method.Program.OnError("Incorrect number of parameters"); return(null); } for (int i = 0; i < Arguments.Count; i++) { method.CreateVariable(method.ArgumentNames[i], this.Method.GetVariable(Arguments[i].Trim())); if (method.ArgumentTypes[i] == "num" && method.GetVariable(method.ArgumentNames[i]) is string) { method.SetVariable(method.ArgumentNames[i], Convert.ToDouble(Arguments[i])); } else if (method.ArgumentTypes[i] == "string" && method.GetVariable(method.ArgumentNames[i]) is double) { method.SetVariable(method.ArgumentNames[i], this.Method.GetVariable(Arguments[i]).ToString()); } } method.Run(this.Method.Program); this.Method.Program.callStack.Pop(); return(null); }
public DecisionInstruction(int lineNumber, PsudoMethod method, string exp) : base(lineNumber, method) { this.expression = InstructionFactory.CleanupExpression(exp); expTree = new PseudoCodeCompiler.ExpressionTree.ExpressionTree(this.expression); }
protected PsudoMethod CompileMethod(PsudoMethodInfo mInfo, PsudoClassInfo pClassInfo, PsudoClass pClass) { PsudoMethod method = new PsudoMethod(mInfo.Name, pClass); mInfo.ParentClass = pClassInfo; mInfo.Processed = true; if (mInfo.Name != "Main") { Match value = Regex.Match(codeLines[mInfo.StartLine], @"(?<=[(])[a-zA-Z0-9_,\s -]*(?=[)])", RegexOptions.IgnoreCase); string[] args = value.Value.Split(','); foreach (string arg in args) { if (arg.Trim().Length > 0) { Match typeMatch = Regex.Match(arg, @"(string|num)", RegexOptions.IgnoreCase); Match match = Regex.Match(arg, @"(?<=(string|num))[\s]*[a-zA-Z0-9_-]*", RegexOptions.IgnoreCase); method.ArgumentTypes.Add(typeMatch.Value.Trim().ToLower()); method.ArgumentNames.Add(match.Value.Trim().ToLower()); } } } method.Instructions = CompileBlock(method, mInfo.StartLine, mInfo.EndLine); return(method); }
public virtual PsudoInstruction CopyTo(PsudoMethod newMethod) { // by default this will work but where needed we can override. PsudoInstruction copy = this.MemberwiseClone() as PsudoInstruction; copy.Method = newMethod; return(copy); }
public MathmaticAssignmentInstruction(int lineNumber, PsudoMethod method, string variable, string exp) : base(lineNumber, method) { this.variable = variable; this.expression = InstructionFactory.CleanupExpression(exp); expTree = new PseudoCodeCompiler.ExpressionTree.ExpressionTree(this.expression); }
public override PsudoInstruction CopyTo(PsudoMethod newMethod) { BlockInstruction clone = new BlockInstruction(this.Line, newMethod); clone.Instructions = new List <PsudoInstruction>(); foreach (PsudoInstruction ins in this.Instructions) { clone.Instructions.Add(ins.CopyTo(newMethod)); } return(clone); }
public override PsudoInstruction CopyTo(PsudoMethod newMethod) { WhileLoopInstruction clone = new WhileLoopInstruction(this.Line, newMethod, this.expression); clone.Instructions = new List <PsudoInstruction>(); foreach (PsudoInstruction ins in this.Instructions) { clone.Instructions.Add(ins.CopyTo(newMethod)); } return(clone); }
public PromptInstruction(int lineNumber, PsudoMethod method, params string[] variables) : base(lineNumber, method) { this.variables = variables; foreach (string var in variables) { if (!VariableRegex.IsMatch(var)) { throw new Exception("Illegal Variable Name: \"" + var + "\""); } } }
public override PsudoInstruction CopyTo(PsudoMethod newMethod) { DecisionInstruction clone = new DecisionInstruction(this.Line, newMethod, this.expression); clone.FalseInstruction = this.FalseInstruction.CopyTo(newMethod); clone.EndInstruction = this.EndInstruction.CopyTo(newMethod); clone.Instructions = new List <PsudoInstruction>(); foreach (PsudoInstruction ins in this.Instructions) { clone.Instructions.Add(ins.CopyTo(newMethod)); } return(clone); }
private PsudoInstruction CompileCase(PsudoMethod method, string variable, int start, out int endLine) { int nextStart = codeLines.ToList().FindIndex(start + 1, item => item.Contains(":") || Regex.IsMatch(item, @"^[\s]*\b(endcase)\b[\s]*", RegexOptions.IgnoreCase) ); if (nextStart < 0) { throw new Exception("CASE found with no ENDCASE"); } string[] parts = codeLines[start].Split(':'); string lineBackup = codeLines[start]; // Do this to help the compiler codeLines[start] = parts[1].Trim(); if (parts[0].Trim().ToLower().Contains("other")) { BlockInstruction ins = new BlockInstruction(start, method); ins.Instructions = CompileBlock(method, start, nextStart - 1); endLine = nextStart; codeLines[start] = lineBackup; return(ins); } else { string decision = variable + "==" + parts[0].Trim(); DecisionInstruction ins = new DecisionInstruction(start, method, decision); ins.Instructions = CompileBlock(method, start, nextStart - 1); if (codeLines[nextStart].ToLower().Contains("endcase")) { endLine = nextStart; ins.FalseInstruction = new NoOpInstruction(endLine, method); } else { ins.FalseInstruction = CompileCase(method, variable, nextStart, out endLine); } ins.EndInstruction = new NoOpInstruction(endLine, method); codeLines[start] = lineBackup; return(ins); } }
public override PsudoInstruction CopyTo(PsudoMethod newMethod) { if (!this.Instructions.Contains(this.InitInstruction)) { this.Instructions.Add(this.InitInstruction); } ForLoopInstruction clone = new ForLoopInstruction(this.Line, newMethod, this.expression, this.InitInstruction); clone.InitInstruction = this.InitInstruction.CopyTo(newMethod); clone.Instructions = new List <PsudoInstruction>(); foreach (PsudoInstruction ins in this.Instructions) { clone.Instructions.Add(ins.CopyTo(newMethod)); } return(clone); }
public DoLoopInstruction(int lineNumber, PsudoMethod method, string exp) : base(lineNumber, method, exp) { }
public PsudoInstruction(int lineNumber, PsudoMethod method) { this.Line = lineNumber; this.Method = method; }
public ReturnInstruction(int lineNumber, PsudoMethod method) : base(lineNumber, method) { }
public BlockInstruction(int lineNumber, PsudoMethod method) : base(lineNumber, method) { }
private ForLoopInstruction(int lineNumber, PsudoMethod method, string expression, PsudoInstruction init) : base(lineNumber, method, expression) { InitInstruction = init.CopyTo(method); }
public AbstractAssignmentInstruction(int lineNumber, PsudoMethod method) : base(lineNumber, method) { }
public ForLoopInstruction(int lineNumber, PsudoMethod method, string variable, string initVal, string endVal) : base(lineNumber, method, variable + " <= " + endVal) { InitInstruction = new AssignVariable(lineNumber, method, variable, initVal); UpdateInstruction = new MathmaticAssignmentInstruction(lineNumber, method, variable, variable + " + 1"); }
public CallMethodInstruction(int lineNumber, PsudoMethod method, string methodName) : base(lineNumber, method) { this.methodName = methodName; this.Arguments = new List <string>(); }
public AssignVariable(int lineNumber, PsudoMethod method, string variable, string value) : base(lineNumber, method) { this.variable = variable; this.value = value; }
private static PsudoInstruction RealCompileInstruction(string line, int lineNum, PsudoMethod method) { string args = ""; string variableRegex = VariableRegexString; if (CheckSimpleCommand(line, "read", out args)) { string[] vars = SplitVariableLiteralList(args); return(new ReadInstruction(lineNum, method, vars)); } else if (CheckSimpleCommand(line, "get", out args)) { if (lastInstruction is PromptInstruction) { return(new NoOpInstruction(lineNum, method)); } throw new Exception("Cannot use get without a prompt command"); } else if (CheckSimpleCommand(line, "print", out args) || CheckSimpleCommand(line, "write", out args) || CheckSimpleCommand(line, "output", out args) || CheckSimpleCommand(line, "put", out args) || CheckSimpleCommand(line, "display", out args) ) { string[] vars = SplitVariableLiteralList(args); return(new PrintInstruction(lineNum, method, vars)); } else if (CheckSimpleCommand(line, "prompt", out args) || CheckSimpleCommand(line, "input", out args)) { string withoutFor = args.Trim(); if (args.Trim().StartsWith("for")) { withoutFor = withoutFor.Substring(3).Trim(); } string[] vars = SplitVariableLiteralList(withoutFor); return(new PromptInstruction(lineNum, method, vars)); } else if (CheckSimpleCommand(line, "add", out args)) { string oper = "+"; // This should be in the format "add number to total" Match number = Regex.Match(args, @"^[\s]*\b" + variableRegex + @"\b[\s]+(?=([\s]*\b(to)\b[\s]*))", RegexOptions.IgnoreCase); Match total = Regex.Match(args, @"(?<=([\s]*\b(to)\b[\s]*))\b" + variableRegex + @"\b[\s]*", RegexOptions.IgnoreCase); if (!number.Success || !total.Success) { throw new Exception("Invalid Operation Arguments on " + lineNum); } string expression = total.Value + oper + number.Value; return(new MathmaticAssignmentInstruction(lineNum, method, total.Value.Trim(), expression)); } else if (CheckSimpleCommand(line, "subtract", out args)) { string oper = "-"; // This should be in the format "add number to total" Match number = Regex.Match(args, @"^[\s]*\b" + variableRegex + @"\b[\s](?=([\s]*\b(from)\b[\s]*))", RegexOptions.IgnoreCase); Match total = Regex.Match(args, @"(?<=([\s]*\b(from)\b[\s]*))\b" + variableRegex + @"\b[\s]*", RegexOptions.IgnoreCase); if (!number.Success || !total.Success) { throw new Exception("Invalid Operation Arguments on " + lineNum); } string expression = total.Value + oper + number.Value; return(new MathmaticAssignmentInstruction(lineNum, method, total.Value.Trim(), expression)); } else if (CheckSimpleCommand(line, "multiply", out args)) { string oper = "*"; // This should be in the format "add number to total" Match total = Regex.Match(args, @"^[\s]*\b" + variableRegex + @"\b[\s](?=([\s]*\b(by)\b[\s]*))", RegexOptions.IgnoreCase); Match number = Regex.Match(args, @"(?<=([\s]*\b(by)\b[\s]*))\b" + variableRegex + @"\b[\s]*", RegexOptions.IgnoreCase); if (!number.Success || !total.Success) { throw new Exception("Invalid Operation Arguments on " + lineNum); } string expression = total.Value + oper + number.Value; return(new MathmaticAssignmentInstruction(lineNum, method, total.Value.Trim(), expression)); } else if (CheckSimpleCommand(line, "divide", out args)) { string oper = "/"; // This should be in the format "add number to total" Match total = Regex.Match(args, @"^[\s]*\b" + variableRegex + @"\b[\s](?=([\s]*\b(by)\b[\s]*))", RegexOptions.IgnoreCase); Match number = Regex.Match(args, @"(?<=([\s]*\b(by)\b[\s]*))\b" + variableRegex + @"\b[\s]*", RegexOptions.IgnoreCase); if (!number.Success || !total.Success) { throw new Exception("Invalid Operation Arguments on " + lineNum); } string expression = total.Value + oper + number.Value; return(new MathmaticAssignmentInstruction(lineNum, method, total.Value.Trim(), expression)); } else if (CheckSimpleCommand(line, "initialize", out args) || CheckSimpleCommand(line, "set", out args)) { // This should be in the format "set number to total" Match name = Regex.Match(args, @"^[\s]*\b" + variableRegex + @"\b[\s](?=([\s]*\b(to)\b[\s]*))", RegexOptions.IgnoreCase); Match value = Regex.Match(args, @"(?<=([\s]*to[\s]*))\b" + variableRegex + @"\b[\s]*", RegexOptions.IgnoreCase); if (!value.Success || !name.Success) { throw new Exception("Invalid Operation Arguments on " + lineNum); } return(new AssignVariable(lineNum, method, name.Value.Trim(), value.Value.Trim())); } // Simple Assignment Instructions else if ( // check for normal assignment Regex.IsMatch(line, @"^[\s]*" + variableRegex + @"[\s]*=[\s]*[$]*[a-zA-Z0-9._ ,]*[\s]*$", RegexOptions.IgnoreCase) // check for string literals || Regex.IsMatch(line, @"^[\s]*" + variableRegex + @"[\s]*=[\s]*" + "[\\'\"]" + @"[a-zA-Z0-9_' -]*" + "[\\'\"]" + @"[\s]*$", RegexOptions.IgnoreCase) ) { Match name = Regex.Match(line, @"^[\s]*" + variableRegex + @"[\s]*=", RegexOptions.IgnoreCase); Match value = Regex.Match(line, @"(?<=(=[\s]))*[$]*[a-zA-Z0-9._," + '"' + @"' -]*[\s]*$", RegexOptions.IgnoreCase); // This is a simple assignment to either a variable or literal return(new AssignVariable(lineNum, method, name.Value.Trim('=').Trim(), value.Value.Trim())); } // Mathmatic assignment else if (Regex.IsMatch(line, @"^[\s]*" + variableRegex + @"[\s]*=[\s]*[a-zA-Z0-9.()\s" + "\"" + @"_+-/*,]*[\s]*$", RegexOptions.IgnoreCase)) { Match name = Regex.Match(line, @"^[\s]*" + variableRegex + @"[\s]", RegexOptions.IgnoreCase); Match value = Regex.Match(line, @"(?<=(=[\s]))*[a-zA-Z0-9._ ()" + "\"" + @"+-/*,]*[\s]*$", RegexOptions.IgnoreCase); // This is a simple assignment to either a variable or literal return(new MathmaticAssignmentInstruction(lineNum, method, name.Value.Trim(), value.Value.Trim())); } // Simple Call Method else if (Regex.IsMatch(line, @"^[\s]*[\s]*[a-zA-Z0-9_]*[\s]*$", RegexOptions.IgnoreCase)) { string name = line.Trim(); CallMethodInstruction ins = new CallMethodInstruction(lineNum, method, name.Trim()); return(ins); } throw new Exception(string.Format( "Invalid Instruction in Method \"{0}\"", method.Name)); }
public PrintInstruction(int lineNumber, PsudoMethod method, params string[] variables) : base(lineNumber, method) { this.variables = variables; }
protected PsudoInstruction CompileLoop(PsudoMethod method, int line, out int endLine) { if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(while|dowhile)\b[\s]*", RegexOptions.IgnoreCase)) { string decision = codeLines[line].Trim(); if (decision.ToLower().StartsWith("dowhile")) { decision = decision.Substring(7).Trim(); } else { decision = decision.Substring(5).Trim(); } WhileLoopInstruction ins = new WhileLoopInstruction(line, method, decision); //int end = codeLines.ToList().FindIndex(line, item => Regex.IsMatch(item, @"^[\s]*\b(endwhile|enddo)\b[\s]*", RegexOptions.IgnoreCase)); int end = FindNestedEnd(line, "(while|dowhile|do)", "(endwhile|enddo)"); if (end < 0) { throw new Exception("WHILE found with no ENDWHILE"); } ins.Instructions = CompileBlock(method, line + 1, end - 1); endLine = end; return(ins); } if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(repeat)\b[\s]*", RegexOptions.IgnoreCase)) { //int end = codeLines.ToList().FindIndex(line, item => Regex.IsMatch(item, @"^[\s]*\b(until)\b[\s]*", RegexOptions.IgnoreCase)); int end = FindNestedEnd(line, "(repeat)", "(until)"); if (end < 0) { throw new Exception("REPEAT found with no UNTIL"); } string decision = codeLines[end].Trim(); decision = decision.Substring(5).Trim(); DoLoopInstruction ins = new DoLoopInstruction(line, method, decision); ins.Instructions = CompileBlock(method, line + 1, end - 1); endLine = end; return(ins); } if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(do)\b[\s]*", RegexOptions.IgnoreCase)) { string decision = codeLines[line].Trim(); Match variable = Regex.Match(decision, @"(?<=do[\s]+)[a-zA-Z0-9_()-]+", RegexOptions.IgnoreCase); Match initVal = Regex.Match(decision, @"(?<=[=][\s]*)[a-zA-Z0-9_()-]+(?=[\s]*(to))", RegexOptions.IgnoreCase); Match endVal = Regex.Match(decision, @"(?<=\b(to)\b[\s]*)[a-zA-Z0-9_()-]+", RegexOptions.IgnoreCase); if (!variable.Success || !initVal.Success || !endVal.Success) { throw new Exception("Error in Do Loop Formatting"); } //int end = codeLines.ToList().FindIndex(line, item => Regex.IsMatch(item, @"^[\s]*\b(enddo)\b[\s]*", RegexOptions.IgnoreCase)); int end = FindNestedEnd(line, "(do|while|dowhile|do)", "(enddo)"); if (end < 0) { throw new Exception("DO found with no ENDDO"); } ForLoopInstruction ins = new ForLoopInstruction(line, method, variable.Value.Trim(), initVal.Value.Trim(), endVal.Value.Trim()); ins.Instructions = CompileBlock(method, line + 1, end - 1); endLine = end; return(ins); } endLine = line; return(null); }
protected PsudoInstruction CompileDecision(PsudoMethod method, int line, out int endLine) { if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(if|elseif)\b[\s]*", RegexOptions.IgnoreCase)) { string decision = codeLines[line].Trim(); if (decision.ToLower().Contains("elseif")) { decision = decision.Substring(6); } else { decision = decision.Substring(2); } while (!decision.ToLower().Contains("then")) { if (line + 1 == codeLines.Length || Regex.IsMatch(codeLines[line + 1], @"^[\s]*\b(else|elseif|endif)\b[\s]*", RegexOptions.IgnoreCase) ) { throw new Exception("IF found without THEN"); } decision += " " + codeLines[line + 1]; line += 1; } decision = decision.Trim(); decision = decision.Substring(0, decision.Length - 4).Trim(); DecisionInstruction ins = new DecisionInstruction(line, method, decision); int next = -1; int end = -1; int nested = 0; for (int num = line + 1; num < codeLines.Length; num++) { string item = codeLines[num]; if (Regex.IsMatch(item, @"^[\s]*\b(if)\b[\s]*", RegexOptions.IgnoreCase)) { nested++; } if (Regex.IsMatch(item, @"^[\s]*\b(endif)\b[\s]*", RegexOptions.IgnoreCase)) { if (nested == 0) { if (next < 0) { next = num; } end = num; } else { nested--; } } if (nested == 0 && next < 0) { if (Regex.IsMatch(item, @"^[\s]*\b(elseif|else)\b[\s]*", RegexOptions.IgnoreCase)) { next = num; } } } if (end < 0) { throw new Exception("IF found with no ENDIF"); } ins.Instructions = CompileBlock(method, line + 1, next - 1); int temp; ins.FalseInstruction = CompileDecision(method, next, out temp); ins.EndInstruction = CompileDecision(method, end, out temp); endLine = end; return(ins); } else if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(else)\b[\s]*", RegexOptions.IgnoreCase)) { BlockInstruction ins = new BlockInstruction(line, method); int next = codeLines.ToList().FindIndex(line, item => Regex.IsMatch(item, @"^[\s]*\b(endif)\b[\s]*", RegexOptions.IgnoreCase)); ins.Instructions = CompileBlock(method, line + 1, next - 1); endLine = next; return(ins); } else if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(endif)\b[\s]*", RegexOptions.IgnoreCase)) { endLine = line; return(new NoOpInstruction(line, method)); } else if (Regex.IsMatch(codeLines[line], @"^[\s]*\b(case of|case)\b[\s]*", RegexOptions.IgnoreCase)) { // Trim of case/case of string variable = Regex.Replace(codeLines[line], @"\b(case of|case)\b", "").Trim(); int start = codeLines.ToList().FindIndex(line + 1, item => item.Contains(":")); if (start < 0) { throw new Exception("CASE Statement contains no options or options are formmed incorrectly"); } return(CompileCase(method, variable, start, out endLine)); } endLine = line; return(null); }
protected List <PsudoInstruction> CompileBlock(PsudoMethod method, int startLine, int endLine) { List <PsudoInstruction> list = new List <PsudoInstruction>(); for (int i = startLine; i <= endLine; i++) { try { switch (this.scanner.lineTypes[i]) { case PsudoLineType.Variable: PsudoVariableInfo vInfo = this.scanner.variableInfo.Find( item => item.Line == i); vInfo.Processed = true; list.Add(new CreateLocalVariable(i, method, vInfo.Type, vInfo.Name, vInfo.Default)); break; case PsudoLineType.StartDecision: case PsudoLineType.StartStartDecision: int end; list.Add(CompileDecision(method, i, out end)); i = end; break; case PsudoLineType.StartLoop: int end2; list.Add(CompileLoop(method, i, out end2)); i = end2; break; case PsudoLineType.Instruction: list.Add(InstructionFactory.CompileInstruction( this.codeLines[i], i, method)); break; // Nothing to do for the following case PsudoLineType.StartMain: case PsudoLineType.StartMethod: case PsudoLineType.Whitespace: case PsudoLineType.Comment: case PsudoLineType.EndMethod: break; case PsudoLineType.EndDecision: throw new Exception("Unexpected End Decision"); case PsudoLineType.EndLoop: throw new Exception("Unexpected End Loop"); case PsudoLineType.EndClass: case PsudoLineType.StartClass: throw new Exception("Classes Not Supported Currently"); default: throw new Exception(string.Format( "Error Compiling Method \"{0}\" on Line #{1}", method.Name, i + 1)); } } catch (Exception e) { this.Errors.Add(new CompileError(e.Message, i + 1)); } } return(list); }
public static PsudoInstruction CompileInstruction(string line, int lineNum, PsudoMethod method) { lastInstruction = RealCompileInstruction(line, lineNum, method); return(lastInstruction); }