예제 #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());
        }
예제 #2
0
파일: ETGen.cs 프로젝트: kuny/MeagerLisp
        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)
                       ));
        }
예제 #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()));
        }
예제 #4
0
파일: ETGen.cs 프로젝트: kuny/MeagerLisp
 // 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()
                        ));
         }
     }
 }