02. Hello world
This time, it is an introduction of Hello world using LuneScript.
lnsc command
Installing LuneScript installs the lnsc command.
Use the lnsc command as follows:
$ lnsc src.lns exe
where src.lns is the path of the script created with LuneScript. exe is an option for lnsc and means to run the specified script.
Hello world
Now let's run the traditional Hello world using LuneScript.
Create a file hello.lns with the following contents:
// @lnsFront: ok
print( "Hello world." );
And then run the following command:
$ lnsc hello.lns exe
This should print "Hello world".
If it's just this, it's not interesting or anything, so I'll continue the story a little more.
First, modify hello.lns slightly as follows:
// @lnsFront: ok
let txt = "world";
print( "Hello %s." ( txt ) );
The result of this script is also Hello world.
.
Now try running the following command:
$ lnsc hello.lns lua
You should see the following output:
--hello.lns
local _moduleObj = {}
local __mod__ = 'hello'
if not _lune then
_lune = {}
end
local txt = "world"
print( string.format( "Hello %s.", txt) )
return _moduleObj
This is the code converted from hello.lns to Lua.
It's kind of messy, but you can see that print( string.format( "Hello %s.", txt) )
is being output.
This shows that print( "Hello %s." ( txt ) )
written in LuneScript is expanded to print( string.format( "Hello %s.", txt) )
when transpiling to Lua.
Now run the following command:
$ lnsc hello.lns save
This created a hello.lua file. The content of the hello.lua file is the same as the Lua code we printed earlier.
Now run hello.lua with the following command:
$ lua5.3 hello.lua
Hello world.
should have been printed. Code transcompiled to Lua is Lua code that does not depend on LuneScript.
The first lnsc hello.lns exe
is a command that transcompiles a LuneScript script and executes it.
Next, lnsc hello.lns lua
is a command that transcompiles the LuneScript script and outputs the Lua code to the standard output.
The last lnsc hello.lns save
is a command that transcompiles the LuneScript script and saves the Lua code.
While using exe in this document, we will use the save command when checking the converted code.
Main function
You can handle command line options by defining a main function.
Please refer to the following.
Error message
LuneScript requires the delimiter ;
. An error will occur if ;
is not put at the end as shown below.
// @lnsFront: error
print( "Hello world." )
At this time, the following error message is output.
mini.lns:1:23: error: EOF
lua5.3: ./lune/base/Util.lua:176: has error
stack traceback:
[C]: in function 'error'
./lune/base/Util.lua:176: in function 'lune.base.Util.err'
./lune/base/TransUnit.lua:3465: in method 'error'
./lune/base/TransUnit.lua:3538: in method 'getToken'
./lune/base/TransUnit.lua:11641: in method 'analyzeStatement'
./lune/base/TransUnit.lua:3710: in method 'analyzeStatementList'
./lune/base/TransUnit.lua:5430: in function <./lune/base/TransUnit.lua:5393>
(...tail calls...)
./lune/base/front.lua:848: in method 'loadFileToLuaCode'
./lune/base/front.lua:914: in method 'loadFile'
./lune/base/front.lua:1066: in method 'loadModule'
./lune/base/front.lua:1709: in method 'exec'
./lune/base/front.lua:1744: in function 'lune.base.front.exec'
lune/base/base.lua:1: in main chunk
[C]: in ?
In this error output, the following messages indicate compilation errors.
mini.lns:1:23: error: EOF
This error indicates an unexpected EOF error at line 1, byte 23 of mini.lns.
Any other error output is an error internal to LuneScript. To suppress error output inside LuneScript, specify the following option (diag –nodebug).
$ lnsc hello.lns exe diag --nodebug
mini.lns:1:23: error: EOF
has error
The current version suppresses internal error output by default.
Specify the –debug option to enable internal error output.
runtime
It's a bit heavy for an article about Hello world, but I'll explain the runtime while looking at the output Lua code.
Code output from LuneScript to Lua will have the runtime necessary to make it work.
For example, converting the following LuneScript code to Lua:
// @lnsFront: ok
fn add( val:int! ):int {
return 10 + unwrap val default 0;
}
print( add( 1 ) ); // 11
print( add( nil ) ); // 10
It will be as follows.
--mini.lns
local _moduleObj = {}
local __mod__ = 'mini'
local _lune = {}
if _lune1 then
_lune = _lune1
end
function _lune.unwrap( val )
if val == nil then
__luneScript:error( 'unwrap val is nil' )
end
return val
end
function _lune.unwrapDefault( val, defval )
if val == nil then
return defval
end
return val
end
if not _lune1 then
_lune1 = _lune
end
local function add( val )
return 10 + _lune.unwrapDefault( val, 0)
end
print( add( 1 ) )
print( add( nil ) )
return _moduleObj
You can see that there is a decent amount of runtime output. By the way, above local function add( val )
is the runtime.
The amount of runtime inserted depends on the source LuneScript code content. When I print the full runtime, it's about 10KB in size.
This runtime is emitted in all converted Lua code.
If you are concerned about the runtime code being injected into your Lua code, you can specify -r
in the lnsc command line option to replace the runtime expansion with require
as follows:
--mini.lns
local _moduleObj = {}
local __mod__ = 'mini'
local _lune = require( "lune.base._lune1" )
if not _lune1 then
_lune1 = _lune
end
local function add( val )
return 10 + _lune.unwrapDefault( val, 0)
end
print( add( 1 ) )
print( add( nil ) )
return _moduleObj
However, in this case, lune.base._lune1 will be required, so it is necessary to pass through the load path so that lune.base._lune1 can be loaded.
where 1 in _lune1 indicates the runtime version.
If the Lua version of LuneScript is running in an environment, you don't have to worry about it, but if you run only the converted Lua code in another environment, you need to be careful.
By specifying the --runtime mod
option instead of the -r
option,
--mini.lns
local _moduleObj = {}
local __mod__ = 'mini'
local _lune = require( "mod" )
if not _lune1 then
_lune1 = _lune
end
local function add( val )
return 10 + _lune.unwrapDefault( val, 0)
end
print( add( 1 ) )
print( add( nil ) )
return _moduleObj
Instead of loading lune.base._lune as above, you can switch to the specified mod module.
As LuneScript versions change, the LuneScript runtime may also change. If Lua modules converted with different versions of LuneScript are mixed, using the default lune.base._lune may not work properly.
To avoid this, use the –runtime option to prevent an unintended version of the runtime from being loaded.
By specifying -mklunemod path
on the command line, a runtime module file will be generated in the specified path.
comment
The comments in LuneScript are //
and /* */
.
//
treats all lines as comments, and /* */
treats multiple lines as comments.
Next time, I will explain the values handled by LuneScript.