private StackElement Get(bool destroy) { if (stack.Count() == 0) { return(null); } StackElement r = stack.Peek(); if (destroy) { stack.Pop(); } return(r); }
private void Push(StackElement val) { stack.Push(val); }
private string ProcessCode(string codeToProcess) { int index = 0; bool isReadingNumber = false; int number = 0; int bracketsSign = 0; bool isReadingFunction = false; string function = ""; bool isReadingString = false; string readString = ""; bool isReadVar = false; int varIndex = -1; bool isReadingChar = false; bool isLastSlash = false; bool isReadingComment = false; int commentsSign = 0; string comment = ""; while (index < codeToProcess.Length) { char c = codeToProcess [index]; if (!isLastSlash && c == '\\' && (isReadingComment || isReadingFunction || isReadingString)) { isLastSlash = true; index++; continue; } if (isReadingComment) { if (isLastSlash) { comment += TranslateChar(c); isLastSlash = false; index++; continue; } if (c == '}') { commentsSign--; if (commentsSign == 0) { ProcessComment(comment); comment = ""; isReadingComment = false; index++; continue; } if (commentsSign < 0) { return("Error: Wrong {}comment expression. At: " + index + "."); } } if (c == '{') { commentsSign++; } comment += c; index++; continue; } if (isReadingFunction) { if (isLastSlash) { function += TranslateChar(c); isLastSlash = false; index++; continue; } if (c == ']') { bracketsSign--; if (bracketsSign == 0) { isReadingFunction = false; Push(new StackElement(function)); function = ""; bracketsSign = 0; index++; continue; } if (bracketsSign < 0) { return("Error: Wrong []brackets expression. At: " + index + "."); } } if (c == '[') { bracketsSign++; } function += c; index++; continue; } if (c == '\"' && !isLastSlash) { if (isReadingString) { isReadingString = false; Push(new StackElement(readString)); readString = ""; } else { isReadingString = true; readString = ""; } index++; continue; } if (isReadingString) { if (isLastSlash) { readString += TranslateChar(c); isLastSlash = false; index++; continue; } readString += c; index++; continue; } if (isReadingChar) { Push(new StackElement((int)c)); isReadingChar = false; index++; continue; } if (IsVar(c)) { if (isReadVar) { return("Variable can only have a one-symbol name from 'a' to 'z'. At: " + index + "."); } varIndex = (int)c - (int)'a'; isReadVar = true; index++; continue; } if (IsNumber(c)) { isReadingNumber = true; number = number * 10 + ((int)c - (int)'0'); } else { if (isReadingNumber) { isReadingNumber = false; stack.Push(new StackElement(number)); number = 0; } } StackElement a, b, p; switch (c) { case '+': a = Get(true); b = Get(true); if (b == null) { return("Error: Not enough parameters. Function: \"+\". At: " + index + "."); } if (a.isInteger) { if (b.isInteger) { Push(new StackElement(b.i + a.i)); } else { Push(new StackElement(b.f + a.i.ToString())); } } else { if (b.isInteger) { Push(new StackElement(b.i.ToString() + a.f)); } else { Push(new StackElement(b.f + a.f)); } } break; case '-': a = Get(true); b = Get(true); if (b == null || !(a.isInteger && b.isInteger)) { return("Error: One of parameters is not a number. Function: \"-\". At: " + index + "."); } Push(new StackElement(b.i - a.i)); break; case '*': a = Get(true); b = Get(true); if (b == null || !(a.isInteger && b.isInteger)) { return("Error: One of parameters is not a number. Function: \"*\". At: " + index + "."); } Push(new StackElement(b.i * a.i)); break; case '/': a = Get(true); b = Get(true); if (b == null || !(a.isInteger && b.isInteger)) { return("Error: One of parameters is not a number. Function: \"/\". At: " + index + "."); } if (a.i == 0) { return("Error: Division by zero. Function: \"/\". At: " + index + "."); } Push(new StackElement(b.i / a.i)); break; case '_': a = Get(true); if (a == null || !(a.isInteger)) { return("Error: Parameter is not a number. Function: \"_\". At: " + index + "."); } Push(new StackElement(-a.i)); break; case '=': a = Get(true); b = Get(true); if (b == null || a.isInteger != b.isInteger) { return("Error: Parameters have different types. At: " + index + "."); } Push(new StackElement((a.isInteger ? a.i == b.i : a.f == b.f))); break; case '>': a = Get(true); b = Get(true); if (b == null || !(a.isInteger && b.isInteger)) { return("Error: One of parameters is not a number. Function: \">\". At: " + index + "."); } Push(new StackElement(a.i < b.i)); break; case '~': a = Get(true); if (a == null) { return("Error: One of parameters is not a number. Function: \"~\". At: " + index + "."); } Push(new StackElement(!a.IsTrue())); break; case '&': a = Get(true); b = Get(true); if (b == null) { return("Error: One of parameters is not a number. Function: \"&\". At: " + index + "."); } Push(new StackElement(a.IsTrue() && b.IsTrue())); break; case '|': a = Get(true); b = Get(true); if (b == null) { return("Error: One of parameters is not a number. Function: \"&\". At: " + index + "."); } Push(new StackElement(a.IsTrue() || b.IsTrue())); break; case '[': isReadingFunction = true; bracketsSign = 1; break; case ']': return("Error: Wrong []brackets expression. At: " + index + "."); case '$': a = Get(false); if (a == null) { return("Error: Not enough parameters. Function: \"$\". At: " + index + "."); } Push(a); break; case '%': Get(true); break; case '\\': a = Get(true); b = Get(true); if (b == null) { return("Error: Not enough parameters. Function: \"\\\". At: " + index + "."); } Push(a); Push(b); break; case '@': a = Get(true); b = Get(true); p = Get(true); if (p == null) { return("Error: Not enough parameters. Function: \"@\". At: " + index + "."); } Push(p); Push(a); Push(b); break; case 'ø': case 'O': a = Get(true); b = a; if (a == null || !a.isInteger) { return("Error: Parameter is not a number. Function: \"ø\\O\". At: " + index + "."); } a.i++; var d = new Stack <StackElement> (stack); StackElement res = null; while (d.Count > 0 && a.i > 0) { res = d.Pop(); a.i--; } if (a.i == 0) { Push(res); } else { return("Error: No such index \"" + b.i + "\" in stack. Function: \"ø\\O\". At: " + index + "."); } break; case '!': a = Get(true); if (a == null || a.isInteger) { return("Error: Parameter is not a function. Function: \"!\". At: " + index + "."); } string resProcess = ProcessCode(a.f); if (resProcess != "") { return(resProcess + " Caused by \"[" + a.f + "]\" At: " + index + ".\n"); } break; case '?': a = Get(true); b = Get(true); if (a == null || b == null || a.isInteger) { return("Error: Parameter is not a function. Function: \"?\". At: " + index + "."); } if (b.IsTrue()) { string resProcess1 = ProcessCode(a.f); if (resProcess1 != "") { return(resProcess1 + " Caused by \"[" + a.f + "]\" At: " + index + ".\n"); } } break; case '#': StackElement a1 = Get(true); StackElement a2 = Get(true); if (a2 == null || a1 == null || a1.isInteger || a2.isInteger) { return("Error: Parameters are not a functions. Function: \"#\". At: " + index + "."); } do { string resProcess2 = ProcessCode(a2.f); if (resProcess2 != "") { return(resProcess2 + " Caused by \"[" + a2.f + "]\" At: " + index + ".\n"); } b = Get(true); if (b.IsTrue()) { string resProcess1 = ProcessCode(a1.f); if (resProcess1 != "") { return(resProcess1 + " Caused by \"[" + a1.f + "]\" At: " + index + ".\n"); } } } while (b.IsTrue()); break; case '.': a = Get(true); if (a == null) { return("Error: Not enough parameters. Function: \".\". At: " + index + "."); } output += (a.isInteger?a.i.ToString() : a.f); break; case ',': a = Get(true); if (!a.isInteger) { return("Error: Parameter is not a symbol. Function: \",\". At: " + index + "."); } output += (char)(int)a.i; break; case '^': Push(ReadChar()); break; case ':': a = Get(true); if (!isReadVar) { return("Error: No variables have found (use it like '1f:' - Push 1; f := 1;). At: " + index + "."); } if (a == null) { return("Error: Parameter is NULL. At: " + index + "."); } vars[varIndex] = a; break; case ';': if (!isReadVar) { return("Error: No variables have found (use it like 'f;' - Push f;). At: " + index + "."); } Push(vars[varIndex]); break; case '\'': isReadingChar = true; break; case 'ß': case 'B': input = ""; output = ""; break; case '{': isReadingComment = true; comment = ""; commentsSign = 1; break; case 'W': a = Get(true); if (a == null) { return("Error: Not enough parameters. Function: \"W\". At: " + index + "."); } Write(a.isInteger ? a.i.ToString() : a.f); break; case 'R': if (paramtersList.Count > 0) { string resProcess1 = ProcessCode(paramtersList [0]); if (resProcess1 != "") { return(resProcess1 + " Caused by \"[" + paramtersList [0] + "]\" At: " + index + ".\n"); } paramtersList.RemoveAt(0); } break; case 'C': a = Get(true); b = Get(true); p = Get(true); if (p == null) { return("Error: Not enough parameters. Function: \"C\". At: " + index + "."); } if (!a.isInteger || !b.isInteger || !p.isInteger) { return("Error: parameters are not integers. Function: \"C\". At: " + index + "."); } Click(p.i, b.i, a.i); break; case 'S': a = Get(true); if (a == null) { return("Error: Not enough parameters. Function: \"S\". At: " + index + "."); } if (!a.isInteger) { return("Error: parameter is not integer. Function: \"S\". At: " + index + "."); } Sleep(a.i); break; case 'M': a = Get(true); if (a == null) { return("Error: Not enough parameters. Function: \"M\". At: " + index + "."); } Message(a.isInteger ? a.i.ToString() : a.f); break; case 'V': a = Get(true); b = Get(true); if (b == null) { return("Error: Not enough parameters. Function: \"V\". At: " + index + "."); } if (!a.isInteger || !b.isInteger) { return("Error: parameters are not integers. Function: \"V\". At: " + index + "."); } MoveMouse(b.i, a.i); break; case 'X': a = Get(true); b = Get(true); if (b == null) { return("Error: Not enough parameters. Function: \"X\". At: " + index + "."); } if (!a.isInteger || !b.isInteger) { return("Error: parameters are not integers. Function: \"X\". At: " + index + "."); } var color = GetPixel(b.i, a.i); Push(new StackElement(color.R)); Push(new StackElement(color.G)); Push(new StackElement(color.B)); break; case 'P': var pos = GetMousePosition(); Push(new StackElement(pos.X)); Push(new StackElement(pos.Y)); break; case 'E': a = Get(true); if (a == null) { return("Error: Not enough parameters. Function: \"S\". At: " + index + "."); } if (a.isInteger) { return("Error: parameter is not string. Function: \"S\". At: " + index + "."); } System.Diagnostics.Process.Start(a.f); break; case 'D': Push(new StackElement(r.Next())); break; } index++; isReadVar = false; isLastSlash = false; } if (isReadingFunction) { return("Error: Wrong []brackets expression. At: the end."); } if (isReadingNumber) { stack.Push(new StackElement(number)); } if (isReadingString) { return("Error: Missing \" in string expression. At: the end."); } return(""); }