示例#1
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        public static Expression AnalyzeBreakExpr(SymplBreakExpr expr,
                                                  AnalysisScope scope)
        {
            var loopscope = _findFirstLoop(scope);

            if (loopscope == null)
            {
                throw new InvalidOperationException(
                          "Call to Break not inside loop.");
            }
            Expression value;

            if (expr.Value == null)
            {
                value = Expression.Constant(null, typeof(object));
            }
            else
            {
                // Ok if value jumps to break label.
                value = AnalyzeExpr(expr.Value, loopscope);
            }
            // Need final type=object arg because the Goto is in a value returning
            // position, and the Break factory doesn't set the GotoExpr.Type property
            // to the type of the LoopBreak label target's type.  For example, removing
            // this would cause the Convert to object for an If branch to throw because
            // the Goto is void without this last arg.
            return(Expression.Break(loopscope.LoopBreak, value, typeof(object)));
        }
示例#2
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // AnalyzeLetStar returns a Block with vars, each initialized in the order
        // they appear.  Each var's init expr can refer to vars initialized before it.
        // The Block's body is the Let*'s body.
        //
        public static Expression AnalyzeLetStarExpr(SymplLetStarExpr expr,
                                                    AnalysisScope scope)
        {
            var letscope = new AnalysisScope(scope, "let*");
            // Analyze bindings.
            List <Expression>          inits       = new List <Expression>();
            List <ParameterExpression> varsInOrder = new List <ParameterExpression>();

            foreach (var b in expr.Bindings)
            {
                // Need richer logic for mvbind
                var v = Expression.Parameter(typeof(object), b.Variable.Name);
                varsInOrder.Add(v);
                inits.Add(
                    Expression.Assign(
                        v,
                        Expression.Convert(AnalyzeExpr(b.Value, letscope), v.Type))
                    );
                // Add var to scope after analyzing init value so that init value
                // references to the same ID do not bind to his uninitialized var.
                letscope.Names[b.Variable.Name.ToLower()] = v;
            }
            List <Expression> body = new List <Expression>();

            foreach (var e in expr.Body)
            {
                body.Add(AnalyzeExpr(e, letscope));
            }
            // Order of vars to BlockExpr don't matter semantically, but may as well
            // keep them in the order the programmer specified in case they look at the
            // Expr Trees in the debugger or for meta-programming.
            inits.AddRange(body);
            return(Expression.Block(typeof(object), varsInOrder.ToArray(), inits));
        }
示例#3
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // _findIdDef returns the ParameterExpr for the name by searching the scopes,
        // or it returns None.
        //
        private static Expression FindIdDef(string name, AnalysisScope scope)
        {
            var curscope = scope;

            name = name.ToLower();
            ParameterExpression res;

            while (curscope != null && !curscope.IsModule)
            {
                if (curscope.Names.TryGetValue(name, out res))
                {
                    return(res);
                }
                else
                {
                    curscope = curscope.Parent;
                }
            }

            if (scope == null)
            {
                throw new InvalidOperationException(
                          "Got bad AnalysisScope chain with no module at end.");
            }

            return(null);
        }
示例#4
0
文件: Sympl.cs 项目: kuny/MeagerLisp
        ParseFileToLambda(string filename, TextReader reader)
        {
            var asts  = new Parser().ParseFile(reader);
            var scope = new AnalysisScope(
                null,
                filename,
                this,
                Expression.Parameter(typeof(Sympl), "symplRuntime"),
                Expression.Parameter(typeof(IDynamicMetaObjectProvider),
                                     "fileModule"));
            List <Expression> body = new List <Expression>();

            foreach (var e in asts)
            {
                body.Add(ETGen.AnalyzeExpr(e, scope));
            }
            body.Add(Expression.Constant(null));
            var moduleFun = Expression.Lambda <Func <Sympl, IDynamicMetaObjectProvider,
                                                     object> >(
                Expression.Block(body),
                scope.RuntimeExpr,
                scope.ModuleExpr);

            return(moduleFun);
        }
示例#5
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)
                       ));
        }
示例#6
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // AnalyzeBlockExpr returns a Block with the body exprs.
        //
        public static Expression AnalyzeBlockExpr(SymplBlockExpr expr,
                                                  AnalysisScope scope)
        {
            List <Expression> body = new List <Expression>();

            foreach (var e in expr.Body)
            {
                body.Add(AnalyzeExpr(e, scope));
            }
            return(Expression.Block(typeof(object), body));
        }
示例#7
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
                           ));
            }
        }
示例#8
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        public static Expression AnalyzeConsExpr(SymplConsExpr expr,
                                                 AnalysisScope scope)
        {
            var mi = typeof(RuntimeHelpers).GetMethod("MakeCons");

            return(Expression.Call(mi, Expression.Convert(
                                       AnalyzeExpr(expr.Left, scope),
                                       typeof(object)),
                                   Expression.Convert(
                                       AnalyzeExpr(expr.Right, scope),
                                       typeof(object))));
        }
示例#9
0
文件: ETGen.cs 项目: kuny/MeagerLisp
 public static DynamicExpression AnalyzeDefunExpr(SymplDefunExpr expr,
                                                  AnalysisScope scope)
 {
     if (!scope.IsModule)
     {
         throw new InvalidOperationException(
                   "Use Defmethod or Lambda when not defining top-level function.");
     }
     return(Expression.Dynamic(
                scope.GetRuntime().GetSetMemberBinder(expr.Name),
                typeof(object),
                scope.ModuleExpr,
                AnalyzeLambdaDef(expr.Params, expr.Body, scope,
                                 "defun " + expr.Name)));
 }
示例#10
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        public AnalysisScope(AnalysisScope parent,
                             string name,
                             Sympl runtime,
                             ParameterExpression runtimeParam,
                             ParameterExpression moduleParam)
        {
            _parent       = parent;
            _name         = name;
            _runtime      = runtime;
            _runtimeParam = runtimeParam;
            _moduleParam  = moduleParam;

            _names    = new Dictionary <string, ParameterExpression>();
            _isLambda = false;
        }
示例#11
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // AnalyzeEltExpr returns and Expression for accessing an element of an
        // aggregate structure.  This also works for .NET objs with indexer Item
        // properties.  We handle analyzing Elt for assignment in AnalyzeAssignExpr.
        //
        public static Expression AnalyzeEltExpr(SymplEltExpr expr,
                                                AnalysisScope scope)
        {
            List <Expression> args = new List <Expression>();

            args.Add(AnalyzeExpr(expr.ObjectExpr, scope));
            args.AddRange(expr.Indexes.Select(e => AnalyzeExpr(e, scope)));

            return(Expression.Dynamic(
                       scope.GetRuntime().GetGetIndexBinder(
                           new CallInfo(expr.Indexes.Length)),
                       typeof(object),
                       args
                       ));
        }
示例#12
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        public static Expression AnalyzeListCallExpr(SymplListCallExpr expr,
                                                     AnalysisScope scope)
        {
            var mi   = typeof(Cons).GetMethod("_List");
            int len  = expr.Elements.Length;
            var args = new Expression[len];

            for (int i = 0; i < len; i++)
            {
                args[i] = Expression.Convert(AnalyzeExpr(expr.Elements[i], scope),
                                             typeof(object));
            }
            return(Expression.Call(mi, Expression
                                   .NewArrayInit(typeof(object), args)));
        }
示例#13
0
文件: ETGen.cs 项目: kuny/MeagerLisp
 public static Expression AnalyzeUnaryExpr(SymplUnaryExpr expr,
                                           AnalysisScope scope)
 {
     if (expr.Operation == ExpressionType.Not)
     {
         return(Expression.Not(WrapBooleanTest(AnalyzeExpr(expr.Operand,
                                                           scope))));
     }
     // Example purposes only, we should never get here since we only have Not.
     return(Expression.Dynamic(
                scope.GetRuntime().GetUnaryOperationBinder(expr.Operation),
                typeof(object),
                AnalyzeExpr(expr.Operand, scope)
                ));
 }
示例#14
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        public static Expression AnalyzeNewExpr(SymplNewExpr expr,
                                                AnalysisScope scope)
        {
            List <Expression> args = new List <Expression>();

            args.Add(AnalyzeExpr(expr.Type, scope));
            args.AddRange(expr.Arguments.Select(a => AnalyzeExpr(a, scope)));

            return(Expression.Dynamic(
                       scope.GetRuntime().GetCreateInstanceBinder(
                           new CallInfo(expr.Arguments.Length)),
                       typeof(object),
                       args
                       ));
        }
示例#15
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // _findFirstLoop returns the first loop AnalysisScope or None.
        //
        private static AnalysisScope _findFirstLoop(AnalysisScope scope)
        {
            var curscope = scope;

            while (curscope != null)
            {
                if (curscope.IsLoop)
                {
                    return(curscope);
                }
                else
                {
                    curscope = curscope.Parent;
                }
            }
            return(null);
        }
示例#16
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        public static Expression AnalyzeLoopExpr(SymplLoopExpr expr,
                                                 AnalysisScope scope)
        {
            var loopscope = new AnalysisScope(scope, "loop ");

            loopscope.IsLoop    = true; // needed for break and continue
            loopscope.LoopBreak = Expression.Label(typeof(object), "loop break");
            int len  = expr.Body.Length;
            var body = new Expression[len];

            for (int i = 0; i < len; i++)
            {
                body[i] = AnalyzeExpr(expr.Body[i], loopscope);
            }
            return(Expression.Loop(Expression.Block(typeof(object), body),
                                   loopscope.LoopBreak));
        }
示例#17
0
文件: ETGen.cs 项目: kuny/MeagerLisp
 public static Expression AnalyzeImportExpr(SymplImportExpr expr,
                                            AnalysisScope scope)
 {
     if (!scope.IsModule)
     {
         throw new InvalidOperationException(
                   "Import expression must be a top level expression.");
     }
     return(Expression.Call(
                typeof(RuntimeHelpers).GetMethod("SymplImport"),
                scope.RuntimeExpr,
                scope.ModuleExpr,
                Expression.Constant(expr.NamespaceExpr.Select(id => id.Name)
                                    .ToArray()),
                Expression.Constant(expr.MemberNames.Select(id => id.Name)
                                    .ToArray()),
                Expression.Constant(expr.Renames.Select(id => id.Name)
                                    .ToArray())));
 }
示例#18
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        public static Expression AnalyzeIfExpr(SymplIfExpr expr,
                                               AnalysisScope scope)
        {
            Expression alt = null;

            if (expr.Alternative != null)
            {
                alt = AnalyzeExpr(expr.Alternative, scope);
            }
            else
            {
                alt = Expression.Constant(false);
            }
            return(Expression.Condition(
                       WrapBooleanTest(AnalyzeExpr(expr.Test, scope)),
                       Expression.Convert(AnalyzeExpr(expr.Consequent, scope),
                                          typeof(object)),
                       Expression.Convert(alt, typeof(object))));
        }
示例#19
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // Returns a chain of GetMember and InvokeMember dynamic expressions for
        // the dotted expr.
        //
        public static Expression AnalyzeDottedExpr(SymplDottedExpr expr,
                                                   AnalysisScope scope)
        {
            var curExpr = AnalyzeExpr(expr.ObjectExpr, scope);

            foreach (var e in expr.Exprs)
            {
                if (e is SymplIdExpr)
                {
                    curExpr = Expression.Dynamic(
                        scope.GetRuntime()
                        .GetGetMemberBinder(((SymplIdExpr)e).IdToken.Name),
                        typeof(object),
                        curExpr
                        );
                }
                else if (e is SymplFunCallExpr)
                {
                    var call = (SymplFunCallExpr)e;
                    List <Expression> args = new List <Expression>();
                    args.Add(curExpr);
                    args.AddRange(call.Arguments.Select(a => AnalyzeExpr(a, scope)));

                    curExpr = Expression.Dynamic(
                        // Dotted exprs must be simple invoke members, a.b.(c ...)
                        scope.GetRuntime().GetInvokeMemberBinder(
                            new InvokeMemberBinderKey(
                                ((SymplIdExpr)call.Function).IdToken.Name,
                                new CallInfo(call.Arguments.Length))),
                        typeof(object),
                        args
                        );
                }
                else
                {
                    throw new InvalidOperationException(
                              "Internal: dotted must be IDs or Funs.");
                }
            }
            return(curExpr);
        }
示例#20
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()
                        ));
         }
     }
 }
示例#21
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        private static Expression AnalyzeLambdaDef
            (IdOrKeywordToken[] parms, SymplExpr[] body,
            AnalysisScope scope, string description)
        {
            var funscope = new AnalysisScope(scope, description);

            funscope.IsLambda = true;  // needed for return support.
            var paramsInOrder = new List <ParameterExpression>();

            foreach (var p in parms)
            {
                var pe = Expression.Parameter(typeof(object), p.Name);
                paramsInOrder.Add(pe);
                funscope.Names[p.Name.ToLower()] = pe;
            }
            // No need to add fun name to module scope since recursive call just looks
            // up global name late bound.  For lambdas,to get the effect of flet to
            // support recursion, bind a variable to nil and then set it to a lambda.
            // Then the lambda's body can refer to the let bound var in its def.
            var bodyexprs = new List <Expression>();

            foreach (var e in body)
            {
                bodyexprs.Add(AnalyzeExpr(e, funscope));
            }
            // Set up the Type arg array for the delegate type.  Must include
            // the return type as the last Type, which is object for Sympl defs.
            var funcTypeArgs = new List <Type>();

            for (int i = 0; i < parms.Length + 1; i++)
            {
                funcTypeArgs.Add(typeof(object));
            }
            return(Expression.Lambda(
                       Expression.GetFuncType(funcTypeArgs.ToArray()),
                       Expression.Block(bodyexprs),
                       paramsInOrder));
        }
示例#22
0
文件: Sympl.cs 项目: kuny/MeagerLisp
        ParseExprToLambda(TextReader reader)
        {
            var ast   = new Parser().ParseExpr(reader);
            var scope = new AnalysisScope(
                null,
                "__snippet__",
                this,
                Expression.Parameter(typeof(Sympl), "symplRuntime"),
                Expression.Parameter(typeof(IDynamicMetaObjectProvider),
                                     "fileModule"));
            List <Expression> body = new List <Expression>();

            body.Add(Expression.Convert(ETGen.AnalyzeExpr(ast, scope),
                                        typeof(object)));
            var moduleFun = Expression.Lambda <Func <Sympl, IDynamicMetaObjectProvider,
                                                     object> >(
                Expression.Block(body),
                scope.RuntimeExpr,
                scope.ModuleExpr
                );

            return(moduleFun);
        }
示例#23
0
文件: ETGen.cs 项目: kuny/MeagerLisp
 public static Expression AnalyzeExpr(SymplExpr expr, AnalysisScope scope)
 {
     if (expr is SymplImportExpr)
     {
         return(AnalyzeImportExpr((SymplImportExpr)expr, scope));
     }
     else if (expr is SymplFunCallExpr)
     {
         return(AnalyzeFunCallExpr((SymplFunCallExpr)expr, scope));
     }
     else if (expr is SymplDefunExpr)
     {
         return(AnalyzeDefunExpr((SymplDefunExpr)expr, scope));
     }
     else if (expr is SymplLambdaExpr)
     {
         return(AnalyzeLambdaExpr((SymplLambdaExpr)expr, scope));
     }
     else if (expr is SymplIdExpr)
     {
         return(AnalyzeIdExpr((SymplIdExpr)expr, scope));
     }
     else if (expr is SymplQuoteExpr)
     {
         return(AnalyzeQuoteExpr((SymplQuoteExpr)expr, scope));
     }
     else if (expr is SymplLiteralExpr)
     {
         return(Expression.Constant(((SymplLiteralExpr)expr).Value));
     }
     else if (expr is SymplAssignExpr)
     {
         return(AnalyzeAssignExpr((SymplAssignExpr)expr, scope));
     }
     else if (expr is SymplLetStarExpr)
     {
         return(AnalyzeLetStarExpr((SymplLetStarExpr)expr, scope));
     }
     else if (expr is SymplBlockExpr)
     {
         return(AnalyzeBlockExpr((SymplBlockExpr)expr, scope));
     }
     else if (expr is SymplEqExpr)
     {
         return(AnalyzeEqExpr((SymplEqExpr)expr, scope));
     }
     else if (expr is SymplConsExpr)
     {
         return(AnalyzeConsExpr((SymplConsExpr)expr, scope));
     }
     else if (expr is SymplListCallExpr)
     {
         return(AnalyzeListCallExpr((SymplListCallExpr)expr, scope));
     }
     else if (expr is SymplIfExpr)
     {
         return(AnalyzeIfExpr((SymplIfExpr)expr, scope));
     }
     else if (expr is SymplDottedExpr)
     {
         return(AnalyzeDottedExpr((SymplDottedExpr)expr, scope));
     }
     else if (expr is SymplNewExpr)
     {
         return(AnalyzeNewExpr((SymplNewExpr)expr, scope));
     }
     else if (expr is SymplLoopExpr)
     {
         return(AnalyzeLoopExpr((SymplLoopExpr)expr, scope));
     }
     else if (expr is SymplBreakExpr)
     {
         return(AnalyzeBreakExpr((SymplBreakExpr)expr, scope));
     }
     else if (expr is SymplEltExpr)
     {
         return(AnalyzeEltExpr((SymplEltExpr)expr, scope));
     }
     else if (expr is SymplBinaryExpr)
     {
         return(AnalyzeBinaryExpr((SymplBinaryExpr)expr, scope));
     }
     else if (expr is SymplUnaryExpr)
     {
         return(AnalyzeUnaryExpr((SymplUnaryExpr)expr, scope));
     }
     else
     {
         throw new InvalidOperationException(
                   "Internal: no expression to analyze.");
     }
 }
示例#24
0
文件: ETGen.cs 项目: kuny/MeagerLisp
        // AnalyzeAssignExpr handles IDs, indexing, and member sets.  IDs are either
        // lexical or dynamic exprs on the module scope.  Everything
        // else is dynamic.
        //
        public static Expression AnalyzeAssignExpr(SymplAssignExpr expr,
                                                   AnalysisScope scope)
        {
            if (expr.Location is SymplIdExpr)
            {
                var idExpr = (SymplIdExpr)(expr.Location);
                var lhs    = AnalyzeExpr(expr.Location, scope);
                var val    = AnalyzeExpr(expr.Value, scope);
                var param  = FindIdDef(idExpr.IdToken.Name, scope);
                if (param != null)
                {
                    // Assign returns value stored.
                    return(Expression.Assign(
                               lhs,
                               Expression.Convert(val, param.Type)));
                }
                else
                {
                    var tmp = Expression.Parameter(typeof(object),
                                                   "assignTmpForRes");
                    // Ensure stored value is returned.  Had some erroneous
                    // MOs come through here and left the code for example.
                    return(Expression.Block(
                               new[] { tmp },
                               Expression.Assign(
                                   tmp,
                                   Expression.Convert(val, typeof(object))),
                               Expression.Dynamic(
                                   scope.GetRuntime()
                                   .GetSetMemberBinder(idExpr.IdToken.Name),
                                   typeof(object),
                                   scope.GetModuleExpr(),
                                   tmp),
                               tmp));
                }
            }
            else if (expr.Location is SymplEltExpr)
            {
                var eltExpr = (SymplEltExpr)(expr.Location);
                var args    = new List <Expression>();
                args.Add(AnalyzeExpr(eltExpr.ObjectExpr, scope));
                args.AddRange(eltExpr.Indexes.Select(e => AnalyzeExpr(e, scope)));
                args.Add(AnalyzeExpr(expr.Value, scope));
                // Trusting MO convention to return stored values.
                return(Expression.Dynamic(
                           scope.GetRuntime().GetSetIndexBinder(
                               new CallInfo(eltExpr.Indexes.Length)),
                           typeof(object),
                           args));
            }
            else if (expr.Location is SymplDottedExpr)
            {
                // For now, one dot only.  Later, pick oflast dotted member
                // access (like AnalyzeFunctionCall), and use a temp and block.
                var dottedExpr = (SymplDottedExpr)(expr.Location);
                if (dottedExpr.Exprs.Length > 1)
                {
                    throw new InvalidOperationException(
                              "Don't support assigning with more than simple dotted " +
                              "expression, o.foo.");
                }
                if (!(dottedExpr.Exprs[0] is SymplIdExpr))
                {
                    throw new InvalidOperationException(
                              "Only support unindexed field or property when assigning " +
                              "dotted expression location.");
                }
                var id = (SymplIdExpr)(dottedExpr.Exprs[0]);
                // Trusting MOs convention to return stored values.
                return(Expression.Dynamic(
                           scope.GetRuntime().GetSetMemberBinder(id.IdToken.Name),
                           typeof(object),
                           AnalyzeExpr(dottedExpr.ObjectExpr, scope),
                           AnalyzeExpr(expr.Value, scope)
                           ));
            }

            throw new InvalidOperationException("Invalid left hand side type.");
        }
示例#25
0
文件: ETGen.cs 项目: kuny/MeagerLisp
 public AnalysisScope(AnalysisScope parent, string name)
     : this(parent, name, null, null, null)
 {
 }
示例#26
0
文件: ETGen.cs 项目: kuny/MeagerLisp
 // AnalyzeQuoteExpr converts a list, literal, or id expr to a runtime quoted
 // literal and returns the Constant expression for it.
 //
 public static Expression AnalyzeQuoteExpr(SymplQuoteExpr expr,
                                           AnalysisScope scope)
 {
     return(Expression.Constant(MakeQuoteConstant(
                                    expr.Expr, scope.GetRuntime())));
 }
示例#27
0
文件: ETGen.cs 项目: kuny/MeagerLisp
 public static LambdaExpression AnalyzeLambdaExpr(SymplLambdaExpr expr,
                                                  AnalysisScope scope)
 {
     return((LambdaExpression)AnalyzeLambdaDef(expr.Params, expr.Body,
                                               scope, "lambda"));
 }