Example #1
0
File: ASTNode.cs Project: AxFab/amy
 public ASTNode(Token token, ASTOperand operand)
 {
     Token = token;
     Priority = 0;
     Operand = operand;
     Type = operand.Type;
     Operator = ASTOperator.None;
 }
Example #2
0
File: ASTNode.cs Project: AxFab/amy
 public ASTNode(Token token, ASTType type, long value)
 {
     Token = token;
     Type = type;
     Operator = ASTOperator.None;
     Operand = null;
     IValue = value;
     Computed = true;
 }
Example #3
0
 private static void BuildOperatorTree(Stack <ASTNode> parameters, Stack <ASTOperator> operators)
 {
     while (operators.Count > 0)
     {
         ASTNode left  = parameters.Pop();
         ASTNode right = null;
         if (parameters.Count > 0)
         {
             right = parameters.Pop();
         }
         ASTOperator op = operators.Pop();
         op.Left  = left;
         op.Right = right;
         parameters.Push(op);
     }
 }
Example #4
0
    ASTExpression ParseExpression()
    {
        ASTExpression firstExpr = ParseExpressionImpl();

        if (lexer.IsReading)
        {
            if (lexer.PeekNext() == TokenType.Operator)  // Operators
            {
                Token opToken = lexer.NextToken();

                ASTExpression rightSide = ParseExpression();

                ASTOperator opNode = new ASTOperator(opToken.Source, firstExpr, rightSide);

                return(opNode);
            }
            else if (lexer.PeekNext() == TokenType.SquareBraceOpen)    // Array access
            {
                ASTIndexer upper = null;

                while (lexer.PeekNext() == TokenType.SquareBraceOpen)
                {
                    MatchNext(TokenType.SquareBraceOpen);

                    ASTExpression index = ParseExpression();

                    upper     = new ASTIndexer(firstExpr, index);
                    firstExpr = upper;

                    MatchNext(TokenType.SquareBraceClose);
                }

                return(upper);
            }
        }
        return(firstExpr);
    }
Example #5
0
File: ASTNode.cs Project: AxFab/amy
 public ASTNode(Token token, ASTOperator op)
 {
     Token = token;
     Operator = op;
     Priority = Priorities[(int)op];
 }
Example #6
0
        public ASTStatement PushOperator(Token token, ASTOperator opcode)
        {
            ASTNode node = new ASTNode(token, opcode);
            while (inFixStack.Count > 0 && inFixStack.Peek().Priority > node.Priority)
            {
                ASTNode nd = inFixStack.Pop();
                addPostFixOperator(nd);
            }

            inFixStack.Push(node);
            return this;
        }
Example #7
0
        public static ASTStatement ParseStatement()
        {
            List <ASTNode> nodes       = new List <ASTNode>();
            ASTNode        currentNode = null;

            int countClauses = 0;

            for (; currentToken < currentTokens.Count; currentToken++)
            {
                if (currentTokens[currentToken] is SpecialToken)
                {
                    if (currentTokens[currentToken].Token == "{" || currentTokens[currentToken].Token == "," ||
                        (currentTokens[currentToken].Token == ")" && countClauses <= 0))
                    {
                        break;
                    }
                    if (currentTokens[currentToken].Token == ";" || currentTokens[currentToken].Token == "]")
                    {
                        currentToken++;
                        break;
                    }

                    if (currentTokens[currentToken].Token == "(")
                    {
                        countClauses++;
                        currentNode = new ASTOperator()
                        {
                            Operator   = "(",
                            Precedence = -1,
                            Left       = null,
                            Right      = null
                        };
                    }
                    else if (currentTokens[currentToken].Token == ")")
                    {
                        --countClauses;
                    }
                }

                if (currentTokens[currentToken] is OperatorToken)
                {
                    // 2 Operators means at least one is an unary one
                    if (currentTokens[currentToken + 1] is OperatorToken)
                    {
                        // Example case "1++ - 2"
                        if (currentTokens[currentToken].Token == "++" || currentTokens[currentToken].Token == "--")
                        {
                            nodes.RemoveAt(nodes.Count - 1);
                            ASTNode left = currentNode;
                            currentNode = new ASTOperator()
                            {
                                Operator   = currentTokens[currentToken].Token,
                                Precedence = 0,
                                Left       = left,
                                Right      = null
                            };
                            nodes.Add(currentNode);

                            // 2. Operator
                            currentToken++;
                            string op         = currentTokens[currentToken].Token;
                            int    precedence = ((OperatorToken)currentTokens[currentToken]).Precedence;
                            currentNode = new ASTOperator()
                            {
                                Operator   = op,
                                Precedence = precedence,
                                Left       = null,
                                Right      = null
                            };
                        }
                        // case "1 - ++2"
                        else
                        {
                            currentNode = new ASTOperator()
                            {
                                Operator   = currentTokens[currentToken].Token,
                                Precedence = 0,
                                Left       = null,
                                Right      = null
                            };
                            nodes.Add(currentNode);

                            // 2. Operator
                            currentToken++;
                            string op         = currentTokens[currentToken].Token;
                            int    precedence = ((OperatorToken)currentTokens[currentToken]).Precedence;
                            currentToken++;
                            currentNode = new ASTOperator()
                            {
                                Operator   = op,
                                Precedence = precedence,
                                Left       = ParseSingleStatement(),
                                Right      = null
                            };

                            //for will increase and ParseSingleStatement will do also
                            --currentToken;
                        }
                    }
                    // Statement starts with an unary operator example ("-1 * 2") || "(-1+2)*5"
                    else if (currentToken == 0 || (currentTokens[currentToken - 1] is SpecialToken && currentTokens[currentToken - 1].Token == "("))
                    {
                        string op = currentTokens[currentToken].Token;
                        currentToken++;
                        currentNode = new ASTOperator()
                        {
                            Operator   = op,
                            Precedence = 0,
                            Left       = ParseSingleStatement(),
                            Right      = null
                        };
                        //for will increase and ParseSingleStatement will do also
                        --currentToken;
                    }
                    else
                    {
                        currentNode = new ASTOperator()
                        {
                            Operator   = currentTokens[currentToken].Token,
                            Precedence = ((OperatorToken)currentTokens[currentToken]).Precedence,
                            Left       = null,
                            Right      = null
                        };
                    }
                }
                else
                {
                    currentNode = ParseSingleStatement();

                    //for will increase and ParseSingleStatement will do also
                    --currentToken;
                }
                nodes.Add(currentNode);
            }

            // Prevent being stuck at a ;
//            if (currentTokens[currentToken].Token == ";")
//                currentToken++;

            if (nodes.Count > 1)
            {
                // Algorithm to take care of operator precedence
                Stack <ASTNode>     parameters = new Stack <ASTNode>();
                Stack <ASTOperator> operators  = new Stack <ASTOperator>();
                int  lastPrecedence            = int.MinValue;
                bool isOperator = false;
                for (int i = nodes.Count - 1; i >= 0; i--)
                {
                    if (nodes[i] is ASTOperator && ((ASTOperator)nodes[i]).Operator == "(")
                    {
                        // Build Operator Tree
                        BuildOperatorTree(parameters, operators);

                        // After a ( always has to come an operator or nothing
                        isOperator = true;
                    }
                    else
                    {
                        if (isOperator)
                        {
                            if (nodes[i] is ASTOperator)
                            {
                                ASTOperator op = (ASTOperator)nodes[i];
                                if (lastPrecedence < op.Precedence)
                                {
                                    BuildOperatorTree(parameters, operators);
                                }

                                lastPrecedence = op.Precedence;

                                operators.Push(op);
                            }
                            else
                            {
                                if (parameters.Count == 1)
                                {
                                    ASTNode node = parameters.Pop();

                                    if (node is ASTOperator)
                                    {
                                        ASTOperator op = (ASTOperator)node;
                                        op.Left = nodes[i];
                                        parameters.Push(op);
                                        continue;
                                    }
                                }
                                // This should never ever happen, because else earlier a exception should be raised
                                throw new ParserException("Expected an operator.", -1);
                            }
                        }
                        else
                        {
                            parameters.Push(nodes[i]);
                        }
                        isOperator = !isOperator;
                    }
                }
                BuildOperatorTree(parameters, operators);

                return(new ASTStatement()
                {
                    Statement = parameters.Pop()
                });
            }
            else if (nodes.Count == 1)
            {
                return(new ASTStatement()
                {
                    Statement = nodes[0]
                });
            }
            else
            {
                return(null);
            }
        }
        private static void PrintNode(ASTNode node, int incident)
        {
            if (node == null)
            {
                return;
            }
            for (int i = 0; i < incident; i++)
            {
                sw.Write("\t");
            }
            if (node is ASTString)
            {
                sw.WriteLine("ASTString: " + ((ASTString)node).String.Replace("\n", "\\n"));
            }
            else if (node is ASTNumber)
            {
                sw.WriteLine("ASTNumber: " + ((ASTNumber)node).Number);
            }
            else if (node is ASTIdentifier)
            {
                sw.WriteLine("ASTIdentifier: " + ((ASTIdentifier)node).Identifier);
            }
            else if (node is ASTOperator)
            {
                ASTOperator op = (ASTOperator)node;
                sw.WriteLine("ASTOperator: " + op.Operator);
                PrintNode(op.Left, incident + 1);
                PrintNode(op.Right, incident + 1);
            }
            else if (node is ASTStatement)
            {
                ASTStatement stm = (ASTStatement)node;
                sw.WriteLine("ASTStatement: ");
                PrintNode(stm.Statement, incident + 1);
            }
            else if (node is ASTFunctionCall)
            {
                ASTFunctionCall call = (ASTFunctionCall)node;
                sw.WriteLine("ASTFunctionCall: " + call.Scope + "." + call.FunctionName);
                foreach (ASTNode param in call.Parameter)
                {
                    PrintNode(param, incident + 1);
                }
            }
            else if (node is ASTClassParameter)
            {
                ASTClassParameter classP = (ASTClassParameter)node;
                sw.WriteLine("ASTClassParameter: " + classP.Scope);
                PrintNode(classP.Parameter, incident + 1);
            }
            else if (node is ASTIf)
            {
                ASTIf ifNode = (ASTIf)node;
                sw.WriteLine("ASTIf:");
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCondition:");
                PrintNode(ifNode.Condition, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in ifNode.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
                if (ifNode.ElseCodeBlock != null)
                {
                    for (int i = 0; i < incident; i++)
                    {
                        sw.Write("\t");
                    }
                    sw.WriteLine("\tElse:");
                    foreach (ASTNode codeBlock in ifNode.ElseCodeBlock)
                    {
                        PrintNode(codeBlock, incident + 2);
                    }
                }
            }
            else if (node is ASTFor)
            {
                ASTFor forNode = (ASTFor)node;
                sw.WriteLine("ASTFor:");
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tInit:");
                PrintNode(forNode.Initialise, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCondition:");
                PrintNode(forNode.Condition, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCounter:");
                PrintNode(forNode.Count, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in forNode.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
            }
            else if (node is ASTWhile)
            {
                ASTWhile wNode = (ASTWhile)node;
                sw.WriteLine("ASTWhile:");
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCondition:");
                PrintNode(wNode.Condition, incident + 2);
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in wNode.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
            }
            else if (node is ASTFunction)
            {
                ASTFunction func = (ASTFunction)node;
                if (node is ASTConstructor)
                {
                    sw.WriteLine("ASTConstructor:");
                }
                else
                {
                    sw.WriteLine("ASTFunction: " + func.ReturnValue.ToString() + " " + func.Name);
                }
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tParameter:");
                foreach (ASTNode n in func.Parameter)
                {
                    PrintNode(n, incident + 2);
                }
                for (int i = 0; i < incident; i++)
                {
                    sw.Write("\t");
                }
                sw.WriteLine("\tCodeBlock:");
                foreach (ASTNode codeBlock in func.CodeBlock)
                {
                    PrintNode(codeBlock, incident + 2);
                }
            }
            else if (node is ASTFunctionParameter)
            {
                ASTFunctionParameter param = (ASTFunctionParameter)node;
                switch (param.Type)
                {
                case VMType.Object:
                    sw.WriteLine("Object: " + param.Name);
                    break;

                case VMType.String:
                    sw.WriteLine("String: " + param.Name);
                    break;

                case VMType.Number:
                    sw.WriteLine("Number: " + param.Name);
                    break;
                }
            }
            else if (node is ASTLocalVariable)
            {
                ASTLocalVariable param = (ASTLocalVariable)node;
                switch (param.Type)
                {
                case VMType.Object:
                    sw.WriteLine("var Object: " + param.Name);
                    break;

                case VMType.String:
                    sw.WriteLine("var String: " + param.Name);
                    break;

                case VMType.Number:
                    sw.WriteLine("var Number: " + param.Name);
                    break;
                }
            }
            else if (node is ASTReturn)
            {
                sw.WriteLine("ASTReturn:");
                PrintNode(((ASTReturn)node).Return, incident + 1);
            }
            else if (node is ASTClass)
            {
                ASTClass cNode = (ASTClass)node;
                sw.WriteLine("ASTClass: " + cNode.Name);
                sw.WriteLine("\tAttributes:");
                foreach (ASTNode n in cNode.Attributes)
                {
                    PrintNode(n, incident + 2);
                }
                sw.WriteLine("\tConstructors:");
                foreach (ASTNode n in cNode.Constructors)
                {
                    PrintNode(n, incident + 2);
                }
                sw.WriteLine("\tFunctions:");
                foreach (ASTNode n in cNode.Functions)
                {
                    PrintNode(n, incident + 2);
                }
            }
        }