コード例 #1
0
 public dynamic Factor()
 {
     /* Factor: INTEGER
      | LPAREN expr RPAREN
      | Variable
      | STRING
      | TRUE
      | FALSE
      *
      */
     if (currentToken.GetTokenValueType() == TokenValues.LPAREN)
     {
         Eat(TokenValues.LPAREN);
         BinOp result = Expr();
         Eat(TokenValues.RPAREN);
         return(result);
     }
     else if (this.currentToken.GetTokenValueType() == TokenValues.INTEGER)
     {
         Token token = this.currentToken;
         Eat(TokenValues.INTEGER);
         return(new Num(token));
     }
     else if (this.currentToken.GetTokenValueType() == TokenValues.STRING)
     {
         Token token = this.currentToken;
         Eat(TokenValues.STRING);
         return(new Str(token));
     }
     else if (this.currentToken.GetTokenValueType() == TokenValues.TRUE)
     {
         Token token = this.currentToken;
         Eat(TokenValues.TRUE);
         return(new BoolNode(token));
     }
     else if (this.currentToken.GetTokenValueType() == TokenValues.FALSE)
     {
         Token token = this.currentToken;
         Eat(TokenValues.FALSE);
         return(new BoolNode(token));
     }
     else
     {
         return(Variable());
     }
 }
コード例 #2
0
        public dynamic Expr()
        {
            VisitableNode result = Term();

            HashSet <TokenValues> values = new HashSet <TokenValues>();

            values.Add(TokenValues.PLUS);
            values.Add(TokenValues.MINUS);
            values.Add(TokenValues.EQUAL);
            values.Add(TokenValues.LESSTHAN);

            /*
             *  expr    : Term ((PLUS|MINUS|EQUAL|LESSTHAN) Term) *
             *  Term    : Factor ((MUL|DIV) Factor) *
             *  Factor  : INTEGER | LPAREN expr RPAREN | Variable | STRING | TRUE | FALSE
             */
            while (values.Contains(this.currentToken.GetTokenValueType()))
            {
                TokenValues type = this.currentToken.GetTokenValueType();
                Token       curr = this.currentToken;
                switch (type)
                {
                case TokenValues.MINUS:
                    Eat(TokenValues.MINUS);
                    break;

                case TokenValues.PLUS:
                    Eat(TokenValues.PLUS);
                    break;

                case TokenValues.EQUAL:
                    Eat(TokenValues.EQUAL);
                    break;

                case TokenValues.LESSTHAN:
                    Eat(TokenValues.LESSTHAN);
                    break;

                default:
                    throw new InterpreterException("syntax error");
                }
                result = new BinOp(result, curr, this.Term());
            }
            return(result);
        }
コード例 #3
0
        public dynamic Term()
        {
            //Term: Factor ((MUL|DIV) factor)*
            var result = Factor();

            while (this.currentToken.GetTokenValueType() == TokenValues.DIVISION || this.currentToken.GetTokenValueType() == TokenValues.MULTIPLY)
            {
                Token token = this.currentToken;
                if (currentToken.GetTokenValueType() == TokenValues.MULTIPLY)
                {
                    Eat(TokenValues.MULTIPLY);
                }
                else
                {
                    Eat(TokenValues.DIVISION);
                }
                result = new BinOp(result, token, this.Factor());
            }


            return(result);
        }
コード例 #4
0
        // A hot mess but gets the return value based on types given left and right
        public dynamic visit(BinOp binOp)
        {
            int  left      = 0;
            int  right     = 0;
            Type leftType  = binOp.getLeft().GetType();
            Type rightType = binOp.getRight().GetType();

            if (leftType == typeof(Num))
            {
                left = this.visit((Num)binOp.getLeft());
            }
            else if (leftType == typeof(BinOp))
            {
                left = this.visit((BinOp)binOp.getLeft());
            }
            else if (leftType == typeof(Var))
            {
                left = this.visit((Var)binOp.getLeft());
            }

            if (rightType == typeof(Num))
            {
                right = this.visit((Num)binOp.getRight());
            }
            else if (rightType == typeof(BinOp))
            {
                right = this.visit((BinOp)binOp.getRight());
            }
            else if (rightType == typeof(Var))
            {
                right = this.visit((Var)binOp.getRight());
            }

            if (leftType == typeof(Str))
            {
                if (rightType == typeof(Str))
                {
                    if (binOp.getOp().GetTokenValueType() == TokenValues.PLUS)
                    {
                        return(this.visit((Str)binOp.getLeft()) + this.visit((Str)binOp.getRight()));
                    }
                }
                else
                {
                    throw new InterpreterException(String.Format("Incompatible types for operation {0}: {1} {2}", binOp.getOp().GetTokenValueType(), leftType, rightType));
                }
            }

            switch (binOp.getOp().GetTokenValueType())
            {
            case TokenValues.PLUS:
                return(left + right);

            case TokenValues.MINUS:
                return(left - right);

            case TokenValues.MULTIPLY:
                return(left * right);

            case TokenValues.DIVISION:
                return(left / right);

            case TokenValues.EQUAL:
                return(left == right);

            case TokenValues.LESSTHAN:
                return(left < right);

            default:
                throw(new InterpreterException("Invalid syntax"));
            }
        }