GithubHelp home page GithubHelp logo

gamesys / moonshine Goto Github PK

View Code? Open in Web Editor NEW
502.0 502.0 35.0 4.9 MB

A lightweight Lua VM for the browser

Home Page: http://moonshinejs.org

License: MIT License

JavaScript 39.38% CSS 1.07% Lua 57.75% ActionScript 0.52% Shell 0.02% HTML 0.56% Roff 0.70%

moonshine's People

Contributors

cntkillme avatar fcr-- avatar jason-kempster avatar jkempster avatar paulcuth avatar pitcher99 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

moonshine's Issues

coroutine.wrap fails on resume

Uncaught TypeError: Cannot read property '_coroutineStack' of undefined moonshine.js:2428
shine.Coroutine._remove moonshine.js:2428
shine.Coroutine.resume moonshine.js:2508
shine.lib.coroutine.shine.Table.resume moonshine.js:3621
result

Minimal example:

local f = coroutine.wrap ( function(resume)
    window:setTimeout(resume,0)
    coroutine.yield()
    print("HERE")
end )
f ( f )

DOM INPUT value invalid

Hello,

When I attempt to get a value like "2" from a DOM INPUT box, it looks like a 2, displays like a 2 and prints like a 2, but it doesn't act like a 2.

x = window.document:createElement("INPUT")
x:setAttribute("value", "2")
window.document.body:appendChild(x) --optional
tbl = {"abc", "def"}
print(x.value)
print(tbl[x.value])
print(tbl[2])

Output:
2
nil
def

The code example prints x.value as a 2, but that same x.value is unable to be used as an index into the table. For anything I've done with INPUT that is just treated like a string, everything has worked perfectly. But now when I try to use this value like a number, it fails. Is this a misunderstanding on my part or a bug?

Thank you.

Mark

Support lua-TestMore Lua implementation test suite

http://fperrad.github.io/lua-TestMore/

This is a good and well-known test suite for Lua programming language implementations. (Note that the test suite is hiding behind Test::More port to Lua, don't be confused by that.)

I see that the Moonshine has its own tests, but it is not exactly the same thing. IMO, it will be very nice for the Moonshine to publish how well it passes lua-TestMore tests, as it will illustrate how well it conforms to the language standards.

Would be also cool to have a a coverage report — like this one:

http://fperrad.github.io/lua-TestMore/cover_lua515/src/index.html

Note that it is usually OK to have small deviations from other implementations — especially in gray or unspecified areas, like this:

https://github.com/fperrad/lua-TestMore/blob/master/test_lua51/014-fornum.t#L92

lua-TestMore author, @fperrad, in my experience, usually reacts quite well to the pull requests, feature requests etc., so I encourage you to cooperate with him in getting this thing working. I'm sure he'll be OK with adding the Moonshine as yet another "target" for his suite.

Pattern translator does not escape special characters correctly.

The following example highlights differences in output of pattern matching functions between C Lua and Moonshine.

print(string.gsub('ReturnRegionNotification', '\\u.?.?.?.?', 'XXX'))

C Lua returns:

ReturnRegionNotification    0

Moonshine returns:

RetXXXgionNotification  1

I believe there's some escaping of special chars missing from the translated pattern prior to construction of the RegExp object.

Debug and editor examples not running

Are Debug and / or Editor examples still active? Both demos do not work for me.
I also try to get 'How to debug locally' working, but without success.
Is anyone still busy with the LUA VM and the debugger and could give me some hints how to use them?

Thanks
Dieter

Quick question about lua.json bytecode format

Hi,

I found this moonshine project from the luaworkshop2013 videos (awesome presentation btw!). It's quickly becoming my favorite project over lua.vm.js since it's much lighter and better maintained by comparison.

Onto my question, what does the json file that contains the lua bytecode look like? I'm wondering if it's feasible to also have this post-processed and generated by lua instead of node.js.

Thanks!

Moonshine prevents load of d3.js

Hello.

d3.js publishes itself with this way:
if (typeof define === "function" && define.amd) this.d3 = d3, define(d3);
else if (typeof module === "object" && module.exports) module.exports = d3;
else this.d3 = d3;

I load d3.js later than moonshine and moonshine creates module.exports --> d3 will not be defined. Could module.exports be named differently inside moonsine?

Don't use `undefined`

Don't use undefined: some evil module could define it.

The proper equivalent is void 0

'use strict' and var shine = shine || {};

Howdy! I'm enjoying moonshine, thank you!

I see that several files use the idiom:

'use strict'
var shine = shine || {};

In Chrome, this results in:

var shine;           // implicitly undefined
shine = shine || {}; // ... therefore always {}

Thus, you can't use this technique to augment the same object (e.g. including moonshine.js and distillery.moonshine.js together).

This is further confused because in moonshine.js, 'use strict' is not the first line of code, so it actually has no effect. Things sometimes work as intended, depending on the exact mechanism used to include those two files.

I verified two possible ways of fixing this:

  1. Remove 'use strict'.
  2. Use var shine = this.shine = this.shine || {};

If you pursue the second case, I recommend moving 'use strict'; to the top of moonshine.js, to get the intended effect.

Cheers, and thanks again!

about lua coroutine

A error sample:
c = coroutine.create(function() print(1) coroutine.yield() print(2) end)
coroutine.resume(c)
coroutine.resume(c)

ReferenceError: e is not defined

I'm afraid there is a bug in distil.js. I can't know what's the real reason that use moonshine to distil my lua file unsuccessfully like this:

D:\lua>moonshine distil hello.lua

C:\Users\w00222107\AppData\Roaming\npm\node_modules\moonshine\bin\commands\distil.js:154
if (errPart[1] != 'luac') throw e;
^
ReferenceError: e is not defined
at C:\Users\w00222107\AppData\Roaming\npm\node_modules\moonshine\bin\commands\distil.js:154:36
at ChildProcess.exithandler (child_process.js:641:7)
at ChildProcess.EventEmitter.emit (events.js:98:17)
at maybeClose (child_process.js:743:16)
at Socket. (child_process.js:956:11)
at Socket.EventEmitter.emit (events.js:95:17)
at Pipe.close (net.js:466:12)

lua distillery

It seems kind of odd that the distillery script is only available in javascript; is there no port to lua to integrate this into, for example, openresty? If no, will there ever be one?

Passing JSON Directly Yields Error

I'm trying to use Moonshine in react-native and as such the only way I think I can get this to work is by passing the distilled JSON directly to the VM. However when I try this I get a strange error:

attempt to perform arithmetic on a string value
    @src/lua/test.lua [(compiled code):2]

My code is pretty straight forward:

var luaVm = new shine.VM({
    global: 42,
    speak: console.log,
});
var luaSource = require('../../test.lua.json');
luaVm.load(luaSource);

The distilled file is:

{"sourceName":"@src/lua/test.lua","lineDefined":0,"lastLineDefined":0,"upvalueCount":0,"paramCount":0,"is_vararg":2,"maxStackSize":3,"instructions":[1,0,0,0,5,1,1,0,5,2,2,0,12,2,2,259,12,2,2,0,12,2,2,260,28,1,2,1,30,0,1,0],"constants":["dog","speak","global",": "," says woof!"],"functions":[],"linePositions":[1,2,2,2,2,2,2,2],"locals":[{"varname":"animal","startpc":1,"endpc":7}],"upvalues":[],"sourcePath":"src/lua/test.lua"}

I couldn't find any documentation about this use case but while reading the source code this seems like the way to do this.

Thank you.

Incompatibility with node 12

$ moonshine distil api.lua
fs.js:151
    throw new ERR_INVALID_CALLBACK(cb);
    ^

TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined
    at makeCallback (fs.js:151:11)
    at Object.unlink (fs.js:1041:14)
    at C:\Users\buds\AppData\Roaming\npm\node_modules\moonshine\bin\commands\distil.js:170:6
    at ChildProcess.exithandler (child_process.js:294:7)
    at ChildProcess.emit (events.js:311:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5) {
  code: 'ERR_INVALID_CALLBACK'
}

This is fixed by replacing in bin\commands\distil.js line 170

fs.unlink(luacFilename);

with

fs.unlinkSync(luacFilename);

Calling JavaScript instance functions from Lua does not respect the JS function's scope

When calling an instance of a JS prototype's function from Lua, this always refers to Window when it should instead refer to the instance.

Consider this code:

var employee = function(name) {
  this.name = name;
}

employee.prototype.say_name = function(){
  console.log(this.name);
}

var fred = new employee("fred");

When calling fred.say_name(); from JS, this refers to the fred object.
When calling fred.say_name() from Lua, this refers to Window.

I believe this to be because of this line setting the first argument to apply to be null. It's not obvious to me how to fix this because the instance does not seem to be in scope when executing the instruction.

Perhaps the caller needs to be closed over when creating the instruction? I'm a bit out of my depth here.

I've created a small branch to showcase this issue in action if it helps: https://github.com/TannerRogalsky/moonshine-love2d/tree/prototype_scope_bug

moonshinejs.org/editor/ does not compile, CORS issue with distillery.moonshinejs.org

Steps:

Status shows: "Compliling..."
The POST to http://distrillery.moonshinejs.org returns status 503
Browser console message:

Failed to load http://distillery.moonshinejs.org/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://moonshinejs.org' is therefore not allowed access. The response had HTTP status code 503.

MDN Access-Control-Allow-Origin

Request headers:

POST / HTTP/1.1
Host: distillery.moonshinejs.org
Connection: keep-alive
Content-Length: 1640
Origin: http://moonshinejs.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarynBWgpDsoWuwgrpfv
Accept: */*
DNT: 1
Referer: http://moonshinejs.org/editor/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

Response Headers:

HTTP/1.1 503 Service Unavailable
Connection: keep-alive
Server: Cowboy
Date: Tue, 19 Dec 2017 15:15:58 GMT
Content-Length: 506
Content-Type: text/html; charset=utf-8
Cache-Control: no-cache, no-store

curl:

curl 'http://distillery.moonshinejs.org/' -H 'Origin: http://moonshinejs.org' -H 'Accept-Encoding: gzip, deflate' -H 'Accept-Language: en-US,en;q=0.9' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36' -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundarynBWgpDsoWuwgrpfv' -H 'Accept: */*' -H 'Referer: http://moonshinejs.org/editor/' -H 'Connection: keep-alive' -H 'DNT: 1' --data-binary $'------WebKitFormBoundarynBWgpDsoWuwgrpfv\r\nContent-Disposition: form-data; name="lua"\r\n\r\n\r\n \r\n-- A do block provides scoping\r\ndo\r\n    local foo = \'Hello\'\r\n    print(\'Inside the do block, foo is: \', foo)\r\nend\r\n\r\nprint(\'Outside the do block, foo is: \', foo)\r\n\r\n\r\n\r\n\r\n-- if then else\r\n\r\nlocal kittens = 1\r\n\r\nif kittens > 0 then print(\'You have kitten(s)\') end\r\n\r\nif kittens == 0 then \r\n    print(\'You have no kittens\') \r\nelseif kittens == 1 then \r\n    print(\'You have a kitten\') \r\nelse\r\n    print(\'You have many kittens\') \r\nend\r\n\r\n\r\n\r\n-- while\r\n\r\nlocal kittens = { \'Mr Tibbs\', \'Tufty\', \'Kipper\' }\r\n\r\nwhile #kittens > 0 do\r\n    local kitten = table.remove(kittens, 1)\r\n    print(kitten)\r\nend\r\n\r\n\r\n\r\n\r\n-- repeat until\r\n\r\nlocal kittens = { \'Mr Tibbs\', \'Tufty\', \'Kipper\' }\r\n\r\nrepeat \r\n    local kitten = table.remove(kittens, 1)\r\n    print(kitten)\r\nuntil #kittens == 0 \r\n\r\n\r\n\r\n\r\n-- break\r\n\r\nlocal kittens = { \'Mr Tibbs\', \'Tufty\', \'Kipper\' }\r\n\r\nwhile #kittens > 0 do\r\n    local kitten = table.remove(kittens, 1)\r\n    if kitten == \'Tufty\' then break end\r\n    print(kitten)\r\nend\r\n\r\n\r\n\r\n\r\n-- numeric for\r\n\r\nfor i = 1, 10 do            -- count up\r\n    print(i..\' banana\')\r\nend\r\n\r\nfor i = 10, 1, -1 do        -- count down\r\n    print(i..\' green bottles\')\r\nend\r\n\r\nprint(\'i is scoped to the for loop: \', i)\r\n\r\n\r\n\r\n\r\n-- generic for\r\n\r\nlocal random = { \'boot\', foo = \'bar\', 22 }\r\n\r\nfor key, val in ipairs(random) do   -- ipairs iterates over numerical indexed elements only.\r\n    print(key, val) \r\nend\r\n\r\nfor key, val in pairs(random) do   -- pairs iterates over all elements.\r\n    print(key, val) \r\nend\r\n\r\n\r\n\r\n\r\n------WebKitFormBoundarynBWgpDsoWuwgrpfv--\r\n' --compressed

curl response:

<!DOCTYPE html>
	<html>
	  <head>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<meta charset="utf-8">
		<title>Application Error</title>
		<style media="screen">
		  html,body,iframe {
			margin: 0;
			padding: 0;
		  }
		  html,body {
			height: 100%;
			overflow: hidden;
		  }
		  iframe {
			width: 100%;
			height: 100%;
			border: 0;
		  }
		</style>
	  </head>
	  <body>
		<iframe src="//www.herokucdn.com/error-pages/application-error.html"></iframe>
	  </body>
	</html>

Strange failure with lua 5.2

distilling when luac is from lua 5.2 results in an error from an odd place:

/home/daurnimator/src/moonshine/distillery/distillery.moonshine.js:79
                        if (err) throw err;
                                       ^
Error: Path must be a string without null bytes.
    at nullCheck (fs.js:119:14)
    at Object.fs.open (fs.js:417:8)
    at Object.fs.readFile (fs.js:206:6)
    at Parser.parse (/home/daurnimator/src/moonshine/distillery/distillery.moonshine.js:78:6)
    at /home/daurnimator/src/moonshine/bin/commands/distil.js:178:10
    at /home/daurnimator/src/moonshine/bin/commands/distil.js:161:3
    at ChildProcess.exithandler (child_process.js:635:7)
    at ChildProcess.EventEmitter.emit (events.js:98:17)
    at maybeClose (child_process.js:735:16)
    at Process.ChildProcess._handle.onexit (child_process.js:802:5)

Small bugs when parsing code

Hello. Great project!

http://tylerneylon.com/a/learn-lua/

u = {['@!#'] = 'qbert', [{}] = 1729, [6.28] = 'tau'}
print(u[6.28]) -- prints "tau"

I had to comment 2 parts to get this file to run:
u = {['@!#'] = 'qbert', [6.28] = 'tau'} -- , [{}] = 1729
-- print(u[6.28]) -- prints "tau"

Also os.clock() returns nil. I was able to get timing to wor with this js:
var timer = function () {
var d=new Date();
return d.getTime();
}

can I use moonshine with node.js?

In your guide page you showed use shell command to compile lua code to a json-for-bytecode file, like this:

moonshine distil hello.lua

I am wondering is there any API I could use to do the same thing in node.js ? maybe something like:

var shine = require('vm/moonshine.js');
var jsonForByteCode = shine.distil("print 'hello'");

Thanks.

'luac' is not recognized as an internal or external command

After downloading and building Lua 5.1, I ended up with the files lua.exe, and lua51.dll. Then I tried to run moonshine distil on a simple hello.lua file, which ran into an error, saying that luac is not recognized as an internal command. The thrown error comes from ./moonshine/bin/commands/distil.js at line 163. I guess that's normal considering I didn't get any luac.exe file after building Lua 5.1.

But what I noticed is that I do get the luac.exe file when building the latest version of Lua, 5.3.5, but when I try to run moonshine with that Lua version, it says that only 5.1 is supported by moonshine.
So my question is how can I get this luac.exe file in order to execute luac commands?

javascript objects as userdata

Native javascript objects could be represented as userdata
This requires userdata behaviour to actually be respected (in regards to metatables and more)

A few changes I've started making to facilitate this:

diff --git a/vm/moonshine.js b/vm/moonshine.js
index 1b2fc37..94f61ca 100644
--- a/vm/moonshine.js
+++ b/vm/moonshine.js
@@ -1380,6 +1380,18 @@ shine.Closure.prototype.dispose = function (force) {
        } else if (typeof b == 'string' && shine.lib.string[c]) {
            result = shine.lib.string[c];

+       } else if (b.__shine) {
+           var mt, __index;
+           if ( (mt = b.__shine.metatable) && (__index = mt.getMember("__index"))) {
+               if (__index instanceof shine.Table) {
+                   result = __index.getMember(c);
+               } else {
+                   result = __index(b, c);
+               }
+           } else {
+               throw new shine.Error('Attempt to index a userdata value');
+           }
+
        } else {
            result = b[c];
        }
@@ -3517,12 +3529,12 @@ var shine = shine || {};
        tostring: function (e) {
            var mt, mm;

-           if (e !== undefined && e instanceof shine.Table && (mt = e.__shine.metatable) && (mm = mt.getMember('__tostring'))) return mm.call(mm, e);
+           if (e !== undefined && typeof e == "object" && (mt = e.__shine.metatable) && (mm = mt.getMember('__tostring'))) return mm.call(mm, e);

            if (e instanceof shine.Table || e instanceof shine.Function) return e.toString();
            if (typeof e == 'function') return 'function: [host code]';

-           return shine.utils.coerce(e, 'string') || 'userdata';
+           return shine.utils.coerce(e, 'string');
        },

And a better DOMAPI with consistent metatables

diff --git a/extensions/DOMAPI/DOMAPI.moonshine.js b/extensions/DOMAPI/DOMAPI.moonshine.js
index 1c5867b..b2304ff 100644
--- a/extensions/DOMAPI/DOMAPI.moonshine.js
+++ b/extensions/DOMAPI/DOMAPI.moonshine.js
@@ -21,127 +21,101 @@
  */

 (function (shine) {
-
-   function jsToLua (obj) {
-       var t, mt;
-
-       mt = new shine.Table({
-
+   var object_mt = new shine.Table({
        __index: function (t, key) {
-               var property = obj[key];
-
-               // Bind methods to object and convert args and return values
-               if (typeof property == 'function' || (property && property.prototype && typeof property.prototype.constructor == 'function')) { // KLUDGE: Safari reports native constructors as objects, not functions :-s
-                   var f = function () {
-                       var args = convertArguments(arguments, luaToJS),
-                           retval = property.apply(args.shift(), args);
-
-                       if (typeof retval == 'object') return jsToLua(retval);
-                       return [retval];
-                   };
-
-                   // Add a new method for instantiating classes
-                   f.new = function () { 
-                       var args = convertArguments(arguments, luaToJS),
-                           argStr,
-                           obj,
-                           i, l;
-
-                       argStr = (l = args.length)? 'args[0]' : '';
-                       for (i = 1; i < l; i++) argStr += ',args[' + i + ']';
-
-                       obj = eval('new property(' + argStr + ')');
-                       return jsToLua(obj);
-                   };
-
-                   return f;
-               }
-
-               // Recurse down properties
-               if (typeof property == 'object') return jsToLua(property);
-
-               // Return primatives as is
-               return property;
+           return jsToLua(t.__native[key]);
        },
-
-
        __newindex: function (t, key, val) {
-               obj[key] = luaToJS(val);
+           t.__native[key] = luaToJS(val);
+       },
+       __tostring: function (t) {
+           console.log(t,t.__native)
+           return "userdata: " + toString(t.__native);
        }
-
    });

-       mt.source = obj;
-
-
-       t = new shine.Table();
-       shine.gc.incrRef(t);
+   var function_mt = new shine.Table({
+       __call: function(t) {
+           var args = Array.prototype.slice.call(arguments,1).map(luaToJS);
+           return [jsToLua(t.__native.apply(null, args))];
+       },
+       __new: function(t) {
+           var args = Array.prototype.slice.call(arguments,1).map(luaToJS);
+           return [jsToLua(new t._constructor(args))];
+       },
+       __index: object_mt.__index,
+       __newindex: object_mt.__newindex,
+       __tostring: object_mt.__tostring
+   });

-       // Return proxy table
-       return shine.lib.setmetatable(t, mt);
+   function jsToLua (obj) {
+       switch (typeof obj) {
+           case 'undefined':
+           case 'number':
+           case 'boolean':
+           case 'string':
+               return obj;
+           case 'object':
+               if (obj instanceof Number ||
+                   obj instanceof Boolean ||
+                   obj instanceof String) {
+                   return obj.valueOf();
                }
+               return {
+                   __shine: {
+                       metatable: object_mt
+                   },
+                   __native: obj
+               };
+           case 'function':
+               function constructor(args) {
+                   return obj.apply(this, args);
+               }
+               constructor.prototype = obj.prototype;

-
-
+               return {
+                   __shine: {
+                       metatable: function_mt
+                   },
+                   __native: obj,
+                   __constructor: constructor
+               };
+           default:
+               throw "Unable to convert to js value to lua";
+       }
+   }

    function luaToJS (val) {
-       var mt;
-
-       // Make shine.Functions invokable
+       switch (typeof val) {
+           case 'undefined':
+           case 'number':
+           case 'boolean':
+           case 'string':
+           case 'function':
+               return val;
+           case 'object':
                if (val instanceof shine.Function) {
                    return function () {
-               return jsToLua(val.apply(undefined, convertArguments(arguments, jsToLua)));
+                       var args = Array.prototype.slice.call(arguments,0).map(jsToLua);
+                       return jsToLua(val.apply(void 0, args));
                    };
+               } else if (val instanceof shine.Table) {
+                   // TODO: reverse proxy
+                   return shine.utils.toObject(val);
+               } else {
+                   switch(val.__shine) {
+                       case function_mt:
+                       case object_mt:
+                           return val.__native;
+                       default:
+                           throw "Unable to convert userdata object";
                    }
-
-       if (val instanceof shine.Table) {
-           // If object has been wrapped by jsToLua(), use original object instead
-           if ((mt = shine.lib.getmetatable(val)) && mt.source) return mt.source;
-
-           // Else iterate over table
-           var isArr = shine.lib.table.getn(val) > 0,
-               result = shine.gc['create' + (isArr? 'Array' : 'Object')](),
-               numValues = val.__shine.numValues,
-               i,
-               l = numValues.length;
-
-           for (i = 1; i < l; i++) {
-               result[i - 1] = ((numValues[i] || shine.EMPTY_OBJ) instanceof shine.Table)? luaToJS(numValues[i]) : numValues[i];
                }
-
-           for (i in val) {
-               if (val.hasOwnProperty(i) && !(i in shine.Table.prototype) && i !== '__shine') {
-                   result[i] = ((val[i] || shine.EMPTY_OBJ) instanceof shine.Table)? luaToJS(val[i]) : val[i];
+           default:
+               throw "How did this get in the lua vm?"
        }
    }

-           return result;
-       }
-
-
-       // Convert tables to objects
-       if (typeof val == 'object') return shine.utils.toObject(val);
-
-       // return primatives as is
-       return val;
-   }
-
-
-
-
-   function convertArguments (arguments, translateFunc) {
-       var args = [], i, l;
-
-       for (i = 0, l = arguments.length; i < l; i++) {
-           args.push(translateFunc(arguments[i]));
-       }
-
-       return args;
-   };
-
-
-
-
    // Create wrapped window API
    shine.DOMAPI = { window: jsToLua(window) };

String.fromCharCode()

Hello,

I am trying to use String.fromCharCode(keyCode) from the DOMAPI. The following code seems to work:

local s = window.String.new("abc")
print(s:charCodeAt(1))

98

But String.fromCharCode() is a static global and my attempts at calling this function have all failed:
window.String.fromCharCode(65) -> Attempt to call non-function
window.String:fromCharCode(65) -> Attempt to call non-function
window.extract() String.fromCharCode(65) -> Attempt to call non-function
window.extract() String:fromCharCode(65) -> Attempt to call non-function
window.String.fromCharCode(window.String, 65) -> Attempt to call non-function

Can you help me out?

Thank you.

How to convert LUA Table to javascript object

My question is basically in the title.

Is there a way to convert a table passed in from LUA to native JS?

{key:value} objects seem to work alright, but [value, value, value] arrays do not.

Here's an example:

Lua:

{obj = {key = "value"},  str = "string", arr = {1,2,3} }

Calling an environment function..

JS:

{
  "obj": {
    "__shine": {
      "type": "table",
      "index": 55,
      "keys": [],
      "values": [],
      "numValues": [
        null
      ],
      "refCount": 1
    },
    "key": "value"
  },
  "str": "string",
  "arr": {
    "__shine": {
      "type": "table",
      "index": 56,
      "keys": [],
      "values": [],
      "numValues": [
        null,
        1,
        2,
        3
      ],
      "refCount": 2
    }
  }
}

What I wanted:

{
  "obj": {
    "key": "value"
  },
  "str": "string",
  "arr": [
    1,
    2,
    3
  ]
}

This would obviously need to be done in a recursive manner.

Does a functionality like this exist already?

Lua 5.2 support?

Do you have any plans to add support for Lua 5.2? If not, how difficult do you estimate that it would be to fork and add support to the existing code? I'm not really familiar with the differences between the two VMs.

Issue with ipairs() and tables with "holes"

ipairs() appears to happily iterate over holes in numerical tables, whereas it should stop at the first nil value.

For example the following code should output nothing:

t = {nil, 1, 2} 

for i, v in ipairs(t) do 
    print (i, v)
end

lib-date tests assume local timezone is UTC

lib-date.lua does a full test of os.date using multiple timestamps, exercising both "local" and "utc" versions of the format string. When the test is run in non-UTC timezones, many of the tests fail.

One alternative would be to adjust the input timestamp by local timezone's utc-offset, before passing it to the local format tests.

Iterating over a hash with pairs does not return keys that are numbers that are not positive integers

ipairs works properly but the results of pairs are not consistent with the reference implementation.

When running the following code:

test = {
  [0] = "zero",
  [1] = "one",
  [2] = "two",
  [4] = "four",
  [-1] = "negative",
  foo = "string",
  [0.5] = "half"
}
print("pairs")
for k,v in pairs(test) do
  print(k,v)
end
print("ipairs")
for i,v in ipairs(test) do
  print(i,v)
end

Through the Lua interpreter we get:

pairs
0   zero
1   one
2   two
4   four
-1  negative
foo string
0.5 half
ipairs
1   one
2   two

Through Moonshine we get:

pairs
1 one
2 two
4 four
foo string
ipairs
1 one
2 two 

string.sub broken for j=0 or j<i

string.sub('abcde', 4, 1) should be an empty string, not 'bc'.
string.sub('abcde', 3, 0) should be an empty string, not 'cde'.

Support LuaSocket 2.0.x

It would be super-useful to support LuaSocket API.
Internally, the calls could be translated to WebRTC or other natively-supported networking library.

Incorrect behaviour when dividing by zero.

I started this bug report because I thought xpcall() wasn't working, but everything is actually working perfectly. Since I don't see how to delete a bug once it's opened, so I'll leave this code as an example of how to figure out if a browser supports touch() events. If myfunction() works, then the device supports touch().

function myfunction()
window.document:createEvent("TouchEvent")
end

function errHandler()
print("err")
end

local status = xpcall(myfunction, errHandler)
print(status)

DOM element can't call function?

Hello,
I am using your fabulous vm with the DOM extension. Can you tell me if this code should work or what I'm doing wrong? I am trying to create web page formatting with just Lua commands.

 para = window.document:createElement("p") 
  para:createTextNode("abc") 

Unfortunately, I get this error:

Uncaught Moonshine run-time error: Attempt to call non-function
@dv.lua [./null:8]

Thank you.

Performance

Some tests in OSX 10.9, using http://tylerneylon.com/a/learn-lua/.

100 loops of learn.lua is Safari with print redirecrted to empty function takes 207 ms, 483 loops/sec. Firefox: 166 loops/sec. Chrome mac: 263 loops/sec.

Luajit runs in 13.362 ms, 7483 loops/sec.

Lua 5.1 runs in 22.293 ms, 4485 loops/sec.

Support for Lua modules

Hi there, I want to use moonshine in a project and I need to know if I import a Lua module within a Lua script, will it work?

Add noConflict function.

moonshine.noConflict() should restore previous value of the moonshine global variable and return a reference to the value it assigned.

distil can't handle spaces in filename

When supplying a directory, distil will choke on any files in that directory that contain spaces. So for example running "moonshine distil -d target lua" where lua has a file "background tests.lua" will result in the error:

$ moonshine distil -d target lua
/usr/local/lib/node_modules/moonshine/bin/commands/distil.js:164
        if (errPart[1] != 'luac') throw err;
                                  ^

Error: Command failed: /bin/sh -c luac -o lua/backgrounds test.lua.moonshine.luac lua/backgrounds test.lua
luac: cannot open test.lua.moonshine.luac: No such file or directory

Google Chrome TypeError

Chrome just updated their browser to Version 37.0.2062.103 m and Moonshine stopped working with this error:
Uncaught Moonshine run-time error: Error in host call: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
at shine.Table.__index (DOMAPI.moonshine.js:49:27)

                                   // Add static methods, etc
                if (Object.getOwnPropertyNames) {
                    children = Object.getOwnPropertyNames(property);

                    for (i = 0; child = children[i]; i++) {
                        f[child] = property[child];
                    }  <-- Error here --
                }

Internet Explorer is still working.

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.