Пример #1
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()
                        ));
         }
     }
 }
Пример #2
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()
                    );
                }
            }
        }
Пример #3
0
		// 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.");
        }
Пример #4
0
        // AnalyzeAssignExpr handles IDs, indexing, and member sets.  IDs are either
        // lexical or dynamic exprs on the module scope (ExpandoObject).  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.");
        }