// 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."); }
// 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."); }