From 4502061ce98c4bb1b447501482145889321670f8 Mon Sep 17 00:00:00 2001 From: xiangnan <280145668@qq.com> Date: Wed, 9 Oct 2024 23:35:01 +0800 Subject: [PATCH] fix:smart additon in case of binary expression contains string literal, close #4 --- README.md | 24 ++++++++++++++++++++++++ package.json | 2 +- src/js2lua.mjs | 33 ++++++++++++++++++++++++++++++++- test/smartAddition.mjs | 7 +++++++ 4 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 test/smartAddition.mjs diff --git a/README.md b/README.md index 359cacb..07e1155 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,7 @@ js2lua(`let a = 1`, { importStatementHoisting: true }); * [operator](#operator) * [optionalNullish](#optionalNullish) * [others](#others) +* [smartAddition](#smartAddition) * [spread](#spread) * [stringTemplate](#stringTemplate) * [switch](#switch) @@ -1005,6 +1006,29 @@ local constraints = (function() return __tmp end)() +``` +## smartAddition +### js +```js +const s1 = b + c +const s2 = b + 'c' +const s3 = 'c' + b +const s4 = a + b + 'c' +const s7 = 'a' + b + c +const s5 = a + b + 'c' + d + f +const s6 = a + b + c + d + f + +``` +### lua +```lua +local s1 = b + c +local s2 = b .. "c" +local s3 = "c" .. b +local s4 = a .. b .. "c" +local s7 = "a" .. b .. c +local s5 = a .. b .. "c" .. d .. f +local s6 = a + b + c + d + f + ``` ## spread ### js diff --git a/package.json b/package.json index b10b240..8a24ca7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@xiangnanscu/js2lua", - "version": "0.43.0", + "version": "0.44.0", "type": "module", "description": "Writing LuaJIT with the expressiveness of JavaScript.", "main": "src/js2lua.mjs", diff --git a/src/js2lua.mjs b/src/js2lua.mjs index f91a4fc..62f9996 100644 --- a/src/js2lua.mjs +++ b/src/js2lua.mjs @@ -577,6 +577,37 @@ function ast2lua(ast, opts = {}) { // tohex = case "BinaryExpression": { const op = logicMap[ast.operator] || ast.operator; + // first handle addition operator + const isAdditionNode = (node) => node.type === "BinaryExpression" && node.operator === "+"; + const containsString = (node) => { + if (node.type === "StringLiteral") return true; + if (isAdditionNode(node)) { + return containsString(node.left) || containsString(node.right); + } + return false; + }; + const processAddition = (node) => { + if (!isAdditionNode(node)) { + return _ast2lua(node); + } + if (node.stringConcat) { + return `${_ast2lua(node.left)} .. ${_ast2lua(node.right)}`; + } + if (containsString(node.left) || containsString(node.right)) { + walkAst(node, (e) => { + if (isAdditionNode(e)) { + e.stringConcat = true; + } + }); + return `${_ast2lua(node.left)} .. ${_ast2lua(node.right)}`; + } else { + return `${_ast2lua(node.left)} + ${_ast2lua(node.right)}`; + } + }; + // then handle other operators + if (ast.operator === "+") { + return processAddition(ast); + } const left = _ast2lua(ast.left); const right = _ast2lua(ast.right); if (ast.operator == "instanceof") { @@ -599,7 +630,7 @@ function ast2lua(ast, opts = {}) { } else if (ast.operator == "**") { return `math.pow(${left}, ${right})`; } else { - return `${left} ${op} ${_ast2lua(ast.right)}`; + return `${left} ${op} ${right}`; } } case "UnaryExpression": { diff --git a/test/smartAddition.mjs b/test/smartAddition.mjs new file mode 100644 index 0000000..277ad9b --- /dev/null +++ b/test/smartAddition.mjs @@ -0,0 +1,7 @@ +const s1 = b + c +const s2 = b + 'c' +const s3 = 'c' + b +const s4 = a + b + 'c' +const s7 = 'a' + b + c +const s5 = a + b + 'c' + d + f +const s6 = a + b + c + d + f