Skip to content

Commit 857a125

Browse files
author
Cathal Garvey
committed
Updating readme with example. Should be ready to PR for issue yuin#55.
1 parent 79f827a commit 857a125

File tree

1 file changed

+81
-45
lines changed

1 file changed

+81
-45
lines changed

README.rst

Lines changed: 81 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ GopherLua: VM and compiler for Lua in Go.
99
:target: https://travis-ci.org/yuin/gopher-lua
1010

1111
.. image:: https://coveralls.io/repos/yuin/gopher-lua/badge.svg
12-
:target: https://coveralls.io/r/yuin/gopher-lua
12+
:target: https://coveralls.io/r/yuin/gopher-lua
1313

1414
.. image:: https://badges.gitter.im/Join%20Chat.svg
1515
:alt: Join the chat at https://gitter.im/yuin/gopher-lua
@@ -19,7 +19,7 @@ GopherLua: VM and compiler for Lua in Go.
1919
2020
GopherLua is a Lua5.1 VM and compiler written in Go. GopherLua has a same goal
2121
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
22+
Go APIs that allow you to easily embed a scripting language to your Go host
2323
programs.
2424

2525
.. contents::
@@ -31,7 +31,7 @@ Design principle
3131

3232
- Be a scripting language with extensible semantics.
3333
- User-friendly Go API
34-
- The stack based API like the one used in the original Lua
34+
- The stack based API like the one used in the original Lua
3535
implementation will cause a performance improvements in GopherLua
3636
(It will reduce memory allocations and concrete type <-> interface conversions).
3737
GopherLua API is **not** the stack based API.
@@ -49,31 +49,31 @@ Installation
4949
----------------------------------------------------------------
5050

5151
.. code-block:: bash
52-
52+
5353
go get github.com/yuin/gopher-lua
5454
5555
GopherLua supports >= Go1.4.
5656

5757
----------------------------------------------------------------
5858
Usage
5959
----------------------------------------------------------------
60-
GopherLua APIs perform in much the same way as Lua, **but the stack is used only
60+
GopherLua APIs perform in much the same way as Lua, **but the stack is used only
6161
for passing arguments and receiving returned values.**
6262

6363
GopherLua supports channel operations. See **"Goroutines"** section.
6464

6565
Import a package.
6666

6767
.. code-block:: go
68-
68+
6969
import (
7070
"github.com/yuin/gopher-lua"
7171
)
7272
7373
Run scripts in the VM.
7474

7575
.. code-block:: go
76-
76+
7777
L := lua.NewState()
7878
defer L.Close()
7979
if err := L.DoString(`print("hello")`); err != nil {
@@ -95,7 +95,7 @@ Note that elements that are not commented in `Go doc <http://godoc.org/github.co
9595
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9696
Data model
9797
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
98-
All data in a GopherLua program is an ``LValue`` . ``LValue`` is an interface
98+
All data in a GopherLua program is an ``LValue`` . ``LValue`` is an interface
9999
type that has following methods.
100100

101101
- ``String() string``
@@ -146,10 +146,10 @@ To test ``LNilType`` and ``LBool``, You **must** use pre-defined constants.
146146
.. code-block:: go
147147
148148
lv := L.Get(-1) // get the value at the top of the stack
149-
149+
150150
if lv == LTrue { // correct
151151
}
152-
152+
153153
if bl, ok == lv.(lua.LBool); ok && bool(bl) { // wrong
154154
}
155155
@@ -160,12 +160,12 @@ In Lua, both ``nil`` and ``false`` make a condition false. ``LVIsFalse`` and ``L
160160
lv := L.Get(-1) // get the value at the top of the stack
161161
if LVIsFalse(lv) { // lv is nil or false
162162
}
163-
163+
164164
if LVAsBool(lv) { // lv is neither nil nor false
165165
}
166166
167167
Objects that based on go structs(``LFunction``. ``LUserData``, ``LTable``)
168-
have some public methods and fields. You can use these methods and fields for
168+
have some public methods and fields. You can use these methods and fields for
169169
performance and debugging, but there are some limitations.
170170

171171
- Metatable does not work.
@@ -201,6 +201,7 @@ Miscellaneous lua.NewState options
201201
- **Options.SkipOpenLibs bool(default false)**
202202
- By default, GopherLua opens all built-in libraries when new LState is created.
203203
- 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.
204205
- **Options.IncludeGoStackTrace bool(default false)**
205206
- By default, GopherLua does not show Go stack traces when panics occur.
206207
- You can get Go stack traces by setting this to ``true`` .
@@ -222,7 +223,7 @@ Calling Go from Lua
222223
L.Push(lua.LNumber(lv * 2)) /* push result */
223224
return 1 /* number of results */
224225
}
225-
226+
226227
func main() {
227228
L := lua.NewState()
228229
defer L.Close()
@@ -252,17 +253,52 @@ Working with coroutines.
252253
fmt.Println(err.Error())
253254
break
254255
}
255-
256+
256257
for i, lv := range values {
257258
fmt.Printf("%v : %v\n", i, lv)
258259
}
259-
260+
260261
if st == lua.ResumeOK {
261262
fmt.Println("yield break(ok)")
262263
break
263264
}
264265
}
265266
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+
package main
278+
279+
import (
280+
"github.com/yuin/gopher-lua"
281+
)
282+
283+
func main() {
284+
L := lua.NewState(lua.Options{SkipOpenLibs: true})
285+
defer L.Close()
286+
for _, loader := range []lua.LGFunction{
287+
lua.OpenLoad, // Must be first!
288+
lua.OpenBase, // Contains most builtins, pretty much required
289+
lua.OpenString,
290+
lua.OpenMath,
291+
lua.OpenTable,
292+
lua.OpenCoroutine,
293+
lua.OpenChannel,
294+
} {
295+
_ = loader(L)
296+
}
297+
if err := L.DoFile("main.lua"); err != nil {
298+
panic(err)
299+
}
300+
}
301+
266302
+++++++++++++++++++++++++++++++++++++++++
267303
Creating a module by Go
268304
+++++++++++++++++++++++++++++++++++++++++
@@ -272,26 +308,26 @@ mymodule.go
272308
.. code-block:: go
273309
274310
package mymodule
275-
311+
276312
import (
277313
"github.com/yuin/gopher-lua"
278314
)
279-
315+
280316
func Loader(L *lua.LState) int {
281317
// register functions to the table
282318
mod := L.SetFuncs(L.NewTable(), exports)
283319
// register other stuff
284320
L.SetField(mod, "name", lua.LString("value"))
285-
321+
286322
// returns the module
287323
L.Push(mod)
288324
return 1
289325
}
290-
326+
291327
var exports = map[string]lua.LGFunction{
292328
"myfunc": myfunc,
293329
}
294-
330+
295331
func myfunc(L *lua.LState) int {
296332
return 0
297333
}
@@ -301,12 +337,12 @@ mymain.go
301337
.. code-block:: go
302338
303339
package main
304-
340+
305341
import (
306342
"./mymodule"
307343
"github.com/yuin/gopher-lua"
308344
)
309-
345+
310346
func main() {
311347
L := lua.NewState()
312348
defer L.Close()
@@ -359,9 +395,9 @@ You can extend GopherLua with new types written in Go.
359395
type Person struct {
360396
Name string
361397
}
362-
398+
363399
const luaPersonTypeName = "person"
364-
400+
365401
// Registers my person type to given L.
366402
func registerPersonType(L *lua.LState) {
367403
mt := L.NewTypeMetatable(luaPersonTypeName)
@@ -371,7 +407,7 @@ You can extend GopherLua with new types written in Go.
371407
// methods
372408
L.SetField(mt, "__index", L.SetFuncs(L.NewTable(), personMethods))
373409
}
374-
410+
375411
// Constructor
376412
func newPerson(L *lua.LState) int {
377413
person := &Person{L.CheckString(1)}
@@ -381,7 +417,7 @@ You can extend GopherLua with new types written in Go.
381417
L.Push(ud)
382418
return 1
383419
}
384-
420+
385421
// Checks whether the first lua argument is a *LUserData with *Person and returns this *Person.
386422
func checkPerson(L *lua.LState) *Person {
387423
ud := L.CheckUserData(1)
@@ -391,11 +427,11 @@ You can extend GopherLua with new types written in Go.
391427
L.ArgError(1, "person expected")
392428
return nil
393429
}
394-
430+
395431
var personMethods = map[string]lua.LGFunction{
396432
"name": personGetSetName,
397433
}
398-
434+
399435
// Getter and setter for the Person#Name
400436
func personGetSetName(L *lua.LState) int {
401437
p := checkPerson(L)
@@ -406,7 +442,7 @@ You can extend GopherLua with new types written in Go.
406442
L.Push(lua.LString(p.Name))
407443
return 1
408444
}
409-
445+
410446
func main() {
411447
L := lua.NewState()
412448
defer L.Close()
@@ -468,7 +504,7 @@ You **must not** send these objects from Go APIs to channels.
468504
panic(err)
469505
}
470506
}
471-
507+
472508
func sender(ch, quit chan lua.LValue) {
473509
L := lua.NewState()
474510
defer L.Close()
@@ -483,7 +519,7 @@ You **must not** send these objects from Go APIs to channels.
483519
ch <- lua.LString("3")
484520
quit <- lua.LTrue
485521
}
486-
522+
487523
func main() {
488524
ch := make(chan lua.LValue)
489525
quit := make(chan lua.LValue)
@@ -508,8 +544,8 @@ Lua API
508544
- Create new channel that has a buffer size of ``buf``. By default, ``buf`` is 0.
509545

510546
- **channel.select(case:table [, case:table, case:table ...]) -> {index:int, recv:any, ok}**
511-
- Same as the ``select`` statement in Go. It returns the index of the chosen case and, if that
512-
case was a receive operation, the value received and a boolean indicating whether the channel has been closed.
547+
- Same as the ``select`` statement in Go. It returns the index of the chosen case and, if that
548+
case was a receive operation, the value received and a boolean indicating whether the channel has been closed.
513549
- ``case`` is a table that outlined below.
514550
- receiving: `{"|<-", ch:channel [, handler:func(ok, data:any)]}`
515551
- sending: `{"<-|", ch:channel, data:any [, handler:func(data:any)]}`
@@ -558,12 +594,12 @@ The LState pool pattern
558594
To create per-thread LState instances, You can use the ``sync.Pool`` like mechanism.
559595

560596
.. code-block:: go
561-
597+
562598
type lStatePool struct {
563599
m sync.Mutex
564600
saved []*lua.LState
565601
}
566-
602+
567603
func (pl *lStatePool) Get() *lua.LState {
568604
pl.m.Lock()
569605
defer pl.m.Unlock()
@@ -575,26 +611,26 @@ To create per-thread LState instances, You can use the ``sync.Pool`` like mechan
575611
pl.saved = pl.saved[0 : n-1]
576612
return x
577613
}
578-
614+
579615
func (pl *lStatePool) New() *lua.LState {
580616
L := lua.NewState()
581617
// setting the L up here.
582618
// load scripts, set global variables, share channels, etc...
583619
return L
584620
}
585-
621+
586622
func (pl *lStatePool) Put(L *lua.LState) {
587623
pl.m.Lock()
588624
defer pl.m.Unlock()
589625
pl.saved = append(pl.saved, L)
590626
}
591-
627+
592628
func (pl *lStatePool) Shutdown() {
593629
for _, L := range pl.saved {
594630
L.Close()
595631
}
596632
}
597-
633+
598634
// Global LState pool
599635
var luaPool = &lStatePool{
600636
saved: make([]*lua.LState, 0, 4),
@@ -603,7 +639,7 @@ To create per-thread LState instances, You can use the ``sync.Pool`` like mechan
603639
Now, you can get per-thread LState objects from the ``luaPool`` .
604640

605641
.. code-block:: go
606-
642+
607643
func MyWorker() {
608644
L := luaPool.Get()
609645
defer luaPool.Put(L)
@@ -633,7 +669,7 @@ Goroutines
633669
Unsupported functions
634670
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
635671

636-
- ``string.dump``
672+
- ``string.dump``
637673
- ``os.setlocale``
638674
- ``collectgarbage``
639675
- ``lua_Debug.namewhat``
@@ -692,24 +728,24 @@ Our workflow is based on the `github-flow <https://guides.github.com/introductio
692728

693729
4. Pull new changes from the upstream.
694730
::
695-
731+
696732
git checkout master
697733
git fetch upstream
698734
git merge upstream/master
699735

700736
5. Create a feature branch
701737
::
702-
738+
703739
git checkout -b <branch-name>
704740

705741
6. Commit your changes and reference the issue number in your comment.
706742
::
707-
743+
708744
git commit -m "Issue #<issue-ref> : <your message>"
709745

710746
7. Push the feature branch to your remote repository.
711747
::
712-
748+
713749
git push origin <branch-name>
714750

715751
8. Open new pull request.

0 commit comments

Comments
 (0)