luar

package module
v0.0.0-...-fc1320f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 20, 2015 License: MIT Imports: 5 Imported by: 0

README

gopher-luar GoDoc

custom type reflection for gopher-lua.

License

MIT

Documentation

Overview

Package luar provides custom type reflection to gopher-lua.

Notice

This package is currently in development, and its behavior may change. This message will be removed once the package is considered stable.

Basic types

Go bool, number, and string types are converted to the equivalent basic Lua type.

Example:

New(L, "Hello World") -> lua.LString("Hello World")
New(L, uint(834))     -> lua.LNumber(uint(834))

Channel types

Channel types have the following methods defined:

receive():    Receives data from the channel. Returns nil plus false if the
              channel is closed.
send(data):   Sends data to the channel.
close():      Closes the channel.

Taking the length (#) of a channel returns how many unread items are in its buffer.

Example:

ch := make(chan string)
L.SetGlobal("ch", New(L, ch))
---
ch:receive()      -- equivalent to v, ok := ch
ch:send("hello")  -- equivalent to ch <- "hello"
ch:close()        -- equivalent to close(ch)

Function types

Function types can be called from Lua. Its arguments and returned values will be automatically converted from and to Lua types, respectively (see exception below). However, a function that uses luar.LState can bypass the automatic argument and return value conversion (see luar.LState documentation for example).

Example:

fn := func(name string, age uint) string {
  return fmt.Sprintf("Hello %s, age %d", name, age)
}
L.SetGlobal("fn", New(L, fn))
---
print(fn("Tim", 5)) -- prints "Hello Tim, age 5"

A special conversion case happens when function returns a lua.LValue slice. In that case, luar will automatically unpack the slice.

Example:

fn := func() []lua.LValue {
  return []lua.LValue{lua.LString("Hello"), lua.LNumber(2.5)}
}
L.SetGlobal("fn", New(L, fn))
---
x, y = fn()
print(x) -- prints "Hello"
print(y) -- prints "2.5"

Map types

Map types can be accessed and modified like a normal Lua table a meta table. Its length can also be queried using the # operator.

Rather than using pairs to create an map iterator, calling the value (e.g. map_variable()) will return an iterator for the map.

Example:

places := map[string]string{
  "NA": "North America",
  "EU": "European Union",
}
L.SetGlobal("places", New(L, places))
---
print(#places)       -- prints "2"
print(places.NA)     -- prints "North America"
print(places["EU"])  -- prints "European Union"
for k, v in places() do
  print(k .. ": " .. v)
end

Slice types

Like map types, slices be accessed, be modified, and have their length queried. Additionally, the following methods are defined for slices:

append(items...):   Appends the items to the slice. Returns a slice with
                    the items appended.
capacity():         Returns the slice capacity.

For consistency with other Lua code, slices use one-based indexing.

Example:

letters := []string{"a", "e", "i"}
L.SetGlobal("letters", New(L, letters))
---
letters = letters:append("o", "u")

Struct types

Struct types can have their fields accessed and modified and their methods called. First letters of field/method names are automatically converted to uppercase.

Example:

type Person {
  Name string
}
func (p Person) SayHello() {
  fmt.Printf("Hello, %s\n", p.Name)
}

tim := Person{"Tim"}
L.SetGlobal("tim", New(L, tim))
---
tim:SayHello() -- same as tim:sayHello()

Pointer types

Pointers to structs operate the same way structs do. Pointers can also be dereferenced using the unary minus (-) operator.

Example:

str := "hello"
L.SetGlobal("strptr", New(L, &str))
---
print(-strptr) -- prints "hello"

The pointed to value can changed using the pow (^) operator.

Example:

str := "hello"
L.SetGlobal("strptr", New(L, &str))
---
print(str^"world") -- prints "world", and str's value is now "world"

Type types

Type constructors can be created using NewType. When called, it returns a new variable which is of the same type that was passed to NewType. Its behavior is dependent on the kind of value passed, as described below:

Kind      Constructor arguments          Return value
-----------------------------------------------------
Channel   Buffer size (opt)              Channel
Map       None                           Map
Slice     Length (opt), Capacity (opt)   Slice
Default   None                           Pointer to the newly allocated value

Example:

type Person struct {
  Name string
}
L.SetGlobal("Person", NewType(L, Person{}))
---
p = Person()
p.Name = "John"
print("Hello, " .. p.Name)  // prints "Hello, John"

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func New

func New(L *lua.LState, value interface{}) lua.LValue

New creates and returns a new lua.LValue for the given value.

The following types are supported:

Kind            gopher-lua Type
-------------------------------
nil             LNil
Bool            LBool
Int             LNumber
Int8            LNumber
Int16           LNumber
Int32           LNumber
Int64           LNumber
Uint            LNumber
Uint8           LNumber
Uint32          LNumber
Uint64          LNumber
Float32         LNumber
Float64         LNumber
Complex64       *LUserData
Complex128      *LUserData
Array           *LUserData
Chan            *LUserData
Interface       *LUserData
Func            *lua.LFunction
Map             *LUserData
Ptr             *LUserData
Slice           *LUserData
String          LString
Struct          *LUserData
UnsafePointer   *LUserData

func NewType

func NewType(L *lua.LState, value interface{}) lua.LValue

NewType returns a new type creator for the given value's type.

When the lua.LValue is called, a new value will be created that is the same type as value's type.

Example
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

Types

type LState

type LState struct {
	*lua.LState
}

LState is an wrapper for gopher-lua's LState. It should be used when you wish to have a function/method with the standard "func(*lua.LState) int" signature.

Example
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

type Meta

type Meta interface {
	LuarCall(arguments ...interface{}) interface{}
	LuarIndex(key interface{}) interface{}
	LuarNewIndex(key, value interface{})
}

Meta can be implemented by a struct or struct pointer. Each method defines a fallback action for the corresponding Lua metamethod.

The signature of the methods does not matter; they will be converted using the standard function conversion rules. Also, a type is allowed to implement only a subset of the interface.

Example
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!

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL