public void EvalAsIs(double expected)
        {
            var sut    = new NodeNumber(expected);
            var actual = sut.Eval(null);

            Assert.Equal(expected, actual);
        }
Example #2
0
 public override string ToString()
 {
     return(NodeNumber.ToString());
 }
Example #3
0
        private INode ParseLeaf()
        {
            if (tokenizer.currentToken == Token.Number)
            {
                var node = new NodeNumber(tokenizer.number);
                tokenizer.NextToken();

                return(node);
            }

            if (tokenizer.currentToken == Token.OpenParens)
            {
                tokenizer.NextToken();
                var node = ParseAddSubtract();

                if (tokenizer.currentToken != Token.CloseParens)
                {
                    throw new SyntaxException("Falta cerrar paréntesis");
                }

                tokenizer.NextToken();

                return(node);
            }

            if (tokenizer.currentToken == Token.Identifier)
            {
                var name = tokenizer.identifier;
                tokenizer.NextToken();

                if (tokenizer.currentToken != Token.OpenParens)
                {
                    NodeVariable node = new NodeVariable(name);

                    if (!node.isReserved())
                    {
                        variables.Add(name);
                    }

                    return(node);
                }
                else
                {
                    tokenizer.NextToken();

                    var arguments = new List <INode>();

                    while (true)
                    {
                        arguments.Add(ParseAddSubtract());

                        if (tokenizer.currentToken == Token.Comma)
                        {
                            tokenizer.NextToken();
                            continue;
                        }

                        break;
                    }

                    if (tokenizer.currentToken != Token.CloseParens)
                    {
                        throw new SyntaxException("Falta cerrar paréntesis");
                    }

                    tokenizer.NextToken();

                    return(new NodeFunctionCall(name, arguments.ToArray()));
                }
            }

            throw new SyntaxException(GetUnexpectedTokenMessage(tokenizer.currentToken));
        }
Example #4
0
    // Parse a leaf node
    // (For the moment this is just a number)
    Node ParseLeaf()
    {
        // Is it a number?
        if (m_tokeniser.getToken == Token.Number)
        {
            var node = new NodeNumber(m_tokeniser.getNumber);
            m_tokeniser.NextToken();
            return(node);
        }

        // Parenthesis?
        if (m_tokeniser.getToken == Token.OpenParens)
        {
            // Skip '('
            m_tokeniser.NextToken();

            // Parse a top-level expression
            var node = ParseAddSubtract();

            // Check and skip ')'
            if (m_tokeniser.getToken != Token.CloseParens)
            {
                throw new Exception("Missing close parenthesis");
            }
            m_tokeniser.NextToken();

            // Return
            return(node);
        }
        // Variable
        if (m_tokeniser.getToken == Token.Identifier)
        {
            // Capture the name and skip it
            var name = m_tokeniser.getIdentifier;
            m_tokeniser.NextToken();

            // Parens indicate a function call, otherwise just a variable
            if (m_tokeniser.getToken != Token.OpenParens)
            {
                // Variable
                return(new NodeVariable(name));
            }
            else
            {
                // Function call

                // Skip parens
                m_tokeniser.NextToken();

                // Parse arguments
                var arguments = new List <Node>();
                while (true)
                {
                    // Parse argument and add to list
                    arguments.Add(ParseAddSubtract());

                    // Is there another argument?
                    if (m_tokeniser.getToken == Token.Comma)
                    {
                        m_tokeniser.NextToken();
                        continue;
                    }

                    // Get out
                    break;
                }

                // Check and skip ')'
                if (m_tokeniser.getToken != Token.CloseParens)
                {
                    throw new Exception("Missing close parenthesis");
                }
                m_tokeniser.NextToken();

                // Create the function call node
                return(new NodeFunctionCall(name, arguments.ToArray()));
            }
        }



        // Don't Understand
        throw new Exception($"Unexpect token: {m_tokeniser.getToken}");
    }
        // ParseLeaf is the lowest level of the expression parsers.
        // It is used to extract the fundamental elements of an expression.
        // These elements are numbers, function calls and arrays.
        Node ParseLeaf()
        {
            // NodeNumber:
            // If current token is a number we simply extract it as a NodeNumber.
            if (fCurrentToken.Type == TokenType.Integer)
            {
                var node = new NodeNumber(fCurrentToken.IntValue());
                ReadNextToken();
                return(node);
            }

            // Parenthesis:
            // If an open parenthesis is read, it must be skipped and the expression
            // it encloses must be parsed. We must also check again at the end of the
            // expression if the parenthesis is correctly closed otherwise an exception
            // is thrown.
            if (fCurrentToken.Equals(TokenType.Symbol, "("))
            {
                // Skip '('
                ReadNextToken();

                // Check for "others" statement that is commonly used in VHDL.
                if (fCurrentToken.Equals(TokenType.Word, "others"))
                {
                    fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, "'");
                    var node = new NodeNumber(fCurrentToken.IntValue());
                    fCurrentToken = fLexicalAnalyser.SkipOver(TokenType.Symbol, ")");
                    return(node);
                }
                // Else we have an expression inside of parenthesis.
                else
                {
                    // Parse a top-level expression
                    var arguments = new List <Node> ();
                    while (true)
                    {
                        // Parse argument and add to list
                        arguments.Add(ParseAddSubtract());

                        // Is there another argument?
                        if (fCurrentToken.Equals(TokenType.Symbol, ","))
                        {
                            ReadNextToken();
                            continue;
                        }

                        // Get out
                        break;
                    }

                    // Check and skip ')'
                    if (!fCurrentToken.Equals(TokenType.Symbol, ")"))
                    {
                        throw new ParserException("Missing close parenthesis");
                    }
                    ReadNextToken();

                    // Return
                    return(new NodeArray(arguments.ToArray()));
                }
            }

            // Single/Double Quote Literals:
            // In vhdl we can have single digit values enclosed in signle quote literals and longer values
            // enclosed in double quote literals. We must therefore extract the number from within these quotation literals.
            if (fCurrentToken.Equals(TokenType.Symbol, "\"") || fCurrentToken.Equals(TokenType.Symbol, "\'"))
            {
                // Skip '"'
                ReadNextToken();                  //Read the number

                var node = new NodeNumber(fCurrentToken.IntValue());

                ReadNextToken();                  //Skip the number

                // Check and skip ')'
                if (!(fCurrentToken.Equals(TokenType.Symbol, "\"") || fCurrentToken.Equals(TokenType.Symbol, "\'")))
                {
                    throw new ParserException("Missing closing quote literals");
                }
                ReadNextToken();

                // Return
                return(node);
            }

            if (fCurrentToken.Type == TokenType.Word)
            {
                // Parse a top-level expression
                var name = fCurrentToken.Value;
                ReadNextToken();
                if (fCurrentToken.Equals(TokenType.Symbol, "\'"))
                {
                    //Type Attribute has been requested
                    ReadNextToken();
                    var attribute = DetermineAttribute(fCurrentToken.Value, name);
                    var node      = new NodeNumber(attribute);
                    ReadNextToken();                      //Skip the found attribute
                    return(node);
                }
                else if (!fCurrentToken.Equals(TokenType.Symbol, "("))
                {
                    if (ConstantList.Any(x => x.Identifier == name))
                    {
                        ConstantDeclaration result = ConstantList.Find(x => x.Identifier == name);
                        var node = new NodeNumber(result.Value);
                        return(node);
                    }
                    else if (ConstantList.Any(x => x.Identifier == name.ToUpper()))
                    {
                        ConstantDeclaration result = ConstantList.Find(x => x.Identifier == name.ToUpper());
                        var node = new NodeNumber(result.Value);
                        return(node);
                    }
                    else if (ConstantList.Any(x => x.Identifier == name.ToLower()))
                    {
                        ConstantDeclaration result = ConstantList.Find(x => x.Identifier.ToUpper() == name.ToLower());
                        var node = new NodeNumber(result.Value);
                        return(node);
                    }
                    else
                    {
                        throw new ParserException("Constant value is unknown.");
                    }
                }
                else
                {
                    // Function call
                    // Skip parens
                    ReadNextToken();

                    // Parse arguments
                    var arguments = new List <Node> ();
                    while (true)
                    {
                        // Parse argument and add to list
                        arguments.Add(ParseAddSubtract());

                        // Is there another argument?
                        if (fCurrentToken.Equals(TokenType.Symbol, ","))
                        {
                            ReadNextToken();
                            continue;
                        }

                        // Get out
                        break;
                    }
                    // Check and skip ')'
                    if (!fCurrentToken.Equals(TokenType.Symbol, ")"))
                    {
                        throw new ParserException("Missing Closing Parenthesis");
                    }

                    ReadNextToken();

                    // Create the function call node
                    return(new NodeFunctionCall(name, arguments.ToArray()));
                }
            }
            // Don't Understand
            throw new ParserException("Expected ; and end of line but instead got: " + fCurrentToken.Value);
        }