Пример #1
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];
                    Stream    s;
                    int       start = 0;

                    if (obj.ValueType == LuaValueType.Table)
                    {
                        s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        if (s == null)
                        {
                            throw new ArgumentException("First argument to io.read must be a file-stream or a file path, make sure to use file:read.");
                        }
                        start = 1;
                    }
                    else if (obj.GetValue() is Stream)
                    {
                        s     = obj.GetValue() as Stream;
                        start = 1;
                    }
                    else
                    {
                        s     = _input;
                        start = 0;
                    }

                    int[] a = _parse(args.Skip(start), "io.read");
                    return(_read(a, new StreamReader(s), Environment));
                }
Пример #2
0
        internal void Do()
        {
            try
            {
                lock (handle_)
                {
                    while (Status != LuaThreadStatus.Running)
                    {
                        Monitor.Wait(handle_);
                    }
                }

                ILuaMultiValue args = Interlocked.Exchange(ref args_, null);
                ILuaMultiValue ret  = method_.Invoke(LuaNil.Nil, false, -1, args);

                lock (handle_)
                {
                    args_      = ret;
                    exception_ = null;
                    Status     = LuaThreadStatus.Complete;
                    Monitor.Pulse(handle_);
                }
            }
            catch (Exception e)
            {
                lock (handle_)
                {
                    exception_ = e;
                    Status     = LuaThreadStatus.Complete;
                    Monitor.Pulse(handle_);
                }
            }
        }
Пример #3
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    string str = Path.GetTempFileName();
                    Stream s   = File.Open(str, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                    return(_environment.Runtime.CreateMultiValue(_createFile(s, _environment)));
                }
Пример #4
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                    {
                        throw new ArgumentException("Expecting one argument to function 'dofile'.");
                    }

                    string file = args[0].GetValue() as string;

                    if (string.IsNullOrEmpty(file))
                    {
                        throw new ArgumentException("First argument to 'loadfile' must be a file path.");
                    }

                    if (!File.Exists(file))
                    {
                        throw new FileNotFoundException("Unable to locate file at '" + file + "'.");
                    }

                    string chunk  = File.ReadAllText(file);
                    var    parsed = PlainParser.Parse(_environment.Parser, chunk,
                                                      Path.GetFileNameWithoutExtension(file));
                    var r = _environment.CodeCompiler.Compile(_environment, parsed, null);

                    return(r.Invoke(LuaNil.Nil, false, -1, LuaMultiValue.Empty));
                }
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                    {
                        throw new ArgumentException("Expecting at least one argument to function 'pcall'.");
                    }

                    ILuaValue func = args[0];

                    if (func.ValueType == LuaValueType.Function)
                    {
                        try
                        {
                            var ret = func.Invoke(LuaNil.Nil, false, -1, Environment.Runtime.CreateMultiValue(args.Skip(1).ToArray()));
                            return(Environment.Runtime.CreateMultiValue(new ILuaValue[] { LuaBoolean.True }.Union(ret).ToArray()));
                        }
                        catch (ThreadAbortException)
                        {
                            throw;
                        }
                        catch (ThreadInterruptedException)
                        {
                            throw;
                        }
                        catch (Exception e)
                        {
                            return(Environment.Runtime.CreateMultiValueFromObj(false, e.Message, e));
                        }
                    }
                    else
                    {
                        throw new ArgumentException("First argument to 'pcall' must be a function.");
                    }
                }
Пример #6
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 2)
                    {
                        throw new ArgumentException("Expecting at least two arguments to function 'overload'.");
                    }

                    ILuaValue meth = args[0];
                    ILuaValue obj  = args[1];

                    if (meth.ValueType != LuaValueType.Function)
                    {
                        throw new ArgumentException("First argument to function 'overload' must be a method.");
                    }

                    if (obj.ValueType != LuaValueType.Number || ((double)obj.GetValue() % 1 != 0))
                    {
                        throw new ArgumentException(
                                  "Second argument to function 'overload' must be an integer.");
                    }

                    int i = Convert.ToInt32((double)obj.GetValue());

                    return(meth.Invoke(null, false, i,
                                       _environment.Runtime.CreateMultiValue(args.Skip(2).ToArray())));
                }
Пример #7
0
        protected override ILuaMultiValue _invokeInternal(ILuaValue target, bool memberCall,
                                                          int overload, ILuaMultiValue args)
        {
            ILuaValue method = (ILuaValue)Activator.CreateInstance(_type, new[] { _env });

            return(method.Invoke(LuaNil.Nil, false, -1, args));
        }
Пример #8
0
        internal void _do()
        {
            try {
                lock (_handle) {
                    while (Status != LuaThreadStatus.Running)
                    {
                        Monitor.Wait(_handle);
                    }
                }

                ILuaMultiValue args = Interlocked.Exchange(ref _args, null);
                ILuaMultiValue ret  = _method.Invoke(LuaNil.Nil, false, -1, args);

                lock (_handle) {
                    _args      = ret;
                    _exception = null;
                    Status     = LuaThreadStatus.Complete;
                    Monitor.Pulse(_handle);
                }
            } catch (Exception e) {
                lock (_handle) {
                    _exception = e;
                    Status     = LuaThreadStatus.Complete;
                    Monitor.Pulse(_handle);
                }
            }
        }
Пример #9
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];

                    if (obj != LuaNil.Nil)
                    {
                        if (obj.ValueType == LuaValueType.String)
                        {
                            Stream s = File.OpenRead(obj.GetValue() as string);
                            _output = s;
                        }
                        else if (obj.ValueType == LuaValueType.Table)
                        {
                            Stream s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                            if (s == null)
                            {
                                throw new InvalidOperationException("First argument to function 'io.output' must be a file-stream or a string path.");
                            }

                            _output = s;
                        }
                        else if (obj is Stream)
                        {
                            _output = obj as Stream;
                        }
                        else
                        {
                            throw new InvalidOperationException("First argument to function 'io.output' must be a file-stream or a string path.");
                        }
                    }

                    return(Environment.Runtime.CreateMultiValue(_CreateFile(_output, Environment)));
                }
Пример #10
0
    protected override ILuaMultiValue _invokeInternal(ILuaValue target, bool methodCall,
                                                     int overload, ILuaMultiValue args) {
      if (methodCall) {
        args = new LuaMultiValue(new[] { target }.Concat(args).ToArray());
      }

      return _invokeInternal(args);
    }
Пример #11
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];
                    Stream    s;
                    int       start = 0;

                    if (obj.ValueType == LuaValueType.Table)
                    {
                        s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        if (s == null)
                        {
                            return(Environment.Runtime.CreateMultiValueFromObj(null, "First argument must be a file-stream or a file path."));
                        }
                        start = 1;
                    }
                    else if (obj is Stream)
                    {
                        s     = obj as Stream;
                        start = 1;
                    }
                    else
                    {
                        s     = _output;
                        start = 0;
                    }

                    try
                    {
                        for (int i = start; i < args.Count; i++)
                        {
                            var temp = args[i].GetValue();
                            if (temp is double)
                            {
                                var bt = (Environment.Settings.Encoding ?? Encoding.UTF8).GetBytes(((double)temp).ToString(CultureInfo.InvariantCulture));
                                s.Write(bt, 0, bt.Length);
                            }
                            else if (temp is string)
                            {
                                var bt = (Environment.Settings.Encoding ?? Encoding.UTF8).GetBytes(temp as string);
                                s.Write(bt, 0, bt.Length);
                            }
                            else
                            {
                                throw new ArgumentException("Arguments to io.write must be a string or number.");
                            }
                        }

                        return(Environment.Runtime.CreateMultiValue(_CreateFile(s, Environment)));
                    }
                    catch (ArgumentException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        return(Environment.Runtime.CreateMultiValueFromObj(null, e.Message, e));
                    }
                }
Пример #12
0
        public virtual IEnumerable <ILuaMultiValue> GenericLoop(ILuaEnvironment env,
                                                                ILuaMultiValue args)
        {
            // TODO: Replace this.
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }

            if (env == null)
            {
                throw new ArgumentNullException(nameof(env));
            }

            ILuaValue target = args[0];
            object    temp   = target.GetValue();

            if (temp is IEnumerable <ILuaMultiValue> enumT)
            {
                foreach (var item in enumT)
                {
                    yield return(item);
                }
            }
            else if (temp is IEnumerable en)
            {
                foreach (var item in en)
                {
                    yield return(new LuaMultiValue(CreateValue(item)));
                }
            }
            else if (target.ValueType == LuaValueType.Function)
            {
                ILuaValue s   = args[1];
                ILuaValue var = args[2];

                while (true)
                {
                    var ret = target.Invoke(LuaNil.Nil, false, -1, CreateMultiValue(s, var));
                    if (ret == null || ret[0] == null || ret[0] == LuaNil.Nil)
                    {
                        yield break;
                    }

                    var = ret[0];

                    yield return(ret);
                }
            }
            else
            {
                throw new InvalidOperationException(
                          $"Cannot enumerate over an object of type '{args[0]}'.");
            }
        }
Пример #13
0
                public int Compare(ILuaValue x, ILuaValue y)
                {
                    if (method_ != null)
                    {
                        ILuaMultiValue ret = method_.Invoke(
                            LuaNil.Nil, false, -1, E_.Runtime.CreateMultiValueFromObj(x, y));
                        return(ret.IsTrue ? -1 : 1);
                    }

                    return(x.CompareTo(y));
                }
Пример #14
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                    {
                        throw new ArgumentException("Expecting at least one argument to function 'load'.");
                    }

                    ILuaValue ld = args[0];
                    string    chunk;

                    if (ld.ValueType == LuaValueType.Function)
                    {
                        chunk = "";
                        while (true)
                        {
                            var ret = ld.Invoke(LuaNil.Nil, false, -1, Environment.Runtime.CreateMultiValue());
                            if (ret[0].ValueType == LuaValueType.String)
                            {
                                if (string.IsNullOrEmpty(ret[0].GetValue() as string))
                                {
                                    break;
                                }
                                else
                                {
                                    chunk += ret[0].GetValue() as string;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    else if (ld.ValueType == LuaValueType.String)
                    {
                        chunk = ld.GetValue() as string;
                    }
                    else
                    {
                        throw new ArgumentException("First argument to 'load' must be a string or a method.");
                    }

                    try
                    {
                        return(Environment.Runtime.CreateMultiValue(Environment.CodeCompiler.Compile(Environment, PlainParser.Parse(Environment.Parser, chunk, null), null)));
                    }
                    catch (Exception e)
                    {
                        return(Environment.Runtime.CreateMultiValueFromObj(null, e.Message));
                    }
                }
Пример #15
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];
                    bool      close;
                    Stream    s;
                    int       start;
                    string    oString = obj.GetValue() as string;

                    if (oString != null)
                    {
                        if (oString[0] != '*')
                        {
                            s     = File.OpenRead(oString);
                            close = true;
                            start = 1;
                        }
                        else
                        {
                            s     = _input;
                            close = false;
                            start = 0;
                        }
                    }
                    else if (obj.ValueType == LuaValueType.Table)
                    {
                        s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        if (s == null)
                        {
                            throw new ArgumentException("First argument to io.lines must be a file-stream or a " +
                                                        "file path, make sure to use file:lines.");
                        }

                        close = false;
                        start = 1;
                    }
                    else if (obj.GetValue() is Stream st)
                    {
                        s     = st;
                        close = false;
                        start = 1;
                    }
                    else
                    {
                        s     = _input;
                        close = false;
                        start = 0;
                    }

                    int[] a = _parse(args.Skip(start), "io.lines");
                    return(_environment.Runtime.CreateMultiValue(new LinesHelper(_environment, close, s, a)));
                }
Пример #16
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    var t = _getStream(args[0], _environment, out Stream s);

                    if (t != null)
                    {
                        return(t);
                    }

                    try {
                        s.Close();
                        return(_environment.Runtime.CreateMultiValue(_createFile(s, _environment)));
                    } catch (Exception e) {
                        return(_environment.Runtime.CreateMultiValueFromObj(null, e.Message, e));
                    }
                }
Пример #17
0
 IEnumerable <ILuaValue> resume(ILuaThread thread, params ILuaValue[] args)
 {
     try {
         ILuaMultiValue ret = thread.Resume(_env.Runtime.CreateMultiValue(args));
         return(new[] { _env.Runtime.CreateValue(true) }.Concat(ret));
     } catch (Exception e) {
         if (e.Message == "Cannot resume a dead thread.")
         {
             return(_env.Runtime.CreateMultiValueFromObj(false, "cannot resume dead coroutine"));
         }
         else
         {
             return(_env.Runtime.CreateMultiValueFromObj(false, e.Message, e));
         }
     }
 }
Пример #18
0
                public string Match(Match match)
                {
                    if (count_ >= max_)
                    {
                        return(match.Value);
                    }

                    count_++;
                    if (string_ != null)
                    {
                        return(Regex.Replace(string_, @"%[0-9%]", m =>
                        {
                            if (m.Value == "%%")
                            {
                                return "%";
                            }
                            int i = int.Parse(m.Groups[0].Value.Substring(1));
                            return i == 0 ? match.Value : (match.Groups.Count > i ? match.Groups[i].Value : "");
                        }));
                    }
                    else if (table_ != null)
                    {
                        string    key   = match.Groups.Count == 0 ? match.Value : match.Groups[1].Value;
                        ILuaValue value = table_.GetItemRaw(new LuaString(key));
                        if (value != null && value.IsTrue)
                        {
                            return(value.ToString());
                        }
                    }
                    else if (method_ != null)
                    {
                        var            groups = match.Groups.Cast <Group>().Skip(1).Select(c => c.Value).ToArray();
                        var            args   = LuaMultiValue.CreateMultiValueFromObj(groups);
                        ILuaMultiValue obj    = method_.Invoke(LuaNil.Nil, false, -1, args);
                        if (obj != null && obj.Count > 0)
                        {
                            ILuaValue value = obj[0];
                            if (value != null && value.IsTrue)
                            {
                                return(value.ToString());
                            }
                        }
                    }

                    return(match.Value);
                }
Пример #19
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (_stream == null)
                        return LuaMultiValue.Empty;

                    var ret = _read(_ops, _stream, Environment);

                    if (_stream.EndOfStream)
                    {
                        if (_close)
                            _stream.Close();

                        _stream = null;
                    }

                    return ret;
                }
Пример #20
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];

                    if (obj.GetValue() is Stream)
                    {
                        return(Environment.Runtime.CreateMultiValueFromObj("file"));
                    }
                    else if (obj.ValueType == LuaValueType.Table)
                    {
                        Stream s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        return(Environment.Runtime.CreateMultiValueFromObj((s == null ? null : "file")));
                    }
                    else
                    {
                        return(LuaMultiValue.Empty);
                    }
                }
Пример #21
0
        /// <summary>
        /// Suspends the current thread to allow the wating thread to execute.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">If the thread
        /// is running or dead -or- if this is not a Lua thread.</exception>
        /// <exception cref="System.Reflection.TargetInvocationException">If
        /// the thread throws an exception.</exception>
        public override ILuaMultiValue Resume(ILuaMultiValue args)
        {
            lock (handle_)
            {
                if (!IsLua)
                {
                    throw new InvalidOperationException(
                              "Cannot resume a thread that has been created outside Lua.");
                }
                if (Status == LuaThreadStatus.Running)
                {
                    throw new InvalidOperationException(
                              "Cannot resume a running thread.");
                }
                if (Status == LuaThreadStatus.Complete)
                {
                    throw new InvalidOperationException(
                              "Cannot resume a dead thread.");
                }

                if (backing_.ThreadState == ThreadState.Unstarted)
                {
                    backing_.Start();
                }

                args   = args ?? E_.Runtime.CreateMultiValue();
                args_  = args;
                Status = LuaThreadStatus.Running;

                Monitor.Pulse(handle_);
                while (Status == LuaThreadStatus.Running)
                {
                    Monitor.Wait(handle_);
                }

                if (exception_ != null)
                {
                    throw new TargetInvocationException(exception_);
                }

                ILuaMultiValue ret = Interlocked.Exchange(ref args_, null);
                return(ret ?? E_.Runtime.CreateMultiValue());
            }
        }
Пример #22
0
        /// <summary>
        /// Suspends the current thread to allow the wating thread to execute.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">If the thread
        /// is running or dead -or- if this is not a Lua thread.</exception>
        /// <exception cref="System.Reflection.TargetInvocationException">If
        /// the thread throws an exception.</exception>
        public override ILuaMultiValue Resume(ILuaMultiValue args)
        {
            lock (handle_)
            {
                if (!IsLua)
                {
                    throw new InvalidOperationException(
                        "Cannot resume a thread that has been created outside Lua.");
                }
                if (Status == LuaThreadStatus.Running)
                {
                    throw new InvalidOperationException(
                        "Cannot resume a running thread.");
                }
                if (Status == LuaThreadStatus.Complete)
                {
                    throw new InvalidOperationException(
                        "Cannot resume a dead thread.");
                }

                if (backing_.ThreadState == ThreadState.Unstarted)
                {
                    backing_.Start();
                }

                args = args ?? E_.Runtime.CreateMultiValue();
                args_ = args;
                Status = LuaThreadStatus.Running;

                Monitor.Pulse(handle_);
                while (Status == LuaThreadStatus.Running)
                {
                    Monitor.Wait(handle_);
                }

                if (exception_ != null)
                    throw new TargetInvocationException(exception_);

                ILuaMultiValue ret = Interlocked.Exchange(ref args_, null);
                return ret ?? E_.Runtime.CreateMultiValue();
            }
        }
Пример #23
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    Stream s;
                    var    t = _getStream(args[0], Environment, out s);

                    if (t != null)
                    {
                        return(t);
                    }

                    try
                    {
                        _output.Flush();
                        return(Environment.Runtime.CreateMultiValue(_CreateFile(_output, Environment)));
                    }
                    catch (Exception e)
                    {
                        return(Environment.Runtime.CreateMultiValueFromObj(null, e.Message, e));
                    }
                }
Пример #24
0
                protected override ILuaMultiValue _invokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                    {
                        throw new ArgumentException("Expecting at least one argument to function 'loadfile'.");
                    }

                    string file = args[0].GetValue() as string;
                    string mode = args[1].GetValue() as string;

                    if (string.IsNullOrEmpty(file))
                    {
                        throw new ArgumentException("First argument to 'loadfile' must be a file path.");
                    }

                    if (!File.Exists(file))
                    {
                        throw new FileNotFoundException("Unable to locate file at '" + file + "'.");
                    }

                    if (string.IsNullOrEmpty(mode) && args.Count > 1)
                    {
                        throw new ArgumentException("Second argument to 'loadfile' must be a string mode.");
                    }

                    if (mode != "type")
                    {
                        throw new ArgumentException("The only mode supported by loadfile is 'type'.");
                    }

                    string chunk = File.ReadAllText(file);

                    try {
                        var parsed = PlainParser.Parse(_environment.Parser, chunk,
                                                       Path.GetFileNameWithoutExtension(file));
                        return(_environment.Runtime.CreateMultiValue(
                                   _environment.CodeCompiler.Compile(_environment, parsed, null)));
                    } catch (Exception e) {
                        return(_environment.Runtime.CreateMultiValueFromObj(null, e.Message));
                    }
                }
Пример #25
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (_stream == null)
                    {
                        return(LuaMultiValue.Empty);
                    }

                    var ret = _read(_ops, _stream, Environment);

                    if (_stream.EndOfStream)
                    {
                        if (_close)
                        {
                            _stream.Close();
                        }

                        _stream = null;
                    }

                    return(ret);
                }
Пример #26
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    StringBuilder str = new StringBuilder();

                    if (args != null)
                    {
                        for (int i = 0; i < args.Count; i++)
                        {
                            ILuaValue temp = args[i];
                            str.Append(temp.ToString());
                            str.Append('\t');
                        }
                        str.Append("\n");
                    }

                    Stream s = Environment.Settings.Stdout;

                    byte[] txt = (Environment.Settings.Encoding ?? Encoding.UTF8).GetBytes(str.ToString());
                    s.Write(txt, 0, txt.Length);

                    return(LuaMultiValue.Empty);
                }
Пример #27
0
        /// <summary>
        /// Yields the calling thread.
        /// </summary>
        /// <param name="args">The arguments to return from Resume.</param>
        /// <returns>The objects passed to Resume.</returns>
        /// <exception cref="System.InvalidOperationException">If the thread
        /// is not already running -or- if this is not a Lua thread.</exception>
        public override ILuaMultiValue Yield(ILuaMultiValue args)
        {
            lock (handle_)
            {
                if (!IsLua)
                {
                    throw new InvalidOperationException(
                              "Cannot resume a thread that has been created outside Lua.");
                }
                if (Status != LuaThreadStatus.Running)
                {
                    throw new InvalidOperationException("Thread must be running to yield.");
                }

                // Fire the OnYield event.
                var e = new YieldEventArgs(args);
                CallOnYield(e);

                // If the yield is rejected, simply return the arguments.
                if (e.RejectYield)
                {
                    return(e.ReturnArguments);
                }

                args   = args ?? E_.Runtime.CreateMultiValue();
                args_  = args;
                Status = LuaThreadStatus.Suspended;

                Monitor.Pulse(handle_);
                while (Status != LuaThreadStatus.Running)
                {
                    Monitor.Wait(handle_);
                }

                ILuaMultiValue ret = Interlocked.Exchange(ref args_, null);
                return(ret ?? E_.Runtime.CreateMultiValue());
            }
        }
Пример #28
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];
                    Stream s;
                    int start = 0;

                    if (obj.ValueType == LuaValueType.Table)
                    {
                        s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        if (s == null)
                            return Environment.Runtime.CreateMultiValueFromObj(null, "First argument must be a file-stream or a file path.");
                        start = 1;
                    }
                    else if (obj is Stream)
                    {
                        s = obj as Stream;
                        start = 1;
                    }
                    else
                    {
                        s = _output;
                        start = 0;
                    }

                    try
                    {
                        for (int i = start; i < args.Count; i++)
                        {
                            var temp = args[i].GetValue();
                            if (temp is double)
                            {
                                var bt = (Environment.Settings.Encoding ?? Encoding.UTF8).GetBytes(((double)temp).ToString(CultureInfo.InvariantCulture));
                                s.Write(bt, 0, bt.Length);
                            }
                            else if (temp is string)
                            {
                                var bt = (Environment.Settings.Encoding ?? Encoding.UTF8).GetBytes(temp as string);
                                s.Write(bt, 0, bt.Length);
                            }
                            else
                                throw new ArgumentException("Arguments to io.write must be a string or number.");
                        }

                        return Environment.Runtime.CreateMultiValue(_CreateFile(s, Environment));
                    }
                    catch (ArgumentException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        return Environment.Runtime.CreateMultiValueFromObj(null, e.Message, e);
                    }
                }
Пример #29
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];

                    if (obj.GetValue() is Stream)
                    {
                        return Environment.Runtime.CreateMultiValueFromObj("file");
                    }
                    else if (obj.ValueType == LuaValueType.Table)
                    {
                        Stream s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        return Environment.Runtime.CreateMultiValueFromObj((s == null ? null : "file"));
                    }
                    else
                        return LuaMultiValue.Empty;
                }
Пример #30
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    string str = Path.GetTempFileName();
                    Stream s = File.Open(str, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                    Remove.Add(s);
                    return Environment.Runtime.CreateMultiValue(_CreateFile(s, Environment));
                }
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    StringBuilder str = new StringBuilder();
                    if (args != null)
                    {
                        for (int i = 0; i < args.Count; i++)
                        {
                            ILuaValue temp = args[i];
                            str.Append(temp.ToString());
                            str.Append('\t');
                        }
                        str.Append("\n");
                    }

                    Stream s = Environment.Settings.Stdout;
                    byte[] txt = (Environment.Settings.Encoding ?? Encoding.UTF8).GetBytes(str.ToString());
                    s.Write(txt, 0, txt.Length);

                    return LuaMultiValue.Empty;
                }
Пример #32
0
 /// <summary>
 /// Performs that actual invokation of the method.
 /// </summary>
 /// <param name="E">The current environment.</param>
 /// <param name="target">The object that this was called on.</param>
 /// <param name="memberCall">Whether the call used member call syntax (:).</param>
 /// <param name="args">The current arguments, not null but maybe empty.</param>
 /// <param name="overload">The overload to chose or negative to do 
 /// overload resoltion.</param>
 /// <param name="byRef">An array of the indicies that are passed by-reference.</param>
 /// <returns>The values to return to Lua.</returns>
 /// <exception cref="System.ArgumentException">If the object cannot be
 /// invoked with the given arguments.</exception>
 /// <exception cref="System.Reflection.AmbiguousMatchException">If there are two
 /// valid overloads for the given arguments.</exception>
 /// <exception cref="System.IndexOutOfRangeException">If overload is
 /// larger than the number of overloads.</exception>
 /// <exception cref="System.NotSupportedException">If this object does
 /// not support overloads.</exception>
 protected override ILuaMultiValue InvokeInternal(ILuaValue target, bool methodCall, int overload, ILuaMultiValue args)
 {
     return _Method(_E, args, target, methodCall);
 }
Пример #33
0
 /// <summary>
 /// Invokes the object with the given arguments.
 /// </summary>
 /// <param name="self">The object being called on.</param>
 /// <param name="memberCall">Whether the call was using member call notation (:).</param>
 /// <param name="args">The arguments for the call.</param>
 /// <param name="overload">Specifies the overload to call; -1 to use overload-resolution.</param>
 /// <returns>The return values from the invokation.</returns>
 public virtual ILuaMultiValue Invoke(ILuaValue self, bool memberCall, int overload, ILuaMultiValue args)
 {
     return(InvokeInternal(self, memberCall, overload, args));
 }
 /// <summary>
 /// Performs that actual invokation of the method.
 /// </summary>
 /// <param name="target">The object that this was called on.</param>
 /// <param name="memberCall">Whether the call used member call syntax (:).</param>
 /// <param name="args">The current arguments, not null but maybe empty.</param>
 /// <param name="overload">The overload to chose or negative to do 
 /// overload resoltion.</param>
 /// <param name="byRef">An array of the indicies that are passed by-reference.</param>
 /// <returns>The values to return to Lua.</returns>
 /// <exception cref="System.ArgumentException">If the object cannot be
 /// invoked with the given arguments.</exception>
 /// <exception cref="System.Reflection.AmbiguousMatchException">If there are two
 /// valid overloads for the given arguments.</exception>
 /// <exception cref="System.IndexOutOfRangeException">If overload is
 /// larger than the number of overloads.</exception>
 /// <exception cref="System.NotSupportedException">If this object does
 /// not support overloads.</exception>
 protected override ILuaMultiValue InvokeInternal(ILuaValue target, bool methodCall, int overload, ILuaMultiValue args)
 {
     if (methodCall) args = new LuaMultiValue(new[] { target }.Concat(args).ToArray());
     return InvokeInternal(args);
 }
Пример #35
0
        /// <summary>
        /// Starts a generic for loop and returns an enumerator object used to
        /// get the values.
        /// </summary>
        /// <param name="args">The input arguments.</param>
        /// <param name="E">The current environment.</param>
        /// <returns>An object used to enumerate over the loop, cannot be null.</returns>
        /// <exception cref="System.ArgumentNullException">If args or E is null.</exception>
        /// <exception cref="System.InvalidOperationException">If the object(s)
        /// cannot be enumerated over.</exception>
        public virtual IEnumerable<ILuaMultiValue> GenericLoop(ILuaEnvironment E, ILuaMultiValue args)
        {
            // TODO: Replace this.
            if (args == null)
                throw new ArgumentNullException("args");
            if (E == null)
                throw new ArgumentNullException("E");

            ILuaValue target = args[0];
            object temp = target.GetValue();
            if (temp is IEnumerable<ILuaMultiValue>)
            {
                foreach (var item in (IEnumerable<ILuaMultiValue>)temp)
                    yield return item;
            }
            else if (temp is IEnumerable)
            {
                foreach (var item in (IEnumerable)temp)
                {
                    yield return new LuaMultiValue(CreateValue(item));
                }
            }
            else if (target.ValueType == LuaValueType.Function)
            {
                ILuaValue s = args[1];
                ILuaValue var = args[2];

                while (true)
                {
                    var ret = target.Invoke(LuaNil.Nil, false, -1, CreateMultiValue(s, var));
                    if (ret == null || ret[0] == null || ret[0] == LuaNil.Nil)
                        yield break;
                    var = ret[0];

                    yield return ret;
                }
            }
            else
                throw new InvalidOperationException("Cannot enumerate over an object of type '" + args[0] + "'.");
        }
Пример #36
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                        throw new ArgumentException("Expecting at least one argument to function 'load'.");

                    ILuaValue ld = args[0];
                    string chunk;

                    if (ld.ValueType == LuaValueType.Function)
                    {
                        chunk = "";
                        while (true)
                        {
                            var ret = ld.Invoke(LuaNil.Nil, false, -1, Environment.Runtime.CreateMultiValue());
                            if (ret[0].ValueType == LuaValueType.String)
                            {
                                if (string.IsNullOrEmpty(ret[0].GetValue() as string))
                                    break;
                                else
                                    chunk += ret[0].GetValue() as string;
                            }
                            else
                                break;
                        }
                    }
                    else if (ld.ValueType == LuaValueType.String)
                    {
                        chunk = ld.GetValue() as string;
                    }
                    else
                        throw new ArgumentException("First argument to 'load' must be a string or a method.");

                    try
                    {
                        return Environment.Runtime.CreateMultiValue(Environment.CodeCompiler.Compile(Environment, PlainParser.Parse(Environment.Parser, chunk, null), null));
                    }
                    catch (Exception e)
                    {
                        return Environment.Runtime.CreateMultiValueFromObj(null, e.Message);
                    }
                }
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 2)
                        throw new ArgumentException("Expecting at least two arguments to function 'overload'.");

                    ILuaValue meth = args[0];
                    ILuaValue obj = args[1];

                    if (meth.ValueType != LuaValueType.Function)
                        throw new ArgumentException("First argument to function 'overload' must be a method.");
                    if (obj.ValueType != LuaValueType.Number || ((double)obj.GetValue() % 1 != 0))
                        throw new ArgumentException("Second argument to function 'overload' must be an integer.");

                    int i = Convert.ToInt32((double)obj.GetValue());

                    return meth.Invoke(null, false, i, Environment.Runtime.CreateMultiValue(args.Skip(2).ToArray()));
                }
Пример #38
0
        /// <summary>
        /// Yields the calling thread.
        /// </summary>
        /// <param name="args">The arguments to return from Resume.</param>
        /// <returns>The objects passed to Resume.</returns>
        /// <exception cref="System.InvalidOperationException">If the thread
        /// is not already running -or- if this is not a Lua thread.</exception>
        public override ILuaMultiValue Yield(ILuaMultiValue args)
        {
            lock (handle_)
            {
                if (!IsLua)
                {
                    throw new InvalidOperationException(
                        "Cannot resume a thread that has been created outside Lua.");
                }
                if (Status != LuaThreadStatus.Running)
                    throw new InvalidOperationException("Thread must be running to yield.");

                // Fire the OnYield event.
                var e = new YieldEventArgs(args);
                CallOnYield(e);

                // If the yield is rejected, simply return the arguments.
                if (e.RejectYield)
                    return e.ReturnArguments;

                args = args ?? E_.Runtime.CreateMultiValue();
                args_ = args;
                Status = LuaThreadStatus.Suspended;

                Monitor.Pulse(handle_);
                while (Status != LuaThreadStatus.Running)
                {
                    Monitor.Wait(handle_);
                }

                ILuaMultiValue ret = Interlocked.Exchange(ref args_, null);
                return ret ?? E_.Runtime.CreateMultiValue();
            }
        }
Пример #39
0
        internal void Do()
        {
            try
            {
                lock (handle_)
                {
                    while (Status != LuaThreadStatus.Running)
                    {
                        Monitor.Wait(handle_);
                    }
                }

                ILuaMultiValue args = Interlocked.Exchange(ref args_, null);
                ILuaMultiValue ret = method_.Invoke(LuaNil.Nil, false, -1, args);

                lock (handle_)
                {
                    args_ = ret;
                    exception_ = null;
                    Status = LuaThreadStatus.Complete;
                    Monitor.Pulse(handle_);
                }
            }
            catch (Exception e)
            {
                lock (handle_)
                {
                    exception_ = e;
                    Status = LuaThreadStatus.Complete;
                    Monitor.Pulse(handle_);
                }
            }
        }
Пример #40
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                        throw new ArgumentException("Expecting one argument to function 'dofile'.");

                    string file = args[0].GetValue() as string;

                    if (string.IsNullOrEmpty(file))
                        throw new ArgumentException("First argument to 'loadfile' must be a file path.");
                    if (!File.Exists(file))
                        throw new FileNotFoundException("Unable to locate file at '" + file + "'.");

                    string chunk = File.ReadAllText(file);
                    var r = Environment.CodeCompiler.Compile(Environment,
                        PlainParser.Parse(Environment.Parser, chunk, Path.GetFileNameWithoutExtension(file)), null);
                    return r.Invoke(LuaNil.Nil, false, -1, LuaMultiValue.Empty);
                }
Пример #41
0
 /// <summary>
 /// Performs that actual invokation of the method.
 /// </summary>
 /// <param name="target">The object that this was called on.</param>
 /// <param name="memberCall">Whether the call used member call syntax (:).</param>
 /// <param name="args">The current arguments, not null but maybe empty.</param>
 /// <param name="overload">The overload to chose or negative to do 
 /// overload resoltion.</param>
 /// <param name="byRef">An array of the indicies that are passed by-reference.</param>
 /// <returns>The values to return to Lua.</returns>
 /// <exception cref="System.ArgumentException">If the object cannot be
 /// invoked with the given arguments.</exception>
 /// <exception cref="System.Reflection.AmbiguousMatchException">If there are two
 /// valid overloads for the given arguments.</exception>
 /// <exception cref="System.IndexOutOfRangeException">If overload is
 /// larger than the number of overloads.</exception>
 /// <exception cref="System.NotSupportedException">If this object does
 /// not support overloads.</exception>
 protected override ILuaMultiValue InvokeInternal(ILuaValue target, bool memberCall, int overload, ILuaMultiValue args)
 {
     ILuaValue method = (ILuaValue)Activator.CreateInstance(_Type, new[] { _E });
     Contract.Assume(method != null);
     return method.Invoke(LuaNil.Nil, false, -1, args);
 }
Пример #42
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                        throw new ArgumentException("Expecting at least one argument to function 'loadfile'.");

                    string file = args[0].GetValue() as string;
                    string mode = args[1].GetValue() as string;

                    if (string.IsNullOrEmpty(file))
                        throw new ArgumentException("First argument to 'loadfile' must be a file path.");
                    if (!File.Exists(file))
                        throw new FileNotFoundException("Unable to locate file at '" + file + "'.");
                    if (string.IsNullOrEmpty(mode) && args.Count > 1)
                        throw new ArgumentException("Second argument to 'loadfile' must be a string mode.");
                    if (mode != "type")
                        throw new ArgumentException("The only mode supported by loadfile is 'type'.");

                    string chunk = File.ReadAllText(file);
                    try
                    {
                        return Environment.Runtime.CreateMultiValue(Environment.CodeCompiler.Compile(Environment,
                            PlainParser.Parse(Environment.Parser, chunk, Path.GetFileNameWithoutExtension(file)), null));
                    }
                    catch (Exception e)
                    {
                        return Environment.Runtime.CreateMultiValueFromObj(null, e.Message);
                    }
                }
Пример #43
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    Stream s;
                    var t = _getStream(args[0], Environment, out s);
                    if (t != null)
                        return t;

                    try
                    {
                        _output.Flush();
                        return Environment.Runtime.CreateMultiValue(_CreateFile(_output, Environment));
                    }
                    catch (Exception e)
                    {
                        return Environment.Runtime.CreateMultiValueFromObj(null, e.Message, e);
                    }
                }
Пример #44
0
 /// <summary>
 /// Creates a new YieldEventArgs object.
 /// </summary>
 /// <param name="args">The arguments given to Yield.</param>
 internal YieldEventArgs(ILuaMultiValue args)
 {
     this.Arguments = args;
     this.RejectYield = false;
     this.ReturnArguments = null;
 }
Пример #45
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];
                    bool close;
                    Stream s;
                    int start = 0;
                    string oString = obj.GetValue() as string;

                    if (oString != null)
                    {
                        if (oString[0] != '*')
                        {
                            s = File.OpenRead(oString);
                            close = true;
                            start = 1;
                        }
                        else
                        {
                            s = _input;
                            close = false;
                            start = 0;
                        }
                    }
                    else if (obj.ValueType == LuaValueType.Table)
                    {
                        s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        if (s == null)
                            throw new ArgumentException("First argument to io.lines must be a file-stream or a file path, make sure to use file:lines.");
                        close = false;
                        start = 1;
                    }
                    else if (obj.GetValue() is Stream)
                    {
                        s = obj.GetValue() as Stream;
                        close = false;
                        start = 1;
                    }
                    else
                    {
                        s = _input;
                        close = false;
                        start = 0;
                    }

                    int[] a = _parse(args.Skip(start), "io.lines");
                    return Environment.Runtime.CreateMultiValue(new LinesHelper(Environment, close, s, a));
                }
 /// <summary>
 /// Does the actual work of invoking the method.
 /// </summary>
 /// <param name="args">The arguments that were passed to the method,
 /// never null.</param>
 /// <returns>The values returned by this method.</returns>
 protected abstract ILuaMultiValue InvokeInternal(ILuaMultiValue args);
Пример #47
0
 public abstract ILuaMultiValue Resume(ILuaMultiValue args);
 protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
 {
     Contract.Requires(args != null, "args");
     Contract.Ensures(Contract.Result<ILuaMultiValue>() != null);
     return null;
 }
Пример #49
0
 /// <summary>
 /// Creates a new YieldEventArgs object.
 /// </summary>
 /// <param name="args">The arguments given to Yield.</param>
 internal YieldEventArgs(ILuaMultiValue args)
 {
     Arguments       = args;
     RejectYield     = false;
     ReturnArguments = null;
 }
Пример #50
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    string s = args[0].GetValue() as string;
                    string mode = args[1].GetValue() as string;
                    FileMode fileMode;
                    FileAccess access;
                    bool seek = false;
                    mode = mode == null ? null : mode.ToLowerInvariant();

                    if (string.IsNullOrWhiteSpace(s))
                        return Environment.Runtime.CreateMultiValueFromObj(null, "First argument must be a string filename.");

                    switch (mode)
                    {
                        case "r":
                        case "rb":
                        case "":
                        case null:
                            fileMode = FileMode.Open;
                            access = FileAccess.Read;
                            break;
                        case "w":
                        case "wb":
                            fileMode = FileMode.Create;
                            access = FileAccess.Write;
                            break;
                        case "a":
                        case "ab":
                            fileMode = FileMode.OpenOrCreate;
                            access = FileAccess.ReadWrite;
                            seek = true;
                            break;
                        case "r+":
                        case "r+b":
                            fileMode = FileMode.Open;
                            access = FileAccess.ReadWrite;
                            break;
                        case "w+":
                        case "w+b":
                            fileMode = FileMode.Create;
                            access = FileAccess.ReadWrite;
                            break;
                        case "a+":
                        case "a+b":
                            fileMode = FileMode.OpenOrCreate;
                            access = FileAccess.ReadWrite;
                            seek = true;
                            break;
                        default:
                            return Environment.Runtime.CreateMultiValueFromObj(null, "Second argument must be a valid string mode.");
                    }

                    try
                    {
                        using (Stream stream = File.Open(s, fileMode, access))
                        {
                            if (seek && stream.CanSeek)
                                stream.Seek(0, SeekOrigin.End);

                            return Environment.Runtime.CreateMultiValue(_CreateFile(stream, Environment));
                        }
                    }
                    catch (Exception e)
                    {
                        return Environment.Runtime.CreateMultiValueFromObj(null, e.Message, e);
                    }
                }
Пример #51
0
        protected override ILuaMultiValue _invokeInternal(ILuaValue self, bool methodCall, int overload,
                                                          ILuaMultiValue args)
        {
            MethodInfo method;
            object     target;

            if (overload < 0)
            {
                if (!Helpers.GetCompatibleMethod(_methods, args, out method, out target))
                {
                    throw new ArgumentException(
                              $"No overload of method '{Name}' could be found with specified parameters.");
                }
            }
            else
            {
                Tuple <MethodInfo, object> temp;
                if (!_methods.TryGetIndex(overload, out temp))
                {
                    throw new InvalidOperationException(
                              $"There is not an overload for '{Name}' with the index of '{overload}'.");
                }

                if (!Helpers.GetCompatibleMethod(new[] { temp }, args, out method, out target))
                {
                    throw new ArgumentException(
                              $"No overload of method '{Name}' could be found with specified parameters.");
                }
            }

            // Invoke the selected method
            object retObj;

            object[] r_args = Helpers.ConvertForArgs(args, method);
            retObj = Helpers.DynamicInvoke(method, target, r_args);

            // Restore by-reference variables.
            var min = Math.Min(method.GetParameters().Length, args.Count);

            for (int i = 0; i < min; i++)
            {
                args[i] = LuaValueBase.CreateValue(r_args[i]);
            }

            if (retObj is ILuaMultiValue ret)
            {
                return(ret);
            }

            // Convert the return type and return
            Type returnType = method.ReturnType;

            if (method.GetCustomAttributes(typeof(MultipleReturnAttribute), true).Length > 0)
            {
                if (typeof(IEnumerable).IsAssignableFrom(returnType))
                {
                    // TODO: Support restricted variables.
                    IEnumerable tempE = (IEnumerable)retObj;
                    return(LuaMultiValue.CreateMultiValueFromObj(tempE.Cast <object>().ToArray()));
                }
                else
                {
                    throw new InvalidOperationException(
                              "Methods marked with MultipleReturnAttribute must return a type compatible with " +
                              "IEnumerable.");
                }
            }
            else
            {
                return(LuaMultiValue.CreateMultiValueFromObj(retObj));
            }
        }
Пример #52
0
 public abstract ILuaMultiValue Yield(ILuaMultiValue args);
Пример #53
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];
                    if (obj != LuaNil.Nil)
                    {
                        if (obj.ValueType == LuaValueType.String)
                        {
                            Stream s = File.OpenRead(obj.GetValue() as string);
                            _output = s;
                        }
                        else if (obj.ValueType == LuaValueType.Table)
                        {
                            Stream s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                            if (s == null)
                                throw new InvalidOperationException("First argument to function 'io.output' must be a file-stream or a string path.");

                            _output = s;
                        }
                        else if (obj is Stream)
                        {
                            _output = obj as Stream;
                        }
                        else
                            throw new InvalidOperationException("First argument to function 'io.output' must be a file-stream or a string path.");
                    }

                    return Environment.Runtime.CreateMultiValue(_CreateFile(_output, Environment));
                }
Пример #54
0
 public IEnumerable<ILuaMultiValue> GenericLoop(ILuaEnvironment E, ILuaMultiValue args)
 {
     Contract.Requires(E != null);
     Contract.Requires(args != null);
     Contract.Ensures(Contract.Result<IEnumerable<ILuaMultiValue>>() != null);
     return null;
 }
Пример #55
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    ILuaValue obj = args[0];
                    Stream s;
                    int start = 0;

                    if (obj.ValueType == LuaValueType.Table)
                    {
                        s = ((ILuaTable)obj).GetItemRaw(_stream) as Stream;
                        if (s == null)
                            throw new ArgumentException("First argument to io.read must be a file-stream or a file path, make sure to use file:read.");
                        start = 1;
                    }
                    else if (obj.GetValue() is Stream)
                    {
                        s = obj.GetValue() as Stream;
                        start = 1;
                    }
                    else
                    {
                        s = _input;
                        start = 0;
                    }

                    int[] a = _parse(args.Skip(start), "io.read");
                    return _read(a, new StreamReader(s), Environment);
                }
Пример #56
0
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    Stream s = args[0].GetValue() as Stream;
                    SeekOrigin origin = SeekOrigin.Current;
                    long off = 0;

                    if (s == null)
                    {
                        ILuaTable table = args[0] as ILuaTable;
                        if (table != null)
                            s = table.GetItemRaw(_stream) as Stream;

                        if (s == null)
                            throw new ArgumentException("First real argument to function file:seek must be a file-stream, make sure to use file:seek.");
                    }

                    if (args.Count > 1)
                    {
                        string str = args[1].GetValue() as string;
                        if (str == "set")
                            origin = SeekOrigin.Begin;
                        else if (str == "cur")
                            origin = SeekOrigin.Current;
                        else if (str == "end")
                            origin = SeekOrigin.End;
                        else
                            throw new ArgumentException("First argument to function file:seek must be a string.");

                        if (args.Count > 2)
                        {
                            object obj = args[2].GetValue();
                            if (obj is double)
                                off = Convert.ToInt64((double)obj);
                            else
                                throw new ArgumentException("Second argument to function file:seek must be a number.");
                        }
                    }

                    if (!s.CanSeek)
                        return Environment.Runtime.CreateMultiValueFromObj(null, "Specified stream cannot be seeked.");

                    try
                    {
                        return Environment.Runtime.CreateMultiValueFromObj(Convert.ToDouble(s.Seek(off, origin)));
                    }
                    catch (Exception e)
                    {
                        return Environment.Runtime.CreateMultiValueFromObj(null, e.Message, e);
                    }
                }
                protected override ILuaMultiValue InvokeInternal(ILuaMultiValue args)
                {
                    if (args.Count < 1)
                        throw new ArgumentException("Expecting at least one argument to function 'pcall'.");

                    ILuaValue func = args[0];
                    if (func.ValueType == LuaValueType.Function)
                    {
                        try
                        {
                            var ret = func.Invoke(LuaNil.Nil, false, -1, Environment.Runtime.CreateMultiValue(args.Skip(1).ToArray()));
                            return Environment.Runtime.CreateMultiValue(new ILuaValue[] { LuaBoolean.True }.Union(ret).ToArray());
                        }
                        catch (ThreadAbortException)
                        {
                            throw;
                        }
                        catch (ThreadInterruptedException)
                        {
                            throw;
                        }
                        catch (Exception e)
                        {
                            return Environment.Runtime.CreateMultiValueFromObj(false, e.Message, e);
                        }
                    }
                    else
                        throw new ArgumentException("First argument to 'pcall' must be a function.");
                }