Skip to content

Commit

Permalink
Make 'arg' semantics more Lua like
Browse files Browse the repository at this point in the history
  • Loading branch information
edubart committed Sep 4, 2020
1 parent ef8a031 commit 16f2816
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 35 deletions.
9 changes: 3 additions & 6 deletions lib/allocators/gc.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -531,15 +531,12 @@ function GC:_mark_statics()
]]
end

local function nelua_main(): cint <cimport,nodecl> end
local function nelua_main(argc: cint, argv: cstring*): cint <cimport,nodecl> end

global arg: span(cstring)

local function main(argc: cint, argv: cchar**): cint <entrypoint>
local function main(argc: cint, argv: cstring*): cint <entrypoint>
gc:start(&argc)
gc:_mark_statics()
arg = {data=argv, size=argc}
local ret: cint = nelua_main()
local ret: cint = nelua_main(argc, argv)
gc:stop()
return ret
end
Expand Down
40 changes: 22 additions & 18 deletions lib/arg.nelua
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
-- Include this file to get have the global "arg"
-- with your program command line arguments.

## if pragmas.nogc then

require 'span'

global arg: span(cstring)

local function nelua_main(): cint <cimport,nodecl> end

local function main(argc: cint, argv: cchar**): cint <entrypoint>
arg = {data=argv, size=argc}
return nelua_main()
-- filled with your program command line arguments.

require 'sequence'
require 'allocators.general'

-- Import argc and argv from C 'nelua_main'
local nelua_argc: cint <cimport, nodecl>
local nelua_argv: cstring[0]* <cimport, nodecl>

-- List of command line arguments.
-- The index 0 usually is filled with the program executable.
-- The arguments goes from 1 up to #arg (like in Lua).
global arg: sequence(stringview, GeneralAllocator)

do -- setup args
local narg: usize = (@usize)(nelua_argc-1)
arg:reserve(narg)
for i:usize=0,narg do
arg[i] = nelua_argv[i]
end
end

## else

require 'allocators.gc'

## end
-- NOTE: the memory of 'arg' is never freed,
-- but this is fine, is not a leak for global variables.
1 change: 0 additions & 1 deletion lib/string.nelua
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ function string._create(size: usize): string
self.data = (@byte[0]*)(string_allocator:alloc(size+1))
check(self.data ~= nilptr, 'string._create: out of memory')
self.data[size] = 0
--self.refs = 1
return self
end

Expand Down
6 changes: 3 additions & 3 deletions nelua/cgenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,7 @@ local function emit_main(ast, context)

if not context.entrypoint or context.hookmain then
mainemitter:inc_indent()
mainemitter:add_ln("int nelua_main() {")
mainemitter:add_ln("int nelua_main(int nelua_argc, char** nelua_argv) {")
mainemitter:add_traversal(ast)
if not context.rootscope.has_return then
-- main() must always return an integer
Expand All @@ -1411,7 +1411,7 @@ local function emit_main(ast, context)
mainemitter:add_ln("}")
mainemitter:dec_indent()

context:add_declaration('int nelua_main();\n')
context:add_declaration('int nelua_main(int nelua_argc, char** nelua_argv);\n')
else
mainemitter:inc_indent()
mainemitter:add_traversal(ast)
Expand All @@ -1421,7 +1421,7 @@ local function emit_main(ast, context)
if not context.entrypoint then
mainemitter:add_indent_ln('int main(int argc, char **argv) {')
mainemitter:inc_indent(2)
mainemitter:add_indent_ln('return nelua_main();')
mainemitter:add_indent_ln('return nelua_main(argc, argv);')
mainemitter:dec_indent(2)
mainemitter:add_indent_ln('}')
end
Expand Down
14 changes: 7 additions & 7 deletions spec/05-cgenerator_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@ describe("Nelua should parse and generate C", function()

it("empty file", function()
assert.generate_c("", [[
int nelua_main() {
int nelua_main(int nelua_argc, char** nelua_argv) {
return 0;
}]])
end)

it("return", function()
assert.generate_c("return", [[
int nelua_main() {
int nelua_main(int nelua_argc, char** nelua_argv) {
return 0;
}]])
assert.generate_c("return 1", [[
int nelua_main() {
int nelua_main(int nelua_argc, char** nelua_argv) {
return 1;
}]])
assert.generate_c("return 1")
Expand Down Expand Up @@ -2061,11 +2061,11 @@ end)

it("hook main", function()
assert.run_c([[
local function nelua_main(): cint <cimport,nodecl> end
local function main(argc: cint, argv: cchar**): cint <entrypoint>
local function nelua_main(argc: cint, nelua_argv: cstring*): cint <cimport,nodecl> end
local function main(argc: cint, argv: cstring*): cint <entrypoint>
print 'before'
local ret = nelua_main()
print('after')
local ret = nelua_main(argc, argv)
print 'after'
return ret
end
print 'inside'
Expand Down
10 changes: 10 additions & 0 deletions spec/08-runner_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,14 @@ it("debug options", function()
]]}, "scope resolved 1 symbols")
end)

it("program arguments", function()
assert.run({'--eval',[[
require 'arg'
assert(arg[1] == 'a')
assert(arg[2] == 'b')
assert(arg[3] == 'c')
assert(#arg == 3)
]], 'a', 'b', 'c'})
end)

end)

0 comments on commit 16f2816

Please sign in to comment.