예제 #1
0
        private Expr Relational()
        {
            var expr = Additive();

            while (Match(TokenType.GREATER, TokenType.GREATER_EQUAL, TokenType.LESS, TokenType.LESS_EQUAL))
            {
                Token op    = Previous;
                Expr  right = Additive();

                if (expr is Expr.Literal l && right is Expr.Literal r)
                {
                    var typel = new TypeSpecifier {
                        Type = l.Type, Dimensions = 0
                    };
                    var typer = new TypeSpecifier {
                        Type = r.Type, Dimensions = 0
                    };

                    if (typer.ImplicitCastableTo(typel))
                    {
                        if (typel.Type == TypeEnum.BOOL)
                        {
                            throw Error($"Boolean values are not comparable with '{op.Type}'");
                        }

                        if (typel.IsInt())
                        {
                            return(CompareLiterals <long>(op.Type, l.Value, r.Value));
                        }
                        else if (typel.IsFloat())
                        {
                            return(CompareLiterals <double>(op.Type, l.Value, r.Value));
                        }
                        else
                        {
                            throw Error("Something wrong with literal comparison");
                        }
                    }
                    else
                    {
                        throw Error($"'{typer}' not implicitly castable to '{typel}'");
                    }
                }

                expr = new Expr.Binary(expr, op, right);
            }

            return(expr);
        }
예제 #2
0
        private Expr Equality()
        {
            var expr = Relational();

            while (Match(TokenType.NOT_EQUAL, TokenType.EQUAL))
            {
                Token op    = Previous;
                Expr  right = Relational();

                if (expr is Expr.Literal l && right is Expr.Literal r)
                {
                    var typel = new TypeSpecifier {
                        Type = l.Type, Dimensions = 0
                    };
                    var typer = new TypeSpecifier {
                        Type = r.Type, Dimensions = 0
                    };

                    if (typer.ImplicitCastableTo(typel))
                    {
                        if (op.Type == TokenType.NOT_EQUAL)
                        {
                            return(new Expr.Literal(TypeEnum.BOOL, !l.Value.Equals(r.Value)));
                        }
                        else
                        {
                            return(new Expr.Literal(TypeEnum.BOOL, l.Value.Equals(r.Value)));
                        }
                    }
                    else
                    {
                        throw Error($"'{typer}' not implicitly castable to '{typel}'");
                    }
                }

                expr = new Expr.Binary(expr, op, right);
            }

            return(expr);
        }
예제 #3
0
        private Expr Multiplicative()
        {
            var expr = Cast();

            while (Match(TokenType.DIV, TokenType.MULT))
            {
                Token op    = Previous;
                Expr  right = Cast();

                if (expr is Expr.Literal l && right is Expr.Literal r)
                {
                    var typel = new TypeSpecifier {
                        Type = l.Type, Dimensions = 0
                    };
                    var typer = new TypeSpecifier {
                        Type = r.Type, Dimensions = 0
                    };

                    if (typer.ImplicitCastableTo(typel))
                    {
                        if (typel.IsInt())
                        {
                            long one = (long)l.Value;
                            long two = (long)r.Value;

                            if (op.Type == TokenType.DIV)
                            {
                                return(new Expr.Literal(typel.Type, one / two));
                            }
                            else
                            {
                                return(new Expr.Literal(typel.Type, one * two));
                            }
                        }
                        else if (typel.IsFloat())
                        {
                            double one = (double)l.Value;
                            double two = (double)r.Value;

                            if (op.Type == TokenType.DIV)
                            {
                                return(new Expr.Literal(typel.Type, one / two));
                            }
                            else
                            {
                                return(new Expr.Literal(typel.Type, one * two));
                            }
                        }
                        else
                        {
                            throw Error("Something wrong on Multiplicative");
                        }
                    }
                    else
                    {
                        throw Error($"'{typer}' not implicitly castable to '{typel}'");
                    }
                }

                expr = new Expr.Binary(expr, op, right);
            }

            return(expr);
        }