Пример #1
0
        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();
            }
        }
Пример #2
0
        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);
                        }
                    }
                }
            }
        }