github.com/xrash/gopher-lua@v0.0.0-20160304065408-e5faab4db06a/README.rst (about)

     1  ===============================================================================
     2  GopherLua: VM and compiler for Lua in Go.
     3  ===============================================================================
     4  
     5  .. image:: https://godoc.org/github.com/yuin/gopher-lua?status.svg
     6      :target: http://godoc.org/github.com/yuin/gopher-lua
     7  
     8  .. image:: https://travis-ci.org/yuin/gopher-lua.svg
     9      :target: https://travis-ci.org/yuin/gopher-lua
    10  
    11  .. image:: https://coveralls.io/repos/yuin/gopher-lua/badge.svg
    12      :target: https://coveralls.io/r/yuin/gopher-lua
    13  
    14  .. image:: https://badges.gitter.im/Join%20Chat.svg
    15      :alt: Join the chat at https://gitter.im/yuin/gopher-lua
    16      :target: https://gitter.im/yuin/gopher-lua?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
    17  
    18  |
    19  
    20  GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal
    21  with Lua: **Be a scripting language with extensible semantics** . It provides
    22  Go APIs that allow you to easily embed a scripting language to your Go host
    23  programs.
    24  
    25  .. contents::
    26     :depth: 1
    27  
    28  ----------------------------------------------------------------
    29  Design principle
    30  ----------------------------------------------------------------
    31  
    32  - Be a scripting language with extensible semantics.
    33  - User-friendly Go API
    34      - The stack based API like the one used in the original Lua
    35        implementation will cause a performance improvements in GopherLua
    36        (It will reduce memory allocations and concrete type <-> interface conversions).
    37        GopherLua API is **not** the stack based API.
    38        GopherLua give preference to the user-friendliness over the performance.
    39  
    40  ----------------------------------------------------------------
    41  How about performance?
    42  ----------------------------------------------------------------
    43  GopherLua is not fast but not too slow, I think.
    44  
    45  There are some benchmarks on the `wiki page <https://github.com/yuin/gopher-lua/wiki/Benchmarks>`_ .
    46  
    47  ----------------------------------------------------------------
    48  Installation
    49  ----------------------------------------------------------------
    50  
    51  .. code-block:: bash
    52  
    53     go get github.com/yuin/gopher-lua
    54  
    55  GopherLua supports >= Go1.4.
    56  
    57  ----------------------------------------------------------------
    58  Usage
    59  ----------------------------------------------------------------
    60  GopherLua APIs perform in much the same way as Lua, **but the stack is used only
    61  for passing arguments and receiving returned values.**
    62  
    63  GopherLua supports channel operations. See **"Goroutines"** section.
    64  
    65  Import a package.
    66  
    67  .. code-block:: go
    68  
    69     import (
    70         "github.com/yuin/gopher-lua"
    71     )
    72  
    73  Run scripts in the VM.
    74  
    75  .. code-block:: go
    76  
    77     L := lua.NewState()
    78     defer L.Close()
    79     if err := L.DoString(`print("hello")`); err != nil {
    80         panic(err)
    81     }
    82  
    83  .. code-block:: go
    84  
    85     L := lua.NewState()
    86     defer L.Close()
    87     if err := L.DoFile("hello.lua"); err != nil {
    88         panic(err)
    89     }
    90  
    91  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.
    92  
    93  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.
    94  
    95  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    96  Data model
    97  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    98  All data in a GopherLua program is an ``LValue`` . ``LValue`` is an interface
    99  type that has following methods.
   100  
   101  - ``String() string``
   102  - ``Type() LValueType``
   103  
   104  
   105  Objects implement an LValue interface are
   106  
   107  ================ ========================= ================== =======================
   108   Type name        Go type                   Type() value       Constants
   109  ================ ========================= ================== =======================
   110   ``LNilType``      (constants)              ``LTNil``          ``LNil``
   111   ``LBool``         (constants)              ``LTBool``         ``LTrue``, ``LFalse``
   112   ``LNumber``        float64                 ``LTNumber``       ``-``
   113   ``LString``        string                  ``LTString``       ``-``
   114   ``LFunction``      struct pointer          ``LTFunction``     ``-``
   115   ``LUserData``      struct pointer          ``LTUserData``     ``-``
   116   ``LState``         struct pointer          ``LTThread``       ``-``
   117   ``LTable``         struct pointer          ``LTTable``        ``-``
   118   ``LChannel``       chan LValue             ``LTChannel``      ``-``
   119  ================ ========================= ================== =======================
   120  
   121  You can test an object type in Go way(type assertion) or using a ``Type()`` value.
   122  
   123  .. code-block:: go
   124  
   125     lv := L.Get(-1) // get the value at the top of the stack
   126     if str, ok := lv.(lua.LString); ok {
   127         // lv is LString
   128         fmt.Println(string(str))
   129     }
   130     if lv.Type() != lua.LTString {
   131         panic("string required.")
   132     }
   133  
   134  .. code-block:: go
   135  
   136     lv := L.Get(-1) // get the value at the top of the stack
   137     if tbl, ok := lv.(*lua.LTable); ok {
   138         // lv is LTable
   139         fmt.Println(L.ObjLen(tbl))
   140     }
   141  
   142  Note that ``LBool`` , ``LNumber`` , ``LString`` is not a pointer.
   143  
   144  To test ``LNilType`` and ``LBool``, You **must** use pre-defined constants.
   145  
   146  .. code-block:: go
   147  
   148     lv := L.Get(-1) // get the value at the top of the stack
   149  
   150     if lv == LTrue { // correct
   151     }
   152  
   153     if bl, ok == lv.(lua.LBool); ok && bool(bl) { // wrong
   154     }
   155  
   156  In Lua, both ``nil`` and ``false`` make a condition false. ``LVIsFalse`` and ``LVAsBool`` implement this specification.
   157  
   158  .. code-block:: go
   159  
   160     lv := L.Get(-1) // get the value at the top of the stack
   161     if LVIsFalse(lv) { // lv is nil or false
   162     }
   163  
   164     if LVAsBool(lv) { // lv is neither nil nor false
   165     }
   166  
   167  Objects that based on go structs(``LFunction``. ``LUserData``, ``LTable``)
   168  have some public methods and fields. You can use these methods and fields for
   169  performance and debugging, but there are some limitations.
   170  
   171  - Metatable does not work.
   172  - No error handlings.
   173  
   174  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   175  Callstack & Registry size
   176  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   177  Size of the callstack & registry is **fixed** for mainly performance.
   178  You can change the default size of the callstack & registry.
   179  
   180  .. code-block:: go
   181  
   182     lua.RegistrySize = 1024 * 20
   183     lua.CallStackSize = 1024
   184     L := lua.NewState()
   185     defer L.Close()
   186  
   187  You can also create an LState object that has the callstack & registry size specified by ``Options`` .
   188  
   189  .. code-block:: go
   190  
   191      L := lua.NewState(lua.Options{
   192          CallStackSize: 120,
   193          RegistrySize:  120*20,
   194      })
   195  
   196  An LState object that has been created by ``*LState#NewThread()`` inherits the callstack & registry size from the parent LState object.
   197  
   198  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   199  Miscellaneous lua.NewState options
   200  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   201  - **Options.SkipOpenLibs bool(default false)**
   202      - By default, GopherLua opens all built-in libraries when new LState is created.
   203      - You can skip this behaviour by setting this to ``true`` .
   204      - Using the various `OpenXXX(L *LState) int` functions you can open only those libraries that you require, for an example see below.
   205  - **Options.IncludeGoStackTrace bool(default false)**
   206      - By default, GopherLua does not show Go stack traces when panics occur.
   207      - You can get Go stack traces by setting this to ``true`` .
   208  
   209  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   210  API
   211  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   212  
   213  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.
   214  
   215  +++++++++++++++++++++++++++++++++++++++++
   216  Calling Go from Lua
   217  +++++++++++++++++++++++++++++++++++++++++
   218  
   219  .. code-block:: go
   220  
   221     func Double(L *lua.LState) int {
   222         lv := L.ToInt(1)             /* get argument */
   223         L.Push(lua.LNumber(lv * 2)) /* push result */
   224         return 1                     /* number of results */
   225     }
   226  
   227     func main() {
   228         L := lua.NewState()
   229         defer L.Close()
   230         L.SetGlobal("double", L.NewFunction(Double)) /* Original lua_setglobal uses stack... */
   231     }
   232  
   233  .. code-block:: lua
   234  
   235     print(double(20)) -- > "40"
   236  
   237  Any function registered with GopherLua is a ``lua.LGFunction``, defined in ``value.go``
   238  
   239  .. code-block:: go
   240  
   241     type LGFunction func(*LState) int
   242  
   243  Working with coroutines.
   244  
   245  .. code-block:: go
   246  
   247     co := L.NewThread() /* create a new thread */
   248     fn := L.GetGlobal("coro").(*lua.LFunction) /* get function from lua */
   249     for {
   250         st, err, values := L.Resume(co, fn)
   251         if st == lua.ResumeError {
   252             fmt.Println("yield break(error)")
   253             fmt.Println(err.Error())
   254             break
   255         }
   256  
   257         for i, lv := range values {
   258             fmt.Printf("%v : %v\n", i, lv)
   259         }
   260  
   261         if st == lua.ResumeOK {
   262             fmt.Println("yield break(ok)")
   263             break
   264         }
   265     }
   266  
   267  +++++++++++++++++++++++++++++++++++++++++
   268  Opening a subset of builtin modules
   269  +++++++++++++++++++++++++++++++++++++++++
   270  
   271  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.
   272  
   273  main.go
   274  
   275  .. code-block:: go
   276  
   277      func main() {
   278          L := lua.NewState(lua.Options{SkipOpenLibs: true})
   279          defer L.Close()
   280          for _, pair := range []struct {
   281              n string
   282              f lua.LGFunction
   283          }{
   284              {lua.LoadLibName, lua.OpenPackage}, // Must be first
   285              {lua.BaseLibName, lua.OpenBase},
   286              {lua.TabLibName, lua.OpenTable},
   287          } {
   288              if err := L.CallByParam(lua.P{
   289                  Fn:      L.NewFunction(pair.f),
   290                  NRet:    0,
   291                  Protect: true,
   292              }, lua.LString(pair.n)); err != nil {
   293                  panic(err)
   294              }
   295          }
   296          if err := L.DoFile("main.lua"); err != nil {
   297              panic(err)
   298          }
   299      }
   300  
   301  +++++++++++++++++++++++++++++++++++++++++
   302  Creating a module by Go
   303  +++++++++++++++++++++++++++++++++++++++++
   304  
   305  mymodule.go
   306  
   307  .. code-block:: go
   308  
   309      package mymodule
   310  
   311      import (
   312          "github.com/yuin/gopher-lua"
   313      )
   314  
   315      func Loader(L *lua.LState) int {
   316          // register functions to the table
   317          mod := L.SetFuncs(L.NewTable(), exports)
   318          // register other stuff
   319          L.SetField(mod, "name", lua.LString("value"))
   320  
   321          // returns the module
   322          L.Push(mod)
   323          return 1
   324      }
   325  
   326      var exports = map[string]lua.LGFunction{
   327          "myfunc": myfunc,
   328      }
   329  
   330      func myfunc(L *lua.LState) int {
   331          return 0
   332      }
   333  
   334  mymain.go
   335  
   336  .. code-block:: go
   337  
   338      package main
   339  
   340      import (
   341          "./mymodule"
   342          "github.com/yuin/gopher-lua"
   343      )
   344  
   345      func main() {
   346          L := lua.NewState()
   347          defer L.Close()
   348          L.PreloadModule("mymodule", mymodule.Loader)
   349          if err := L.DoFile("main.lua"); err != nil {
   350              panic(err)
   351          }
   352      }
   353  
   354  main.lua
   355  
   356  .. code-block:: lua
   357  
   358      local m = require("mymodule")
   359      m.myfunc()
   360      print(m.name)
   361  
   362  
   363  +++++++++++++++++++++++++++++++++++++++++
   364  Calling Lua from Go
   365  +++++++++++++++++++++++++++++++++++++++++
   366  
   367  .. code-block:: go
   368  
   369     L := lua.NewState()
   370     defer L.Close()
   371     if err := L.DoFile("double.lua"); err != nil {
   372         panic(err)
   373     }
   374     if err := L.CallByParam(lua.P{
   375         Fn: L.GetGlobal("double"),
   376         NRet: 1,
   377         Protect: true,
   378         }, lua.LNumber(10)); err != nil {
   379         panic(err)
   380     }
   381     ret := L.Get(-1) // returned value
   382     L.Pop(1)  // remove received value
   383  
   384  If ``Protect`` is false, GopherLua will panic instead of returning an ``error`` value.
   385  
   386  +++++++++++++++++++++++++++++++++++++++++
   387  User-Defined types
   388  +++++++++++++++++++++++++++++++++++++++++
   389  You can extend GopherLua with new types written in Go.
   390  ``LUserData`` is provided for this purpose.
   391  
   392  .. code-block:: go
   393  
   394      type Person struct {
   395          Name string
   396      }
   397  
   398      const luaPersonTypeName = "person"
   399  
   400      // Registers my person type to given L.
   401      func registerPersonType(L *lua.LState) {
   402          mt := L.NewTypeMetatable(luaPersonTypeName)
   403          L.SetGlobal("person", mt)
   404          // static attributes
   405          L.SetField(mt, "new", L.NewFunction(newPerson))
   406          // methods
   407          L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), personMethods))
   408      }
   409  
   410      // Constructor
   411      func newPerson(L *lua.LState) int {
   412          person := &Person{L.CheckString(1)}
   413          ud := L.NewUserData()
   414          ud.Value = person
   415          L.SetMetatable(ud, L.GetTypeMetatable(luaPersonTypeName))
   416          L.Push(ud)
   417          return 1
   418      }
   419  
   420      // Checks whether the first lua argument is a *LUserData with *Person and returns this *Person.
   421      func checkPerson(L *lua.LState) *Person {
   422          ud := L.CheckUserData(1)
   423          if v, ok := ud.Value.(*Person); ok {
   424              return v
   425          }
   426          L.ArgError(1, "person expected")
   427          return nil
   428      }
   429  
   430      var personMethods = map[string]lua.LGFunction{
   431          "name": personGetSetName,
   432      }
   433  
   434      // Getter and setter for the Person#Name
   435      func personGetSetName(L *lua.LState) int {
   436          p := checkPerson(L)
   437          if L.GetTop() == 2 {
   438              p.Name = L.CheckString(2)
   439              return 0
   440          }
   441          L.Push(lua.LString(p.Name))
   442          return 1
   443      }
   444  
   445      func main() {
   446          L := lua.NewState()
   447          defer L.Close()
   448          registerPersonType(L)
   449          if err := L.DoString(`
   450              p = person.new("Steeve")
   451              print(p:name()) -- "Steeve"
   452              p:name("Alice")
   453              print(p:name()) -- "Alice"
   454          `); err != nil {
   455              panic(err)
   456          }
   457      }
   458  
   459  +++++++++++++++++++++++++++++++++++++++++
   460  Goroutines
   461  +++++++++++++++++++++++++++++++++++++++++
   462  The ``LState`` is not goroutine-safe. It is recommended to use one LState per goroutine and communicate between goroutines by using channels.
   463  
   464  Channels are represented by ``channel`` objects in GopherLua. And a ``channel`` table provides functions for performing channel operations.
   465  
   466  Some objects can not be sent over channels due to having non-goroutine-safe objects inside itself.
   467  
   468  - a thread(state)
   469  - a function
   470  - an userdata
   471  - a table with a metatable
   472  
   473  You **must not** send these objects from Go APIs to channels.
   474  
   475  
   476  
   477  .. code-block:: go
   478  
   479      func receiver(ch, quit chan lua.LValue) {
   480          L := lua.NewState()
   481          defer L.Close()
   482          L.SetGlobal("ch", lua.LChannel(ch))
   483          L.SetGlobal("quit", lua.LChannel(quit))
   484          if err := L.DoString(`
   485          local exit = false
   486          while not exit do
   487            channel.select(
   488              {"|<-", ch, function(ok, v)
   489                if not ok then
   490                  print("channel closed")
   491                  exit = true
   492                else
   493                  print("received:", v)
   494                end
   495              end},
   496              {"|<-", quit, function(ok, v)
   497                  print("quit")
   498                  exit = true
   499              end}
   500            )
   501          end
   502        `); err != nil {
   503              panic(err)
   504          }
   505      }
   506  
   507      func sender(ch, quit chan lua.LValue) {
   508          L := lua.NewState()
   509          defer L.Close()
   510          L.SetGlobal("ch", lua.LChannel(ch))
   511          L.SetGlobal("quit", lua.LChannel(quit))
   512          if err := L.DoString(`
   513          ch:send("1")
   514          ch:send("2")
   515        `); err != nil {
   516              panic(err)
   517          }
   518          ch <- lua.LString("3")
   519          quit <- lua.LTrue
   520      }
   521  
   522      func main() {
   523          ch := make(chan lua.LValue)
   524          quit := make(chan lua.LValue)
   525          go receiver(ch, quit)
   526          go sender(ch, quit)
   527          time.Sleep(3 * time.Second)
   528      }
   529  
   530  '''''''''''''''
   531  Go API
   532  '''''''''''''''
   533  
   534  ``ToChannel``, ``CheckChannel``, ``OptChannel`` are available.
   535  
   536  Refer to `Go doc(LState methods) <http://godoc.org/github.com/yuin/gopher-lua>`_ for further information.
   537  
   538  '''''''''''''''
   539  Lua API
   540  '''''''''''''''
   541  
   542  - **channel.make([buf:int]) -> ch:channel**
   543      - Create new channel that has a buffer size of ``buf``. By default, ``buf`` is 0.
   544  
   545  - **channel.select(case:table [, case:table, case:table ...]) -> {index:int, recv:any, ok}**
   546      - Same as the ``select`` statement in Go. It returns the index of the chosen case and, if that
   547        case was a receive operation, the value received and a boolean indicating whether the channel has been closed.
   548      - ``case`` is a table that outlined below.
   549          - receiving: `{"|<-", ch:channel [, handler:func(ok, data:any)]}`
   550          - sending: `{"<-|", ch:channel, data:any [, handler:func(data:any)]}`
   551          - default: `{"default" [, handler:func()]}`
   552  
   553  ``channel.select`` examples:
   554  
   555  .. code-block:: lua
   556  
   557      local idx, recv, ok = channel.select(
   558        {"|<-", ch1},
   559        {"|<-", ch2}
   560      )
   561      if not ok then
   562          print("closed")
   563      elseif idx == 1 then -- received from ch1
   564          print(recv)
   565      elseif idx == 2 then -- received from ch2
   566          print(recv)
   567      end
   568  
   569  .. code-block:: lua
   570  
   571      channel.select(
   572        {"|<-", ch1, function(ok, data)
   573          print(ok, data)
   574        end},
   575        {"<-|", ch2, "value", function(data)
   576          print(data)
   577        end},
   578        {"default", function()
   579          print("default action")
   580        end}
   581      )
   582  
   583  - **channel:send(data:any)**
   584      - Send ``data`` over the channel.
   585  - **channel:receive() -> ok:bool, data:any**
   586      - Receive some data over the channel.
   587  - **channel:close()**
   588      - Close the channel.
   589  
   590  ''''''''''''''''''''''''''''''
   591  The LState pool pattern
   592  ''''''''''''''''''''''''''''''
   593  To create per-thread LState instances, You can use the ``sync.Pool`` like mechanism.
   594  
   595  .. code-block:: go
   596  
   597      type lStatePool struct {
   598          m     sync.Mutex
   599          saved []*lua.LState
   600      }
   601  
   602      func (pl *lStatePool) Get() *lua.LState {
   603          pl.m.Lock()
   604          defer pl.m.Unlock()
   605          n := len(pl.saved)
   606          if n == 0 {
   607              return pl.New()
   608          }
   609          x := pl.saved[n-1]
   610          pl.saved = pl.saved[0 : n-1]
   611          return x
   612      }
   613  
   614      func (pl *lStatePool) New() *lua.LState {
   615          L := lua.NewState()
   616          // setting the L up here.
   617          // load scripts, set global variables, share channels, etc...
   618          return L
   619      }
   620  
   621      func (pl *lStatePool) Put(L *lua.LState) {
   622          pl.m.Lock()
   623          defer pl.m.Unlock()
   624          pl.saved = append(pl.saved, L)
   625      }
   626  
   627      func (pl *lStatePool) Shutdown() {
   628          for _, L := range pl.saved {
   629              L.Close()
   630          }
   631      }
   632  
   633      // Global LState pool
   634      var luaPool = &lStatePool{
   635          saved: make([]*lua.LState, 0, 4),
   636      }
   637  
   638  Now, you can get per-thread LState objects from the ``luaPool`` .
   639  
   640  .. code-block:: go
   641  
   642      func MyWorker() {
   643         L := luaPool.Get()
   644         defer luaPool.Put(L)
   645         /* your code here */
   646      }
   647  
   648      func main() {
   649          defer luaPool.Shutdown()
   650          go MyWorker()
   651          go MyWorker()
   652          /* etc... */
   653      }
   654  
   655  
   656  ----------------------------------------------------------------
   657  Differences between Lua and GopherLua
   658  ----------------------------------------------------------------
   659  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   660  Goroutines
   661  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   662  
   663  - GopherLua supports channel operations.
   664      - GopherLua has a type named ``channel``.
   665      - The ``channel`` table provides functions for performing channel operations.
   666  
   667  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   668  Unsupported functions
   669  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   670  
   671  - ``string.dump``
   672  - ``os.setlocale``
   673  - ``collectgarbage``
   674  - ``lua_Debug.namewhat``
   675  - ``package.loadlib``
   676  - debug hooks
   677  
   678  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   679  Miscellaneous notes
   680  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   681  
   682  - ``file:setvbuf`` does not support a line buffering.
   683  - Daylight saving time is not supported.
   684  - GopherLua has a function to set an environment variable : ``os.setenv(name, value)``
   685  
   686  ----------------------------------------------------------------
   687  Standalone interpreter
   688  ----------------------------------------------------------------
   689  Lua has an interpreter called ``lua`` . GopherLua has an interpreter called ``glua`` .
   690  
   691  .. code-block:: bash
   692  
   693     go get github.com/yuin/gopher-lua/cmd/glua
   694  
   695  ``glua`` has same options as ``lua`` .
   696  
   697  ----------------------------------------------------------------
   698  How to Contribute
   699  ----------------------------------------------------------------
   700  See `Guidlines for contributors <https://github.com/yuin/gopher-lua/tree/master/.github/CONTRIBUTING.md>`_ .
   701  
   702  ----------------------------------------------------------------
   703  Libraries for GopherLua
   704  ----------------------------------------------------------------
   705  
   706  - `gopher-luar <https://github.com/layeh/gopher-luar>`_ : Custom type reflection for gopher-lua
   707  - `gluamapper <https://github.com/yuin/gluamapper>`_ : Mapping a Lua table to a Go struct
   708  - `gluare <https://github.com/yuin/gluare>`_ : Regular expressions for gopher-lua
   709  - `gluahttp <https://github.com/cjoudrey/gluahttp>`_ : HTTP request module for gopher-lua
   710  - `gopher-json <https://github.com/layeh/gopher-json>`_ : A simple JSON encoder/decoder for gopher-lua
   711  - `gluayaml <https://github.com/kohkimakimoto/gluayaml>`_ : Yaml parser for gopher-lua
   712  - `glua-lfs <https://github.com/layeh/gopher-lfs>`_ : Partially implements the luafilesystem module for gopher-lua
   713  - `gluaurl <https://github.com/cjoudrey/gluaurl>`_ : A url parser/builder module for gopher-lua
   714  
   715  ----------------------------------------------------------------
   716  Donation
   717  ----------------------------------------------------------------
   718  
   719  BTC: 1NEDSyUmo4SMTDP83JJQSWi1MvQUGGNMZB
   720  
   721  ----------------------------------------------------------------
   722  License
   723  ----------------------------------------------------------------
   724  MIT
   725  
   726  ----------------------------------------------------------------
   727  Author
   728  ----------------------------------------------------------------
   729  Yusuke Inuzuka