internal protected override Expression ToExpression(ParameterBinder parameterBinder, IList <Expression> parameters, bool[] hasBeenUsed) { if (_tmp == null) { _tmp = parameterBinder.GetTemporary(Type, "outParam"); } return(Ast.Block(Ast.Assign(_tmp, base.ToExpression(parameterBinder, parameters, hasBeenUsed)), _tmp)); }
public Ast DeclareVariable(string name, Ast value) { System.Linq.Expressions.ParameterExpression param; if (!_variables.TryGetValue(name, out param)) { _variables[name] = param = Ast.Variable(typeof(object), name); } return(Ast.Assign(param, value)); }
private MSAst.Expression AddFinally(MSAst.Expression /*!*/ body) { if (_finally != null) { MSAst.ParameterExpression tryThrows = Ast.Variable(typeof(Exception), "$tryThrows"); MSAst.ParameterExpression locException = Ast.Variable(typeof(Exception), "$localException"); MSAst.Expression @finally = _finally; // lots is going on here. We need to consider: // 1. Exceptions propagating out of try/except/finally. Here we need to save the line # // from the exception block and not save the # from the finally block later. // 2. Exceptions propagating out of the finally block. Here we need to report the line number // from the finally block and leave the existing stack traces cleared. // 3. Returning from the try block: Here we need to run the finally block and not update the // line numbers. body = AstUtils.Try( // we use a fault to know when we have an exception and when control leaves normally (via // either a return or the body completing successfully). AstUtils.Try( Parent.AddDebugInfo(AstUtils.Empty(), new SourceSpan(Span.Start, GlobalParent.IndexToLocation(_headerIndex))), Ast.Assign(tryThrows, AstUtils.Constant(null, typeof(Exception))), body, AstUtils.Empty() ).Catch( locException, Expression.Block( Ast.Assign(tryThrows, locException), Expression.Rethrow() ) ) ).FinallyWithJumps( // if we had an exception save the line # that was last executing during the try AstUtils.If( Expression.NotEqual(tryThrows, Expression.Default(typeof(Exception))), Parent.GetSaveLineNumberExpression(tryThrows, false) ), // clear the frames incase thae finally throws, and allow line number // updates to proceed UpdateLineUpdated(false), // run the finally code @finally, // if we took an exception in the try block we have saved the line number. Otherwise // we have no line number saved and will need to continue saving them if // other exceptions are thrown. AstUtils.If( Expression.NotEqual(tryThrows, Expression.Default(typeof(Exception))), UpdateLineUpdated(true) ) ); body = Ast.Block(new[] { tryThrows }, body); } return(body); }
internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { // TODO: // {target}[{arguments}] op= rhs // we need to evaluate {arguments} once: http://ironruby.codeplex.com/workitem/4525 // first, read target into a temp: MSA.Expression transformedLeftTarget = _left.TransformTargetRead(gen); MSA.Expression leftTargetTemp; if (transformedLeftTarget != null) { leftTargetTemp = gen.CurrentScope.DefineHiddenVariable(String.Empty, transformedLeftTarget.Type); } else { leftTargetTemp = null; } MSA.Expression transformedRight = _right.TransformRead(gen); // lhs &&= rhs --> lhs && (lhs = rhs) // lhs ||= rhs --> lhs || (lhs = rhs) if (Operation == Symbols.And || Operation == Symbols.Or) { MSA.Expression transformedLeftRead = _left.TransformRead(gen, (transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null, true // tryRead ); MSA.Expression transformedWrite = _left.TransformWrite(gen, leftTargetTemp, transformedRight); if (Operation == Symbols.And) { return(AndExpression.TransformRead(gen, transformedLeftRead, transformedWrite)); } else { return(OrExpression.TransformRead(gen, transformedLeftRead, transformedWrite)); } } else { // lhs op= rhs --> lhs = lhs op rhs if (Operation != null) { MSA.Expression transformedLeftRead = _left.TransformRead(gen, leftTargetTemp, false); transformedRight = MethodCall.TransformRead(this, gen, false, Operation, transformedLeftRead, null, null, transformedRight, null); } // transform lhs write assigning lhs-target temp: return(_left.TransformWrite(gen, (transformedLeftTarget != null) ? Ast.Assign(leftTargetTemp, transformedLeftTarget) : null, transformedRight )); } }
internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (_tmp == null) { _tmp = resolver.GetTemporary(Type, "outParam"); } return(Ast.Block(Ast.Assign(_tmp, base.ToExpression(resolver, args, hasBeenUsed)), _tmp)); }
internal static MSAst.Expression /*!*/ Delete(MSAst.Expression /*!*/ expression) { if (expression is IPythonVariableExpression pyGlobal) { return(pyGlobal.Delete()); } return(Ast.Assign(expression, Ast.Field(null, typeof(Uninitialized).GetField(nameof(Uninitialized.Instance))))); }
internal sealed override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { string debugString = (IsSingletonDeclaration) ? "SINGLETON" : ((this is ClassDefinition) ? "CLASS" : "MODULE") + " " + QualifiedName.Name; ScopeBuilder outerLocals = gen.CurrentScope; // definition needs to take place outside the defined lexical scope: var definition = MakeDefinitionExpression(gen); var selfVariable = outerLocals.DefineHiddenVariable("#module", typeof(RubyModule)); var parentScope = gen.CurrentScopeVariable; // inner locals: ScopeBuilder scope = DefineLocals(); var scopeVariable = scope.DefineHiddenVariable("#scope", typeof(RubyScope)); gen.EnterModuleDefinition( scope, selfVariable, scopeVariable, IsSingletonDeclaration ); // transform body: MSA.Expression transformedBody = Body.TransformRead(gen); // outer local: MSA.Expression resultVariable = outerLocals.DefineHiddenVariable("#result", transformedBody.Type); // begin with new scope // self = DefineModule/Class(... parent scope here ...) // <body> // end MSA.Expression result = new AstBlock { gen.DebugMarker(debugString), Ast.Assign(selfVariable, definition), scope.CreateScope( scopeVariable, Methods.CreateModuleScope.OpCall( scope.MakeLocalsStorage(), scope.GetVariableNamesExpression(), parentScope, selfVariable ), Ast.Block( Ast.Assign(resultVariable, transformedBody), AstUtils.Empty() ) ), gen.DebugMarker("END OF " + debugString), resultVariable }; gen.LeaveModuleDefinition(); return(result); }
private DynamicMetaObject MakeMethodIndexRule(IndexType oper, OverloadResolverFactory resolverFactory, DynamicMetaObject[] args) { MethodInfo[] defaults = GetMethodsFromDefaults(args[0].GetLimitType().GetDefaultMembers(), oper); if (defaults.Length != 0) { DynamicMetaObject[] selfWithArgs = args; ParameterExpression arg2 = null; if (oper == IndexType.Set) { Debug.Assert(args.Length >= 2); // need to save arg2 in a temp because it's also our result arg2 = Ast.Variable(args[2].Expression.Type, "arg2Temp"); args[2] = new DynamicMetaObject( Ast.Assign(arg2, args[2].Expression), args[2].Restrictions ); } BindingRestrictions restrictions = BindingRestrictions.Combine(args); var resolver = resolverFactory.CreateOverloadResolver(selfWithArgs, new CallSignature(selfWithArgs.Length), CallTypes.ImplicitInstance); BindingTarget target = resolver.ResolveOverload(oper == IndexType.Get ? "get_Item" : "set_Item", defaults, NarrowingLevel.None, NarrowingLevel.All); if (target.Success) { if (oper == IndexType.Get) { return(new DynamicMetaObject( target.MakeExpression(), restrictions.Merge(target.RestrictedArguments.GetAllRestrictions()) )); } else { return(new DynamicMetaObject( Ast.Block( new ParameterExpression[] { arg2 }, target.MakeExpression(), arg2 ), restrictions.Merge(target.RestrictedArguments.GetAllRestrictions()) )); } } return(MakeError( resolver.MakeInvalidParametersError(target), restrictions, typeof(object) )); } return(null); }
// // rescue stmts ... if (StandardError === $!) { stmts; } // rescue <types> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { stmts; } // rescue <types> => <lvalue> stmts ... temp1 = type1; ...; if (<temp1> === $! || ...) { <lvalue> = $!; stmts; } // internal IfStatementTest /*!*/ Transform(AstGenerator /*!*/ gen, ResultOperation resultOperation) { Assert.NotNull(gen); MSA.Expression condition; if (_types.Length != 0) { var comparisonSiteStorage = Ast.Constant(new BinaryOpStorage(gen.Context)); if (_types.Length == 1) { condition = MakeCompareException(gen, comparisonSiteStorage, _types[0].TransformRead(gen), _types[0] is SplattedArgument); } else { // forall{i}: <temps[i]> = evaluate type[i] var temps = new MSA.Expression[_types.Length]; var exprs = new BlockBuilder(); for (int i = 0; i < _types.Length; i++) { var t = _types[i].TransformRead(gen); var tmp = gen.CurrentScope.DefineHiddenVariable("#type_" + i, t.Type); temps[i] = tmp; exprs.Add(Ast.Assign(tmp, t)); } // CompareException(<temps[0]>) || ... CompareException(<temps[n]>) || CompareSplattedExceptions(<splatTypes>) condition = MakeCompareException(gen, comparisonSiteStorage, temps[0], _types[0] is SplattedArgument); for (int i = 1; i < _types.Length; i++) { condition = Ast.OrElse(condition, MakeCompareException(gen, comparisonSiteStorage, temps[i], _types[i] is SplattedArgument)); } // (temps[0] = type[0], ..., temps[n] == type[n], condition) exprs.Add(condition); condition = exprs; } } else { condition = Methods.CompareDefaultException.OpCall(gen.CurrentScopeVariable); } return(AstUtils.IfCondition(condition, gen.TransformStatements( // <lvalue> = e; (_target != null) ? _target.TransformWrite(gen, Methods.GetCurrentException.OpCall(gen.CurrentScopeVariable)) : null, // body: _statements, resultOperation ) )); }
private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ invoke, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke"); DynamicMetaObject self = Restrict(typeof(OldInstance)); Expression[] exprArgs = new Expression[args.Length + 1]; for (int i = 0; i < args.Length; i++) { exprArgs[i + 1] = args[i].Expression; } ParameterExpression tmp = Ast.Variable(typeof(object), "callFunc"); exprArgs[0] = tmp; return(new DynamicMetaObject( // we could get better throughput w/ a more specific rule against our current custom old class but // this favors less code generation. Ast.Block( new ParameterExpression[] { tmp }, Ast.Condition( Ast.Call( typeof(PythonOps).GetMethod("OldInstanceTryGetBoundCustomMember"), codeContext, self.Expression, AstUtils.Constant("__call__"), tmp ), Ast.Block( Utils.Try( Ast.Call(typeof(PythonOps).GetMethod("FunctionPushFrameCodeContext"), codeContext), Ast.Assign( tmp, Ast.Dynamic( PythonContext.GetPythonContext(invoke).Invoke( BindingHelpers.GetCallSignature(invoke) ), typeof(object), ArrayUtils.Insert(codeContext, exprArgs) ) ) ).Finally( Ast.Call(typeof(PythonOps).GetMethod("FunctionPopFrame")) ), tmp ), Utils.Convert( BindingHelpers.InvokeFallback(invoke, codeContext, this, args).Expression, typeof(object) ) ) ), self.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
internal static MSAst.Expression /*!*/ Delete(MSAst.Expression /*!*/ expression) { IPythonVariableExpression pyGlobal = expression as IPythonVariableExpression; if (pyGlobal != null) { return(pyGlobal.Delete()); } return(Ast.Assign(expression, Ast.Field(null, typeof(Uninitialized).GetField("Instance")))); }
public static MSAst.Expression /*!*/ Assign(MSAst.Expression /*!*/ expression, MSAst.Expression value) { IPythonVariableExpression pyGlobal = expression as IPythonVariableExpression; if (pyGlobal != null) { return(pyGlobal.Assign(value)); } return(Ast.Assign(expression, value)); }
internal override Expression ToExpression(MethodBinderContext context, Expression[] parameters) { #if FULL if (_tmp == null) { _tmp = context.GetTemporary(Type, "outParam"); } #endif return(Ast.Comma(Ast.Assign(_tmp, base.ToExpression(context, parameters)), Ast.Read(_tmp))); }
internal static MSAst.Expression /*!*/ AssignValue(MSAst.Expression /*!*/ expression, MSAst.Expression value) { Debug.Assert(expression != null); Debug.Assert(value != null); if (expression is IPythonVariableExpression pyGlobal) { return(pyGlobal.Assign(value)); } return(Ast.Assign(expression, value)); }
internal override void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name) { Expression expr = null; Expression instance = _fieldInfo.IsStatic ? null : Ast.Convert(args.TargetExpression, _fieldInfo.DeclaringType); if (_isSetter) { // parameters should be: instance/type, value if (args.SimpleArgumentCount == 0 && args.Signature.HasRhsArgument) { expr = Ast.Assign( Ast.Field(instance, _fieldInfo), // TODO: remove args.RubyContext.Binder.ConvertExpression( args.GetRhsArgumentExpression(), _fieldInfo.FieldType, ConversionResultKind.ExplicitCast, args.ScopeExpression ) ); } } else { // parameter should be: instance/type if (args.SimpleArgumentCount == 0) { if (_fieldInfo.IsLiteral) { // TODO: seems like Compiler should correctly handle the literal field case // (if you emit a read to a literal field, you get a NotSupportedExpception from // FieldHandle when we try to emit) expr = Ast.Constant(_fieldInfo.GetValue(null)); } else { expr = Ast.Field(instance, _fieldInfo); } } } if (expr != null) { metaBuilder.Result = expr; } else { metaBuilder.SetError( Methods.MakeInvalidArgumentTypesError.OpCall(Ast.Constant(_isSetter ? name + "=" : name)) ); } }
// This is a compound comparison operator like: a < b < c. // That's represented as binary operators, but it's not the same as (a<b) < c, so we do special transformations. // We need to: // - return true iff (a<b) && (b<c), but ensure that b is only evaluated once. // - ensure evaluation order is correct (a,b,c) // - don't evaluate c if a<b is false. private MSAst.Expression FinishCompare(MSAst.Expression left) { Debug.Assert(_right is BinaryExpression); BinaryExpression bright = (BinaryExpression)_right; // Transform the left child of my right child (the next node in sequence) MSAst.Expression rleft = bright.Left; // Store it in the temp MSAst.ParameterExpression temp = Ast.Parameter(typeof(object), "chained_comparison"); // Create binary operation: left <_op> (temp = rleft) MSAst.Expression comparison = MakeBinaryOperation( _op, left, Ast.Assign(temp, AstUtils.Convert(rleft, temp.Type)), Span ); MSAst.Expression rright; // Transform rright, comparing to temp if (IsComparison(bright._right)) { rright = bright.FinishCompare(temp); } else { MSAst.Expression transformedRight = bright.Right; rright = MakeBinaryOperation( bright.Operator, temp, transformedRight, bright.Span ); } // return (left (op) (temp = rleft)) and (rright) MSAst.ParameterExpression tmp; MSAst.Expression res = AstUtils.CoalesceTrue( comparison, rright, AstMethods.IsTrue, out tmp ); return(Ast.Block( new[] { temp, tmp }, res )); }
internal override MSA.Expression /*!*/ TransformWriteVariable(AstGenerator /*!*/ gen, MSA.Expression /*!*/ rightValue) { if (_definitionLexicalDepth >= 0) { // static lookup: return(Ast.Assign(gen.CurrentScope.GetVariableAccessor(_definitionLexicalDepth, _closureIndex), AstUtils.Box(rightValue))); } else { // dynamic lookup: return(Methods.SetLocalVariable.OpCall(AstUtils.Box(rightValue), gen.CurrentScopeVariable, AstUtils.Constant(Name))); } }
internal override MSA.Expression /*!*/ TransformWriteVariable(AstGenerator /*!*/ gen, MSA.Expression /*!*/ rightValue) { if (_transformed != null) { // static lookup: return(Ast.Assign(_transformed, AstUtils.Convert(rightValue, _transformed.Type))); } else { // dynamic lookup: return(Methods.SetLocalVariable.OpCall(AstFactory.Box(rightValue), gen.CurrentScopeVariable, AstUtils.Constant(Name))); } }
public override MSAst.LambdaExpression ReduceAst(PythonAst instance, string name) { return(Ast.Lambda <Func <FunctionCode, object> >( Ast.Block( new[] { PythonAst._globalArray, PythonAst._globalContext }, Ast.Assign(PythonAst._globalArray, instance.GlobalArrayInstance), Ast.Assign(PythonAst._globalContext, Ast.Constant(instance.ModuleContext.GlobalContext)), AstUtils.Convert(instance.ReduceWorker(), typeof(object)) ), name, new[] { PythonAst._functionCode } )); }
public override void PrepareScope(PythonAst ast, System.Runtime.CompilerServices.ReadOnlyCollectionBuilder <MSAst.ParameterExpression> locals, List <MSAst.Expression> init) { locals.Add(PythonAst._globalArray); init.Add( Ast.Assign( PythonAst._globalArray, Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.GetGlobalArrayFromContext)), PythonAst._globalContext ) ) ); }
internal static MSA.Expression /*!*/ MakeUserMethodBody(AstGenerator gen, int lastLine, MSA.Expression /*!*/ blockParameter, MSA.Expression /*!*/ rfcVariable, MSA.ParameterExpression /*!*/ methodUnwinder, MSA.Expression /*!*/ bodyStatement, ResultOperation resultOperation, int profileTickIndex, MSA.ParameterExpression stampVariable, MSA.LabelTarget returnLabel) { Assert.NotNull(blockParameter, rfcVariable, bodyStatement, methodUnwinder); Debug.Assert(!resultOperation.IsIgnore, "return value should not be ignored"); Debug.Assert(returnLabel != null || resultOperation.Variable != null, "return label needed"); MSA.Expression resultExpression = Ast.Field(methodUnwinder, MethodUnwinder.ReturnValueField); if (resultOperation.Variable != null) { resultExpression = Ast.Assign(resultOperation.Variable, resultExpression); } else { resultExpression = Ast.Return(returnLabel, resultExpression); } // TODO: move this to the caller: MSA.Expression profileStart, profileEnd; if (stampVariable != null) { profileStart = Ast.Assign(stampVariable, Methods.Stopwatch_GetTimestamp.OpCall()); profileEnd = Methods.UpdateProfileTicks.OpCall(Ast.Constant(profileTickIndex), stampVariable); } else { profileStart = profileEnd = Ast.Empty(); } return(AstUtils.Try( // initialize frame (RFC): profileStart, Ast.Assign(rfcVariable, Methods.CreateRfcForMethod.OpCall(AstUtils.Convert(blockParameter, typeof(Proc)))), bodyStatement ).Filter(methodUnwinder, Ast.Equal(Ast.Field(methodUnwinder, MethodUnwinder.TargetFrameField), rfcVariable), // return unwinder.ReturnValue; resultExpression ).Finally( Ast.Assign(Ast.Field(rfcVariable, RuntimeFlowControl.IsActiveMethodField), Ast.Constant(false)), profileEnd, gen != null && gen.TraceEnabled ? Methods.TraceMethodReturn.OpCall( gen.CurrentScopeVariable, Ast.Convert(Ast.Constant(gen.SourceUnit.Path), typeof(string)), Ast.Constant(lastLine) ) : Ast.Empty() )); }
private DynamicMetaObject /*!*/ MakeCallRule(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke w/ " + args.Length + " args"); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass Invoke"); CallSignature signature = BindingHelpers.GetCallSignature(call); // TODO: If we know __init__ wasn't present we could construct the OldInstance directly. Expression[] exprArgs = new Expression[args.Length]; for (int i = 0; i < args.Length; i++) { exprArgs[i] = args[i].Expression; } ParameterExpression init = Ast.Variable(typeof(object), "init"); ParameterExpression instTmp = Ast.Variable(typeof(object), "inst"); DynamicMetaObject self = Restrict(typeof(OldClass)); return(new DynamicMetaObject( Ast.Block( new ParameterExpression[] { init, instTmp }, Ast.Assign( instTmp, Ast.New( typeof(OldInstance).GetConstructor(new Type[] { typeof(CodeContext), typeof(OldClass) }), codeContext, self.Expression ) ), Ast.Condition( Ast.Call( typeof(PythonOps).GetMethod("OldClassTryLookupInit"), self.Expression, instTmp, init ), Ast.Dynamic( PythonContext.GetPythonContext(call).Invoke( signature ), typeof(object), ArrayUtils.Insert <Expression>(codeContext, init, exprArgs) ), NoInitCheckNoArgs(signature, self, args) ), instTmp ), self.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
// Function Body Code Generation // // object Func(object self, object[] args) { // object p1 = ...; // object p2 = ...; // ... // object pn = ...; // (..Body..) // } // // <if has_default(p[i]) then> // <p[i]> = <i> < args.Length ? (args[<i>] == void ? <default(p[i])> : args[<i>]) : <default(p[i])>; // <else if any_length_args(p[i]) then> // <if has_name(p[i]) then> // <p[i]> = new Array(args.Skip(<i>)); // <else> // <p[i]> = new UnnamedSpreadArguments(args, <i>); // <end if> // <else> // <p[i]> = <i> < args.Length ? args[<i>] : void; // <end if> public System.Linq.Expressions.Expression <Func <object, object, object[], object> > TransformLambda() { List <Ast> body = new List <Ast>(); for (int i = 0; i < Parameters.Count; i++) { var capCheck = Ast.LessThan(Ast.Constant(i), Ast.Property(_arguments, "Length")); Ast exp; if (Parameters[i].HasDefaultValue) { exp = Ast.Condition(capCheck, Ast.Condition(Ast.TypeEqual(Ast.ArrayAccess(_arguments, Ast.Constant(i)), typeof(Builtins.Void)), Ast.Constant(Parameters[i].DefaultValue, typeof(object)), Ast.ArrayAccess(_arguments, Ast.Constant(i)) ), Ast.Constant(Parameters[i].DefaultValue, typeof(object)) ); } else if (Parameters[i].ExpandToArray) { if (Parameters[i].ParameterVariable.Name != null) { exp = Ast.New((System.Reflection.ConstructorInfo)Utils.GetMember(() => new Builtins.Array(null)), Ast.Call(new Func <IEnumerable <object>, int, IEnumerable <object> >(Enumerable.Skip).Method, _arguments, Ast.Constant(i)) ); } else { exp = Ast.New((System.Reflection.ConstructorInfo)Utils.GetMember(() => new Runtime.UnnamedSpreadArguments(null, 0)), _arguments, Ast.Constant(i) ); } } else { exp = Ast.Condition(capCheck, Ast.ArrayAccess(_arguments, Ast.Constant(i)), Ast.Constant(Builtins.Void.Value, typeof(object)) ); } body.Add(Ast.Assign(Parameters[i].ParameterVariable, exp)); } foreach (var statement in Body) { body.Add(statement.Transform()); } body.Add(Ast.Label(ReturnLabel, Ast.Constant(Builtins.Void.Value))); return(Ast.Lambda <Func <object, object, object[], object> >(Ast.Block(_variables.Values.Concat(Parameters.Select(x => x.ParameterVariable)), body), Name, new[] { _global, _context, _arguments })); }
internal override MSA.Expression /*!*/ TransformRead(AstGenerator /*!*/ gen) { MSA.Expression transformedCondition = AstFactory.Box(_condition.TransformRead(gen)); MSA.Expression tmpVariable = gen.CurrentScope.DefineHiddenVariable("#tmp_cond", transformedCondition.Type); return(AstFactory.Block( Ast.Assign(tmpVariable, transformedCondition), AstUtils.IfThen( (_negateCondition ? AstFactory.IsFalse(tmpVariable) : AstFactory.IsTrue(tmpVariable)), _jumpStatement.Transform(gen) ), (_value != null) ? _value.TransformRead(gen) : tmpVariable )); }
private MSAst.Expression AssignOne() { Debug.Assert(_left.Length == 1); SequenceExpression seLeft = _left[0] as SequenceExpression; SequenceExpression seRight = _right as SequenceExpression; bool isStarred = seLeft != null && seLeft.Items.OfType <StarredExpression>().Any(); if (!isStarred && seLeft != null && seRight != null && seLeft.Items.Count == seRight.Items.Count) { int cnt = seLeft.Items.Count; // a, b = 1, 2, or [a,b] = 1,2 - not something like a, b = range(2) // we can do a fast parallel assignment MSAst.ParameterExpression[] tmps = new MSAst.ParameterExpression[cnt]; MSAst.Expression[] body = new MSAst.Expression[cnt * 2 + 1]; // generate the body, the 1st n are the temporary assigns, the // last n are the assignments to the left hand side // 0: tmp0 = right[0] // ... // n-1: tmpn-1 = right[n-1] // n: right[0] = tmp0 // ... // n+n-1: right[n-1] = tmpn-1 // allocate the temps first before transforming so we don't pick up a bad temp... for (int i = 0; i < cnt; i++) { MSAst.Expression tmpVal = seRight.Items[i]; tmps[i] = Ast.Variable(tmpVal.Type, "parallelAssign"); body[i] = Ast.Assign(tmps[i], tmpVal); } // then transform which can allocate more temps for (int i = 0; i < cnt; i++) { body[i + cnt] = seLeft.Items[i].TransformSet(SourceSpan.None, tmps[i], PythonOperationKind.None); } // 4. Create and return the resulting suite body[cnt * 2] = AstUtils.Empty(); return(GlobalParent.AddDebugInfoAndVoid(Ast.Block(tmps, body), Span)); } return(_left[0].TransformSet(Span, _right, PythonOperationKind.None)); }
private static BinaryExpression /*!*/ MakeOneConvert(DynamicMetaObjectBinder /*!*/ conversion, DynamicMetaObject /*!*/ self, string name, ParameterExpression /*!*/ tmp) { return(Ast.NotEqual( Ast.Assign( tmp, Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.OldInstanceConvertNonThrowing)), AstUtils.Constant(PythonContext.GetPythonContext(conversion).SharedContext), self.Expression, AstUtils.Constant(name) ) ), AstUtils.Constant(null) )); }
internal MSA.Expression /*!*/ TryCatchAny(MSA.Expression /*!*/ tryBody, MSA.Expression /*!*/ catchBody) { var variable = CurrentScope.DefineHiddenVariable("#value", tryBody.Type); return (Ast.Block( Ast.TryCatch( Ast.Assign(variable, tryBody), Ast.Catch(typeof(Exception), Ast.Assign(variable, catchBody) ) ), variable )); }
/// <summary> /// Gets the expression for the actual updating of the line number for stack traces to be available /// </summary> internal MSAst.Expression GetSaveLineNumberExpression(bool preventAdditionalAdds) { MSAst.Expression res; if (preventAdditionalAdds) { res = _saveLineNumberNoAdds; } else { res = _saveLineNumberAdds; } if (res == null) { res = Ast.Block( AstUtils.If( Ast.Not( LineNumberUpdated ), Ast.Call( AstMethods.UpdateStackTrace, LocalContext, _funcCodeExpr, _GetCurrentMethod, AstUtils.Constant(Name), AstUtils.Constant(GlobalParent.SourceUnit.Path ?? "<string>"), new LastFaultingLineExpression(LineNumberExpression) ) ), Ast.Assign( LineNumberUpdated, AstUtils.Constant(preventAdditionalAdds) ), AstUtils.Empty() ); if (preventAdditionalAdds) { _saveLineNumberNoAdds = res; } else { _saveLineNumberAdds = res; } } return(res); }
/// <summary> /// Transform and handle the result according to the specified result operation. /// </summary> internal virtual MSA.Expression /*!*/ TransformResult(AstGenerator /*!*/ gen, ResultOperation resultOperation) { MSA.Expression resultExpression = TransformRead(gen); MSA.Expression statement; if (resultOperation.Variable != null) { statement = Ast.Assign(resultOperation.Variable, Ast.Convert(resultExpression, resultOperation.Variable.Type)); } else { statement = gen.Return(resultExpression); } return(gen.AddDebugInfo(statement, Location)); }
/// <summary> /// Gets the expression for the actual updating of the line number for stack traces to be available /// </summary> internal MSAst.Expression GetSaveLineNumberExpression(MSAst.ParameterExpression exception, bool preventAdditionalAdds) { Debug.Assert(exception.Type == typeof(Exception)); return Ast.Block( AstUtils.If( Ast.Not( LineNumberUpdated ), UpdateStackTrace(exception) ), Ast.Assign( LineNumberUpdated, AstUtils.Constant(preventAdditionalAdds) ), AstUtils.Empty() ); }