scream/vendor/src/github.com/layeh/gopher-luar/example_test.go

782 lines
11 KiB
Go

package luar_test
import (
"fmt"
"strconv"
"github.com/layeh/gopher-luar"
"github.com/yuin/gopher-lua"
)
type Person struct {
Name string
Age int
Friend *Person
}
func (p Person) Hello() string {
return "Hello, " + p.Name
}
func (p Person) String() string {
return p.Name + " (" + strconv.Itoa(p.Age) + ")"
}
func (p *Person) AddNumbers(L *luar.LState) int {
sum := 0
for i := L.GetTop(); i >= 1; i-- {
sum += L.CheckInt(i)
}
L.Push(lua.LString("Tim counts: " + strconv.Itoa(sum)))
return 1
}
type Proxy struct {
XYZ string
}
func (p *Proxy) LuarCall(args ...lua.LValue) {
fmt.Printf("I was called with %d arguments!\n", len(args))
}
func (p *Proxy) LuarNewIndex(key string, value lua.LValue) {
str := value.String()
p.XYZ = str + str
}
func Example__1() {
const code = `
print(user1.Name)
print(user1.Age)
print(user1:Hello())
print(user2.Name)
print(user2.Age)
hello = user2.Hello
print(hello(user2))
`
L := lua.NewState()
defer L.Close()
tim := &Person{
Name: "Tim",
Age: 30,
}
john := Person{
Name: "John",
Age: 40,
}
L.SetGlobal("user1", luar.New(L, tim))
L.SetGlobal("user2", luar.New(L, john))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// Tim
// 30
// Hello, Tim
// John
// 40
// Hello, John
}
func Example__2() {
const code = `
for i = 1, #things do
print(things[i])
end
things[1] = "cookie"
print()
print(thangs.ABC)
print(thangs.DEF)
print(thangs.GHI)
thangs.GHI = 789
thangs.ABC = nil
`
L := lua.NewState()
defer L.Close()
things := []string{
"cake",
"wallet",
"calendar",
"phone",
"speaker",
}
thangs := map[string]int{
"ABC": 123,
"DEF": 456,
}
L.SetGlobal("things", luar.New(L, things))
L.SetGlobal("thangs", luar.New(L, thangs))
if err := L.DoString(code); err != nil {
panic(err)
}
fmt.Println()
fmt.Println(things[0])
fmt.Println(thangs["GHI"])
_, ok := thangs["ABC"]
fmt.Println(ok)
// Output:
// cake
// wallet
// calendar
// phone
// speaker
//
// 123
// 456
// nil
//
// cookie
// 789
// false
}
func Example__3() {
const code = `
user2 = Person()
user2.Name = "John"
user2.Friend = user1
print(user2.Name)
print(user2.Friend.Name)
everyone = People()
everyone["tim"] = user1
everyone["john"] = user2
`
L := lua.NewState()
defer L.Close()
tim := &Person{
Name: "Tim",
}
L.SetGlobal("user1", luar.New(L, tim))
L.SetGlobal("Person", luar.NewType(L, Person{}))
L.SetGlobal("People", luar.NewType(L, map[string]*Person{}))
if err := L.DoString(code); err != nil {
panic(err)
}
everyone := L.GetGlobal("everyone").(*lua.LUserData).Value.(map[string]*Person)
fmt.Println(len(everyone))
// Output:
// John
// Tim
// 2
}
func Example__4() {
const code = `
print(getHello(person))
`
L := lua.NewState()
defer L.Close()
tim := &Person{
Name: "Tim",
}
fn := func(p *Person) string {
return "Hello, " + p.Name
}
L.SetGlobal("person", luar.New(L, tim))
L.SetGlobal("getHello", luar.New(L, fn))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// Hello, Tim
}
func Example__5() {
const code = `
print(ch:receive())
ch:send("John")
print(ch:receive())
`
L := lua.NewState()
defer L.Close()
ch := make(chan string)
go func() {
ch <- "Tim"
name, ok := <-ch
fmt.Printf("%s\t%v\n", name, ok)
close(ch)
}()
L.SetGlobal("ch", luar.New(L, ch))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// Tim true
// John true
// nil false
}
func Example__6() {
const code = `
local sorted = {}
for k, v in countries() do
table.insert(sorted, v)
end
table.sort(sorted)
for i = 1, #sorted do
print(sorted[i])
end
`
L := lua.NewState()
defer L.Close()
countries := map[string]string{
"JP": "Japan",
"CA": "Canada",
"FR": "France",
}
L.SetGlobal("countries", luar.New(L, countries))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// Canada
// France
// Japan
}
func Example__7() {
const code = `
fn("a", 1, 2, 3)
fn("b")
fn("c", 4)
`
L := lua.NewState()
defer L.Close()
fn := func(str string, extra ...int) {
fmt.Printf("%s\n", str)
for _, x := range extra {
fmt.Printf("%d\n", x)
}
}
L.SetGlobal("fn", luar.New(L, fn))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// a
// 1
// 2
// 3
// b
// c
// 4
}
func Example__8() {
const code = `
for _, x in ipairs(fn(1, 2, 3)) do
print(x)
end
for _, x in ipairs(fn()) do
print(x)
end
for _, x in ipairs(fn(4)) do
print(x)
end
`
L := lua.NewState()
defer L.Close()
fn := func(x ...float64) *lua.LTable {
tbl := L.NewTable()
for i := len(x) - 1; i >= 0; i-- {
tbl.Insert(len(x)-i, lua.LNumber(x[i]))
}
return tbl
}
L.SetGlobal("fn", luar.New(L, fn))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// 3
// 2
// 1
// 4
}
func Example__9() {
const code = `
print(#items)
print(items:capacity())
items = items:append("hello", "world")
print(#items)
print(items:capacity())
print(items[1])
print(items[2])
`
L := lua.NewState()
defer L.Close()
items := make([]string, 0, 10)
L.SetGlobal("items", luar.New(L, items))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// 0
// 10
// 2
// 10
// hello
// world
}
func Example__10() {
const code = `
ints = newInts(1)
print(#ints, ints:capacity())
ints = newInts(0, 10)
print(#ints, ints:capacity())
`
L := lua.NewState()
defer L.Close()
type ints []int
L.SetGlobal("newInts", luar.NewType(L, ints{}))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// 1 1
// 0 10
}
func Example__11() {
const code = `
print(p1 == p1)
print(p1 == p1_alias)
print(p1 == p2)
`
L := lua.NewState()
defer L.Close()
p1 := Person{
Name: "Tim",
}
p2 := Person{
Name: "John",
}
L.SetGlobal("p1", luar.New(L, &p1))
L.SetGlobal("p1_alias", luar.New(L, &p1))
L.SetGlobal("p2", luar.New(L, &p2))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// true
// true
// false
}
func Example__12() {
const code = `
print(p1)
print(p2)
`
L := lua.NewState()
defer L.Close()
p1 := Person{
Name: "Tim",
Age: 99,
}
p2 := Person{
Name: "John",
Age: 2,
}
L.SetGlobal("p1", luar.New(L, &p1))
L.SetGlobal("p2", luar.New(L, &p2))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// Tim (99)
// John (2)
}
func Example__13() {
const code = `
print(p:AddNumbers(1, 2, 3, 4, 5))
`
L := lua.NewState()
defer L.Close()
p := Person{
Name: "Tim",
}
L.SetGlobal("p", luar.New(L, &p))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// Tim counts: 15
}
func Example__14() {
const code = `
print(p:hello())
print(p.age)
`
L := lua.NewState()
defer L.Close()
p := Person{
Name: "Tim",
Age: 66,
}
L.SetGlobal("p", luar.New(L, &p))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// Hello, Tim
// 66
}
func Example__15() {
const code = `
print(p.XYZ)
p("Hello", "World")
p.nothing = "nice"
`
L := lua.NewState()
defer L.Close()
p := Proxy{
XYZ: "1000+",
}
L.SetGlobal("p", luar.New(L, &p))
if err := L.DoString(code); err != nil {
panic(err)
}
fmt.Println(p.XYZ)
// Output:
// 1000+
// I was called with 2 arguments!
// nicenice
}
func Example__16() {
const code = `
print(fn("tim", 5))
`
L := lua.NewState()
defer L.Close()
fn := func(name string, count int) []lua.LValue {
s := make([]lua.LValue, count)
for i := 0; i < count; i++ {
s[i] = lua.LString(name)
}
return s
}
L.SetGlobal("fn", luar.New(L, fn))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// tim tim tim tim tim
}
func Example__17() {
const code = `
print(-ptr)
`
L := lua.NewState()
defer L.Close()
str := "hello"
L.SetGlobal("ptr", luar.New(L, &str))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// hello
}
func Example__18() {
const code = `
print(ptr1 == nil)
print(ptr2 == nil)
print(ptr1 == ptr2)
`
L := lua.NewState()
defer L.Close()
var ptr1 *string
str := "hello"
L.SetGlobal("ptr1", luar.New(L, ptr1))
L.SetGlobal("ptr2", luar.New(L, &str))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// true
// false
// false
}
func Example__19() {
const code = `
print(-str)
print(str ^ "world")
print(-str)
`
L := lua.NewState()
defer L.Close()
str := "hello"
L.SetGlobal("str", luar.New(L, &str))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// hello
// world
// world
}
type Example__20_A struct {
*Example__20_B
}
type Example__20_B struct {
Value *string
}
func Example__20() {
const code = `
print(a.Value == nil)
a.Value = str_ptr()
_ = a.Value ^ "hello"
print(a.Value == nil)
print(-a.Value)
`
L := lua.NewState()
defer L.Close()
a := Example__20_A{
Example__20_B: &Example__20_B{},
}
L.SetGlobal("a", luar.New(L, a))
L.SetGlobal("str_ptr", luar.NewType(L, ""))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// true
// false
// hello
}
func Example__21() {
const code = `
print(fn == nil)
`
L := lua.NewState()
defer L.Close()
var fn func()
L.SetGlobal("fn", luar.New(L, fn))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// true
}
func Example__22() {
const code = `
fn(arr)
`
L := lua.NewState()
defer L.Close()
arr := [3]int{1, 2, 3}
fn := func(val [3]int) {
fmt.Printf("%d %d %d\n", val[0], val[1], val[2])
}
L.SetGlobal("fn", luar.New(L, fn))
L.SetGlobal("arr", luar.New(L, arr))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// 1 2 3
}
func Example__23() {
const code = `
b = a
`
L := lua.NewState()
defer L.Close()
a := complex(float64(1), float64(2))
L.SetGlobal("a", luar.New(L, a))
if err := L.DoString(code); err != nil {
panic(err)
}
b := L.GetGlobal("b").(*lua.LUserData).Value.(complex128)
fmt.Println(a == b)
// Output:
// true
}
func ExampleMeta() {
const code = `
proxy(234, nil, "asd", {})
`
L := lua.NewState()
defer L.Close()
// Proxy has the following method defined:
// func (p *Proxy) LuarCall(args ...lua.LValue) {
// fmt.Printf("I was called with %d arguments!\n", len(args))
// }
//
proxy := &Proxy{}
L.SetGlobal("proxy", luar.New(L, proxy))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// I was called with 4 arguments!
}
func ExampleLState() {
const code = `
print(sum(1, 2, 3, 4, 5))
`
L := lua.NewState()
defer L.Close()
sum := func(L *luar.LState) int {
total := 0
for i := 1; i <= L.GetTop(); i++ {
total += L.CheckInt(i)
}
L.Push(lua.LNumber(total))
return 1
}
L.SetGlobal("sum", luar.New(L, sum))
if err := L.DoString(code); err != nil {
panic(err)
}
// Output:
// 15
}
func ExampleNewType() {
L := lua.NewState()
defer L.Close()
type Song struct {
Title string
Artist string
}
L.SetGlobal("Song", luar.NewType(L, Song{}))
L.DoString(`
s = Song()
s.Title = "Montana"
s.Artist = "Tycho"
print(s.Artist .. " - " .. s.Title)
`)
// Output:
// Tycho - Montana
}