/// <summary> /// Called when the item is a return item. /// </summary> /// <param name="target">The object that was passed to IParseItem.Visit.</param> /// <returns>The passed target or a modification of it.</returns> /// <exception cref="System.ArgumentNullException">If target is null.</exception> public IParseItem Visit(ReturnItem target) { if (target == null) throw new ArgumentNullException("target"); ILGenerator gen = compiler.CurrentGenerator; if (target.Expressions.Count == 1 && target.Expressions[0] is FuncCallItem) { ((FuncCallItem)target.Expressions[0]).IsTailCall = true; target.Expressions[0].Accept(this); return target; } // ILuaValue[] loc = new ILuaValue[{Expressions.Count}]; LocalBuilder loc = compiler.CreateArray(typeof(ILuaValue), target.Expressions.Count); for (int i = 0; i < target.Expressions.Count; i++) { // loc[{i}] = {Expressions[i]}; gen.Emit(OpCodes.Ldloc, loc); gen.Emit(OpCodes.Ldc_I4, i); target.Expressions[i].Accept(this); gen.Emit(OpCodes.Stelem, typeof(ILuaValue)); } //! push E.Runtime.CreateMultiValue(loc) gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Callvirt, typeof(ILuaEnvironment).GetMethod("get_Runtime")); gen.Emit(OpCodes.Ldloc, loc); gen.Emit(OpCodes.Callvirt, typeof(ILuaRuntime).GetMethod("CreateMultiValue")); compiler.RemoveTemporary(loc); return target; }
/// <summary> /// Called when the item is a return item. /// </summary> /// <param name="target">The object that was passed to IParseItem.Visit.</param> /// <returns>The passed target or a modification of it.</returns> /// <exception cref="System.ArgumentNullException">If target is null.</exception> public IParseItem Visit(ReturnItem target) { if (target == null) throw new ArgumentNullException("target"); foreach (var item in target.Expressions) item.Accept(this); return target; }
/// <summary> /// Reads a return statement from the input. /// </summary> /// <param name="input">Where to read input from.</param> /// <param name="prev">The token to append what is read into.</param> /// <returns>The object that was read.</returns> protected virtual ReturnItem ReadReturn(ITokenizer input, ref Token prev) { var debug = input.Read(); // read 'return' ReturnItem r = new ReturnItem(); if (debug.Value != "return") throw new InvalidOperationException(string.Format(Resources.MustBeOn, "return", "ReadReturn")); var name = input.Peek(); if (name.Value != "end" && name.Value != "until" && name.Value != "elseif" && name.Value != "else") { r.AddExpression(ReadExp(input, ref debug)); while (input.Peek().Value == ",") { Read(input, ref debug); // read ',' r.AddExpression(ReadExp(input, ref debug)); } if (input.Peek().Value == ";") { Read(input, ref debug); // read ';' } // look at the next token for validation but keep it in the // reader for the parrent. name = input.Peek(); if (name.Value != "end" && name.Value != "until" && name.Value != "elseif" && name.Value != "else" && !IsNullOrWhiteSpace(name.Value)) throw new SyntaxException( Resources.ReturnAtEnd, input.Name, debug); } prev.Append(debug); r.Debug = debug; return r; }