From 924569156554770323a9886f366d2f50256d702e Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 13:36:09 +0000 Subject: [PATCH 01/11] Fixes self-executing anonymous function syntax for better support. --- src/build-tools/common/code-generator.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/build-tools/common/code-generator.js b/src/build-tools/common/code-generator.js index 0a89a3f..8abb2c1 100644 --- a/src/build-tools/common/code-generator.js +++ b/src/build-tools/common/code-generator.js @@ -136,7 +136,7 @@ const GENERATORS = { DoStatement(node, outerScope) { let { scope, scopeDef } = extendScope(outerScope); let body = this.Chunk(node, scope); - return `()=>{\n${scopeDef}\n${body}\n}()`; + return `(()=>{\n${scopeDef}\n${body}\n})()`; }, @@ -473,13 +473,13 @@ export function getRuntimeInit() { init += 'let Tget, Tset, Tins, $get, $set, $setLocal, __star_shift;'; - init += '()=>{'; + init += '(()=>{'; init += 'let call = Function.prototype.call, bind = call.bind.bind(call), Tproto = __star_T.prototype, $proto = __star.globalScope.constructor.prototype;'; init += 'Tget = bind(Tproto.get), Tset = bind(Tproto.set), Tins = bind(Tproto.insert);'; init += '$get = bind($proto.get), $set = bind($proto.set), $setLocal = bind($proto.setLocal);'; init += '__star_shift = bind(Array.prototype.shift);'; - init += '}();' + init += '})();' return init; } From 1b5f425da468e8b50d417d57134b99f04504e53b Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 13:37:18 +0000 Subject: [PATCH 02/11] Fixes issue with return values when invoking functions in logical expressions. --- src/build-tools/common/code-generator.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/build-tools/common/code-generator.js b/src/build-tools/common/code-generator.js index 8abb2c1..65a6db7 100644 --- a/src/build-tools/common/code-generator.js +++ b/src/build-tools/common/code-generator.js @@ -295,6 +295,14 @@ const GENERATORS = { let right = scoped(node.right, scope); let operator = node.operator; + if (isCallExpression(node.left)) { + left += '[0]'; + } + + if (isCallExpression(node.right)) { + right += '[0]'; + } + if (operator === 'and') { return `(!__star.op.bool(${left})?${left}:${right})` From 5e5acee31627556589afda7554187583a811d919 Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 13:39:53 +0000 Subject: [PATCH 03/11] Fixes support for multiline string literals. Also fixes octal escape codes. --- src/build-tools/common/code-generator.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/build-tools/common/code-generator.js b/src/build-tools/common/code-generator.js index 65a6db7..0edfd5b 100644 --- a/src/build-tools/common/code-generator.js +++ b/src/build-tools/common/code-generator.js @@ -363,8 +363,12 @@ const GENERATORS = { StringLiteral(node) { - let escaped = node.value.replace(/["']/g, '\\$&').replace(/\n/g, '\\n'); - return `'${escaped}'`; + const raw = node.raw.replace(/\\(\d+)/g, (_, oct) => `\\x0${parseInt(oct, 8).toString(16)}`); + if (/^\[\[[^]*]$/m.test(raw)) { + return `\`${raw.substr(2, raw.length - 4)}\``; + } else { + return raw; + } }, From b63c24b3d068a7f3bf9bc7f6daaf511493b298dc Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 13:40:25 +0000 Subject: [PATCH 04/11] Adds more tests for logical expressions. --- test/lua/operators.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/lua/operators.lua b/test/lua/operators.lua index e2d575e..87d2fd5 100644 --- a/test/lua/operators.lua +++ b/test/lua/operators.lua @@ -152,6 +152,22 @@ assertTrue (not (f or f), 'Or operator should return false if both operands are assertEqual(t and 0 or 1, 0, 'Ternary logic should return the correct result[1]') assertEqual(f and 0 or 1, 1, 'Ternary logic should return the correct result[2]') +function f(x) + return x +end + +assertEqual (f('moo') or false, 'moo', 'Or operator should work with function calls as left operand (+ve)') +assertEqual (f(false) or false, false, 'Or operator should work with function calls as left operand (-ve)') +assertEqual (false or f('moo'), 'moo', 'Or operator should work with function calls as right operand (+ve)') +assertEqual (false or f(false), false, 'Or operator should work with function calls as right operand (-ve)') +assertEqual (f(false) or f('moo'), 'moo', 'Or operator should work with function calls as both operands') + +assertEqual (f('moo') and 'baa', 'baa', 'And operator should work with function calls as left operand (+ve)') +assertEqual (f(false) and true, false, 'And operator should work with function calls as left operand (-ve)') +assertEqual (true and f('moo'), 'moo', 'And operator should work with function calls as right operand (+ve)') +assertEqual (true and f(false), false, 'And operator should work with function calls as right operand (-ve)') +assertEqual (f('moo') and f('moo'), 'moo', 'And operator should work with function calls as both operands') + local function test() return true From 65917cd04b8c342dc9bf1b9868c0333af4bcc376 Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 22:16:08 +0000 Subject: [PATCH 05/11] Adds external implementation of `string.format`. --- package.json | 86 ++++++++++++++++++++------------------- src/runtime/lib/string.js | 5 +++ 2 files changed, 49 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index dbe72d4..cc6a675 100644 --- a/package.json +++ b/package.json @@ -1,43 +1,45 @@ { - "name": "starlight", - "description": "A Lua -> ES6 transpiler", - "version": "0.1.5", - "author": { - "name": "Paul Cuthbertson" - }, - "repository": { - "type": "git", - "url": "https://github.com/paulcuth/starlight" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/paulcuth/starlight/issues" - }, - "dependencies": {}, - "devDependencies": { - "babel": "^5.4.7", - "browserify": "^10.2.4", - "grunt": "^0.4.5", - "grunt-babel": "^5.0.1", - "grunt-browserify": "^3.8.0", - "grunt-cli": "^0.1.13", - "grunt-contrib-concat": "^0.3.0", - "grunt-contrib-copy": "^0.8.0", - "grunt-contrib-uglify": "^0.9.1", - "grunt-task-loader": "^0.6.0", - "gulp": "^3.8.11", - "gulp-babel": "^5.1.0", - "gulp-concat": "^2.5.2", - "gulp-minify-html": "^1.0.3", - "gulp-sourcemaps": "^1.5.2", - "gulp-uglify": "^1.2.0", - "gulp-util": "^3.0.4", - "luaparse": "^0.1.15", - "through": "^2.3.7", - "vinyl-buffer": "^1.0.0", - "vinyl-source-stream": "^1.1.0" - }, - "scripts": { - "test": "grunt grunt-plugin node-test" - } -} \ No newline at end of file + "name": "starlight", + "description": "A Lua -> ES6 transpiler", + "version": "0.1.5", + "author": { + "name": "Paul Cuthbertson" + }, + "repository": { + "type": "git", + "url": "https://github.com/paulcuth/starlight" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/paulcuth/starlight/issues" + }, + "dependencies": { + "printf": "^0.2.3" + }, + "devDependencies": { + "babel": "^5.4.7", + "browserify": "^10.2.4", + "grunt": "^0.4.5", + "grunt-babel": "^5.0.1", + "grunt-browserify": "^3.8.0", + "grunt-cli": "^0.1.13", + "grunt-contrib-concat": "^0.3.0", + "grunt-contrib-copy": "^0.8.0", + "grunt-contrib-uglify": "^0.9.1", + "grunt-task-loader": "^0.6.0", + "gulp": "^3.8.11", + "gulp-babel": "^5.1.0", + "gulp-concat": "^2.5.2", + "gulp-minify-html": "^1.0.3", + "gulp-sourcemaps": "^1.5.2", + "gulp-uglify": "^1.2.0", + "gulp-util": "^3.0.4", + "luaparse": "^0.1.15", + "through": "^2.3.7", + "vinyl-buffer": "^1.0.0", + "vinyl-source-stream": "^1.1.0" + }, + "scripts": { + "test": "grunt grunt-plugin node-test" + } +} diff --git a/src/runtime/lib/string.js b/src/runtime/lib/string.js index 9bcc192..ba7ee54 100644 --- a/src/runtime/lib/string.js +++ b/src/runtime/lib/string.js @@ -1,6 +1,7 @@ import { default as T } from '../Table'; import { default as LuaError } from '../LuaError'; import { tostring } from './string'; +import printf from 'printf'; import { coerceToNumber, @@ -134,6 +135,9 @@ export function find(s, pattern, init = 1, plain = false) { // TODO string.format (formatstring, ยทยทยท) +export function format(formatstring, ...args) { + return printf(formatstring, ...args); +} export function gmatch(s, pattern) { @@ -290,6 +294,7 @@ const string = new T({ char, dump, find, + format, gmatch, gsub, len, From 633c9f2c3edfff331262b12f7e9ed5b3fda374ce Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 22:19:05 +0000 Subject: [PATCH 06/11] Fixes issue with scoping of `self` sugar var. --- src/build-tools/common/code-generator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build-tools/common/code-generator.js b/src/build-tools/common/code-generator.js index 0edfd5b..a3d28c0 100644 --- a/src/build-tools/common/code-generator.js +++ b/src/build-tools/common/code-generator.js @@ -206,7 +206,7 @@ const GENERATORS = { name = identifier.property.replace(/'/g, ''); if (node.identifier.indexer === ':') { - params.unshift("$set($, 'self', __star_shift(args))"); + params.unshift("$setLocal($, 'self', __star_shift(args))"); } } else { name = identifier; From d8c2adf4939425b2295786cd3da81a85bf68bfde Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 22:20:20 +0000 Subject: [PATCH 07/11] Adds ability to use identifiers as keys in Table literals. --- src/build-tools/common/code-generator.js | 5 +++-- test/lua/tables.lua | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/build-tools/common/code-generator.js b/src/build-tools/common/code-generator.js index a3d28c0..8a9094e 100644 --- a/src/build-tools/common/code-generator.js +++ b/src/build-tools/common/code-generator.js @@ -401,7 +401,7 @@ const GENERATORS = { TableKey(node, scope) { - let name = generate(node.key, scope); + let name = scoped(node.key, scope); let value = scoped(node.value, scope); return `Tset(t, ${name}, ${value})`; }, @@ -478,7 +478,8 @@ function generate(ast, scope) { export function getRuntimeInit() { - let init = 'let __star = global.starlight.runtime, $0 = __star.globalScope, $ = $0, __star_tmp;\n'; + let init = '"use strict";\n'; + init += 'let __star = global.starlight.runtime, $0 = __star.globalScope, $ = $0, __star_tmp;\n'; init += 'let __star_call = __star.call, __star_T = __star.T, __star_op_bool = __star.op.bool;'; init += 'let __star_op_unm = __star.op.unm, __star_op_not = __star.op.not, __star_op_len = __star.op.len, __star_op_concat = __star.op.concat, __star_op_add = __star.op.add, __star_op_sub = __star.op.sub, __star_op_mul = __star.op.mul, __star_op_div = __star.op.div, __star_op_mod = __star.op.mod, __star_op_eq = __star.op.eq, __star_op_neq = __star.op.neq, __star_op_lt = __star.op.lt, __star_op_gt = __star.op.gt, __star_op_lte = __star.op.lte, __star_op_gte = __star.op.gte, __star_op_pow = __star.op.pow;'; init += 'let __star_op_and = __star.op.and, __star_op_or = __star.op.or;\n'; diff --git a/test/lua/tables.lua b/test/lua/tables.lua index bdc36ea..4bd8d48 100644 --- a/test/lua/tables.lua +++ b/test/lua/tables.lua @@ -50,6 +50,14 @@ assertTrue (a[2] == nil, 'Square brackets operation on table should return corre assertTrue (a[3] == 40, 'Square brackets operation on table should return correct value for index when keys are used in literal assignment [3]') assertTrue (a[4] == nil, 'Square brackets operation on table should return correct value for index when keys are used in literal assignment [4]') +b = 'hello' +a = {[b] = 'value'} +assertEqual (a.hello, 'value', 'Identifier should be able to be used as a key') + +b = 2 +a = {[b] = 'value2'} +assertEqual (a[2], 'value2', 'Numeric identifier should be able to be used as a key') + From 913e5372522d53f6fad3deccf59834997286604e Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Sun, 20 Mar 2016 22:21:39 +0000 Subject: [PATCH 08/11] Adds ability to use slashes (as well as dots) in modnames passed to `require()`. --- src/runtime/lib/globals.js | 4 +++- test/lua/lib-require.lua | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/runtime/lib/globals.js b/src/runtime/lib/globals.js index b19675d..e4c3b65 100644 --- a/src/runtime/lib/globals.js +++ b/src/runtime/lib/globals.js @@ -236,9 +236,11 @@ export function rawset(table, index, value) { export function _require(modname) { modname = coerceArgToString(modname, 'require', 1); + modname = modname.replace(/\//g, '.'); + let [preload, loaded] = getPackageMethods(); - let modinit = preload.rawget(modname); + if (modinit === void 0) { throw new LuaError(`module '${modname}' not found:\n\tno field package.preload['${modname}']`); } diff --git a/test/lua/lib-require.lua b/test/lua/lib-require.lua index 81ab213..5211855 100644 --- a/test/lua/lib-require.lua +++ b/test/lua/lib-require.lua @@ -36,7 +36,10 @@ assertTrue (testModName == 'lib-require', 'A module\'s name should be passed int local sub = require 'lib-require.sub-module' -- test dot syntax -assertTrue(type(sub) == 'table', 'Module should be able to load more modules.') +assertTrue(type(sub) == 'table', 'Module should be able to load more modules using dot syntax.') + +local sub2 = require 'lib-require/sub-module' -- test slash syntax +assertTrue(type(sub2) == 'table', 'Module should be able to load more modules using slash syntax.') mainGlobal1 = 'innerGlbl' local innerLocal = 'innerLoc' From 275146a40ae5d1a304e6d19d9c7f9b72b9d785df Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Mon, 21 Mar 2016 08:49:45 +0000 Subject: [PATCH 09/11] Removes build-time dependency on browserify. --- src/build-tools/common/code-generator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build-tools/common/code-generator.js b/src/build-tools/common/code-generator.js index 8a9094e..af1225f 100644 --- a/src/build-tools/common/code-generator.js +++ b/src/build-tools/common/code-generator.js @@ -478,7 +478,7 @@ function generate(ast, scope) { export function getRuntimeInit() { - let init = '"use strict";\n'; + let init = '"use strict"; if (typeof global === \'undefined\' && typeof window !== \'undefined\') { window.global = window; }\n'; init += 'let __star = global.starlight.runtime, $0 = __star.globalScope, $ = $0, __star_tmp;\n'; init += 'let __star_call = __star.call, __star_T = __star.T, __star_op_bool = __star.op.bool;'; init += 'let __star_op_unm = __star.op.unm, __star_op_not = __star.op.not, __star_op_len = __star.op.len, __star_op_concat = __star.op.concat, __star_op_add = __star.op.add, __star_op_sub = __star.op.sub, __star_op_mul = __star.op.mul, __star_op_div = __star.op.div, __star_op_mod = __star.op.mod, __star_op_eq = __star.op.eq, __star_op_neq = __star.op.neq, __star_op_lt = __star.op.lt, __star_op_gt = __star.op.gt, __star_op_lte = __star.op.lte, __star_op_gte = __star.op.gte, __star_op_pow = __star.op.pow;'; From 01d377b3b1c84b4ff91adc3e3e795187420380e4 Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Mon, 21 Mar 2016 18:42:24 +0000 Subject: [PATCH 10/11] Removes auto-versioning in CI due to infinite loop. --- ci/bump-project-version.js | 45 -------------------------------------- circle.yml | 3 --- 2 files changed, 48 deletions(-) delete mode 100644 ci/bump-project-version.js diff --git a/ci/bump-project-version.js b/ci/bump-project-version.js deleted file mode 100644 index c17a9c0..0000000 --- a/ci/bump-project-version.js +++ /dev/null @@ -1,45 +0,0 @@ -const childProcess = require('child_process'); - -const PACKAGE_FILENAME = '../package.json'; - -const package = require(PACKAGE_FILENAME); -const oldVersion = package.version; -const version = oldVersion.split('.'); - -function exec (cmd) { - const proc = childProcess.exec(cmd); - proc.stdout.on('data', console.log.bind(console)); - proc.stderr.on('data', console.error.bind(console)); -} - -if (!package.ci) { - version[2]++; - -} else { - if (package.ci.bump == 'major') { - version[0]++; - version[1] = version[2] = 0; - } else if (package.ci.bump = 'minor') { - version[1]++; - version[2] = 0; - } else { - version[2]++; - } - - delete package.ci; -} - -package.version = version.join('.'); -const output = JSON.stringify(package, null, '\t'); - -require('fs').writeFile(__dirname + '/' + PACKAGE_FILENAME, output, function (err) { - if (err) { - throw(err); - } - - exec('git add ./package.json'); - exec('git commit -m "Bumps version to ' + package.version + '"'); - exec('git push'); - - console.log('Bumped version: ' + oldVersion + ' -> ' + package.version); -}); diff --git a/circle.yml b/circle.yml index 8a8358c..27aa207 100644 --- a/circle.yml +++ b/circle.yml @@ -10,9 +10,6 @@ npm: branch: master commands: - - git config --global user.email 'circleci.agent@paulcuth.me.uk' - - git config --global user.name "CircleCI" - - node ci/bump-project-version - grunt grunt-plugin - node ci/sync-plugin-version - node ci/tag From 9a7ba44340dede6876e75e1b9386dc9c77324259 Mon Sep 17 00:00:00 2001 From: Paul Cuthbertson Date: Mon, 21 Mar 2016 18:44:06 +0000 Subject: [PATCH 11/11] Bumps version to `v0.1.6`. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cc6a675..c576a59 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "starlight", "description": "A Lua -> ES6 transpiler", - "version": "0.1.5", + "version": "0.1.6", "author": { "name": "Paul Cuthbertson" },