diff options
author | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-02-03 15:59:29 +0100 |
---|---|---|
committer | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-02-03 16:16:23 +0100 |
commit | b618b835c74a8637e00ba1f4adf6b8884d360d43 (patch) | |
tree | 1fae753a1fd2d3cc1da33e2989bbbb1ce0a9f6aa | |
parent | 2cf246d68c5e658eb6c36a00ac35c7862a54e90e (diff) | |
download | fengari-b618b835c74a8637e00ba1f4adf6b8884d360d43.tar.gz fengari-b618b835c74a8637e00ba1f4adf6b8884d360d43.tar.bz2 fengari-b618b835c74a8637e00ba1f4adf6b8884d360d43.zip |
Table, metatable
-rw-r--r-- | luac.out | bin | 241 -> 190 bytes | |||
-rw-r--r-- | src/lobject.js | 64 | ||||
-rw-r--r-- | src/lvm.js | 2 | ||||
-rw-r--r-- | tests/lvm.js | 23 |
4 files changed, 88 insertions, 1 deletions
Binary files differ diff --git a/src/lobject.js b/src/lobject.js index 7efbef5..876a16f 100644 --- a/src/lobject.js +++ b/src/lobject.js @@ -18,11 +18,73 @@ class TValue { constructor(type, value) { this.type = type; this.value = value; + this.metatable = null; } } + +class TString extends TValue { + + constructor(string) { + super(CT.LUA_TSTRING, string); + } + +} + + +class Table extends TValue { + + constructor(array, hash) { + super(CT.LUA_TTABLE, { + array: array !== undefined ? array : [], + hash: new Map(hash) + }); + + this.usermetatable = null; + + this.metatable = { + __newindex: function (table, key) { + if (key instanceof TValue) { + // Those lua values are used by value, tables and functions by reference + if ([CT.TNUMBER, CT.TSTRING, CT.TSHRSTR, CT.TLNGSTR, CT.TNUMFLT, CT.TNUMINT].indexOf(key.type) > -1) { + key = key.value; + } + } + + if (typeof key === 'number') { + table.value.array[key] = value; + } else { + table.value.hash.set(key, value); + } + }, + + __index: function (table, key, value) { + if (key instanceof TValue) { + // Those lua values are used by value, tables and functions by reference + if ([CT.TNUMBER, CT.TSTRING, CT.TSHRSTR, CT.TLNGSTR, CT.TNUMFLT, CT.TNUMINT].indexOf(key.type) > -1) { + key = key.value; + } + } + + if (typeof key === 'number') { + return table.value.array[key]; + } else { + return table.value.hash.get(key); + } + }, + + __len: function (table) { + return t.value.array.length; + } + }; + } + +} + + module.exports = { LClosure: LClosure, - TValue: TValue + TValue: TValue, + Table: Table };
\ No newline at end of file @@ -5,6 +5,7 @@ const BytecodeParser = require("./lundump.js"); const OC = require('./lopcodes.js'); const CT = require('./lua.js').constant_types; const TValue = require('./lobject.js').TValue; +const Table = require('./lobject.js').Table; class LuaVM { @@ -104,6 +105,7 @@ class LuaVM { break; } case "OP_NEWTABLE": { + L.stack[ra] = new Table(); break; } case "OP_SELF": { diff --git a/tests/lvm.js b/tests/lvm.js index 6a4ed9f..1dbff2e 100644 --- a/tests/lvm.js +++ b/tests/lvm.js @@ -10,6 +10,7 @@ const DataView = require('buffer-dataview'); const BytecodeParser = require("../src/lundump.js"); const lua_State = require("../src/lstate.js").lua_State; const LuaVM = require("../src/lvm.js").LuaVM; +const Table = require("../src/lobject.js").Table; const toByteCode = function (luaCode) { var luaFile = tmp.fileSync(), @@ -134,4 +135,26 @@ test('Unary op, LOADBOOL', function (t) { [-5, true, -6], "Program output is correct" ); +}); + + +test('NEWTABLE', function (t) { + let luaCode = ` + local a = {} + return a + `, vm; + + t.plan(2); + + t.comment("Running following code: \n" + luaCode); + + t.doesNotThrow(function () { + vm = getVM(luaCode); + vm.execute(); + }, "Program executed without errors"); + + t.ok( + vm.L.stack[0] instanceof Table, + "Program output is correct" + ); });
\ No newline at end of file |