Giter Club home page Giter Club logo

lua.js's Introduction

Download

Click here to download precompiled versions of lua.js

To build these files yourself, use make in the root of the project, for example...

make CLOSURE_COMPILER=/path/to/closure/compiler.jar

(the CLOSURE_COMPILER variable only needs to be set if you're building the minified versions of the scripts)

Usage

You can use the lua2js tool to translate Lua code into Javascript.

./lua2js input.lua output.js

(node is required to run lua2js)

lua(.min).js must also be embedded on the same page as generated Javascript code. It contains all the functions necessary to keep the code working.

When a script generated by lua2js is run, the variable lua_script will be set to the global variable (_G) of the script. You can use this variable to interact with the script using the functions in lua.js/lua.as.

<script type="text/javascript" src="lua.min.js">
<script type="text/javascript" src="generated_code.js">
<script type="test/javascript">

  // this is equivalent to: init(1, 2, 3)
  lua_call(lua_tableget(lua_script, "init"), [1, 2, 3]);

  // this is equivalent to: local numActive = activeChars.count
  var numActive = lua_tableget(lua_tableget(lua_script, "activeChars"), "count")[0];
  
  // this is equivalent to: local distFromCenter = get_distance({x=1, y=2})
  var distFromCenter = lua_call(lua_tableget(lua_script, "get_distance"), [lua_newtable(null, "x", 1, "y", 2)])[0];

</script>

If you are dealing with multiple Lua scripts, modules should be used. They can be used normally for inter-Lua interactions, and the lua_module() function can be used by Javascript to retrieve modules.

lua2js also generates valid ActionScript code as well. Include lua.as (not lua.js) and the generated file to make it work.

You can also use the function lua_load() to parse Lua code in the browser. lua_load() is only available when the lua+parser.js version of lua.js is used. lua_load() will parse the script, and return a function that will execute the script when called and returning the global variable of that script.

Known issues

  • There are missing library functions and incomplete implementations of some functions. They should all be marked with TODO comments, or throw "Not supported" errors.
  • The global table does not currently support metatables.
  • Some Lua functions do not handle error conditions in the same way as standard Lua does.
  • Nested comments (e.g. --[=[ ]=]--) are not supported
  • __mode and __gc metamethods are not supported

Some implementation details

  • This project works by converting Lua code directly to ECMAscript. An alternative solution would be to emulate a Lua VM to better maintain compatibility, but this would be much slower.
  • Lua functions in ECMAscript always return arrays. This is to support the multiple return values that Lua uses.
  • Tables are normal objects with sub-objects (str, uints, etc) that seperate different kinds of keys from each other.
  • The uints key in an object can be an array or an object, depending on how it is used. If table.insert is used for example, then it will be converted to an array if it is not already one. To force uints to be one thing or another, use ensure_arraymode() or ensure_notarraymode() to require it be available in a certain form.
  • lua.js can be compiled using Closure Compiler's ADVANCED_OPTIMIZATIONS mode for a dramatically smaller total file size. This is more complicated than traditional minifying so you'll need to use variable maps or combine Lua-related scripts together.

lua.js's People

Contributors

mherkender avatar kyleconroy avatar ackalker avatar nomaed avatar jimbauwens avatar fireblend avatar ghoulsblade avatar

Stargazers

Toby Lai avatar Rinc avatar Hato avatar Ibrahim H. avatar Yemdust avatar neo451 avatar  avatar Julian Uy avatar  avatar Guillaume avatar  avatar Andre Kiste avatar  avatar Quentin Carver avatar Matthew avatar  avatar Eli Bird avatar netheround avatar Tianguang avatar  avatar Deepak Seeni avatar Alice Kile avatar Andy Lu avatar denghe avatar  avatar Vovkiv avatar  avatar wmingjian avatar Agony avatar Yanghui Lu avatar landon avatar NewYear avatar 王胜凯 avatar Jat avatar scus avatar Dom Ginger avatar nullcc avatar  avatar ryan avatar Jared Van Valkengoed avatar Mansib avatar  avatar Shaman avatar  avatar  avatar Gidoong Park avatar Adrien Bertrand avatar  avatar iRuxu avatar Cloorc avatar Sayyed Ali Kiaian Mousavy avatar it's leo avatar csxiaoyao avatar 筑基小修士 avatar David Colson avatar Chien Tran avatar Konstantin Yatsenko avatar Anastasis Germanidis avatar Jordan avatar  avatar  avatar Logan King (DarkComet) avatar Josef Leyva avatar ebigram avatar 文杰 avatar Thunderball avatar  avatar Micheal Wells avatar jaynlo avatar Jorge Gomez avatar LazuliKao avatar  avatar HIRAKI Satoru avatar David Konsumer avatar Kuba Wolanin avatar  avatar Wang Chao avatar Hoang Phan avatar Valerii Baleiko avatar 云起时 avatar  avatar yihong wu avatar Ly avatar Kyle Passarelli avatar Ricky Peng avatar  avatar SeniorPlayer avatar  avatar  avatar Ya Hui Liang avatar 贱人张 avatar AceLam avatar Anthony Ferrando avatar Dian avatar Lee zone avatar CoderM avatar  avatar Chad avatar jtianling avatar Joe DF avatar

Watchers

 avatar Alexander Gladysh avatar Paul Cuthbertson avatar Shinya Hayakawa avatar Gregor Steiner avatar Vytautas Povilaitis avatar tom zhou avatar 임창진(Callin) avatar Michael Wilson avatar Yuan Zhou avatar Jason Fisher avatar Kee-Yip Chan avatar Charles Stewart avatar Caio César Viel avatar David Yu avatar Steven Johnson avatar  avatar Zack Zhang avatar N Nullbuilt, version 20430 avatar  avatar Chii avatar Anthony Scalisi avatar  avatar skylark avatar Michael Anthony avatar ig avatar Frank Yonamine avatar 飞客 avatar  avatar  avatar  avatar Jat avatar jinminglee avatar  avatar  avatar Barry J. Burns (pluggo) avatar Marcos Cruz avatar vitor cortez avatar zhang avatar Zahoor Wang avatar Nico Raftis avatar LeeHo avatar  avatar  avatar

lua.js's Issues

Conflicts encountered

Hi. I've been trying to build the new parser (the prebuilt version is now out-of-date), and I'm running into a LOT of "Resolve R/R conflict (use first production declared in grammar.)
(2,21, 2,14) -> 2,14Resolve R/R conflict (use first production declared in grammar.)" sort of warnings.

These seem to be manifesting as errors along the lines of:

error during main.lua : Error: Parse error on line 26:
...s(tiles) do
TILES[#TILES + 1] = love.
----------------------^
Expecting '=', ',', got '[' :

Rearranging some lines will give me similar errors with other operators.

(From https://dl.dropbox.com/u/14510154/TESTS/take_the_fork/main.lua )

I tried to tease out any parser shenanigans but found myself rather swamped. 😄

I don't have much of an environment set up to run the makefile (I have Cygwin on some other machine...), but I ran it both through node and the web generator at http://zaach.github.com/jison/try/ with similar results.

Thanks in advance for any help or hints on this.

loadstring behaves differently

3 Issues:

  1. Arguments not passed to the top level function of a parsed chunk (via ...).
  2. Parsed chunk has it's own global environment.
  3. Lua understands calling function with func()() but javascript needs () around i.e. (func())()

From command line,

% lua -e 'var=123 loadstring"print(var,...)"(456)'

gives:

123     456

In chrome,

<script src=lua+parser.min.js></script>
<script>lua_load('var=123 loadstring"print(var,...)"(456)')();</script>
<script>lua_load('var=123 (loadstring"print(var,...)")(456)')();</script>
<script>lua_load('var=123 (loadstring"print(var)")(456)')();</script>

gives:

Uncaught Error: Parse error on line 1:
...print(var,...)"(456)
-----------------------^
Expecting '(', ':', '.', 'STRING', '{', '[', got 'EOF' lua+parser.min.js:127
Uncaught ReferenceError: varargs is not defined
undefined lua+parser.min.js:16

require should return the loaded module

I've noticed that when calling require from Lua.js, it doesn't return anything. The code inserted into each compiled Lua module is:

G.str['require'] = function (name) {
  lua_require(G, name);
};

Lua's reference manual states that require should return a value:

Once a loader is found, require calls the loader with a single argument, modname. If the loader returns any value, require assigns the returned value to package.loaded[modname]. If the loader returns no value and has not assigned any value to package.loaded[modname], then require assigns true to this entry. In any case, require returns the final value of package.loaded[modname].

Lua.js isn't doing the bolded part.

I may submit a patch for this if I can figure it out. This is part of my attempt to get the table method of defining a module to work in Lua.js (see #13).

while loop + break compilation bug

I encountered this bug while compiling to JS real-life Lua. This minimal code triggers it:

function a() end
while true do
    break
end

This gets compiled to:

G.str['a'] = (function () {
  var tmp;

  return [];
})
while (true) (function() {
  return;
})();

Notice the immediately-invoked function expression (IIFE) inside the while loop in the generated JS code. The Lua break statement is compiled into a return call but all it does is leave the function body, not the loop. So the loop, which should exit immediately, runs forever (and locks up the browser).

The Lua function declaration function a() end at the top is required to trigger the insertion of the IIFE and thus the bug.

table.copy sample doesn't work

This sample don't work, because of
local mt = getmetatable(t)
and
setmetatable(res,mt)
.

--recursive deep copy
function table.copy(t)
if type(t) ~= 'table' then return t end
local mt = getmetatable(t)
local res = {}
for k,v in pairs(t) do
if type(v) == 'table' then
v = table.copy(v)
end
res[k] = v
end
setmetatable(res,mt)
return res
end

Also this sample doesn't work.

function table.copy(object)
local lookup_table = {}
local function _copy(object)
if type(object) ~= "table" then
return object
elseif lookup_table[object] then
return lookup_table[object]
end
local new_table = {}
lookup_table[object] = new_table
for index, value in pairs(object) do
new_table[_copy(index)] = _copy(value)
end
return setmetatable(new_table, getmetatable(object))
end
return _copy(object)
end

Any hints?

Couple of fixes (node 10 & closure compiler), after 5 years of inactivity

Hi,

I found this repo while reading up about Lua and found it interesting.
I cloned it and tried building but there were two issues I came across:

  1. It no longer builds with the modern Node v10+
  2. Closure Compiler latest version URL changed and also the JAR filename itself in it

While I know that this is a dormant project and there's a chance that nobody will look at it, I still wanted to update the project with a couple of fixes I made, to be able to run this in late 2018 too.

There are 2 pull requests:

  • #42 - Compatibility for Node v10
  • #43 - Fix closure compiler build

I merged these two in my fork (https://github.com/nomaed/lua.js/tree/master) in case anyone wants to build it but these PRs won't be merged in here.

goto breaks the lua2js file

When using a goto in my Lua code, the lua2js tool dies with the following error message:

    throw new Error(str);
    ^

Error: Parse error on line 4778:
... == 0 then               goto stop           end       if id
----------------------^
Expecting '(', ':', '.', 'STRING', '{', '[', got 'NAME'
    at Parser.parseError (/home/runner/Monomod/luajs/lua2js:606:11)
    at Parser.parse (/home/runner/Monomod/luajs/lua2js:658:22)
    at Object.<anonymous> (/home/runner/Monomod/luajs/lua2js:1093:21)
    at Module._compile (node:internal/modules/cjs/loader:1101:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:79:12)
    at node:internal/main/run_main_module:17:47

I'll see if I can fix this by changing my Lua code to not use goto. (I didn't write the code; I'm just modifying it.)

string.format() and sprintf.js

Hello there !

I am currently adding the missing string functions and I use a fork of sprintf.js to power string.format().

My question is where put the code of sprintf in lualib.js or anywhere in the repo ?
Adding a minified version directly in lualib.js works well but I am not sure it's the best way to handle this ?
Adding a separate file in src/ and using require() in lualib should works too but I don't have a node.js environment to test this.
Or maybe include sprintf's code during the build of lua_paser ?

Also, the oiginal sprintf.js is under the 3 clauses BSD licence, I don't know how it could go along lua.js's licence ?

Thanks for your insights.

Semicolon should be allowed after return statement

The grammar doesn't allow having a semicolon after a return statement, although it should.

I suspect the fix is fairly straightforward but I'm very much unfamiliar with the grammar definition syntax so I have no idea how to allow an optional ";" token.

JSON

Is there a working JSON encoder/decoder for lua2js? They all seem to use string.find. Or is there another way to communicate from the converted code to the global JS environment?

next() function unsupported

Hello.

I tried to test if table is empty with "if next(tbl) == nil" but nex() function is unsupported. This is no a big deal, I can use pairs() to test for empty table.

Great library, thanks!

band(), rawequal(), maybe a recursion one

Some more! (I'm finally mostly stable, so this might be it for a while.)

bit.band() starts with 0, versus ~0 or whatever is appropriate (for arguments.length > 0 specifically, I believe?).

rawequal() is returning a non-array, too.

Maybe this was accounted for in the "local x = x" patch (I'm still running into build issues...), but if not:

local function foo ()
DoSomethingWith(foo)
end

The inner foo is getting globalized. (Easy enough to work around, so not urgent.)

-- Edit, sneaking one more in here:

In table.remove(), something like

if (pos == null) pos = table.length;

should go at the beginning.

Bug in operator <

for some reason, the following code doesn't work (parser error) with lua+parser.min.js & lua+parser.js:

    local px = obj1:getPx()
    if (px<self.targetPos[1]) then

replacing

px<self.targetPos[1]

with

self.targetPos[1]>px

works great.

if the second operator is a numeric constant, everything works great also.

Can't pipe input through lua2js

Just a thought, if lua2js listened on stdin and returned data on stdout, it could be used as part of a unix pipe; eg:

for i in `1.lua 2.lua 3.lua`; do
  cat $i | lua2js > "$i.js"
done

I'm working on a pull request which should implement this.

How are lua's requires working?

Hello,

This project is really great!

I'm using it in WebNCL, a web-based implementation of NCL presentation machine. NCL is a multimedia language and one of its features is support fo Lua scripts.

We'd had great success in using the lua.js in your project so far, but I'm facing a problem with requires. I really don't how they work.

some parser bugs and small additions

Hi all, awesome project, i use it to run games made in luascript for Love2D in a experimental webplayer :
https://github.com/ghoulsblade/love-webplayer

i found a few parser bugs, here's the current list, will track new ones in the readme on my project page.

parser bug : clouds demo : parse error in keypressed : >> love.filesystem.load("main.lua")() << workaround : >> (love.filesystem.load("main.lua"))() <<
parser bug : >> myvar = .5 << workaround >> myvar = 0.5 <<
parser bug : iyfct block comment in main.lua >> --[[ bla... ]]-- << workaround : remove comment (js regexp pre load?) or use single line comments
parser bug : iyfct " in table-save.lua >> ""..string.char(26).."" << workaround : >> '"'.."..string.char(26).."..'"' <<
parser bug : sinescroller >> local mytext = "bla" print(mytext:len()) << workaround >> print(string.len(mytext)) <<

i also added small bits to the lua-parser code that might be helpful to others :
see https://github.com/ghoulsblade/love-webplayer/blob/master/js/lua-parser.js all lines marked with ghoulsblade :

near beginning of parser :
"G = G || lua_newtable2(lua_core);\n" + // added 2012-03-16 by ghoulsblade for love-webplayer
since i use multiple lua files in the same state

"LuaBootStrap(G);\n"+ // added 2012-03-16 by ghoulsblade for love-webplayer
to register some custom functions in the api (love2d engine functionality)

if (arguments.length == 0) return [new Date().getTime()]; // added 2012-03-16 by ghoulsblade for love-webplayer
in os.time

keep up the good work =)

Add the travis.ci service hook

Thanks for accepting my testing pull requests. To enable Travis CI, you'll need to sign in with your Github account at travis-ci.org and enable testing for your repository.

assert(), rawset(), select()

Hi. A couple things that tripped me up.

In the parser, "assert" returns value, where it should return [value]. This was a bit puzzling for a while. 😄

According to the manual, "rawset" (and lua_rawset()) take "any value" for index, which would include nil. (This is sometimes handy.)

Not so much an issue, but I'm using this for "select"... so far so good:

    "select": function(n) {
        if (n === "#")
            return [arguments.length - 1];
        return slice(arguments, n);
    }

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.