public object visit_assign(AssignExpr assign_expression) { resolve(assign_expression.value); // Resolve the variable to the interpreter resolve_local_position(assign_expression, assign_expression.name); return(null); }
/// <summary> /// Assign a value to an expression. /// </summary> /// <param name="expr">The assignment expressions</param> /// <returns></returns> public object VisitAssign(AssignExpr expr) { var ctx = expr.Ctx; var varExpr = expr.VarExp; var valueExpr = expr.ValueExp; var node = expr; var isDeclaration = expr.IsDeclaration; // CASE 1: Assign variable. a = 1 if (varExpr.IsNodeType(NodeTypes.SysVariable)) { AssignHelper.SetVariableValue(ctx, this, node, isDeclaration, varExpr, valueExpr); } // CASE 2: Assign member. // e.g. dictionary : user.name = 'kishore' // e.g. property on class: user.age = 20 else if (varExpr.IsNodeType(NodeTypes.SysMemberAccess)) { AssignHelper.SetMemberValue(ctx, this, node, varExpr, valueExpr); } // Case 3: Assign value to index: "users[0]" = <expression>; else if (varExpr.IsNodeType(NodeTypes.SysIndex)) { AssignHelper.SetIndexValue(ctx, this, node, varExpr, valueExpr); } return(LObjects.Null); }
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 override void Visit(AssignExpr expr) { expr.value.Accept(this); ushort addr = chunk.AddConstant(new Value(expr.name.lexeme)); chunk.WriteOpCode(OpCode.SET_GLOBAL); chunk.WriteWord(addr); }
/// <summary> /// Visits the var statement tree. /// </summary> /// <param name="assignExpr"></param> public void Var(AssignExpr assignExpr) { _callBack(assignExpr); foreach (var decl in assignExpr._declarations) { Visit(decl.Item1); Visit(decl.Item2); } }
public override void Visit(AssignExpr expr) { string tempStr = expr.name.lexeme; AddStr(expr.name.lexeme); AddStr(" = "); expr.value.Accept(this); }
/// <summary> /// Visits the var statement tree. /// </summary> /// <param name="expr"></param> public object VisitAssign(AssignExpr expr) { _callBackOnNodeStart(expr); expr.VarExp.Visit(this); if (expr.ValueExp != null) { expr.ValueExp.Visit(this); } return(null); }
/// <summary> /// Creates a unary expression with symbol scope, context, script refernce set. /// </summary> /// <param name="name"></param> /// <param name="token"></param> /// <returns></returns> public static Expr Assign(bool declare, Expr left, Expr right, TokenData token) { var exp = new AssignExpr(); exp.IsDeclaration = declare; exp.VarExp = left; exp.ValueExp = right; SetupContext(exp, token); return(exp); }
private void Assign(Memory memory, string name, object val, bool isConst, object expected) { var ctx = new Context(); ctx.Memory = memory; Expr expr = isConst ? (Expr) new ConstantExpr(val) : (Expr) new VariableExpr(val.ToString()); var exp = new AssignExpr(true, name, expr); expr.Ctx = ctx; exp.Ctx = ctx; exp.Evaluate(); Assert.AreEqual(expected, memory.GetAs <LObject>(name).GetValue()); }
public object visit_assign(AssignExpr assign_expression) { object value = evaluate(assign_expression.value); // If the value is assigning to a local variable, then set it if (local_depths.ContainsKey(assign_expression)) { int distance = local_depths[assign_expression]; local_scope.assign_at(distance, assign_expression.name, value); } // Else the value is assigning to a global else { global_scope.assign(assign_expression.name, value); } return(value); }
Arg ApplyUsualConversions(ArgList args, out Expr writeBack) { writeBack = null; bool hasRefArgs = false; for (int i = 0; i < args.Args.Count; i++) { var e = args.Args[i].Expr; Convert(ref e, Compilation.Get(NativeType.Usual)); if (args.Args[i].RefKind != RefKind.None) { hasRefArgs = true; } } var arguments = new Arg(LiteralArray.Bound(args.Args)); if (hasRefArgs) { var conv = ConversionSymbol.Create(ConversionSymbol.Create(ConversionKind.Identity), new ConversionToTemp(arguments.Expr.Datatype)); Convert(ref arguments.Expr, arguments.Expr.Datatype, conv); for (int i = 0; i < args.Args.Count; i++) { if (args.Args[i].RefKind != RefKind.None) { HandleVarArgWriteBack(conv, args.Args[i].Expr, i, ref writeBack); } } } return(arguments); void HandleVarArgWriteBack(ConversionSymbol conv, Expr e, int i, ref Expr wb) { if (e.Symbol?.HasSetAccess == true || e is AutoVarExpr || e is AliasExpr) { // Handle writeBack Expr t = IdExpr.Bound(conv.IndirectRefConversionTempLocal()); t = ArrayAccessExpr.Bound(t, ArgList.Bound(LiteralExpr.Bound(Constant.Create(i + 1))), this); var wc = Conversion(t, e.Datatype, BindOptions.Default); if (wc.Exists) { Convert(ref t, e.Datatype, wc); SymbolExtensions.AddExpr(ref wb, AssignExpr.Bound(e, t, BindOptions.Default)); } } } }
internal ForStmt ParseForStmt() { Token t; ExpectAndGet(TokenType.FOR, out t); VarDecl d = null; AssignExpr a = null; if (ExpectAny(TokenType.IMPLIED, TokenType.VAR) || (La(2) == TokenType.IMPLIED && Expect(TokenType.LOCAL) && Expect(TokenType.IMPLIED))) { d = ParseForDecl(true); } else if (Expect(TokenType.LOCAL)) { d = ParseForDecl(false); } else { a = ParseExpression() as AssignExpr; Require(a?.Left is IdExpr, ErrorCode.Expected, "variable assignemnt expression"); } var dir = Require(ExpectAndGetAny(TokenType.UPTO, TokenType.DOWNTO, TokenType.TO), ErrorCode.Expected, TokenType.TO); Expr final = RequireExpression(); Expr step = null; if (Expect(TokenType.STEP)) { step = RequireExpression(); } Require(TokenType.EOS); var s = ParseStatementBlock(); if (Expect(TokenType.END)) { Expect(TokenType.FOR); } else { Require(Expect(TokenType.NEXT), ErrorCode.Expected, "END FOR"); } Require(TokenType.EOS); return(a != null ? new ForStmt(t, a, dir, final, step, s) : new ForStmt(t, d, dir, final, step, s)); }
public void Visit(AssignExpr assignExpr, object[] args) { assignExpr.LeftExpr.Accept(this); assignExpr.RightExpr.Accept(this); RightValue v = readRightValue(assignExpr.RightExpr); assignExpr.RightValue = v; if (assignExpr.LeftExpr.LeftValue is VarRef) { VarRef varRef = assignExpr.LeftExpr.LeftValue as VarRef; scopeStack.SetValue(varRef.VarName, v); } else { throw new Exception(); } }
public object visit_assign(AssignExpr assign_expression) { //Console.WriteLine("visiting assign: " + assign_expression.name.value+", "+local_scope.get(new Token(Token.Type.Identifier,"x"))); object value = evaluate(assign_expression.value); //Console.WriteLine("new value: "+value); // If the value is assigning to a local variable, then set it if (local_depths.ContainsKey(assign_expression)) { int distance = local_depths[assign_expression]; local_scope.assign_at(distance, assign_expression.name, value); } // Else the value is assigning to a global else { global_scope.assign(assign_expression.name, value); } return(value); }
public void Can_Validate_Variable_Does_Not_Exist() { var symScope = new Symbols(); symScope.DefineVariable("result"); var semacts = new SemActs(); var a = new VariableExpr("a"); a.Ref = new ScriptRef("", 1, 1); a.SymScope = symScope.Current; var zero = new ConstantExpr(2); zero.Ref = new ScriptRef("", 1, 5); zero.SymScope = symScope.Current; var divExpr = new BinaryExpr(a, Operator.Divide, zero); divExpr.SymScope = symScope.Current; var assignExpr = new AssignExpr(true, new VariableExpr("result"), divExpr); assignExpr.SymScope = symScope.Current; var stmts = new List <Expr>(); stmts.Add(assignExpr); var success = semacts.Validate(stmts); var results = semacts.Results; Assert.IsFalse(success); Assert.IsFalse(results.Success); Assert.IsTrue(results.HasResults); Assert.AreEqual(results.Results.Count, 1); }
public virtual void Visit(AssignExpr expr) { }
public void Visit(AssignExpr assignExpr, object[] args) { assignExpr.LeftExpr.Accept(this); assignExpr.RightExpr.Accept(this); RightValue v = readRightValue(assignExpr.RightExpr); assignExpr.RightValue = v; if (assignExpr.LeftExpr.LeftValue is VarRef) { VarRef varRef = assignExpr.LeftExpr.LeftValue as VarRef; scopeStack.SetValue(varRef.VarName, v); } else { throw new Exception(); } }
/// <summary> /// end表示字符串最后一个字符的后一个位置 /// </summary> /// <param name="begin"></param> /// <param name="end"></param> /// <returns></returns> private Expression parse(int begin, int end) { if (begin >= end) { kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin)); return(null); } while (isWhiteSpace(expr[begin])) { begin++; } while (isWhiteSpace(expr[end - 1])) { end--; } int currentParenLevel; bool hasSideParren = true; while (expr[begin] == '(' && hasSideParren) { currentParenLevel = 0; int currentPos; for (currentPos = begin; currentPos < end; currentPos++) { if (expr[currentPos] == '(') { currentParenLevel++; } else if (expr[currentPos] == ')') { currentParenLevel--; if (currentParenLevel == 0) { if (currentPos == end - 1) { begin++; end--; } else { hasSideParren = false; } break; } } } if (currentPos == end && currentParenLevel > 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin)); return(null); } } currentParenLevel = 0; OpLevel currentLevel = OpLevel.Null; OpLevel minLevel = OpLevel.Null; int minPos = -1; int minOpLength = 0; bool findOp = false; string op = null; MatchTokenResult matchTokenResult; //找到当前应处理的操作符 for (int currentPos = begin; currentPos < end; currentPos = matchTokenResult.EndPos) { //if (expr[currentPos] == ' ' || expr[currentPos] == '\t' || expr[currentPos] == '\n' // || Environment.NewLine.IndexOf(expr[currentPos]) != -1) //{ // op = null; // continue; //} matchTokenResult = MatchToken(currentPos, end); if (matchTokenResult.TokenType == TokenType.Error) { return(null); } if (matchTokenResult.TokenType != TokenType.Operator) { continue; } op = matchTokenResult.Matched; if (op != "(" && op != ")") { findOp = true; } if (op == "(") { currentParenLevel++; continue; } else if (op == ")") { currentParenLevel--; continue; } else if (currentParenLevel > 0) { continue; } else if (currentParenLevel < 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(currentPos)); return(null); } if (currentParenLevel == 0 && ( (int)(currentLevel = getOpLevel(op)) < (int)minLevel) || ((int)currentLevel == (int)minLevel && op != "=") //=为右结合 ) { minLevel = currentLevel; minPos = matchTokenResult.BeginPos; minOpLength = op.Length; } } if (currentParenLevel != 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin)); return(null); } if (!findOp) //单个数据 { string str = expr.Substring(begin, end - begin); int currentPos = begin; matchTokenResult = MatchToken(currentPos, end); switch (matchTokenResult.TokenType) { case TokenType.Int: RightValueExpr intResult = new RightValueExpr(); IntConst intConst = new IntConst(); intConst.Value = int.Parse(matchTokenResult.Matched); intResult.DataType = DataType.Int; intResult.RightValue = intConst; intResult.Location = loc.Offset(begin); return(intResult); case TokenType.Float: RightValueExpr floatResult = new RightValueExpr(); FloatConst floatConst = new FloatConst(); floatConst.Value = float.Parse(matchTokenResult.Matched); floatResult.DataType = DataType.Float; //modified by Wander @ 2011 floatResult.RightValue = floatConst; floatResult.Location = loc.Offset(begin); return(floatResult); case TokenType.String: RightValueExpr strResult = new RightValueExpr(); StringConst strConst = new StringConst(); strConst.Value = matchTokenResult.Matched; strResult.DataType = DataType.String; strResult.RightValue = strConst; strResult.Location = loc.Offset(begin); return(strResult); case TokenType.Bool: RightValueExpr boolResult = new RightValueExpr(); BoolConst boolConst = new BoolConst(); boolConst.Value = bool.Parse(matchTokenResult.Matched); boolResult.DataType = DataType.Bool; boolResult.RightValue = boolConst; boolResult.Location = loc.Offset(begin); return(boolResult); case TokenType.Variable: VarRef varRef = new VarRef(); varRef.VarName = matchTokenResult.Matched; LeftValueExpr leftValueResult = new LeftValueExpr(); leftValueResult.DataType = DataType.Unknown; leftValueResult.Location = loc.Offset(begin); leftValueResult.LeftValue = varRef; return(leftValueResult); default: kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin)); return(null); } } Expression left; Expression right; matchTokenResult = MatchToken(minPos, end); op = matchTokenResult.Matched; left = (begin != minPos) ? parse(begin, minPos) : null; //null表示单目运算符 right = parse(matchTokenResult.EndPos, end); Location currentLoc = loc.Offset(begin); if (right == null) { return(null); } switch (op) { case "=": if (!(left is LeftValueExpr)) { kernel.IssueError(ErrorType.NotLeftValue, currentLoc); return(null); } AssignExpr assignExpr = new AssignExpr(); assignExpr.LeftExpr = left as LeftValueExpr; assignExpr.RightExpr = right; assignExpr.DataType = right.DataType; assignExpr.Location = currentLoc; return(assignExpr); case "&&": return(processBinaryLogicExpr( new AndExpr(), left, right, currentLoc)); case "||": return(processBinaryLogicExpr( new OrExpr(), left, right, currentLoc)); case "==": return(processBinaryCmpExpr(new EquExpr(), left, right, currentLoc)); case "!=": return(processBinaryCmpExpr(new NeqExpr(), left, right, currentLoc)); case ">": return(processBinaryCmpExpr(new GreatExpr(), left, right, currentLoc)); case ">=": return(processBinaryCmpExpr(new GreatEquExpr(), left, right, currentLoc)); case "<": return(processBinaryCmpExpr(new LessExpr(), left, right, currentLoc)); case "<=": return(processBinaryCmpExpr(new LessEquExpr(), left, right, currentLoc)); case "+": return(processBinaryAlgoExpr(new AddExpr(), left, right, currentLoc)); case "-": if (left == null) { NegativeExpr negExpr = new NegativeExpr(); if (right.DataType == DataType.Bool || right.DataType == DataType.String) { kernel.IssueError(ErrorType.OprandTypeError, currentLoc); return(null); } else if (right.DataType == DataType.Int) { negExpr.DataType = DataType.Int; } else if (right.DataType == DataType.Float) { negExpr.DataType = DataType.Float; } else { negExpr.DataType = DataType.Unknown; } negExpr.Op = right; negExpr.Location = currentLoc; return(negExpr); } else { return(processBinaryAlgoExpr(new SubExpr(), left, right, currentLoc)); } case "*": return(processBinaryAlgoExpr(new MulExpr(), left, right, currentLoc)); case "/": return(processBinaryAlgoExpr(new DivExpr(), left, right, currentLoc)); case "^": return(processBinaryAlgoExpr(new PowExpr(), left, right, currentLoc)); case "!": if (left != null) { kernel.IssueError(ErrorType.ExpressionSyntaxError, currentLoc); return(null); } else { NotExpr notExpr = new NotExpr(); notExpr.DataType = DataType.Bool; notExpr.Op = right; notExpr.Location = currentLoc; return(notExpr); } } return(null); }
/// <summary> /// end表示字符串最后一个字符的后一个位置 /// </summary> /// <param name="begin"></param> /// <param name="end"></param> /// <returns></returns> private Expression parse(int begin, int end) { if (begin >= end) { kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin)); return null; } while (isWhiteSpace(expr[begin])) begin++; while (isWhiteSpace(expr[end - 1])) end--; int currentParenLevel; bool hasSideParren = true; while (expr[begin] == '(' && hasSideParren) { currentParenLevel = 0; int currentPos; for (currentPos = begin; currentPos < end; currentPos++) { if (expr[currentPos] == '(') currentParenLevel++; else if (expr[currentPos] == ')') { currentParenLevel--; if (currentParenLevel == 0) { if (currentPos == end - 1) { begin++; end--; } else hasSideParren = false; break; } } } if (currentPos == end && currentParenLevel > 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin)); return null; } } currentParenLevel = 0; OpLevel currentLevel = OpLevel.Null; OpLevel minLevel = OpLevel.Null; int minPos = -1; int minOpLength = 0; bool findOp = false; string op = null; MatchTokenResult matchTokenResult; //找到当前应处理的操作符 for (int currentPos = begin; currentPos < end; currentPos = matchTokenResult.EndPos) { //if (expr[currentPos] == ' ' || expr[currentPos] == '\t' || expr[currentPos] == '\n' // || Environment.NewLine.IndexOf(expr[currentPos]) != -1) //{ // op = null; // continue; //} matchTokenResult = MatchToken(currentPos, end); if (matchTokenResult.TokenType == TokenType.Error) return null; if (matchTokenResult.TokenType != TokenType.Operator) continue; op = matchTokenResult.Matched; if (op != "(" && op != ")") findOp = true; if (op == "(") { currentParenLevel++; continue; } else if (op == ")") { currentParenLevel--; continue; } else if (currentParenLevel > 0) { continue; } else if (currentParenLevel < 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(currentPos)); return null; } if (currentParenLevel == 0 &&( (int)(currentLevel = getOpLevel(op)) < (int)minLevel) || ((int)currentLevel == (int)minLevel && op != "=") //=为右结合 ) { minLevel = currentLevel; minPos = matchTokenResult.BeginPos; minOpLength = op.Length; } } if (currentParenLevel != 0) { kernel.IssueError(ErrorType.SingleParen, loc.Offset(begin)); return null; } if (!findOp) //单个数据 { string str = expr.Substring(begin, end - begin); int currentPos = begin; matchTokenResult = MatchToken(currentPos, end); switch (matchTokenResult.TokenType) { case TokenType.Int: RightValueExpr intResult = new RightValueExpr(); IntConst intConst = new IntConst(); intConst.Value = int.Parse(matchTokenResult.Matched); intResult.DataType = DataType.Int; intResult.RightValue = intConst; intResult.Location = loc.Offset(begin); return intResult; case TokenType.Float: RightValueExpr floatResult = new RightValueExpr(); FloatConst floatConst = new FloatConst(); floatConst.Value = float.Parse(matchTokenResult.Matched); floatResult.DataType = DataType.Int; floatResult.RightValue = floatConst; floatResult.Location = loc.Offset(begin); return floatResult; case TokenType.String: RightValueExpr strResult = new RightValueExpr(); StringConst strConst = new StringConst(); strConst.Value = matchTokenResult.Matched; strResult.DataType = DataType.String; strResult.RightValue = strConst; strResult.Location = loc.Offset(begin); return strResult; case TokenType.Bool: RightValueExpr boolResult = new RightValueExpr(); BoolConst boolConst = new BoolConst(); boolConst.Value = bool.Parse(matchTokenResult.Matched); boolResult.DataType = DataType.Bool; boolResult.RightValue = boolConst; boolResult.Location = loc.Offset(begin); return boolResult; case TokenType.Variable: VarRef varRef = new VarRef(); varRef.VarName = matchTokenResult.Matched; LeftValueExpr leftValueResult = new LeftValueExpr(); leftValueResult.DataType = DataType.Unknown; leftValueResult.Location = loc.Offset(begin); leftValueResult.LeftValue = varRef; return leftValueResult; default: kernel.IssueError(ErrorType.ExpressionSyntaxError, loc.Offset(begin)); return null; } } Expression left; Expression right; matchTokenResult = MatchToken(minPos, end); op = matchTokenResult.Matched; left = (begin != minPos) ? parse(begin, minPos) : null; //null表示单目运算符 right = parse(matchTokenResult.EndPos, end); Location currentLoc = loc.Offset(begin); if (right == null) return null; switch (op) { case "=": if (!(left is LeftValueExpr)) { kernel.IssueError(ErrorType.NotLeftValue, currentLoc); return null; } AssignExpr assignExpr = new AssignExpr(); assignExpr.LeftExpr = left as LeftValueExpr; assignExpr.RightExpr = right; assignExpr.DataType = right.DataType; assignExpr.Location = currentLoc; return assignExpr; case "&&": return processBinaryLogicExpr( new AndExpr(), left, right, currentLoc); case "||": return processBinaryLogicExpr( new OrExpr(), left, right, currentLoc); case "==": return processBinaryCmpExpr(new EquExpr(), left, right, currentLoc); case "!=": return processBinaryCmpExpr(new NeqExpr(), left, right, currentLoc); case ">": return processBinaryCmpExpr(new GreatExpr(), left, right, currentLoc); case ">=": return processBinaryCmpExpr(new GreatEquExpr(), left, right, currentLoc); case "<": return processBinaryCmpExpr(new LessExpr(), left, right, currentLoc); case "<=": return processBinaryCmpExpr(new LessEquExpr(), left, right, currentLoc); case "+": return processBinaryAlgoExpr(new AddExpr(), left, right, currentLoc); case "-": if (left == null) { NegativeExpr negExpr = new NegativeExpr(); if (right.DataType == DataType.Bool || right.DataType == DataType.String) { kernel.IssueError(ErrorType.OprandTypeError, currentLoc); return null; } else if (right.DataType == DataType.Int) { negExpr.DataType = DataType.Int; } else if (right.DataType == DataType.Float) { negExpr.DataType = DataType.Float; } else { negExpr.DataType = DataType.Unknown; } negExpr.Op = right; negExpr.Location = currentLoc; return negExpr; } else { return processBinaryAlgoExpr(new SubExpr(), left, right, currentLoc); } case "*": return processBinaryAlgoExpr(new MulExpr(), left, right, currentLoc); case "/": return processBinaryAlgoExpr(new DivExpr(), left, right, currentLoc); case "^": return processBinaryAlgoExpr(new PowExpr(), left, right, currentLoc); case "!": if (left != null) { kernel.IssueError(ErrorType.ExpressionSyntaxError, currentLoc); return null; } else { NotExpr notExpr = new NotExpr(); notExpr.DataType = DataType.Bool; notExpr.Op = right; notExpr.Location = currentLoc; return notExpr; } } return null; }
void ApplyConversions(ArgList args, OverloadResult ovRes, out Expr writeBack) { writeBack = null; var parameters = ovRes.Parameters.Parameters; for (int i = 0; i < ovRes.FixedArgs; i++) { var conv = ovRes.Conversions[i]; var e = args.Args[i].Expr; if (conv.Kind != ConversionKind.Identity) { Convert(ref args.Args[i].Expr, FindType(parameters[i].ParameterType), conv); } if (conv is ConversionSymbolToConstant) { Convert(ref args.Args[i].Expr, FindType(parameters[i].ParameterType), BindOptions.Default); } HandleArgWriteBack(conv, e, ref writeBack); } if (ovRes.MissingArgs > 0) { for (int i = ovRes.FixedArgs; i < ovRes.FixedArgs + ovRes.MissingArgs; i++) { var conv = ovRes.Conversions[i]; var a = new Arg(LiteralExpr.Bound(((ConversionSymbolToConstant)conv).Constant)); Convert(ref a.Expr, FindType(parameters[i].ParameterType), BindOptions.Default); args.Args.Add(a); } } else if (ovRes.Parameters.HasParamArray) { var varArgs = new List <Expr>(ovRes.VarArgs); var varArgType = FindType(parameters[ovRes.FixedArgs].ParameterType.GetElementType()); bool hasRefArgs = false; for (int i = ovRes.FixedArgs; i < ovRes.FixedArgs + ovRes.VarArgs; i++) { var conv = ovRes.Conversions[i]; var e = args.Args[i].Expr; Convert(ref e, varArgType, conv); varArgs.Add(e); if (args.Args[i].RefKind != RefKind.None) { hasRefArgs = true; } } var varArg = new Arg(LiteralArray.Bound(varArgs, varArgType)); if (hasRefArgs) { var conv = ConversionSymbol.Create(ConversionSymbol.Create(ConversionKind.Identity), new ConversionToTemp(varArg.Expr.Datatype)); Convert(ref varArg.Expr, varArg.Expr.Datatype, conv); for (int i = ovRes.FixedArgs; i < ovRes.FixedArgs + ovRes.VarArgs; i++) { if (args.Args[i].RefKind != RefKind.None) { HandleVarArgWriteBack(conv, args.Args[i].Expr, i - ovRes.FixedArgs, ref writeBack); } } } while (args.Args.Count > ovRes.FixedArgs) { args.Args.RemoveAt(args.Args.Count - 1); } args.Args.Add(varArg); } void HandleArgWriteBack(ConversionSymbol conv, Expr e, ref Expr wb) { if (conv.IsIndirectRefConversion()) { if (e.Symbol?.HasSetAccess == true || e is AutoVarExpr || e is AliasExpr) { // Handle writeBack Expr t = IdExpr.Bound(conv.IndirectRefConversionTempLocal()); var wc = Conversion(t, e.Datatype, BindOptions.Default); if (wc.Exists) { Convert(ref t, e.Datatype, wc); SymbolExtensions.AddExpr(ref wb, AssignExpr.Bound(e, t, BindOptions.Default)); } } } } void HandleVarArgWriteBack(ConversionSymbol conv, Expr e, int i, ref Expr wb) { if (e.Symbol?.HasSetAccess == true || e is AutoVarExpr || e is AliasExpr) { // Handle writeBack Expr t = IdExpr.Bound(conv.IndirectRefConversionTempLocal()); t = ArrayAccessExpr.Bound(t, ArgList.Bound(LiteralExpr.Bound(Constant.Create(i + 1))), this); var wc = Conversion(t, e.Datatype, BindOptions.Default); if (wc.Exists) { Convert(ref t, e.Datatype, wc); SymbolExtensions.AddExpr(ref wb, AssignExpr.Bound(e, t, BindOptions.Default)); } } } }