public static object Evaluate(string expression)
        {
            var ast   = ArmExpressionParser.Parse(expression);
            var value = ArmExpressionEvaluator.Evaluate(ast);

            return(value);
        }
        public static ArmExpressionAst Parse(string armExpression)
        {
            var lexer  = ArmExpressionLexer.Create();
            var tokens = lexer.Lex(armExpression);
            var ast    = ArmExpressionParser.Parse(tokens);

            return(ast);
        }
        public static ArmExpressionAst ParseArmExpressionAst(TokenStream stream)
        {
            var peek = stream.Peek();

            return(peek switch
            {
                OpenParenToken _ => ArmExpressionParser.ParseArmSubexpressionAst(stream),
                IdentifierToken _ => ArmExpressionParser.ParseDottedNotationExpressionAst(stream),
                StringLiteralToken _ => ArmExpressionParser.ParseArmStringLiteralExpressionAst(stream),
                IntegerToken _ => ArmExpressionParser.ParseArmNumericLiteralExpressionAst(stream),
                _ => throw new InvalidOperationException(),
            });
        public static ArmExpressionAst Parse(IEnumerable <SyntaxToken> lexerTokens)
        {
            // remove all whitespace
            var tokens = lexerTokens.Where(lt => !(lt is WhitespaceToken));

            var stream  = new TokenStream(tokens);
            var program = ArmExpressionParser.ParseArmExpressionAst(stream);

            if (!stream.Eof)
            {
                throw new InvalidOperationException("End of expression expected.");
            }

            return(program);
        }