IBoundExpr IUnboundExprVisitor<IBoundExpr>.Visit(AssignExpr expr) { var value = expr.Value.Accept(this); if (expr.Target is TupleExpr) throw new NotSupportedException("Assignment to a tuple must be simplified before binding."); // handle a name target: foo <- 3 var nameTarget = expr.Target as NameExpr; if (nameTarget != null) { // see if it's a local if (Scope.Contains(nameTarget.Name)) { if (!Scope.IsMutable(nameTarget.Name)) throw new CompileException(expr.Position, "Cannot assign to immutable local."); // direct assign to local return new StoreExpr(new LocalsExpr(), Scope[nameTarget.Name], value); } // look for an assignment function return TranslateAssignment(nameTarget.Position, nameTarget.Name, nameTarget.TypeArgs, new UnitExpr(Position.None), value); } // handle a function apply target: Foo 1 <- 3 ==> Foo<- (1, 3) var callTarget = expr.Target as CallExpr; if (callTarget != null) { var callArg = callTarget.Arg.Accept(this); // see if it's a direct function call var funcName = callTarget.Target as NameExpr; if ((funcName != null) && !mContext.Compiler.IsLocal(mFunction, Scope, funcName.Name)) { // translate the call return TranslateAssignment(callTarget.Position, funcName.Name, funcName.TypeArgs, callArg, value); } // not calling a function, so try to desugar to a __Call<- var desugaredCallTarget = callTarget.Target.Accept(this); var desugaredCallArg = new BoundTupleExpr(new IBoundExpr[] { desugaredCallTarget, callArg, value }); var call = mContext.ResolveFunction(mFunction, expr.Target.Position, "__Call<-", new IUnboundDecl[0], desugaredCallArg); if (call != null) return call; throw new CompileException(expr.Position, "Couldn't figure out what you're trying to do on the left side of an assignment."); } // if we got here, it's not a valid assignment expression throw new CompileException(expr.Position, "Cannot assign to " + expr.Target); }
public override IUnboundExpr Transform(AssignExpr expr) { // replaces: // // a, b <- Foo // // with: // // def __temp1 <- Foo // a <- _temp1.0 // b <- _temp1.1 TupleExpr tuple = expr.Target as TupleExpr; // ignore other assignments if (tuple == null) { return(expr); } var exprs = new List <IUnboundExpr>(); var temp = mNameGenerator.Generate(); // evaluate the right-hand side once exprs.Add(new DefineExpr(expr.Target.Position, temp, expr.Value, false)); // split out the fields int index = 0; foreach (var field in tuple.Fields) { exprs.Add(new AssignExpr(expr.Position, field, new CallExpr(new IntExpr(index), new NameExpr(expr.Position, temp)))); index++; } return(new BlockExpr(false, exprs)); }
public virtual IUnboundExpr Transform(AssignExpr expr) { return(expr); }
IUnboundExpr IUnboundExprVisitor <IUnboundExpr> .Visit(AssignExpr expr) { return(Call("AssignExpr", Tuple(expr.Target.Accept(this), expr.Value.Accept(this)))); }