github.com/xyproto/gopher-lua@v1.0.2/README.rst (about)

     1  # This is an experimental fork of yuin/gopher-lua
     2  
     3  ===============================================================================
     4  GopherLua: VM and compiler for Lua in Go.
     5  ===============================================================================
     6  
     7  .. image:: https://godoc.org/github.com/yuin/gopher-lua?status.svg
     8      :target: http://godoc.org/github.com/yuin/gopher-lua
     9  
    10  .. image:: https://travis-ci.org/yuin/gopher-lua.svg
    11      :target: https://travis-ci.org/yuin/gopher-lua
    12  
    13  .. image:: https://coveralls.io/repos/yuin/gopher-lua/badge.svg
    14      :target: https://coveralls.io/r/yuin/gopher-lua
    15  
    16  .. image:: https://badges.gitter.im/Join%20Chat.svg
    17      :alt: Join the chat at https://gitter.im/yuin/gopher-lua
    18      :target: https://gitter.im/yuin/gopher-lua?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
    19  
    20  |
    21  
    22  
    23  GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal
    24  with Lua: **Be a scripting language with extensible semantics** . It provides
    25  Go APIs that allow you to easily embed a scripting language to your Go host
    26  programs.
    27  
    28  .. contents::
    29     :depth: 1
    30  
    31  ----------------------------------------------------------------
    32  Design principle
    33  ----------------------------------------------------------------
    34  
    35  - Be a scripting language with extensible semantics.
    36  - User-friendly Go API
    37      - The stack based API like the one used in the original Lua
    38        implementation will cause a performance improvements in GopherLua
    39        (It will reduce memory allocations and concrete type <-> interface conversions).
    40        GopherLua API is **not** the stack based API.
    41        GopherLua give preference to the user-friendliness over the performance.
    42  
    43  ----------------------------------------------------------------
    44  How about performance?
    45  ----------------------------------------------------------------
    46  GopherLua is not fast but not too slow, I think.
    47  
    48  GopherLua has almost equivalent ( or little bit better ) performance as Python3 on micro benchmarks.
    49  
    50  There are some benchmarks on the `wiki page <https://github.com/yuin/gopher-lua/wiki/Benchmarks>`_ .
    51  
    52  ----------------------------------------------------------------
    53  Installation
    54  ----------------------------------------------------------------
    55  
    56  .. code-block:: bash
    57  
    58     go get github.com/yuin/gopher-lua
    59  
    60  GopherLua supports >= Go1.9.
    61  
    62  ----------------------------------------------------------------
    63  Usage
    64  ----------------------------------------------------------------
    65  GopherLua APIs perform in much the same way as Lua, **but the stack is used only
    66  for passing arguments and receiving returned values.**
    67  
    68  GopherLua supports channel operations. See **"Goroutines"** section.
    69  
    70  Import a package.
    71  
    72  .. code-block:: go
    73  
    74     import (
    75         "github.com/yuin/gopher-lua"
    76     )
    77  
    78  Run scripts in the VM.
    79  
    80  .. code-block:: go
    81  
    82     L := lua.NewState()
    83     defer L.Close()
    84     if err := L.DoString(`print("hello")`); err != nil {
    85         panic(err)
    86     }
    87  
    88  .. code-block:: go
    89  
    90     L := lua.NewState()
    91     defer L.Close()
    92     if err := L.DoFile("hello.lua"); err != nil {
    93         panic(err)
    94     }
    95  
    96  Refer to `Lua Reference Manual <http://www.lua.org/manual/5.1/>`_ and `Go doc <http://godoc.org/github.com/yuin/gopher-lua>`_ for further information.
    97  
    98  Note that elements that are not commented in `Go doc <http://godoc.org/github.com/yuin/gopher-lua>`_ equivalent to `Lua Reference Manual <http://www.lua.org/manual/5.1/>`_ , except GopherLua uses objects instead of Lua stack indices.
    99  
   100  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   101  Data model
   102  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   103  All data in a GopherLua program is an ``LValue`` . ``LValue`` is an interface
   104  type that has following methods.
   105  
   106  - ``String() string``
   107  - ``Type() LValueType``
   108  
   109  
   110  Objects implement an LValue interface are
   111  
   112  ================ ========================= ================== =======================
   113   Type name        Go type                   Type() value       Constants
   114  ================ ========================= ================== =======================
   115   ``LNilType``      (constants)              ``LTNil``          ``LNil``
   116   ``LBool``         (constants)              ``LTBool``         ``LTrue``, ``LFalse``
   117   ``LNumber``        float64                 ``LTNumber``       ``-``
   118   ``LString``        string                  ``LTString``       ``-``
   119   ``LFunction``      struct pointer          ``LTFunction``     ``-``
   120   ``LUserData``      struct pointer          ``LTUserData``     ``-``
   121   ``LState``         struct pointer          ``LTThread``       ``-``
   122   ``LTable``         struct pointer          ``LTTable``        ``-``
   123   ``LChannel``       chan LValue             ``LTChannel``      ``-``
   124  ================ ========================= ================== =======================
   125  
   126  You can test an object type in Go way(type assertion) or using a ``Type()`` value.
   127  
   128  .. code-block:: go
   129  
   130     lv := L.Get(-1) // get the value at the top of the stack
   131     if str, ok := lv.(lua.LString); ok {
   132         // lv is LString
   133         fmt.Println(string(str))
   134     }
   135     if lv.Type() != lua.LTString {
   136         panic("string required.")
   137     }
   138  
   139  .. code-block:: go
   140  
   141     lv := L.Get(-1) // get the value at the top of the stack
   142     if tbl, ok := lv.(*lua.LTable); ok {
   143         // lv is LTable
   144         fmt.Println(L.ObjLen(tbl))
   145     }
   146  
   147  Note that ``LBool`` , ``LNumber`` , ``LString`` is not a pointer.
   148  
   149  To test ``LNilType`` and ``LBool``, You **must** use pre-defined constants.
   150  
   151  .. code-block:: go
   152  
   153     lv := L.Get(-1) // get the value at the top of the stack
   154  
   155     if lv == lua.LTrue { // correct
   156     }
   157  
   158     if bl, ok := lv.(lua.LBool); ok && bool(bl) { // wrong
   159     }
   160  
   161  In Lua, both ``nil`` and ``false`` make a condition false. ``LVIsFalse`` and ``LVAsBool`` implement this specification.
   162  
   163  .. code-block:: go
   164  
   165     lv := L.Get(-1) // get the value at the top of the stack
   166     if lua.LVIsFalse(lv) { // lv is nil or false
   167     }
   168  
   169     if lua.LVAsBool(lv) { // lv is neither nil nor false
   170     }
   171  
   172  Objects that based on go structs(``LFunction``. ``LUserData``, ``LTable``)
   173  have some public methods and fields. You can use these methods and fields for
   174  performance and debugging, but there are some limitations.
   175  
   176  - Metatable does not work.
   177  - No error handlings.
   178  
   179  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   180  Callstack & Registry size
   181  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   182  The size of an ``LState``'s callstack controls the maximum call depth for Lua functions within a script (Go function calls do not count).
   183  
   184  The registry of an ``LState`` implements stack storage for calling functions (both Lua and Go functions) and also for temporary variables in expressions. Its storage requirements will increase with callstack usage and also with code complexity.
   185  
   186  Both the registry and the callstack can be set to either a fixed size or to auto size.
   187  
   188  When you have a large number of ``LStates`` instantiated in a process, it's worth taking the time to tune the registry and callstack options.
   189  
   190  +++++++++
   191  Registry
   192  +++++++++
   193  
   194  The registry can have an initial size, a maximum size and a step size configured on a per ``LState`` basis. This will allow the registry to grow as needed. It will not shrink again after growing.
   195  
   196  .. code-block:: go
   197  
   198      L := lua.NewState(lua.Options{
   199         RegistrySize: 1024 * 20,         // this is the initial size of the registry
   200         RegistryMaxSize: 1024 * 80,      // this is the maximum size that the registry can grow to. If set to `0` (the default) then the registry will not auto grow
   201         RegistryGrowStep: 32,            // this is how much to step up the registry by each time it runs out of space. The default is `32`.
   202      })
   203     defer L.Close()
   204  
   205  A registry which is too small for a given script will ultimately result in a panic. A registry which is too big will waste memory (which can be significant if many ``LStates`` are instantiated).
   206  Auto growing registries incur a small performance hit at the point they are resized but will not otherwise affect performance.
   207  
   208  +++++++++
   209  Callstack
   210  +++++++++
   211  
   212  The callstack can operate in two different modes, fixed or auto size.
   213  A fixed size callstack has the highest performance and has a fixed memory overhead.
   214  An auto sizing callstack will allocate and release callstack pages on demand which will ensure the minimum amount of memory is in use at any time. The downside is it will incur a small performance impact every time a new page of callframes is allocated.
   215  By default an ``LState`` will allocate and free callstack frames in pages of 8, so the allocation overhead is not incurred on every function call. It is very likely that the performance impact of an auto resizing callstack will be negligible for most use cases.
   216  
   217  .. code-block:: go
   218  
   219      L := lua.NewState(lua.Options{
   220          CallStackSize: 120,                 // this is the maximum callstack size of this LState
   221          MinimizeStackMemory: true,          // Defaults to `false` if not specified. If set, the callstack will auto grow and shrink as needed up to a max of `CallStackSize`. If not set, the callstack will be fixed at `CallStackSize`.
   222      })
   223     defer L.Close()
   224  
   225  ++++++++++++++++
   226  Option defaults
   227  ++++++++++++++++
   228  
   229  The above examples show how to customize the callstack and registry size on a per ``LState`` basis. You can also adjust some defaults for when options are not specified by altering the values of ``lua.RegistrySize``, ``lua.RegistryGrowStep`` and ``lua.CallStackSize``.
   230  
   231  An ``LState`` object that has been created by ``*LState#NewThread()`` inherits the callstack & registry size from the parent ``LState`` object.
   232  
   233  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   234  Miscellaneous lua.NewState options
   235  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   236  - **Options.SkipOpenLibs bool(default false)**
   237      - By default, GopherLua opens all built-in libraries when new LState is created.
   238      - You can skip this behaviour by setting this to ``true`` .
   239      - Using the various `OpenXXX(L *LState) int` functions you can open only those libraries that you require, for an example see below.
   240  - **Options.IncludeGoStackTrace bool(default false)**
   241      - By default, GopherLua does not show Go stack traces when panics occur.
   242      - You can get Go stack traces by setting this to ``true`` .
   243  
   244  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   245  API
   246  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   247  
   248  Refer to `Lua Reference Manual <http://www.lua.org/manual/5.1/>`_ and `Go doc(LState methods) <http://godoc.org/github.com/yuin/gopher-lua>`_ for further information.
   249  
   250  +++++++++++++++++++++++++++++++++++++++++
   251  Calling Go from Lua
   252  +++++++++++++++++++++++++++++++++++++++++
   253  
   254  .. code-block:: go
   255  
   256     func Double(L *lua.LState) int {
   257         lv := L.ToInt(1)             /* get argument */
   258         L.Push(lua.LNumber(lv * 2)) /* push result */
   259         return 1                     /* number of results */
   260     }
   261  
   262     func main() {
   263         L := lua.NewState()
   264         defer L.Close()
   265         L.SetGlobal("double", L.NewFunction(Double)) /* Original lua_setglobal uses stack... */
   266     }
   267  
   268  .. code-block:: lua
   269  
   270     print(double(20)) -- > "40"
   271  
   272  Any function registered with GopherLua is a ``lua.LGFunction``, defined in ``value.go``
   273  
   274  .. code-block:: go
   275  
   276     type LGFunction func(*LState) int
   277  
   278  Working with coroutines.
   279  
   280  .. code-block:: go
   281  
   282     co, _ := L.NewThread() /* create a new thread */
   283     fn := L.GetGlobal("coro").(*lua.LFunction) /* get function from lua */
   284     for {
   285         st, err, values := L.Resume(co, fn)
   286         if st == lua.ResumeError {
   287             fmt.Println("yield break(error)")
   288             fmt.Println(err.Error())
   289             break
   290         }
   291  
   292         for i, lv := range values {
   293             fmt.Printf("%v : %v\n", i, lv)
   294         }
   295  
   296         if st == lua.ResumeOK {
   297             fmt.Println("yield break(ok)")
   298             break
   299         }
   300     }
   301  
   302  +++++++++++++++++++++++++++++++++++++++++
   303  Opening a subset of builtin modules
   304  +++++++++++++++++++++++++++++++++++++++++
   305  
   306  The following demonstrates how to open a subset of the built-in modules in Lua, say for example to avoid enabling modules with access to local files or system calls.
   307  
   308  main.go
   309  
   310  .. code-block:: go
   311  
   312      func main() {
   313          L := lua.NewState(lua.Options{SkipOpenLibs: true})
   314          defer L.Close()
   315          for _, pair := range []struct {
   316              n string
   317              f lua.LGFunction
   318          }{
   319              {lua.LoadLibName, lua.OpenPackage}, // Must be first
   320              {lua.BaseLibName, lua.OpenBase},
   321              {lua.TabLibName, lua.OpenTable},
   322          } {
   323              if err := L.CallByParam(lua.P{
   324                  Fn:      L.NewFunction(pair.f),
   325                  NRet:    0,
   326                  Protect: true,
   327              }, lua.LString(pair.n)); err != nil {
   328                  panic(err)
   329              }
   330          }
   331          if err := L.DoFile("main.lua"); err != nil {
   332              panic(err)
   333          }
   334      }
   335  
   336  +++++++++++++++++++++++++++++++++++++++++
   337  Creating a module by Go
   338  +++++++++++++++++++++++++++++++++++++++++
   339  
   340  mymodule.go
   341  
   342  .. code-block:: go
   343  
   344      package mymodule
   345  
   346      import (
   347          "github.com/yuin/gopher-lua"
   348      )
   349  
   350      func Loader(L *lua.LState) int {
   351          // register functions to the table
   352          mod := L.SetFuncs(L.NewTable(), exports)
   353          // register other stuff
   354          L.SetField(mod, "name", lua.LString("value"))
   355  
   356          // returns the module
   357          L.Push(mod)
   358          return 1
   359      }
   360  
   361      var exports = map[string]lua.LGFunction{
   362          "myfunc": myfunc,
   363      }
   364  
   365      func myfunc(L *lua.LState) int {
   366          return 0
   367      }
   368  
   369  mymain.go
   370  
   371  .. code-block:: go
   372  
   373      package main
   374  
   375      import (
   376          "./mymodule"
   377          "github.com/yuin/gopher-lua"
   378      )
   379  
   380      func main() {
   381          L := lua.NewState()
   382          defer L.Close()
   383          L.PreloadModule("mymodule", mymodule.Loader)
   384          if err := L.DoFile("main.lua"); err != nil {
   385              panic(err)
   386          }
   387      }
   388  
   389  main.lua
   390  
   391  .. code-block:: lua
   392  
   393      local m = require("mymodule")
   394      m.myfunc()
   395      print(m.name)
   396  
   397  
   398  +++++++++++++++++++++++++++++++++++++++++
   399  Calling Lua from Go
   400  +++++++++++++++++++++++++++++++++++++++++
   401  
   402  .. code-block:: go
   403  
   404     L := lua.NewState()
   405     defer L.Close()
   406     if err := L.DoFile("double.lua"); err != nil {
   407         panic(err)
   408     }
   409     if err := L.CallByParam(lua.P{
   410         Fn: L.GetGlobal("double"),
   411         NRet: 1,
   412         Protect: true,
   413         }, lua.LNumber(10)); err != nil {
   414         panic(err)
   415     }
   416     ret := L.Get(-1) // returned value
   417     L.Pop(1)  // remove received value
   418  
   419  If ``Protect`` is false, GopherLua will panic instead of returning an ``error`` value.
   420  
   421  +++++++++++++++++++++++++++++++++++++++++
   422  User-Defined types
   423  +++++++++++++++++++++++++++++++++++++++++
   424  You can extend GopherLua with new types written in Go.
   425  ``LUserData`` is provided for this purpose.
   426  
   427  .. code-block:: go
   428  
   429      type Person struct {
   430          Name string
   431      }
   432  
   433      const luaPersonTypeName = "person"
   434  
   435      // Registers my person type to given L.
   436      func registerPersonType(L *lua.LState) {
   437          mt := L.NewTypeMetatable(luaPersonTypeName)
   438          L.SetGlobal("person", mt)
   439          // static attributes
   440          L.SetField(mt, "new", L.NewFunction(newPerson))
   441          // methods
   442          L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), personMethods))
   443      }
   444  
   445      // Constructor
   446      func newPerson(L *lua.LState) int {
   447          person := &Person{L.CheckString(1)}
   448          ud := L.NewUserData()
   449          ud.Value = person
   450          L.SetMetatable(ud, L.GetTypeMetatable(luaPersonTypeName))
   451          L.Push(ud)
   452          return 1
   453      }
   454  
   455      // Checks whether the first lua argument is a *LUserData with *Person and returns this *Person.
   456      func checkPerson(L *lua.LState) *Person {
   457          ud := L.CheckUserData(1)
   458          if v, ok := ud.Value.(*Person); ok {
   459              return v
   460          }
   461          L.ArgError(1, "person expected")
   462          return nil
   463      }
   464  
   465      var personMethods = map[string]lua.LGFunction{
   466          "name": personGetSetName,
   467      }
   468  
   469      // Getter and setter for the Person#Name
   470      func personGetSetName(L *lua.LState) int {
   471          p := checkPerson(L)
   472          if L.GetTop() == 2 {
   473              p.Name = L.CheckString(2)
   474              return 0
   475          }
   476          L.Push(lua.LString(p.Name))
   477          return 1
   478      }
   479  
   480      func main() {
   481          L := lua.NewState()
   482          defer L.Close()
   483          registerPersonType(L)
   484          if err := L.DoString(`
   485              p = person.new("Steeve")
   486              print(p:name()) -- "Steeve"
   487              p:name("Alice")
   488              print(p:name()) -- "Alice"
   489          `); err != nil {
   490              panic(err)
   491          }
   492      }
   493  
   494  +++++++++++++++++++++++++++++++++++++++++
   495  Terminating a running LState
   496  +++++++++++++++++++++++++++++++++++++++++
   497  GopherLua supports the `Go Concurrency Patterns: Context <https://blog.golang.org/context>`_ .
   498  
   499  
   500  .. code-block:: go
   501  
   502      L := lua.NewState()
   503      defer L.Close()
   504      ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
   505      defer cancel()
   506      // set the context to our LState
   507      L.SetContext(ctx)
   508      err := L.DoString(`
   509        local clock = os.clock
   510        function sleep(n)  -- seconds
   511          local t0 = clock()
   512          while clock() - t0 <= n do end
   513        end
   514        sleep(3)
   515      `)
   516      // err.Error() contains "context deadline exceeded"
   517  
   518  With coroutines
   519  
   520  .. code-block:: go
   521  
   522  	L := lua.NewState()
   523  	defer L.Close()
   524  	ctx, cancel := context.WithCancel(context.Background())
   525  	L.SetContext(ctx)
   526  	defer cancel()
   527  	L.DoString(`
   528  	    function coro()
   529  		  local i = 0
   530  		  while true do
   531  		    coroutine.yield(i)
   532  			i = i+1
   533  		  end
   534  		  return i
   535  	    end
   536  	`)
   537  	co, cocancel := L.NewThread()
   538  	defer cocancel()
   539  	fn := L.GetGlobal("coro").(*LFunction)
   540  
   541  	_, err, values := L.Resume(co, fn) // err is nil
   542  
   543  	cancel() // cancel the parent context
   544  
   545  	_, err, values = L.Resume(co, fn) // err is NOT nil : child context was canceled
   546  
   547  **Note that using a context causes performance degradation.**
   548  
   549  .. code-block::
   550  
   551      time ./glua-with-context.exe fib.lua
   552      9227465
   553      0.01s user 0.11s system 1% cpu 7.505 total
   554  
   555      time ./glua-without-context.exe fib.lua
   556      9227465
   557      0.01s user 0.01s system 0% cpu 5.306 total
   558  
   559  +++++++++++++++++++++++++++++++++++++++++
   560  Sharing Lua byte code between LStates
   561  +++++++++++++++++++++++++++++++++++++++++
   562  Calling ``DoFile`` will load a Lua script, compile it to byte code and run the byte code in a ``LState``.
   563  
   564  If you have multiple ``LStates`` which are all required to run the same script, you can share the byte code between them,
   565  which will save on memory.
   566  Sharing byte code is safe as it is read only and cannot be altered by lua scripts.
   567  
   568  .. code-block:: go
   569  
   570      // CompileLua reads the passed lua file from disk and compiles it.
   571      func CompileLua(filePath string) (*lua.FunctionProto, error) {
   572          file, err := os.Open(filePath)
   573          defer file.Close()
   574          if err != nil {
   575              return nil, err
   576          }
   577          reader := bufio.NewReader(file)
   578          chunk, err := parse.Parse(reader, filePath)
   579          if err != nil {
   580              return nil, err
   581          }
   582          proto, err := lua.Compile(chunk, filePath)
   583          if err != nil {
   584              return nil, err
   585          }
   586          return proto, nil
   587      }
   588  
   589      // DoCompiledFile takes a FunctionProto, as returned by CompileLua, and runs it in the LState. It is equivalent
   590      // to calling DoFile on the LState with the original source file.
   591      func DoCompiledFile(L *lua.LState, proto *lua.FunctionProto) error {
   592          lfunc := L.NewFunctionFromProto(proto)
   593          L.Push(lfunc)
   594          return L.PCall(0, lua.MultRet, nil)
   595      }
   596  
   597      // Example shows how to share the compiled byte code from a lua script between multiple VMs.
   598      func Example() {
   599          codeToShare := CompileLua("mylua.lua")
   600          a := lua.NewState()
   601          b := lua.NewState()
   602          c := lua.NewState()
   603          DoCompiledFile(a, codeToShare)
   604          DoCompiledFile(b, codeToShare)
   605          DoCompiledFile(c, codeToShare)
   606      }
   607  
   608  +++++++++++++++++++++++++++++++++++++++++
   609  Goroutines
   610  +++++++++++++++++++++++++++++++++++++++++
   611  The ``LState`` is not goroutine-safe. It is recommended to use one LState per goroutine and communicate between goroutines by using channels.
   612  
   613  Channels are represented by ``channel`` objects in GopherLua. And a ``channel`` table provides functions for performing channel operations.
   614  
   615  Some objects can not be sent over channels due to having non-goroutine-safe objects inside itself.
   616  
   617  - a thread(state)
   618  - a function
   619  - an userdata
   620  - a table with a metatable
   621  
   622  You **must not** send these objects from Go APIs to channels.
   623  
   624  
   625  
   626  .. code-block:: go
   627  
   628      func receiver(ch, quit chan lua.LValue) {
   629          L := lua.NewState()
   630          defer L.Close()
   631          L.SetGlobal("ch", lua.LChannel(ch))
   632          L.SetGlobal("quit", lua.LChannel(quit))
   633          if err := L.DoString(`
   634          local exit = false
   635          while not exit do
   636            channel.select(
   637              {"|<-", ch, function(ok, v)
   638                if not ok then
   639                  print("channel closed")
   640                  exit = true
   641                else
   642                  print("received:", v)
   643                end
   644              end},
   645              {"|<-", quit, function(ok, v)
   646                  print("quit")
   647                  exit = true
   648              end}
   649            )
   650          end
   651        `); err != nil {
   652              panic(err)
   653          }
   654      }
   655  
   656      func sender(ch, quit chan lua.LValue) {
   657          L := lua.NewState()
   658          defer L.Close()
   659          L.SetGlobal("ch", lua.LChannel(ch))
   660          L.SetGlobal("quit", lua.LChannel(quit))
   661          if err := L.DoString(`
   662          ch:send("1")
   663          ch:send("2")
   664        `); err != nil {
   665              panic(err)
   666          }
   667          ch <- lua.LString("3")
   668          quit <- lua.LTrue
   669      }
   670  
   671      func main() {
   672          ch := make(chan lua.LValue)
   673          quit := make(chan lua.LValue)
   674          go receiver(ch, quit)
   675          go sender(ch, quit)
   676          time.Sleep(3 * time.Second)
   677      }
   678  
   679  '''''''''''''''
   680  Go API
   681  '''''''''''''''
   682  
   683  ``ToChannel``, ``CheckChannel``, ``OptChannel`` are available.
   684  
   685  Refer to `Go doc(LState methods) <http://godoc.org/github.com/yuin/gopher-lua>`_ for further information.
   686  
   687  '''''''''''''''
   688  Lua API
   689  '''''''''''''''
   690  
   691  - **channel.make([buf:int]) -> ch:channel**
   692      - Create new channel that has a buffer size of ``buf``. By default, ``buf`` is 0.
   693  
   694  - **channel.select(case:table [, case:table, case:table ...]) -> {index:int, recv:any, ok}**
   695      - Same as the ``select`` statement in Go. It returns the index of the chosen case and, if that
   696        case was a receive operation, the value received and a boolean indicating whether the channel has been closed.
   697      - ``case`` is a table that outlined below.
   698          - receiving: `{"|<-", ch:channel [, handler:func(ok, data:any)]}`
   699          - sending: `{"<-|", ch:channel, data:any [, handler:func(data:any)]}`
   700          - default: `{"default" [, handler:func()]}`
   701  
   702  ``channel.select`` examples:
   703  
   704  .. code-block:: lua
   705  
   706      local idx, recv, ok = channel.select(
   707        {"|<-", ch1},
   708        {"|<-", ch2}
   709      )
   710      if not ok then
   711          print("closed")
   712      elseif idx == 1 then -- received from ch1
   713          print(recv)
   714      elseif idx == 2 then -- received from ch2
   715          print(recv)
   716      end
   717  
   718  .. code-block:: lua
   719  
   720      channel.select(
   721        {"|<-", ch1, function(ok, data)
   722          print(ok, data)
   723        end},
   724        {"<-|", ch2, "value", function(data)
   725          print(data)
   726        end},
   727        {"default", function()
   728          print("default action")
   729        end}
   730      )
   731  
   732  - **channel:send(data:any)**
   733      - Send ``data`` over the channel.
   734  - **channel:receive() -> ok:bool, data:any**
   735      - Receive some data over the channel.
   736  - **channel:close()**
   737      - Close the channel.
   738  
   739  ''''''''''''''''''''''''''''''
   740  The LState pool pattern
   741  ''''''''''''''''''''''''''''''
   742  To create per-thread LState instances, You can use the ``sync.Pool`` like mechanism.
   743  
   744  .. code-block:: go
   745  
   746      type lStatePool struct {
   747          m     sync.Mutex
   748          saved []*lua.LState
   749      }
   750  
   751      func (pl *lStatePool) Get() *lua.LState {
   752          pl.m.Lock()
   753          defer pl.m.Unlock()
   754          n := len(pl.saved)
   755          if n == 0 {
   756              return pl.New()
   757          }
   758          x := pl.saved[n-1]
   759          pl.saved = pl.saved[0 : n-1]
   760          return x
   761      }
   762  
   763      func (pl *lStatePool) New() *lua.LState {
   764          L := lua.NewState()
   765          // setting the L up here.
   766          // load scripts, set global variables, share channels, etc...
   767          return L
   768      }
   769  
   770      func (pl *lStatePool) Put(L *lua.LState) {
   771          pl.m.Lock()
   772          defer pl.m.Unlock()
   773          pl.saved = append(pl.saved, L)
   774      }
   775  
   776      func (pl *lStatePool) Shutdown() {
   777          for _, L := range pl.saved {
   778              L.Close()
   779          }
   780      }
   781  
   782      // Global LState pool
   783      var luaPool = &lStatePool{
   784          saved: make([]*lua.LState, 0, 4),
   785      }
   786  
   787  Now, you can get per-thread LState objects from the ``luaPool`` .
   788  
   789  .. code-block:: go
   790  
   791      func MyWorker() {
   792         L := luaPool.Get()
   793         defer luaPool.Put(L)
   794         /* your code here */
   795      }
   796  
   797      func main() {
   798          defer luaPool.Shutdown()
   799          go MyWorker()
   800          go MyWorker()
   801          /* etc... */
   802      }
   803  
   804  
   805  ----------------------------------------------------------------
   806  Differences between Lua and GopherLua
   807  ----------------------------------------------------------------
   808  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   809  Goroutines
   810  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   811  
   812  - GopherLua supports channel operations.
   813      - GopherLua has a type named ``channel``.
   814      - The ``channel`` table provides functions for performing channel operations.
   815  
   816  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   817  Unsupported functions
   818  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   819  
   820  - ``string.dump``
   821  - ``os.setlocale``
   822  - ``lua_Debug.namewhat``
   823  - ``package.loadlib``
   824  - debug hooks
   825  
   826  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   827  Miscellaneous notes
   828  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   829  
   830  - ``collectgarbage`` does not take any arguments and runs the garbage collector for the entire Go program.
   831  - ``file:setvbuf`` does not support a line buffering.
   832  - Daylight saving time is not supported.
   833  - GopherLua has a function to set an environment variable : ``os.setenv(name, value)``
   834  
   835  ----------------------------------------------------------------
   836  Standalone interpreter
   837  ----------------------------------------------------------------
   838  Lua has an interpreter called ``lua`` . GopherLua has an interpreter called ``glua`` .
   839  
   840  .. code-block:: bash
   841  
   842     go get github.com/yuin/gopher-lua/cmd/glua
   843  
   844  ``glua`` has same options as ``lua`` .
   845  
   846  ----------------------------------------------------------------
   847  How to Contribute
   848  ----------------------------------------------------------------
   849  See `Guidlines for contributors <https://github.com/yuin/gopher-lua/tree/master/.github/CONTRIBUTING.md>`_ .
   850  
   851  ----------------------------------------------------------------
   852  Libraries for GopherLua
   853  ----------------------------------------------------------------
   854  
   855  - `gopher-luar <https://github.com/layeh/gopher-luar>`_ : Simplifies data passing to and from gopher-lua
   856  - `gluamapper <https://github.com/yuin/gluamapper>`_ : Mapping a Lua table to a Go struct
   857  - `gluare <https://github.com/yuin/gluare>`_ : Regular expressions for gopher-lua
   858  - `gluahttp <https://github.com/cjoudrey/gluahttp>`_ : HTTP request module for gopher-lua
   859  - `gopher-json <https://github.com/layeh/gopher-json>`_ : A simple JSON encoder/decoder for gopher-lua
   860  - `gluayaml <https://github.com/kohkimakimoto/gluayaml>`_ : Yaml parser for gopher-lua
   861  - `glua-lfs <https://github.com/layeh/gopher-lfs>`_ : Partially implements the luafilesystem module for gopher-lua
   862  - `gluaurl <https://github.com/cjoudrey/gluaurl>`_ : A url parser/builder module for gopher-lua
   863  - `gluahttpscrape <https://github.com/felipejfc/gluahttpscrape>`_ : A simple HTML scraper module for gopher-lua
   864  - `gluaxmlpath <https://github.com/ailncode/gluaxmlpath>`_ : An xmlpath module for gopher-lua
   865  - `gmoonscript <https://github.com/rucuriousyet/gmoonscript>`_ : Moonscript Compiler for the Gopher Lua VM
   866  - `loguago <https://github.com/rucuriousyet/loguago>`_ : Zerolog wrapper for Gopher-Lua
   867  - `gluacrypto <https://github.com/tengattack/gluacrypto>`_ : A native Go implementation of crypto library for the GopherLua VM.
   868  - `gluasql <https://github.com/tengattack/gluasql>`_ : A native Go implementation of SQL client for the GopherLua VM.
   869  - `purr <https://github.com/leyafo/purr>`_ : A http mock testing tool.
   870  - `vadv/gopher-lua-libs <https://github.com/vadv/gopher-lua-libs>`_ : Some usefull libraries for GopherLua VM.
   871  - `gluaperiphery <https://github.com/BixData/gluaperiphery>`_ : A periphery library for the GopherLua VM (GPIO, SPI, I2C, MMIO, and Serial peripheral I/O for Linux).
   872  - `glua-async <https://github.com/CuberL/glua-async>`_ : An async/await implement for gopher-lua.
   873  - `gopherlua-debugger <https://github.com/edolphin-ydf/gopherlua-debugger>`_ : A debugger for gopher-lua
   874  - `gluamahonia <https://github.com/super1207/gluamahonia>`_ : An encoding converter for gopher-lua
   875  ----------------------------------------------------------------
   876  Donation
   877  ----------------------------------------------------------------
   878  
   879  BTC: 1NEDSyUmo4SMTDP83JJQSWi1MvQUGGNMZB
   880  
   881  ----------------------------------------------------------------
   882  License
   883  ----------------------------------------------------------------
   884  MIT
   885  
   886  ----------------------------------------------------------------
   887  Author
   888  ----------------------------------------------------------------
   889  Yusuke Inuzuka