luar

command
v0.0.0-...-b1dc89e Latest Latest
Warning

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

Go to latest
Published: Nov 22, 2016 License: MIT Imports: 6 Imported by: 0

README

An interactive REPL for Golua

This commandline tool provides a useful Lua REPL for exploring Go in Lua.

You will to get 'go.linenoise':

go get github.com/GeertJohan/go.linenoise

to get line history and tab completion. This is an extended REPL and comes with pretty-printing:

$ ./luar
luar prompt
Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
> = 10,'10',{10}
10	"10"	{10}

One use for the luar REPL is to explore Go libraries. regexp.Compile is exported as regexp, so we can do this. note that the endlessly useful fmt.Println is available as println from Lua. Starting a line with a period ('dot') wraps that line in println; starting a line with '=' wraps it with print (as is usual with the standard Lua prompt.)

> p = regexp '[a-z]+\\S*'
> ms =  p.FindAllString('boo woo koo',99)
> = #ms
3
> println(ms)
[boo woo koo]
> . ms
[boo woo koo]

The next session explores the luar function slice, which generates a Go slice. This is automatically wrapped as a proxy object. Note that the indexing is one-based, and that Go slices have a fixed size! The metatable for slice proxies has an __ipairs metamethod. Although luar is (currently) based on Lua 5.1, it loads code to provide a 5.2-compatible pairs and ipairs.

The inverse of slice is unproxify.

> s = luar.slice(2) // create a Go slice
> = #s
2
> = s[1]
nil
> = s[2]
nil
> = s[3] // has exactly two elements!
[string "print( s[3])"]:1:  slice get: index out of range
> = s
[]interface {}
> for i,v in ipairs(s) do print (i,v) end
1	10
2	20
> = luar.unproxify(s)
{10,20}
> println(s)
[10 20]
> . s
[10 20]

A similar operation is luar.map. Using luar.type we can find the Go type of a proxy (it returns nil if this isn't a Go type). By getting the type of a value we can then do reflection and find out what methods a type has, etc.

> m = luar.map()
> m.one = 1
> m.two = 2
> m.three = 3
> println(m)
map[one:1 two:2 three:3]
> for k,v in pairs(m) do print(k,v) end
three	3
one	1
two	2
> mt = luar.type(m)
> = mt.String()
"map[string]interface {}"
> = mt.Key().String()
"string"
> mtt = luar.type(mt)
> = mtt.String()
"*reflect.rtype"
> = mtt.NumMethod()
31

Tab-completion is implemented in such Lua code: the Lua completion code merely requires that a type implement __pairs. This allows tab to expand mtt.S to mtt.String in the last example.

local function sdump(st)
    local t = luar.type(st)
    local val = luar.value(st)
    local nm = t.NumMethod()
    local mt = t --// type to find methods on ptr receiver
    if t.Kind() == 22 then --// pointer!
        t = t.Elem()
        val = val.Elem()
    end
    local n = t.NumField()
    local cc = {}
    for i = 1,n do
        local f,v = t.Field(i-1)
        if f.PkgPath == "" then --// only public fields!
            v = val.Field(i-1)
            cc[f.Name] = v.Interface()
        end
    end
    --// then public methods...
    for i = 1,nm do
        local m = mt.Method(i-1)
        if m.PkgPath == "" then --// again, only public
            cc[m.Name] = true
        end
    end
    return cc
end

mt = getmetatable(__DUMMY__)
mt.__pairs = function(st)
    local cc = sdump(st)
    return pairs(cc)
end

sdump is pretty much the way this would be encoded in Go itself; again, the eccentric dot-notation makes it more familiar. This luar interpreter is mostly Lua embedded in Go source!

Documentation

Overview

A golua REPL with line editing, pretty-printing and tab completion.

Import any Go functions and values into Lua and play with them interactively!

Jump to

Keyboard shortcuts

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