private int GetInfixPrecedence(MathTokenType type)
        {
            switch (type)
            {
            case MathTokenType.BitwiseOr:
                return((int)Precedences.Or);

            case MathTokenType.BitwiseXor:
                return((int)Precedences.Xor);

            case MathTokenType.BitwiseAnd:
                return((int)Precedences.And);

            case MathTokenType.LeftShift:
            case MathTokenType.RightShift:
            case MathTokenType.ARightShift:
                return((int)Precedences.Shifts);

            case MathTokenType.Plus:
            case MathTokenType.Minus:
                return((int)Precedences.Sums);

            case MathTokenType.Multiply:
            case MathTokenType.Divide:
            case MathTokenType.Modulus:
                return((int)Precedences.Products);

            default:
                return((int)Precedences.NoPrecedence);
            }
        }
Exemple #2
0
        public Token <MathTokenType> Take(MathTokenType type)
        {
            var token = Take();

            if (token.Identifier != type)
            {
                throw new RantException(_src, token, String.Concat("Expression expected ", type, ", but found ", token.Identifier, "."));
            }
            return(token);
        }
        private bool IsPrefixTokenType(MathTokenType type)
        {
            switch (type)
            {
            case MathTokenType.Identifer:
            case MathTokenType.IntLiteral:
            case MathTokenType.LeftParenthesis:
            case MathTokenType.Plus:
            case MathTokenType.Minus:
                return(true);
            }

            return(false);
        }
        private IExpression <T> ParsePrecedence(IScanner <Token> scanner, out Match <Token> match, int precedence)
        {
            match = new Match <Token> (scanner);
            MathTokenType tokenType = GetMathTokenType(scanner.Current);

            if (IsPrefixTokenType(tokenType))
            {
                Match <Token>   prefixMatch;
                IExpression <T> current = ParsePrefix(tokenType, scanner, out prefixMatch);
                match += prefixMatch;

                if (!match.Success)
                {
                    return(null);
                }

                tokenType = GetMathTokenType(scanner.Current);

                while (IsInfixTokenType(tokenType))
                {
                    if (precedence >= GetInfixPrecedence(tokenType))
                    {
                        break;
                    }

                    Match <Token> infixMatch;

                    current = ParseInfix(tokenType, scanner, out infixMatch, current);
                    match  += infixMatch;

                    if (!match.Success)
                    {
                        return(null);
                    }

                    tokenType = GetMathTokenType(scanner.Current);
                }

                return(current);
            }

            match = new Match <Token> (scanner, "couldn't parse math expression");
            return(null);
        }
        private IExpression <T> ParseInfix(MathTokenType type, IScanner <Token> scanner, out Match <Token> match, IExpression <T> previous)
        {
            match = new Match <Token> (scanner);

            ++match;
            scanner.MoveNext();

            Match <Token>   rightMatch;
            IExpression <T> right = ParsePrecedence(scanner, out rightMatch, GetInfixPrecedence(type));

            match += rightMatch;

            if (match.Success)
            {
                return(MakeBinaryOpExpression(type, previous, right, previous.Position));
            }

            return(null);
        }
        private bool IsInfixTokenType(MathTokenType type)
        {
            switch (type)
            {
            case MathTokenType.Plus:
            case MathTokenType.Minus:
            case MathTokenType.Multiply:
            case MathTokenType.Divide:
            case MathTokenType.Modulus:
            case MathTokenType.BitwiseAnd:
            case MathTokenType.BitwiseOr:
            case MathTokenType.BitwiseXor:
            case MathTokenType.LeftShift:
            case MathTokenType.RightShift:
            case MathTokenType.ARightShift:
                return(true);
            }

            return(false);
        }
        private IExpression <T> MakeBinaryOpExpression(MathTokenType type, IExpression <T> left, IExpression <T> right, FilePosition pos)
        {
            switch (type)
            {
            case MathTokenType.Plus:
                return(new Sum <T> (left, right, pos));

            case MathTokenType.Minus:
                return(new Minus <T> (left, right, pos));

            case MathTokenType.Multiply:
                return(new Multiply <T> (left, right, pos));

            case MathTokenType.Divide:
                return(new Division <T> (left, right, pos));

            case MathTokenType.Modulus:
                return(new Modulus <T> (left, right, pos));

            case MathTokenType.BitwiseOr:
                return(new BitwiseOr <T> (left, right, pos));

            case MathTokenType.BitwiseAnd:
                return(new BitwiseAnd <T> (left, right, pos));

            case MathTokenType.BitwiseXor:
                return(new BitwiseXor <T> (left, right, pos));

            case MathTokenType.LeftShift:
                return(new BitShiftLeft <T> (left, right, pos));

            case MathTokenType.RightShift:
                return(new BitShiftRight <T> (left, right, pos));

            case MathTokenType.ARightShift:
                return(new ArithmeticShiftRight <T> (left, right, pos));

            default:
                return(null);
            }
        }
Exemple #8
0
 public MathToken(MathTokenType t, double d)
 {
     Type  = t;
     Value = d;
     Char  = char.MinValue;
 }
Exemple #9
0
 public MathToken(MathTokenType type, double value) : this()
 {
     this.Type = type;
     Value     = value;
 }
Exemple #10
0
 public MathToken(MathTokenType type, char ch) : this()
 {
     this.Type = type;
     Char      = ch;
 }
Exemple #11
0
 public MathExpressionToken(MathTokenType tokenType, Double value)
 {
     TokenType = tokenType;
     Value     = value;
 }
Exemple #12
0
        private IExpression <T> ParsePrefix(MathTokenType type, IScanner <Token> scanner, out Match <Token> match)
        {
            match = new Match <Token> (scanner);
            IExpression <T> result = null;

            switch (type)
            {
            case MathTokenType.Identifer:
                result = new Symbol <T> (scanner.Current.Value, scanner.Current.Position);

                ++match;
                scanner.MoveNext();

                return(result);

            case MathTokenType.IntLiteral:
                try {
                    result = new ValueExpression <T> (evaluate(scanner.Current.Value), scanner.Current.Position);

                    ++match;
                    scanner.MoveNext();

                    return(result);
                } catch (Exception) {
                    match = new Match <Token> (scanner, "failed to parse integer literal \"{0}\"", scanner.Current.Value);
                    return(null);
                }

            case MathTokenType.LeftParenthesis:
            {
                ++match;
                scanner.MoveNext();

                Match <Token> outMatch;
                result = ParsePrecedence(scanner, out outMatch, (int)Precedences.NoPrecedence);

                if (scanner.Current.Type != TokenType.RightParenthesis)
                {
                    match = new Match <Token> (scanner, "couldn't find closing parenthesis");
                    return(null);
                }

                match += outMatch;

                ++match;
                scanner.MoveNext();

                return(result);
            }

            case MathTokenType.Plus:
            {
                ++match;
                scanner.MoveNext();

                Match <Token> outMatch;
                result = ParsePrecedence(scanner, out outMatch, (int)Precedences.Prefixes);
                match += outMatch;

                return(result);
            }

            case MathTokenType.Minus:
            {
                FilePosition pos = scanner.Current.Position;

                ++match;
                scanner.MoveNext();

                Match <Token> outMatch;
                result = ParsePrecedence(scanner, out outMatch, (int)Precedences.Prefixes);
                match += outMatch;

                return(new Minus <T> (null, result, pos));
            }
            }

            return(null);
        }
Exemple #13
0
 public MathExpressionToken(MathTokenType tokenType)
 {
     TokenType = tokenType;
 }
Exemple #14
0
 public MathExpressionToken(MathTokenType tokenType, char op)
 {
     TokenType = tokenType;
     Operator  = op;
 }
Exemple #15
0
 public MathExpressionToken(MathTokenType tokenType, string name)
 {
     TokenType = tokenType;
     Name      = name;
 }
Exemple #16
0
 public MathToken(MathTokenType t, double d)
 {
     Type  = t;
     Char  = '\0';
     Value = d;
 }
Exemple #17
0
 public MathToken(MathTokenType t, char c)
 {
     Type  = t;
     Char  = c;
     Value = double.NaN;
 }
Exemple #18
0
 public Token<MathTokenType> Take(MathTokenType type)
 {
     var token = Take();
     if (token.Identifier != type)
     {
         throw new ManhoodException(_src, token, String.Concat("Expression expected ", type, ", but found ", token.Identifier, "."));
     }
     return token;
 }