Conversation
|
@kaspar030 would you be interested in having a look at this? |
examples/lua/lua.c
Outdated
|
|
||
| #define LUA_INITVARVERSION LUA_INIT_VAR LUA_VERSUFFIX | ||
|
|
||
|
|
There was a problem hiding this comment.
Please remove extra empty line here
examples/lua/lua.c
Outdated
| #include "lauxlib.h" | ||
| #include "lualib.h" | ||
|
|
||
| #if !defined(LUA_PROMPT) |
examples/lua/lua.c
Outdated
| @@ -0,0 +1,658 @@ | |||
| /* | |||
There was a problem hiding this comment.
As far as I see, a large portion of this file is internal code. This should be in pkg/lua/contrib
There was a problem hiding this comment.
A lot of this is implementation of a cli program, rather than the api - similar to e.g. examples/gcoap/gcoap_cli.c. So, is it best to think now about the API which is going to be exposed to an application and rearrange/separate out the lua.c file accordingly? My approach was to leave it to "evolve", but maybe the more usual approach is that code merged to master needs to be well thought out everywhere, is this true? If so will spend some time here...
There was a problem hiding this comment.
Further thoughts: just spoke to @miri64 who suggested I think more about what the user would need to know about to implement a program (goes in example) and what they don't need to know (goes in pkg)
There was a problem hiding this comment.
I'm working on Lua now. The lua.c file is going away. It contains a REPL that is best implemented in Lua itself.
examples/lua/main.c
Outdated
| } | ||
|
|
||
| static const shell_command_t shell_commands[] = { | ||
| { "lua", "Start a Lua prompt", lua_main}, |
There was a problem hiding this comment.
I think it would be good to have a single command here.
E.g lua console, lua run, etc.
examples/lua/README.md
Outdated
|
|
||
| ### How to run | ||
|
|
||
| Type `make flash term |
examples/lua/lua.c
Outdated
|
|
||
| #endif /* } */ | ||
|
|
||
|
|
examples/lua/lua.c
Outdated
|
|
||
| #endif /* } */ | ||
|
|
||
| #endif /* } */ |
There was a problem hiding this comment.
Could you add /* / to mark the closing bracket? E.g / lua_stdin_is_tty */
examples/lua/lua.c
Outdated
|
|
||
| #endif /* } */ | ||
|
|
||
|
|
|
Reduced scope of PR from a command-line interpreter + a script parser and runner, to just the script parser and runner. Updated the top comment accordingly. |
| # example directory. The header file contains a byte array of the | ||
| # ASCII characters in the .lua script. | ||
|
|
||
| LUA_PATH := $(BINDIR)/lua |
There was a problem hiding this comment.
This lines can be moved to the pkg Makefiles and invoked when USEPKG+=lua. See e.g here
There was a problem hiding this comment.
on second thoughts, maybe it's not bad to leave it as is. It explicitly tells the developer where's the file. But it could also be documented in the README.md. I'm OK with both ;)
There was a problem hiding this comment.
I'd prefer to keep it as it is, for consistency with examples/javascript and pkg/jerryscript which do the same thing. Will document in README.md. (How important is consistency between WIP packages and examples?)
There was a problem hiding this comment.
maybe we can think about this later
There was a problem hiding this comment.
Where's the best place for this kind of discussion after a PR has been closed?
There was a problem hiding this comment.
Another PR/RFC should do the trick
examples/lua/main.c
Outdated
| } | ||
|
|
||
| static const shell_command_t shell_commands[] = { | ||
| { "run_lua_script", "Run main.lua", lua_run_main_script}, |
There was a problem hiding this comment.
this command can be dropped, since there's no configuration required to run the main.lua script
pkg/lua/Makefile
Outdated
| .PHONY: all | ||
|
|
||
| all: | ||
| # The lower case "makefile" is so that it copies over the lua makefile |
There was a problem hiding this comment.
It's possible to specify a file with -f. It should be enough to copy the file
pkg/lua/contrib/lua_run_char_array.c
Outdated
| static lua_State *globalL = NULL; | ||
|
|
||
| static const char *progname = "lua"; | ||
|
|
There was a problem hiding this comment.
Here and below, please remove double empty lines. Should be just one empty line between 2 blocks of code
pkg/lua/contrib/lua_run_char_array.c
Outdated
| /* | ||
| ** Hook set by signal function to stop the interpreter. | ||
| */ | ||
| static void lstop (lua_State *L, lua_Debug *ar) { |
There was a problem hiding this comment.
although static, do you think it's possible to prefix these functions?
pkg/lua/contrib/lua_run_char_array.c
Outdated
| ** interpreter. | ||
| */ | ||
| static void laction (int i) { | ||
| signal(i, SIG_DFL); /* if another SIGINT happens, terminate process */ |
examples/lua/main.c
Outdated
| #include "main.lua.h" | ||
|
|
||
| extern int lua_main(int argc, char **argv); | ||
| extern int lua_run_char_array(const char *buffer, size_t buffer_len); |
There was a problem hiding this comment.
This should be in a proper header file with it's Doxygen documentation. See e.g here
examples/lua/main.c
Outdated
|
|
||
| #include <stdio.h> | ||
|
|
||
| #include "msg.h" |
| # example directory. The header file contains a byte array of the | ||
| # ASCII characters in the .lua script. | ||
|
|
||
| LUA_PATH := $(BINDIR)/lua |
There was a problem hiding this comment.
on second thoughts, maybe it's not bad to leave it as is. It explicitly tells the developer where's the file. But it could also be documented in the README.md. I'm OK with both ;)
|
@jia200x the file lua_run_char_array.c was derived from the lua.c file you linked to. Lua.c was their command line interpreter implementation, so not part of the Lua implementation as such... I took that file and cut it down and added the lua_run_char_array function. |
|
@danpetry what differences exists between their CLI and the one proposed here? If it's not part of the official CLI implementation, I think using an external file might help maintainance (if possible though). What do you think? |
|
As discussed offline with @danpetry, the original lua.c can be reused. Only some small functions in contrib folder would be required. |
|
There are a few options for implementation of the pkg/contrib code
lstop - stops the interpreter
Basically, it seems to be a choice between replication of upstream code or a patch. Opinions please? :) |
|
So, here is another option which I think is better The API wrapper code is not patched from Lua code, and it's not downstreamed either. It's re-written in a well-structured and maintainable way that can be extended in future iterations and included in the RIOT repo. It would need to be significantly different from the Lua code for this so neither patched nor downstreamed (nor a combination of both) Re whether we need an API wrapper at all: when this PR was first submitted there was no wrapper, the functionality was implemented in the example, and it was requested for this to be moved to the package directory as an API wrapper - hence its inclusion there. |
|
@danpetry can you provide a concrete example of this kind of wrapper? If it's possible to call Lua instructions with the raw package, the current PR can be merged. I think the wrapper can come later, specially since there are other high level languages that might require also an abstraction layer. |
|
Sorry, just to clarify - by "the current PR" what state of the PR do you refer to? Would it be:
(the current state at the moment is as a wrapper.) |
|
@danpetry check the current JS implementation. It fetches the original jerryscript code, and the application calls pkg functions. I tend to think the Lua CLI can be added in another PR, so this one can easily gets merged with a simple example file showing actual Lua code. What do you think? |
|
That sounds fine to me. Will do :) |
examples/lua/main.c
Outdated
|
|
||
| #include "main.lua.h" | ||
|
|
||
| extern int lua_run_char_array(const char *buffer, size_t buffer_len); |
There was a problem hiding this comment.
This function should be included from a header file with its proper Doxygen documentation. As far as I see, it's intended to be called by the user
| # example directory. The header file contains a byte array of the | ||
| # ASCII characters in the .lua script. | ||
|
|
||
| LUA_PATH := $(BINDIR)/lua |
There was a problem hiding this comment.
maybe we can think about this later
examples/lua/main.c
Outdated
|
|
||
| if (L == NULL) { | ||
| puts("cannot create state: not enough memory"); | ||
| return EXIT_FAILURE; |
There was a problem hiding this comment.
No, they're defined in stdlib.h
There was a problem hiding this comment.
I would prefer here errno (e.g ENOBUFS)
There was a problem hiding this comment.
I've used ENOMEM for this one; EINTR for failure of the protected call to the lua engine, to run the script; and return 0; for success in line with most other examples I looked at.
examples/lua/main.c
Outdated
|
|
||
| #include "main.lua.h" | ||
|
|
||
| int lua_run_script (const char *buffer, size_t buffer_len ){ |
There was a problem hiding this comment.
please remove space between function name and parentheses, and between buffer_len and parentheses.
Also, add a space between the closing parentheses and curly bracket
There was a problem hiding this comment.
Putting the opening curly bracket on the next line as I see that seems to be the most common way of doing it
There was a problem hiding this comment.
yes, sorry. Curly bracket here should be in next line
examples/lua/main.c
Outdated
| } | ||
|
|
||
| luaL_openlibs(L); | ||
|
|
There was a problem hiding this comment.
I would prefer to remove this extra line here
examples/lua/main.c
Outdated
| } | ||
|
|
||
| lua_close(L); | ||
|
|
examples/lua/main.c
Outdated
| int main(void) | ||
| { | ||
| puts("Lua RIOT build"); | ||
|
|
There was a problem hiding this comment.
Thanks. Re the coding conventions, how much will uncrustify catch if I run that? Or is it more a case of learning by doing? (With some leeway re personal preference in certain cases?)
pkg/lua/Makefile
Outdated
| @@ -0,0 +1,13 @@ | |||
| PKG_NAME=lua | |||
| PKG_URL=https://github.com/lua/lua.git | |||
| PKG_VERSION=v5-3-4 | |||
|
@danpetry please address the comments above, squash and I give the ACK. I tested and works as expected. Then I need @kaspar030 approval (or dismissing the review ;) in order to merge. EDIT: I noticed @jcarrano is also reviewing. So, let me know ;) |
|
@kaspar030 said a few weeks ago he's ok with us proceeding, he won't have a look at it. Addressing the rest of the comments now. |
|
@danpetry Ok |
|
I've made the changes, squashed, rebased, and pushed. |
|
Update: it was this PR, which essentially removed some newlib stubs, which stops it building: #8795 |
pkg/lua/Makefile
Outdated
| PKG_LICENSE=MIT | ||
| PKG_BUILDDIR ?= $(BINDIRBASE)/pkg/$(BOARD)/$(PKG_NAME) | ||
|
|
||
| #PKG_SOURCE_LOCAL=~/Sandbox/lua |
pkg/lua/Makefile.lua
Outdated
|
|
||
| # This redefines a lua prng function, avoiding the need for the _times system | ||
| # call, which RIOT doesn't provide | ||
| CFLAGS += -D'l_randomizePivot()=0' |
There was a problem hiding this comment.
I think it's a cleaner approach to remove this function with the patch
There was a problem hiding this comment.
The lua source is written in such a way that one is supposed to redefine things to change them. In this case, the definition of l_randomizePivot() is wrapped inside a #ifndef l_randomizePivot
There was a problem hiding this comment.
I'm for putting all the patches for this fixup together in one patch. eg
#define l_randomizePivot() 0
just above if !defined(l_randomizePivot)
sorts it out.
| - const char *fromname = luaL_checkstring(L, 1); | ||
| - const char *toname = luaL_checkstring(L, 2); | ||
| - return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); | ||
| + return luaL_error(L, "This function is not implemented in RIOT yet"); |
There was a problem hiding this comment.
This errors can be in a buffer, I don't think RIOT compiles with "string pooling".
There was a problem hiding this comment.
What's the advantage of putting the strings in buffers? String literals are all over the lua source code.
There was a problem hiding this comment.
I agree with juan re this... I don't actually think it makes that much difference though. I'm going to just change to buffers to avoid "bikeshedding"
There was a problem hiding this comment.
in theory saves some ROM bytes, but if's the whole source code it won't make a big difference
There was a problem hiding this comment.
ok, let's leave it like that then
|
ok, works as expected. Tested in samr21-xpro and native. ACK |
|
let's wait Murdock |
|
please squash, Travis is complaining |
|
@aabadie @kaspar030 @smlng Murdock has an issue with this PR that we can't reproduce locally. Any idea what is wrong? |
|
@miri64 I guess the murdock slave don't have the LUA-dev package? That's why: |
|
lauxlib.h is part of the pkg added as part of this PR. I suspect it's something to do with the way I've specified include paths. the two "debug commits" are there to get more info |
@smlng I tested the same application with one of the failing boards on my dev machine and installed nothing extra (granted this is no guarantee that something isn't missing, but I most certainly don't have liblua-dev installed, see below) and it worked. |
pkg/lua/Makefile.lua
Outdated
| # This builds for native using POSIX system calls and some extra libraries, and | ||
| # removes a compiler warning that warns against using tmpnam(). | ||
| ifeq ($(BOARD),native) | ||
| CFLAGS += -DLUA_USE_LINUX |
There was a problem hiding this comment.
minor, this should be indented with 2 spaces
There was a problem hiding this comment.
A frustrated Dan just came to my office. Can we stop asking for minor changes when a PR is already ACK'd, please? This is also something that scares away contributors, IMHO. If the PR is defective and the ACK was given wrongly, yes then asking for changes is definitely okay. But not like this! Yes code quality is important, but these kind of non-functional errors can also be fixed in post.
There was a problem hiding this comment.
I was pinged for a build issue, so I came, had a look at the package makefile, saw this and finally decided to comment this. I'm not requesting any change.
There was a problem hiding this comment.
So there's no need for being frustrated @danpetry.
There was a problem hiding this comment.
For me it raises wider issues about the efficiency of our review process, which is something that could be improved, I think.
There was a problem hiding this comment.
Yep, and I guess @miri64 hit the point: Reviewers should carefully work with authors to get things into a state at which code can be merged. For this reviews need structuring, streamlining, and pacing in the most constructive manner.
This means for instance that code-style review should be completed at some early stage, but also means to aid authors in case of troubles with build or similar.
I guess that's a generic discussion, but a very important one: I've seen many old open PRs where authors have been exhausted by being pushed around randomly without hitting anywhere.
There was a problem hiding this comment.
I mean, I was just going to make the changes, as it would have been quicker than having a discussion about it. But the impression I get is that the PRs building up is a real problem and the review process itself should a) allow for valuable support of contributors by maintainers to get it into a good shape, which tbh has formed the bulk of my time on this PR; but also b) try not to duplicate work and streamline the process otherwise. I think it would be worth talking about tomorrow, insofar as it's not just going over the same ground we've already talked about
There was a problem hiding this comment.
I was pinged for a build issue, so I came, had a look at the package makefile, saw this and finally decided to comment this. I'm not requesting any change.
Just to be clear, I appreciate that you only commented on this and did not make a change request.
I didn't know an ACK by one reviewer should stop others from pointing out errors or possible improvements (as minor as they might be) anyway.
I already pointed out, that it's totally fine if the PR is defective. Then a late comment is ok. But it certainly gives a weird impression if a person that wasn't involved in the discussion before suddenly comes in and also comments on minor, non-functional details, when the PR was already ACK'd (even if they were pinged in for a completely different issue).
There was a problem hiding this comment.
Yep, this should be on schedule tomorrow, also automated code style checking. I hear, tools are in place already.
There was a problem hiding this comment.
I think it's worth talking about this over voice call tomorrow... not sure this is a great format for this kind of discussion... :)
examples/lua/Makefile
Outdated
| USEMODULE += ps | ||
|
|
||
| ifneq ($(BOARD),native) | ||
| # This stack size is large enough to run Lua print() functions of |
There was a problem hiding this comment.
indent this block (2 spaces)
- download of v5.3.4 of Lua from git - building using RIOT build system - patched to remove the need for _times and _link to be provided to Lua via newlib.
- Lua print() function is only supported function - Lua script is parsed at compile time and run in example
|
ok, all green. Re-ACK. |
|
@jia200x then hit merge 🎉 |
|
|
GO! |
|
congratz @danpetry 🎉 🎉 |
|
Woop! |

Summary
This is an initial PR intended as a first step in development for adding Lua support. Lua is a lightweight scripting language suitable for embedded devices.
Requirements
The requirements of this PR are to achieve the download and build into RIOT of the Lua interpreter, and demonstrate its working status via a simple example.
Contribution details
Package
Lua v5.3.4 is cloned from github and built into RIOT, ready for its API to be accessed. Currently, only the Lua print() function is supported, which is adequate to demonstrate a working state of the interpreter.
Example
A .lua file called main.lua containing a simple "hello world" program, residing in the RIOT application's home directory, is converted to a char array at compile time, and stored in a header file called main.lua.h. This header file is then #included into an application, and the converted script is run in the program via a helper function called lua_run_script.
Issues/PRs references
#8434