public void ParseExpression(String terminator = ";") { Boolean match = false; Regex intMatcher, negativeIntMatcher, functionMatcher, operatorMatcher, variableMatcher; Match matched; String variableReference = "", functionName = ""; int parameterCount = 0; intMatcher = new Regex("^(" + Tokenizer.intRegex + ")"); negativeIntMatcher = new Regex("^(" + Tokenizer.negativeIntRegex + ")"); functionMatcher = new Regex("^(" + Tokenizer.functionRegex + ")"); operatorMatcher = new Regex("^(" + Tokenizer.operatorRegex + ")"); variableMatcher = new Regex("^(" + Tokenizer.identifierRegex + @")"); while (getCurrentSequence() != terminator) { if (intMatcher.IsMatch(getCurrentSequence())) { output.Enqueue("push constant " + getCurrentSequence()); } if (negativeIntMatcher.IsMatch(getCurrentSequence())) { output.Enqueue("push constant " + getCurrentSequence().Replace("-", "")); output.Enqueue("neg"); } else if (getCurrentSequence() == "null" || getCurrentSequence() == "false") { output.Enqueue("push constant 0"); } else if (getCurrentSequence() == "true") { output.Enqueue("push constant 0"); output.Enqueue("not"); } else if (variableMatcher.IsMatch(getCurrentSequence())) { //Console.WriteLine("variable: " + getCurrentSequence()); if (currentToken.Next.Value.sequence == ".") { variableReference = GetVariableReference(getCurrentSequence()); String objectType = ""; // Console.WriteLine("var reference: " + variableReference); int localParameterCount = 0; if (variableReference != getCurrentSequence() + " not found") { objectType = GetVariableReference(getCurrentSequence(), true); functionName = "call " + objectType + "."; output.Enqueue("push " + variableReference); localParameterCount++; } else { functionName = "call " + getCurrentSequence() + "."; } advanceToken(2); functionName += getCurrentSequence(); if (!(currentToken.Next.Value.sequence == "(" && currentToken.Next.Next.Value.sequence == ")")) { localParameterCount++; } functionName += " " + localParameterCount; operators.Push(functionName); //Console.WriteLine("function: " + functionName); } else if (currentToken.Next.Value.sequence == "(") { functionName = "call " + currentClassName + "." + getCurrentSequence(); functionName += currentToken.Next.Next.Value.sequence == ")" ? " 1" : " 2"; operators.Push(functionName); output.Enqueue("push pointer 0"); //Console.WriteLine(functionName); } else if (currentToken.Next.Value.sequence == "[") { variableReference = getCurrentSequence(); //Console.WriteLine(variableReference + " is array"); advanceToken(2); operators.Push("["); ParseExpression("]"); // Console.WriteLine("after parsing " + variableReference); while (operators.Count > 0 && operators.Peek().ToString() != "[") { //Console.WriteLine(operators.Peek().ToString()); output.Enqueue(operators.Pop()); } if (operators.Count > 0) { //Console.WriteLine("deleting " + operators.Peek().ToString()); operators.Pop(); } output.Enqueue("push " + GetVariableReference(variableReference)); output.Enqueue("add"); output.Enqueue("pop pointer 1"); output.Enqueue("push that 0"); } else { output.Enqueue("push " + GetVariableReference(getCurrentSequence())); } } else if (getCurrentSequence() == ",") { //Console.WriteLine("comma"); while (operators.Peek().ToString() != "(" && operators.Count > 0) { output.Enqueue(operators.Pop()); } int i = 0, currentParameterCount; Stack tempStack = new Stack(); while (operators.Count > 0 && !(operators.Peek().ToString().Length >= 4 && operators.Peek().ToString().Substring(0, 4) == "call")) { //Console.WriteLine(operators.Peek().ToString()); tempStack.Push(operators.Pop()); } String functionCall = ""; if (operators.Count > 0) { functionCall = operators.Pop().ToString(); } currentParameterCount = Convert.ToInt32(functionCall.Substring(functionCall.Length - 1, 1)); currentParameterCount++; functionCall = functionCall.Substring(0, functionCall.Length - 1) + currentParameterCount; operators.Push(functionCall); while (tempStack.Count > 0) { operators.Push(tempStack.Pop()); } } else if (operatorMatcher.IsMatch(getCurrentSequence())) { while (operators.Count > 0 && operatorLowerPrecedence(operators.Peek().ToString(), getCurrentSequence())) { output.Enqueue(operators.Pop()); } operatorDetail currentDetail = (operatorDetail)operatorDetail[getCurrentSequence()]; if (currentDetail != null) { //if (operators.Count > 0 && operators.Peek().ToString() == "(" && currentDetail.vmCommand == "sub") // operators.Push("neg"); //else operators.Push(currentDetail.vmCommand); } else { Console.WriteLine("no detail for " + getCurrentSequence()); } } else if (getCurrentSequence() == "(") { //Console.Write("opening paren"); operators.Push("("); } else if (getCurrentSequence() == ")") { //Console.Write("closing paren"); while (operators.Count > 0 && operators.Peek().ToString() != "(") { output.Enqueue(operators.Pop()); } if (operators.Count > 0) { operators.Pop(); } //if (operators.Count > 0 && new Regex("^(" + Tokenizer.functionRegex + ")").IsMatch(operators.Peek().ToString())) if (operators.Count > 0 && operators.Peek().ToString().Length >= 4 && operators.Peek().ToString().Substring(0, 4) == "call") { //Console.WriteLine("found function"); output.Enqueue(operators.Pop()); } //else if (operators.Count > 0) //{ // Console.WriteLine("not function: " + operators.Peek().ToString()); //} } else if (getCurrentSequence().Length >= 1 && getCurrentSequence().Substring(0, 1) == @"""") { CompileString(); } //else // Console.WriteLine("no match - " + getCurrentSequence()); advanceToken(); } }
public void codeWrite(String expression) { //Console.WriteLine("curent expression - " + expression); if (expression.Trim() == "") { return; } if (new Regex("^" + Tokenizer.intRegex + "$").IsMatch(expression)) { sw.WriteLine("push constant " + expression); } else if (new Regex("^" + Tokenizer.stringRegex + "$").IsMatch(expression)) { sw.WriteLine("push representation of string: " + expression); } else if (expression == "true") { sw.WriteLine("push constant 0"); sw.WriteLine("not"); } else if (expression == "false") { sw.WriteLine("push constant 0"); } else if (expression == "~") { sw.WriteLine("not"); } else if (new Regex("^(" + Tokenizer.operatorRegex + ")?$").IsMatch(expression)) { operatorDetail currentDetail = (operatorDetail)operatorDetail[expression]; sw.WriteLine(currentDetail.vmCommand); } else if (new Regex("^" + Tokenizer.identifierRegex + @"(\[.*\])?$").IsMatch(expression)) { String bracketExpression = ""; Regex arrayMatcher = new Regex(@"(" + Tokenizer.identifierRegex + @")\[(.*)\]"); Match arrayMatched; arrayMatched = arrayMatcher.Match(expression); if (arrayMatched.Groups.Count > 1) { sw.WriteLine("push " + GetVariableReference(arrayMatched.Groups[1].ToString())); bracketExpression = arrayMatched.Groups[2].ToString(); codeWrite(arrayMatched.Groups[2].ToString()); sw.WriteLine("add"); sw.WriteLine("pop pointer 1"); sw.WriteLine("push that 0"); } else { sw.WriteLine("push " + GetVariableReference(expression)); } } else { Regex opmatcher = new Regex("^(" + Tokenizer.operatorRegex + ")(.*)"); Match opmatched; opmatched = opmatcher.Match(expression); if (opmatched.Groups.Count > 2 && opmatched.Groups[2].ToString().Trim() != "") { codeWrite(opmatched.Groups[2].ToString()); codeWrite(opmatched.Groups[1].ToString()); } else { Regex functionmatcher = new Regex("^(" + Tokenizer.functionRegex + @")\((.*)\)"); //Regex functionmatcher = new Regex(@"^(([A-Za-z]+[A-Za-z0-9_]*\.)?([A-Za-z]+[A-Za-z0-9_]))\((.*)\)$"); Match functionmatched; functionmatched = functionmatcher.Match(expression); for (int i = 0; i < functionmatched.Groups.Count; i++) { ;// Console.WriteLine(i + " - " + functionmatched.Groups[i].ToString()); } if (functionmatched.Groups.Count > 1) { int parameterCount = 0; if (functionmatched.Groups[5].ToString() != "") { String[] parameters = functionmatched.Groups[5].ToString().Split(','); foreach (String currentExpression in parameters) { codeWrite(currentExpression); parameterCount++; } } String[] currentFunction = functionmatched.Groups[1].ToString().Split('.'); String instanceVariable = "", functionName = ""; functionName = functionmatched.Groups[1].ToString(); if (currentFunction.Length > 1) { instanceVariable = GetVariableReference(currentFunction[0]); if (instanceVariable != currentFunction[0] + " not found") { sw.WriteLine("push " + instanceVariable); functionName = GetVariableReference(currentFunction[0], true) + "." + currentFunction[1]; parameterCount++; } } if (!functionName.Contains(".")) { sw.WriteLine("push pointer 0"); parameterCount += 1; functionName = currentClassName + "." + functionName; } sw.WriteLine("call " + functionName + " " + parameterCount); } else { Regex multiFunctionmatcher = new Regex("(.*)(" + Tokenizer.operatorRegex + ")(.*)"); Match multiFunctionmatched; multiFunctionmatched = multiFunctionmatcher.Match(expression); if (multiFunctionmatched.Groups.Count > 1) { //Write left half of expression codeWrite(multiFunctionmatched.Groups[1].ToString().Trim()); //Write right half of expression codeWrite(multiFunctionmatched.Groups[3].ToString().Trim()); //Write operator to operate on expressed halves operatorDetail currentDetail = (operatorDetail)operatorDetail[multiFunctionmatched.Groups[2].ToString()]; sw.WriteLine(currentDetail.vmCommand); } else { sw.WriteLine("no match found in codewriter for " + expression); } } } } }