Exemplo n.º 1
0
        // _parseExpr parses an expression from the Lexer passed in.
        //
        private SymplExpr ParseExprAux(Lexer lexer)
        {
            Token     token = lexer.GetToken();
            SymplExpr res   = null;

            if (token == SyntaxToken.EOF)
            {
                throw new SymplParseException(
                          "Unexpected EOF encountered while parsing expression.");
            }
            if (token == SyntaxToken.Quote)
            {
                lexer.PutToken(token);
                res = ParseQuoteExpr(lexer);
            }
            else if (token == SyntaxToken.Paren)
            {
                lexer.PutToken(token);
                res = ParseForm(lexer);
            }
            else if (token is IdOrKeywordToken)
            {
                // If we encounter literal kwd constants, they get turned into ID
                // Exprs.  Code that accepts Id Exprs, needs to check if the token is
                // kwd or not when it matters.
                if ((token is KeywordToken) && !(token == KeywordToken.Nil) &&
                    !(token == KeywordToken.True) && !(token == KeywordToken.False))
                {
                    throw new InvalidCastException("Keyword cannot be an expression");
                }
                else
                {
                    res = new SymplIdExpr((IdOrKeywordToken)token);
                }
            }
            else if (token is LiteralToken)
            {
                res = new SymplLiteralExpr(((LiteralToken)token).Value);
            }
            // check for dotted expr
            if (res != null)
            {
                Token next = lexer.GetToken();
                lexer.PutToken(next);
                if (next == SyntaxToken.Dot)
                {
                    return(ParseDottedExpr(lexer, res));
                }
                else
                {
                    return(res);
                }
            }
            throw new SymplParseException(
                      "Unexpected token when expecting " +
                      "beginning of expression -- " + token.ToString() + " ... " +
                      lexer.GetToken().ToString() + lexer.GetToken().ToString() +
                      lexer.GetToken().ToString() + lexer.GetToken().ToString());
        }
Exemplo n.º 2
0
        public static Expression AnalyzeBinaryExpr(SymplBinaryExpr expr,
                                                   AnalysisScope scope)
        {
            // The language has the following special logic to handle And and Or
            // x And y == if x then y
            // x Or y == if x then x else (if y then y)
            if (expr.Operation == ExpressionType.And)
            {
                return(AnalyzeIfExpr(
                           new SymplIfExpr(
                               expr.Left, expr.Right, null),
                           scope));
            }
            else if (expr.Operation == ExpressionType.Or)
            {
                // Use (LetStar (tmp expr) (if tmp tmp)) to represent (if expr expr)
                // to remore duplicate evaluation.
                // So x Or y is translated into
                // (Let* (tmp1 x)
                //    (If tmp1 tmp1
                //       (Let* (tmp2 y) (If tmp2 tmp2))))
                //

                IdOrKeywordToken tmp2 = new IdOrKeywordToken(
                    // Real implementation needs to ensure unique ID in scope chain.
                    "__tmpLetVariable2");
                var tmpExpr2 = new SymplIdExpr(tmp2);
                var binding2 = new LetBinding(tmp2, expr.Right);;
                var ifExpr2  = new SymplIfExpr(
                    tmpExpr2, tmpExpr2, null);
                var letExpr2 = new SymplLetStarExpr(
                    new[] { binding2 },
                    new[] { ifExpr2 });

                IdOrKeywordToken tmp1 = new IdOrKeywordToken(
                    // Real implementation needs to ensure unique ID in scope chain.
                    "__tmpLetVariable1");
                var        tmpExpr1 = new SymplIdExpr(tmp1);
                LetBinding binding1 = new LetBinding(tmp1, expr.Left);;
                SymplExpr  ifExpr1  = new SymplIfExpr(
                    tmpExpr1, tmpExpr1, letExpr2);
                return(AnalyzeLetStarExpr(
                           new SymplLetStarExpr(
                               new[] { binding1 },
                               new[] { ifExpr1 }
                               ),
                           scope
                           ));
            }

            return(Expression.Dynamic(
                       scope.GetRuntime().GetBinaryOperationBinder(expr.Operation),
                       typeof(object),
                       AnalyzeExpr(expr.Left, scope),
                       AnalyzeExpr(expr.Right, scope)
                       ));
        }
Exemplo n.º 3
0
        // _parseDottedExpr gathers infix dotted member access expressions.  The
        // object expression can be anything and is passed in via expr.  Successive
        // member accesses must be dotted identifier expressions or member invokes --
        // a.b.(c 3).d.  The member invokes cannot have dotted expressions for the
        // member name such as a.(b.c 3).
        //
        private SymplDottedExpr ParseDottedExpr(Lexer lexer, SymplExpr objExpr)
        {
            Token token = lexer.GetToken();

            if (token != SyntaxToken.Dot)
            {
                throw new SymplParseException(
                          "Internal: parsing dotted expressions?");
            }
            List <SymplExpr> exprs = new List <SymplExpr>();

            token = lexer.GetToken();
            while (token is IdOrKeywordToken || token == SyntaxToken.Paren)
            {
                // Needs to be fun call or IDs
                SymplExpr expr;
                if (token is IdOrKeywordToken)
                {
                    // Keywords are ok as member names.
                    expr = new SymplIdExpr((IdOrKeywordToken)token);
                }
                else
                {
                    lexer.PutToken(token);
                    expr = ParseForm(lexer);
                    SymplFunCallExpr funCall = expr as SymplFunCallExpr;
                    if (funCall != null || !(funCall.Function is SymplIdExpr))
                    {
                        throw new SymplParseException(
                                  "Dotted expressions must be identifiers or " +
                                  "function calls with identiers as the function " +
                                  "value -- " + expr.ToString());
                    }
                }
                exprs.Add(expr);
                token = lexer.GetToken();
                if (token != SyntaxToken.Dot)
                {
                    break;
                }
                token = lexer.GetToken();
            }
            lexer.PutToken(token);
            return(new SymplDottedExpr(objExpr, exprs.ToArray()));
        }
Exemplo n.º 4
0
		// _parseExpr parses an expression from the Lexer passed in.
		//
        private SymplExpr ParseExprAux(Lexer lexer) {
            Token token = lexer.GetToken();
            SymplExpr res = null;
            if (token == SyntaxToken.EOF) {
                throw new SymplParseException(
                    "Unexpected EOF encountered while parsing expression.");
            }
            if (token == SyntaxToken.Quote) {
                lexer.PutToken(token);
                res = ParseQuoteExpr(lexer);
            } else if (token == SyntaxToken.Paren) {
                lexer.PutToken(token);
                res = ParseForm(lexer);
            } else if (token is IdOrKeywordToken) {
                // If we encounter literal kwd constants, they get turned into ID
                // Exprs.  Code that accepts Id Exprs, needs to check if the token is
                // kwd or not when it matters.
                if ((token is KeywordToken) && !(token == KeywordToken.Nil) &&
                    !(token == KeywordToken.True) && !(token == KeywordToken.False)) {
                    throw new InvalidCastException("Keyword cannot be an expression");
                } else {
                    res = new SymplIdExpr((IdOrKeywordToken)token);
                }
            } else if (token is LiteralToken) {
                res = new SymplLiteralExpr(((LiteralToken)token).Value);
            }
            // check for dotted expr
            if (res != null) {
                Token next = lexer.GetToken();
                lexer.PutToken(next);
                if (next == SyntaxToken.Dot) {
                    return ParseDottedExpr(lexer, res);
                } else {
                    return res;
                }
            }
            throw new SymplParseException(
                "Unexpected token when expecting " +
                "beginning of expression -- " + token.ToString() + " ... " + 
                lexer.GetToken().ToString() + lexer.GetToken().ToString() + 
                lexer.GetToken().ToString() + lexer.GetToken().ToString());
        }
Exemplo n.º 5
0
 // Return an Expression for referencing the ID.  If we find the name in the
 // scope chain, then we just return the stored ParamExpr.  Otherwise, the
 // reference is a dynamic member lookup on the root scope, a module object.
 //
 public static Expression AnalyzeIdExpr(SymplIdExpr expr,
                                        AnalysisScope scope)
 {
     if (expr.IdToken.IsKeywordToken)
     {
         if (expr.IdToken == KeywordToken.Nil)
         {
             return(Expression.Constant(null, typeof(object)));
         }
         else if (expr.IdToken == KeywordToken.True)
         {
             return(Expression.Constant(true));
         }
         else if (expr.IdToken == KeywordToken.False)
         {
             return(Expression.Constant(false));
         }
         else
         {
             throw new InvalidOperationException(
                       "Internal: unrecognized keyword literal constant.");
         }
     }
     else
     {
         var param = FindIdDef(expr.IdToken.Name, scope);
         if (param != null)
         {
             return(param);
         }
         else
         {
             return(Expression.Dynamic(
                        scope.GetRuntime().GetGetMemberBinder(expr.IdToken.Name),
                        typeof(object),
                        scope.GetModuleExpr()
                        ));
         }
     }
 }
Exemplo n.º 6
0
 // _parseDottedExpr gathers infix dotted member access expressions.  The
 // object expression can be anything and is passed in via expr.  Successive
 // member accesses must be dotted identifier expressions or member invokes --
 // a.b.(c 3).d.  The member invokes cannot have dotted expressions for the
 // member name such as a.(b.c 3).
 //
 private SymplDottedExpr ParseDottedExpr(Lexer lexer, SymplExpr objExpr) {
     Token token = lexer.GetToken();
     if (token != SyntaxToken.Dot) {
         throw new SymplParseException(
             "Internal: parsing dotted expressions?");
     }
     List<SymplExpr> exprs = new List<SymplExpr>();
     token = lexer.GetToken();
     while (token is IdOrKeywordToken || token == SyntaxToken.Paren) {
         // Needs to be fun call or IDs
         SymplExpr expr;
         if (token is IdOrKeywordToken) {
             // Keywords are ok as member names.
             expr = new SymplIdExpr((IdOrKeywordToken)token);
         } else {
             lexer.PutToken(token);
             expr = ParseForm(lexer);
             SymplFunCallExpr funCall = expr as SymplFunCallExpr;
             if (funCall != null || !(funCall.Function is SymplIdExpr)) {
                 throw new SymplParseException(
                     "Dotted expressions must be identifiers or " +
                     "function calls with identiers as the function " +
                     "value -- " + expr.ToString());
             }
         }
         exprs.Add(expr);
         token = lexer.GetToken();
         if (token != SyntaxToken.Dot) {
             break;
         }
         token = lexer.GetToken();
     }
     lexer.PutToken(token);
     return new SymplDottedExpr(objExpr, exprs.ToArray());
 }
Exemplo n.º 7
0
        public static Expression AnalyzeBinaryExpr(SymplBinaryExpr expr,
                                                   AnalysisScope scope) {

            // The language has the following special logic to handle And and Or
            // x And y == if x then y
            // x Or y == if x then x else (if y then y)
            if (expr.Operation == ExpressionType.And) {
                return AnalyzeIfExpr(
                    new SymplIfExpr(
                        expr.Left, expr.Right, null),
                    scope); 
            } else if (expr.Operation == ExpressionType.Or) {
                // Use (LetStar (tmp expr) (if tmp tmp)) to represent (if expr expr)
                // to remore duplicate evaluation.
                // So x Or y is translated into
                // (Let* (tmp1 x) 
                //    (If tmp1 tmp1  
                //       (Let* (tmp2 y) (If tmp2 tmp2))))
                //           

                IdOrKeywordToken tmp2 = new IdOrKeywordToken(
                    // Real implementation needs to ensure unique ID in scope chain.
                    "__tmpLetVariable2");
                var tmpExpr2 = new SymplIdExpr(tmp2);
                var binding2 = new LetBinding(tmp2, expr.Right); ;
                var ifExpr2 = new SymplIfExpr(
                    tmpExpr2, tmpExpr2, null);
                var letExpr2 = new SymplLetStarExpr(
                        new[] { binding2 },
                        new[] { ifExpr2 });

                IdOrKeywordToken tmp1 = new IdOrKeywordToken(
                    // Real implementation needs to ensure unique ID in scope chain.
                    "__tmpLetVariable1");
                var tmpExpr1 = new SymplIdExpr(tmp1);
                LetBinding binding1 = new LetBinding(tmp1, expr.Left); ;
                SymplExpr ifExpr1 = new SymplIfExpr(
                    tmpExpr1, tmpExpr1, letExpr2);
                return AnalyzeLetStarExpr(
                    new SymplLetStarExpr(
                        new[] { binding1 },
                        new[] { ifExpr1 }
                    ),
                    scope
                );
            }

            return Expression.Dynamic(
                scope.GetRuntime().GetBinaryOperationBinder(expr.Operation),
                typeof(object),
                AnalyzeExpr(expr.Left, scope),
                AnalyzeExpr(expr.Right, scope)
            );
        }
Exemplo n.º 8
0
		// Return an Expression for referencing the ID.  If we find the name in the
		// scope chain, then we just return the stored ParamExpr.  Otherwise, the
		// reference is a dynamic member lookup on the root scope, a module object.
		//
        public static Expression AnalyzeIdExpr(SymplIdExpr expr,
                                                AnalysisScope scope) {
            if (expr.IdToken.IsKeywordToken) {
                if (expr.IdToken == KeywordToken.Nil)
                    return Expression.Constant(null, typeof(object));
                else if (expr.IdToken == KeywordToken.True)
                    return Expression.Constant(true);
                else if (expr.IdToken == KeywordToken.False)
                    return Expression.Constant(false);
                else
                    throw new InvalidOperationException(
                        "Internal: unrecognized keyword literal constant.");
            } else {
                var param = FindIdDef(expr.IdToken.Name, scope);
                if (param != null) {
                    return param;
                } else {
                    return Expression.Dynamic(
                       scope.GetRuntime().GetGetMemberBinder(expr.IdToken.Name),
                       typeof(object),
                       scope.GetModuleExpr()
                    );
                }
            }
        }