示例#1
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // Returns a dynamic InvokeMember or Invoke expression, depending on the
        // Function expression.
        //
        public static DynamicExpression AnalyzeFunCallExpr(
            SymplFunCallExpr expr, AnalysisScope scope)
        {
            if (expr.Function is SymplDottedExpr)
            {
                SymplDottedExpr dottedExpr = (SymplDottedExpr)expr.Function;
                Expression      objExpr;
                int             length = dottedExpr.Exprs.Length;
                if (length > 1)
                {
                    objExpr = AnalyzeDottedExpr(
                        // create a new dot expression for the object that doesn't
                        // include the last part
                        new SymplDottedExpr(
                            dottedExpr.ObjectExpr,
                            RuntimeHelpers.RemoveLast(dottedExpr.Exprs)),
                        scope
                        );
                }
                else
                {
                    objExpr = AnalyzeExpr(dottedExpr.ObjectExpr, scope);
                }
                List <Expression> args = new List <Expression>();
                args.Add(objExpr);
                args.AddRange(expr.Arguments.Select(a => AnalyzeExpr(a, scope)));

                // last expr must be an id
                var lastExpr = (SymplIdExpr)(dottedExpr.Exprs.Last());
                return(Expression.Dynamic(
                           scope.GetRuntime().GetInvokeMemberBinder(
                               new InvokeMemberBinderKey(
                                   lastExpr.IdToken.Name,
                                   new CallInfo(expr.Arguments.Length))),
                           typeof(object),
                           args
                           ));
            }
            else
            {
                var fun = AnalyzeExpr(expr.Function, scope);
                List <Expression> args = new List <Expression>();
                args.Add(fun);
                args.AddRange(expr.Arguments.Select(a => AnalyzeExpr(a, scope)));
                // Use DynExpr so that I don't always have to have a delegate to call,
                // such as what happens with IPy interop.
                return(Expression.Dynamic(
                           scope.GetRuntime()
                           .GetInvokeBinder(new CallInfo(expr.Arguments.Length)),
                           typeof(object),
                           args
                           ));
            }
        }
示例#2
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()));
        }