Exemple #1
0
        public override object VisitExpr(Z80AsmParser.ExprContext context)
        {
            if (context == null)
            {
                return(null);
            }

            // --- Extract the expression text
            var sb = new StringBuilder(400);

            for (var i = 0; i < context.ChildCount; i++)
            {
                var token = context.GetChild(i).GetText();
                sb.Append(token);
            }

            ExpressionNode expr = null;

            switch (context)
            {
            // --- Primary operators
            case Z80AsmParser.BuiltInFunctionExprContext ctx:
                expr = (ExpressionNode)VisitBuiltinFunctionInvocation(ctx.builtinFunctionInvocation());
                break;

            case Z80AsmParser.FunctionInvocationExprContext ctx:
                expr = new FunctionInvocationNode(ctx.functionInvocation(), this);
                break;

            case Z80AsmParser.MacroParamExprContext ctx:
                expr = new MacroParamNode(ctx.macroParam(), this);
                break;

            // --- Unary operators
            case Z80AsmParser.UnaryPlusExprContext ctx:
                expr = new UnaryPlusNode(ctx, this);
                break;

            case Z80AsmParser.UnaryMinusExprContext ctx:
                expr = new UnaryMinusNode(ctx, this);
                break;

            case Z80AsmParser.BinaryNotExprContext ctx:
                expr = new UnaryBitwiseNotNode(ctx, this);
                break;

            case Z80AsmParser.LogicalNotExprContext ctx:
                expr = new UnaryLogicalNotNode(ctx, this);
                break;

            // --- Bracketed/Parenthesized expressions
            case Z80AsmParser.BracketedExprContext ctx:
                expr = (ExpressionNode)VisitExpr(ctx.expr());
                break;

            case Z80AsmParser.ParenthesizedExprContext ctx:
                expr = (ExpressionNode)VisitExpr(ctx.expr());
                break;

            // --- Literals
            case Z80AsmParser.LiteralExprContext ctx:
                expr = (ExpressionNode)VisitLiteral(ctx.literal());
                break;

            case Z80AsmParser.SymbolExprContext ctx:
                if (ctx.ChildCount != 0 && ctx.symbol()?.IDENTIFIER() != null)
                {
                    AddIdentifier(ctx);
                    expr = new IdentifierNode(ctx.symbol());
                }
                break;

            // --- Min/Max operators
            case Z80AsmParser.MinMaxExprContext ctx:
                switch (ctx.op?.Text)
                {
                case "<?":
                    expr = new MinOperationNode(ctx, this);
                    break;

                default:
                    expr = new MaxOperationNode(ctx, this);
                    break;
                }
                break;

            // --- Multiplication operators
            case Z80AsmParser.MultExprContext ctx:
                switch (ctx.op?.Text)
                {
                case "*":
                    expr = new MultiplyOperationNode(ctx, this);
                    break;

                case "/":
                    expr = new DivideOperationNode(ctx, this);
                    break;

                default:
                    expr = new ModuloOperationNode(ctx, this);
                    break;
                }
                break;

            // --- Addition operators
            case Z80AsmParser.AddExprContext ctx:
                switch (ctx.op?.Text)
                {
                case "+":
                    expr = new AddOperationNode(ctx, this);
                    break;

                default:
                    expr = new SubtractOperationNode(ctx, this);
                    break;
                }
                break;

            // --- Shift operators
            case Z80AsmParser.ShiftExprContext ctx:
                switch (ctx.op?.Text)
                {
                case "<<":
                    expr = new ShiftLeftOperationNode(ctx, this);
                    break;

                default:
                    expr = new ShiftRightOperationNode(ctx, this);
                    break;
                }
                break;

            // --- Relational operators
            case Z80AsmParser.RelExprContext ctx:
                switch (ctx.op?.Text)
                {
                case "<":
                    expr = new LessThanOperationNode(ctx, this);
                    break;

                case "<=":
                    expr = new LessThanOrEqualOperationNode(ctx, this);
                    break;

                case ">":
                    expr = new GreaterThanOperationNode(ctx, this);
                    break;

                default:
                    expr = new GreaterThanOrEqualOperationNode(ctx, this);
                    break;
                }
                break;

            // --- Equality operators
            case Z80AsmParser.EquExprContext ctx:
                switch (ctx.op?.Text)
                {
                case "==":
                    expr = new EqualOperationNode(ctx, this);
                    break;

                case "===":
                    expr = new CaseInsensitiveEqualOperationNode(ctx, this);
                    break;

                case "!=":
                    expr = new NotEqualOperationNode(ctx, this);
                    break;

                default:
                    expr = new CaseInsensitiveNotEqualOperationNode(ctx, this);
                    break;
                }
                break;

            // --- Bitwise operators
            case Z80AsmParser.AndExprContext ctx:
                expr = new BitwiseAndOperationNode(ctx, this);
                break;

            case Z80AsmParser.XorExprContext ctx:
                expr = new BitwiseXorOperationNode(ctx, this);
                break;

            case Z80AsmParser.OrExprContext ctx:
                expr = new BitwiseOrOperationNode(ctx, this);
                break;

            // --- Ternary operator
            case Z80AsmParser.TernaryExprContext ctx:
                expr = new ConditionalExpressionNode(ctx, this);
                break;
            }

            if (expr != null)
            {
                expr.SourceText = sb.ToString();
            }
            return(expr);
        }
Exemple #2
0
        protected SyntaxNode buildSyntaxTree(List <ISyntaxUnit> postfixForm)
        {
            Queue <ISyntaxUnit> inputQueue   = new Queue <ISyntaxUnit>(postfixForm);
            Stack <SyntaxNode>  operandStack = new Stack <SyntaxNode>();

            while (inputQueue.Count > 0)
            {
                ISyntaxUnit input = inputQueue.Dequeue();
                if (input is Lexeme)
                {
                    Lexeme            token = input as Lexeme;
                    Lexeme.LexemeType ttype = token.Type;
                    if (properties.IsVariable(token.Value))
                    {
                        VariableIdentifierNode variable = new VariableIdentifierNode(token.Value);
                        operandStack.Push(variable);
                    }
                    else if (properties.IsConstant(token.Value))
                    {
                        double constantValue            = properties.getConstantValue(token.Value);
                        ConstantIdentifierNode constant = new ConstantIdentifierNode(token.Value, constantValue);
                        operandStack.Push(constant);
                    }
                    else if (properties.IsFunctionName(token.Value))
                    {
                        int nArguments = properties.getFunctionArgumentsCount(token.Value);
                        FunctionApplyNode.FunctionBody funcBody = properties.getFunctionDefinition(token.Value);
                        ArgumentListNode argumentList           = new ArgumentListNode();
                        try
                        {
                            for (int i = 0; i < nArguments; i++)
                            {
                                argumentList.addArgument(operandStack.Pop());
                            }
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Not enough operands on operand stack for function call.");
                        }

                        FunctionApplyNode functionCall = new FunctionApplyNode(argumentList, funcBody, token.Value);
                        operandStack.Push(functionCall);
                    }
                    else if (ttype == Lexeme.LexemeType.REAL_VALUE)
                    {
                        double value;
                        if (!double.TryParse(token.Value, NumberStyles.Any, CultureInfo.InvariantCulture, out value))
                        {
                            throw new ParseException("Couldn't parse literal value: " + token.Value);
                        }
                        LiteralNode literal = new LiteralNode(value);
                        operandStack.Push(literal);
                    }
                    else if (ttype == Lexeme.LexemeType.OP_PLUS)
                    {
                        try
                        {
                            SyntaxNode   right    = operandStack.Pop();
                            SyntaxNode   left     = operandStack.Pop();
                            AdditionNode addition = new AdditionNode(left, right);
                            operandStack.Push(addition);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for addition.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_MINUS)
                    {
                        try
                        {
                            SyntaxNode      right       = operandStack.Pop();
                            SyntaxNode      left        = operandStack.Pop();
                            SubtractionNode subtraction = new SubtractionNode(left, right);
                            operandStack.Push(subtraction);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for subtraction.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_MUL)
                    {
                        try
                        {
                            SyntaxNode         right          = operandStack.Pop();
                            SyntaxNode         left           = operandStack.Pop();
                            MultiplicationNode multiplication = new MultiplicationNode(left, right);
                            operandStack.Push(multiplication);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for multiplication.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_DIV)
                    {
                        try
                        {
                            SyntaxNode   right    = operandStack.Pop();
                            SyntaxNode   left     = operandStack.Pop();
                            DivisionNode division = new DivisionNode(left, right);
                            operandStack.Push(division);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for division.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_POW)
                    {
                        try
                        {
                            SyntaxNode exponent = operandStack.Pop();
                            SyntaxNode baseNode = operandStack.Pop();
                            PowerNode  power    = new PowerNode(baseNode, exponent);
                            operandStack.Push(power);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for exponentiation.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.EQ_SIGN)
                    {
                        try
                        {
                            SyntaxNode right  = operandStack.Pop();
                            SyntaxNode left   = operandStack.Pop();
                            EqualsNode eqNode = new EqualsNode(left, right);
                            operandStack.Push(eqNode);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand(s) for assignment.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_PLUS_UNARY)
                    {
                        try
                        {
                            SyntaxNode    child     = operandStack.Pop();
                            UnaryPlusNode unaryPlus = new UnaryPlusNode(child);
                            operandStack.Push(unaryPlus);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand for unary plus.");
                        }
                    }
                    else if (ttype == Lexeme.LexemeType.OP_MINUS_UNARY)
                    {
                        try
                        {
                            SyntaxNode     child      = operandStack.Pop();
                            UnaryMinusNode unaryMinus = new UnaryMinusNode(child);
                            operandStack.Push(unaryMinus);
                        }
                        catch (InvalidOperationException ex)
                        {
                            throw new ParseException("Missing operand for unary minus.");
                        }
                    }
                    else
                    {
                        throw new ParseException("Unexpected token in postfix expression: " + token.simpleRepresentation());
                    }
                }
                else if (input is SyntaxNode)
                {
                    operandStack.Push(input as SyntaxNode);
                }
                else
                {
                    throw new ParseException("Unexpected object type in postfix expression.");
                }
            }

            if (operandStack.Count == 1)
            {
                return(operandStack.Pop());
            }
            else
            {
                throw new ParseException("Too many operands in postfix expression.");
            }
        }