Coder Social home page Coder Social logo

Error with glua about lulpeg HOT 31 CLOSED

pygy avatar pygy commented on August 15, 2024
Error with glua

from lulpeg.

Comments (31)

pygy avatar pygy commented on August 15, 2024

Hello, this is most interesting. It looks like GopherLua is not detected as Lua 5.1 because it doesn't set _VERSION as described in the reference manual. I've opened an issue, let's see how it goes:

yuin/gopher-lua#156

from lulpeg.

pygy avatar pygy commented on August 15, 2024

Looking into gopher-lua, chances are MoonScript still won't work because gopher-lua doesn't support newproxy nor setting a _len metatmethod on tables. As a consequence the # operator (lookahead) won't work.

LuLPeg adds a lpeg.L function as a polyfill for that, but the grammar must be written with it in mind, and I don't think that MoonScript does so.

I see that the LuLPeg docs and comments also mention a debug.setmetatable trick, but I don't remember in details how it works and I don't have the time to dig now.

from lulpeg.

 avatar commented on August 15, 2024

from lulpeg.

pygy avatar pygy commented on August 15, 2024

The proxy API is result = newproxy(x) where result is a userdata and x is optional, either a boolean or another userdata.

  • When x is false or absent, result doesn't have a metatable.
  • When x is true, result gets a new, empty metatable.
  • When x is a userdata, result inherits its metatable.

You can ignore the debug.setmetatable remark above, the comment was written at a time I didn't know about the x parameter, and then you must use debug.setmetatable to modify the userdata, the normal setmetatable only accepts tables as arguments.

Since gopher-lua supports both debug.setmetatable and userdata as a data type (AFAICT they can only be created from the Go side), adding support for newproxy should be easy for someone who knows Go. Now I don't know if the gopher-lua author is interested.

For context, that API exists in Lua 5.1 because the # operator is hardcoded to table length for tables, whereas userdata can set a custom __len handler. So newproxy was added to bypass that limitation. In Lua 5.2+, # honours the __len metamethod on tables, so newproxy was removed.

Edit: actually, the __gc metamethod is also unsupported on tables in Lua 5.1, but not on proxies.

from lulpeg.

 avatar commented on August 15, 2024

@pygy You mention that "When x is a userdata, result inherits its metatable." From where is the metatable inherited? I am still trying to wrap my head around Lua userdata types and the newproxy method...

from lulpeg.

 avatar commented on August 15, 2024

It seems as if my initial implementation (however incomplete) solves the first issue... here is the code:

        state.SetGlobal("_VERSION", lua.LString("Lua 5.1"))

	// x == false -> result has no metatable
	// x == true -> result gets a new, empty metatable
	// x == userdata -> result inherits metatable
	state.SetFuncs(state.NewTable(), map[string]lua.LGFunction{
		"newproxy": func(substate *lua.LState) int {
			arg := substate.Get(1)
			typ := arg.Type()

			if typ == lua.LTBool {
				udata := substate.NewUserData()
				if lua.LVAsBool(arg) {
					substate.SetMetatable(udata, substate.NewTable())
				}

				substate.Push(udata)
				return 1
			} else if typ == lua.LTUserData {

			}

			return 0
		},
	})

However, I just encountered another issue.... hoping this isn't a lost cause.

from lulpeg.

 avatar commented on August 15, 2024

Here is the output from err #2

# plugin git:master ●
$ ../sglua testers.lua 
panic: strings: negative Repeat count
stack traceback:
	[G]: in function 'rep'
	@/usr/share/lua/5.3/lulpeg.lua:596: in function <@/usr/share/lua/5.3/lulpeg.lua:593>
	(tailcall): ?
	@/usr/share/lua/5.3/lulpeg.lua:646: in function 'Range'
	@/usr/share/lua/5.3/lulpeg.lua:2404: in function 'R'
	@/usr/share/lua/5.3/lulpeg.lua:2862: in function 'locale'
	@/usr/share/lua/5.3/lulpeg.lua:2844: in function 'LuLPeg'
	@/usr/share/lua/5.3/lulpeg.lua:2848: in function <@/usr/share/lua/5.3/lulpeg.lua:2794>
	@/usr/share/lua/5.3/lulpeg.lua:22: in function <@/usr/share/lua/5.3/lulpeg.lua:15>
	(tailcall): ?
	[G]: in function 'require'
	./moon-bundle.lua:2970: in function <./moon-bundle.lua:0>
	[G]: in function 'require'
	<string>:1: in main chunk
	[G]: ?

goroutine 1 [running]:
main.main()
	/home/rucuriousyet/go/src/gitlab.com/stackmesh/stackd/plugin/lua/glua.go:74 +0xa64
# plugin git:master ●

from lulpeg.

pygy avatar pygy commented on August 15, 2024

Err #2 is due to the fact that string.rep(whatever, negative_index) should return the empty string, not error out. I could use string.rep(input, max(0, n)) as a workaround.

Edit: "should return" is too stringstrong (edit2: heh) here... that's what happens in PUC Lua and LuaJIT, but it is not required per spec.

from lulpeg.

pygy avatar pygy commented on August 15, 2024

The newproxy code is a good start BTW, but LuLPeg uses newproxy(other_userdata) so that branch is needed if you want MoonScript to work.

from lulpeg.

pygy avatar pygy commented on August 15, 2024

A third thing I notice, which may or may not be relevant in the future: LuLPeg is installed in the lua/5.3 directory. It doesn't matter for LuLPeg which does version detection at run time, but it may prove troublesome for other libs.

I suppose that your base Lua install is Lua 5.3, and Luarocks uses the corresponding install folder. Not sure how to tell it to use another folder without changing the Lua version.

from lulpeg.

 avatar commented on August 15, 2024

@pygy I too noticed the version directory... The thing is, I am working with a single lua bundle created using amalgamation with debug stubs to provide those stack traces. In order to remove those, I would need to install lua 5.1 (instead of my current 5.3), reinstall the libraries and build the bundle all over again (I may do it down the road with minified libraries). Also, let me know if the following code is a valid representation of newproxy()... (still guessing as to where the metatable is inherited from).

state.SetFuncs(state.NewTable(), map[string]lua.LGFunction{
		"newproxy": func(substate *lua.LState) int {
			arg := substate.Get(1)
			typ := arg.Type()

			if typ == lua.LTBool {
				udata := substate.NewUserData()
				if lua.LVAsBool(arg) {
					substate.SetMetatable(udata, substate.NewTable())
				}

				substate.Push(udata)
				return 1
			} else if typ == lua.LTUserData {
				metatable := substate.GetMetatable(arg)
				udata := substate.NewUserData()

				substate.SetMetatable(udata, metatable)
				substate.Push(udata)

				return 1
			}

			return 0
		},
	})

from lulpeg.

 avatar commented on August 15, 2024

I've added

const strrepfunc = `
function customrep(str, n)
	if n >= 0 then
		local out = ""
		for i = 0, n do
			out = out..out
		end
		return out
	else
		return ""
	end
end

string.rep = customrep
`

which solves error #2 but now there's a third problem... starting to think this uphill battle is pointless. Any ideas for a better approach? Really hoping to support raw Moonscript in this system without needing to compile anything... may not be a viable option if using Gopher Lua.

from lulpeg.

pygy avatar pygy commented on August 15, 2024

If I were you I'd go

local str_rep = string.rep
string.rep = function(str, n) 
  if type(n) == "number" and n < 0 then n = 0 end
  return str_rep(str, n)
end

It will be more efficient.

What's the third problem? This is actually interesting for me, because it points at places where LuLPeg relies on implementation quirks rather than documented behavior.

What's the third issue?


Edit: for newproxy, this should work for LuLPeg, but to work like PUC Lua 5.1, it has to treat a lack of argument or nil argument as if it were false, and error out with bad argument #1 to 'newproxy' (boolean or proxy expected) where you return 0.

from lulpeg.

 avatar commented on August 15, 2024

Okay thx for the tip @pygy, Ill add that to my TODOs. Here is the error:

# plugin git:master ●
$ ../sglua testers.lua 
panic: @/usr/share/lua/5.3/lulpeg.lua:2382: bad argument #1 to 'P' (lpeg-pattern expected, got nil)
stack traceback:
	[G]: in function 'error'
	@/usr/share/lua/5.3/lulpeg.lua:2382: in function 'LL_P'
	@/usr/share/lua/5.3/lulpeg.lua:2498: in function <@/usr/share/lua/5.3/lulpeg.lua:2496>
	@/usr/share/lua/5.3/lulpeg.lua:1885: in function 'factorize_sequence'
	@/usr/share/lua/5.3/lulpeg.lua:2490: in function <@/usr/share/lua/5.3/lulpeg.lua:2486>
	(tailcall): ?
	@/usr/share/lua/5.3/lulpeg.lua:1104: in function 're'
	@/usr/share/lua/5.3/lulpeg.lua:2845: in function 'LuLPeg'
	@/usr/share/lua/5.3/lulpeg.lua:2848: in function <@/usr/share/lua/5.3/lulpeg.lua:2794>
	@/usr/share/lua/5.3/lulpeg.lua:22: in function <@/usr/share/lua/5.3/lulpeg.lua:15>
	(tailcall): ?
	[G]: in function 'require'
	./moon-bundle.lua:2970: in function <./moon-bundle.lua:0>
	[G]: in function 'require'
	<string>:1: in main chunk
	[G]: ?

goroutine 1 [running]:
main.main()
	/home/rucuriousyet/go/src/gitlab.com/stackmesh/stackd/plugin/lua/glua.go:117 +0xb13
# plugin git:master ●

from lulpeg.

 avatar commented on August 15, 2024

If you'd prefer, I may just be able to set you up with the project I am working on so you can test/work though stuff yourself. Either way is fine.

from lulpeg.

pygy avatar pygy commented on August 15, 2024

@rucuriousyet yup, it would help if I could help me set things up locally, the stack trace you posted goes through the re module which uses lpeg to parse its input and generate a grammar using IIRC constant and folding captures among other things (look at the source for a brain melting session).

I wonder how a nil manages to sneak in there.

from lulpeg.

 avatar commented on August 15, 2024

Okay, It should be pretty simple for the most part. I would install Golang (golang.org/brew/pacaur) and then clone or use go get to retrieve this repo: https://gitlab.com/stackmesh/stackd (all the code related to this in the plugin directory)

from lulpeg.

 avatar commented on August 15, 2024

I am basically doing the following:

go build -o sglua plugin/lua/glua.go
cd plugin
../sglua testers.lua

from lulpeg.

pygy avatar pygy commented on August 15, 2024

@rucuriousyet https://gitlab.com/stackmesh/stackd prompted me to log in into GitLab only to return a 404... Typo?

from lulpeg.

 avatar commented on August 15, 2024

from lulpeg.

 avatar commented on August 15, 2024

from lulpeg.

 avatar commented on August 15, 2024

from lulpeg.

pygy avatar pygy commented on August 15, 2024

So, we're making progress, but go get gitlab.com/stackmesh/core.git still ends up looking for stackmesh/stackd at some point:

~/tmp ❯❯❯ env GIT_TERMINAL_PROMPT=1 go get gitlab.com/stackmesh/core     
Username for 'https://gitlab.com': pygy
Password for 'https://[email protected]':
# cd .; git clone https://gitlab.com/stackmesh/stackd.git /Users/pygy/go/src/gitlab.com/stackmesh/stackd
Cloning into '/Users/pygy/go/src/gitlab.com/stackmesh/stackd'...
remote: The project you were looking for could not be found.
fatal: repository 'https://gitlab.com/stackmesh/stackd.git/' not found
package gitlab.com/stackmesh/stackd/fibre: exit status 128
package gitlab.com/stackmesh/stackd/machapi: cannot find package "gitlab.com/stackmesh/stackd/machapi" in any of:
	/usr/local/go/src/gitlab.com/stackmesh/stackd/machapi (from $GOROOT)
	/Users/pygy/go/src/gitlab.com/stackmesh/stackd/machapi (from $GOPATH)
package gitlab.com/stackmesh/stackd/servman: cannot find package "gitlab.com/stackmesh/stackd/servman" in any of:
	/usr/local/go/src/gitlab.com/stackmesh/stackd/servman (from $GOROOT)
	/Users/pygy/go/src/gitlab.com/stackmesh/stackd/servman (from $GOPATH)
package gitlab.com/stackmesh/stackd/utils: cannot find package "gitlab.com/stackmesh/stackd/utils" in any of:
	/usr/local/go/src/gitlab.com/stackmesh/stackd/utils (from $GOROOT)
	/Users/pygy/go/src/gitlab.com/stackmesh/stackd/utils (from $GOPATH)

I had already installed go through the official macOS installer... Not sure if it's related.

~/tmp ❯❯❯ go version
go version go1.9.2 darwin/amd64

from lulpeg.

 avatar commented on August 15, 2024

from lulpeg.

 avatar commented on August 15, 2024

from lulpeg.

pygy avatar pygy commented on August 15, 2024

It was failing at go get gitlab.com/stackmesh/core, but you were right, renaming the folder and then running go get from there then following your instructions (go build -o sglua plugin/lua/glua.go etc.) allowed me to reproduce your errors. I'll look at it in the coming days.

from lulpeg.

 avatar commented on August 15, 2024

from lulpeg.

yuin avatar yuin commented on August 15, 2024

I've make some changes for GopherLua, now LuLPeg should work on GopherLua.

from lulpeg.

pygy avatar pygy commented on August 15, 2024

The issue stems from yuin/gopher-lua#158, an interpreter bug. The gopher-lua author is quite responsive, this will hopefully be solved soon.

Also, no need to add newproxy, actually. The MoonScript parser is LuLPeg-aware (I found this while exploring this issue), and defines L like this:

local L = lpeg.luversion and lpeg.L or function(p) return #p end

from lulpeg.

pygy avatar pygy commented on August 15, 2024

@yuin I hadn't seen your message here before posting yuin/gopher-lua#158 (I was on the road this afternoon and investigated/wrote the report offline and posted it without refreshing this page).

Assuming you fixed it as well, many thanks for the quick fixes :-)

from lulpeg.

pygy avatar pygy commented on August 15, 2024

@rucuriousyet Closing now as it seems fixed. Feel free to ping me if there are still issues.

from lulpeg.

Related Issues (19)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.