Example #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()
                        ));
         }
     }
 }
Example #2
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.");
        }