diff --git a/package.json b/package.json index be7fea8..463c71c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "starlight", "description": "A Lua -> ES6 transpiler", - "version": "0.1.8", + "version": "0.2.0", "author": { "name": "Paul Cuthbertson" }, @@ -14,7 +14,8 @@ "url": "https://github.com/paulcuth/starlight/issues" }, "dependencies": { - "printf": "^0.2.3" + "printf": "^0.2.3", + "superagent": "^1.8.3" }, "devDependencies": { "babel": "^5.4.7", diff --git a/src/build-tools/grunt/README.md b/src/build-tools/grunt/README.md index 1217eb1..0e59939 100644 --- a/src/build-tools/grunt/README.md +++ b/src/build-tools/grunt/README.md @@ -1,5 +1,5 @@ # grunt-starlight -A Lua to ES6 translator +A Lua to ES6 translator http://starlight.paulcuth.me.uk ## Getting Started diff --git a/src/build-tools/grunt/package.json b/src/build-tools/grunt/package.json index a201668..0b6a1cf 100644 --- a/src/build-tools/grunt/package.json +++ b/src/build-tools/grunt/package.json @@ -1,6 +1,6 @@ { "name": "grunt-starlight", - "description": "A Lua -> ES6 transpiler", + "description": "A Lua to ES6 translator", "version": "0.0.1", "homepage": "https://github.com/paulcuth/starlight", "author": { diff --git a/src/parser/index.js b/src/parser/index.js index c6afa30..abe89d9 100644 --- a/src/parser/index.js +++ b/src/parser/index.js @@ -1,5 +1,7 @@ import { getRuntimeInit, generateJS } from './code-generator'; import { default as parser } from 'luaparse'; +import superagent from 'superagent'; + if (typeof global === undefined) { global = window; @@ -27,33 +29,82 @@ function parseToString (input) { return js; } + function parse (input) { return (new Function('var global = this;' + parseToString(input))).bind(global || window); } + function runScriptTags() { const selectors = SUPPORTED_MIME_TYPES.map(t => `script[type="${t}"]`); - const scripts = document.querySelectorAll(selectors.join()); + const scriptTags = [...document.querySelectorAll(selectors.join())]; let script, i, modname, scriptBody; let lua = ''; - for (i = 0; script = scripts[i]; i++) { - modname = script.dataset.modname; - scriptBody = script.textContent; + const { immediate, deferred } = parseScriptTags(scriptTags); + runNextTag([...immediate, ...deferred]); +} + + +function parseScriptTags (tags) { + const immediate = []; + const deferred = []; + + tags.forEach(tag => { + const src = tag.src; + + if (src) { + const arr = tag.defer? deferred : immediate; + arr.push(new Promise((resolve, reject) => { + let x = superagent + .get(src) + .end((error, response) => { + if (error) { + resolve({}); + + } else { + resolve({ + modname: tag.dataset.modname, + body: response.text + }); + } + }); + })); - if (modname) { - lua += " rawset(package.preload, '" + modname + "', function(...) " + scriptBody + " end) "; } else { - lua += scriptBody; + immediate.push(Promise.resolve({ + modname: tag.dataset.modname, + body: tag.textContent, + })); } - } + }); + + return { immediate, deferred }; +} + - if (lua) { - parse(lua)(); +function runNextTag (tags) { + if (!tags.length) { + return; } + + let tag; + [tag, ...tags] = tags; + + tag.then(({ modname, body, error }) => { + if (body !== undefined) { + if (modname) { + body = " rawset(package.preload, '" + modname + "', function(...) " + body + " end) "; + } + parse(body)(); + } + + runNextTag(tags); + }); } +// Init if (global.document && global.document.querySelector('script[src$="starlight.js"][data-run-script-tags]')) { global.document.addEventListener('DOMContentLoaded', runScriptTags); } diff --git a/src/runtime/lib/string.js b/src/runtime/lib/string.js index ba7ee54..81675c6 100644 --- a/src/runtime/lib/string.js +++ b/src/runtime/lib/string.js @@ -43,6 +43,9 @@ function translatePattern (pattern) { // TODO Add support for balanced character matching (not sure this is easily achieveable). pattern = '' + pattern; + // Replace single backslash with double backslashes + pattern = pattern.replace(new RegExp('\\\\', 'g'), '\\\\'); + for (let i in ROSETTA_STONE) { if (ROSETTA_STONE.hasOwnProperty(i)) { pattern = pattern.replace(new RegExp(i, 'g'), ROSETTA_STONE[i]); diff --git a/src/runtime/operators.js b/src/runtime/operators.js index 48c8133..e1b9133 100644 --- a/src/runtime/operators.js +++ b/src/runtime/operators.js @@ -24,6 +24,14 @@ function binaryArithmetic(left, right, metaMethodName, callback) { } +function binaryStringArithmetic(left, right, metaMethodName, callback) { + if (typeof left == 'string' && typeof right == 'string') { + return callback(left, right); + } + return binaryArithmetic(left, right, metaMethodName, callback); +} + + function concat(left, right) { let mt, f; @@ -134,8 +142,8 @@ const op = { }, mod: (left, right) => binaryArithmetic(left, right, '__mod', mod), pow: (left, right) => binaryArithmetic(left, right, '__pow', Math.pow), - lt: (left, right) => binaryArithmetic(left, right, '__lt', (l, r) => l < r), - lte: (left, right) => binaryArithmetic(left, right, '__le', (l, r) => l <= r), + lt: (left, right) => binaryStringArithmetic(left, right, '__lt', (l, r) => l < r), + lte: (left, right) => binaryStringArithmetic(left, right, '__le', (l, r) => l <= r), gt(left, right) { return !op.lte(left, right); diff --git a/test/lua/lib-string.lua b/test/lua/lib-string.lua index e99d94e..964ecd8 100644 --- a/test/lua/lib-string.lua +++ b/test/lua/lib-string.lua @@ -472,7 +472,6 @@ end - -- gsub a = '<%?xml version="1.0" encoding="UTF%-8"%?>' @@ -514,6 +513,9 @@ assertTrue (d == ':X:X:X:X:X:', 'string.gsub() should replace the matched part o c = string.gsub (';a;', 'a*', 'ITEM') assertTrue (c == 'ITEM;ITEMITEM;ITEM', 'string.gsub() should replace the matched part of the string[2]') +a = 'abc\\def' +b = string.gsub(a, '\\', '\\\\') +assertEqual (b, 'abc\\\\def', 'Allow backslashes in regexes') diff --git a/test/lua/operators.lua b/test/lua/operators.lua index 87d2fd5..3607c3c 100644 --- a/test/lua/operators.lua +++ b/test/lua/operators.lua @@ -233,4 +233,5 @@ for name, test in pairs(tests) do end +assertTrue('abc' < 'def', 'Strings should be comparable')