From 05e78bb7c2afb28e392b8729388dc5257c9dbf31 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Mon, 23 Aug 2021 16:51:36 +0800 Subject: update changelogs. --- CHANGELOG.md | 814 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 448 insertions(+), 366 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d67dd81..b60bf8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,92 @@ The implementation for the original Moonscript language 0.5.0 can be found in the `0.5.0` branch of Yuescript. The Moonscript with fixes and new features is in the main branch of Yuescript. Here are the changelogs for each Yuescript version. +## v0.8.2 + +### Fixed Issues + +* Simplify and extend import syntax. +* Report an error when destructuring nil item. + +### Added Features + +* New metatable syntax. + ```moonscript + #: mt = tb + mt = tb.# + a = #: mt, value: 1 + b = :add#, value: 2 + close _ = close#: -> print "out of scope" + ``` + compiles to: + ```lua + local mt = getmetatable(tb) + mt = getmetatable(tb) + local a = setmetatable({ + value = 1 + }, mt) + local b = setmetatable({ + value = 2 + }, { + __add = add + }) + local _ = setmetatable({ }, { + __close = function() + return print("out of scope") + end + }) + ``` + +* Aliasing symbol :: with \ for writing colon chain items. + ```moonscript + tb\func1()::func2() + ``` + compiles to: + ```lua + tb:func1():func2() + ``` + +* Add until statement. + ```moonscript + a = 3 + until a == 0 + a -= 1 + ``` + compiles to: + ```lua + local a = 3 + while not (a == 0) do + a = a - 1 + end + ``` + +* Add existential check syntax for function argument as a shortcut feature to assign self field. + ```moonscript + tb\func1()::func2() + ``` + compiles to: + ```lua + tb:func1():func2() + ``` + +* Add default value support for destructure syntax. + ```moonscript + {:name = "nameless", :job = "jobless"} = person + ``` + compiles to: + ```lua + local name, job + do + local _obj_0 = person + name, job = _obj_0.name, _obj_0.job + end + if name == nil then + name = "nameless" + end + if job == nil then + job = "jobless" + end + ``` ## v0.6.7 @@ -9,90 +95,90 @@ The implementation for the original Moonscript language 0.5.0 can be found in th * Simplify macro syntax. A macro function can either return a Yuescript string or a config table containing Lua codes. -```moonscript -macro localFunc = (var)-> "local #{var} = ->" -$localFunc f1 -f1 = -> "another function" + ```moonscript + macro localFunc = (var)-> "local #{var} = ->" + $localFunc f1 + f1 = -> "another function" --- or + -- or -macro localFunc = (var)-> - { - codes: "local function #{var}() end" - type: "lua" - locals: {var} - } -$localFunc f2 -f2 = -> "another function" -``` -Compiles to: -```Lua -local f1 -f1 = function() end -f1 = function() - return "another function" -end -local function f2() end -f2 = function() - return "another function" -end -``` + macro localFunc = (var)-> + { + codes: "local function #{var}() end" + type: "lua" + locals: {var} + } + $localFunc f2 + f2 = -> "another function" + ``` + Compiles to: + ```Lua + local f1 + f1 = function() end + f1 = function() + return "another function" + end + local function f2() end + f2 = function() + return "another function" + end + ``` * Change the Yuescript file extension to '.yue' because some of the Moonscript syntax is no longer supported and some codes written in Yuescript syntax won't be accepted by the Moonscript compiler. * Disable the use of local and global statements with wildcard operators. * Change the backcall operator syntax, extra parentheses for multiline chains are no longer needed. -```moonscript -readFile "example.txt" - |> extract language, {} - |> parse language - |> emit - |> render - |> print -``` -Compiles to: -```Lua -return print(render(emit(parse(extract(readFile("example.txt"), language, { }), language)))) -``` + ```moonscript + readFile "example.txt" + |> extract language, {} + |> parse language + |> emit + |> render + |> print + ``` + Compiles to: + ```Lua + return print(render(emit(parse(extract(readFile("example.txt"), language, { }), language)))) + ``` ### Added Features * Supporting multiline chaining function call syntax. -```Moonscript -result = origin - .transform.root - .gameObject - \Parents! - \Descendants! - \SelectEnable! - \SelectVisible! - \TagEqual "fx" - \Where (x)-> - if x\IsTargeted! + ```Moonscript + result = origin + .transform.root + .gameObject + \Parents! + \Descendants! + \SelectEnable! + \SelectVisible! + \TagEqual "fx" + \Where (x)-> + if x\IsTargeted! + return false + x.name\EndsWith "(Clone)" + \Destroy! + + origin.transform.root.gameObject + \Parents!\Descendants! + \SelectEnable! + \SelectVisible! + \TagEqual "fx" + \Where (x)-> x.name\EndsWith "(Clone)" + \Destroy! + ``` + Compiles to: + ```Lua + local result = origin.transform.root.gameObject:Parents():Descendants():SelectEnable():SelectVisible():TagEqual("fx"):Where(function(x) + if x:IsTargeted() then return false - x.name\EndsWith "(Clone)" - \Destroy! - -origin.transform.root.gameObject - \Parents!\Descendants! - \SelectEnable! - \SelectVisible! - \TagEqual "fx" - \Where (x)-> x.name\EndsWith "(Clone)" - \Destroy! -``` -Compiles to: -```Lua -local result = origin.transform.root.gameObject:Parents():Descendants():SelectEnable():SelectVisible():TagEqual("fx"):Where(function(x) - if x:IsTargeted() then - return false - end - return x.name:EndsWith("(Clone)") -end):Destroy() -return origin.transform.root.gameObject:Parents():Descendants():SelectEnable():SelectVisible():TagEqual("fx"):Where(function(x) - return x.name:EndsWith("(Clone)") -end):Destroy() -``` + end + return x.name:EndsWith("(Clone)") + end):Destroy() + return origin.transform.root.gameObject:Parents():Descendants():SelectEnable(): SelectVisible():TagEqual("fx"):Where(function(x) + return x.name:EndsWith("(Clone)") + end):Destroy() + ``` @@ -186,19 +272,17 @@ end):Destroy() Compiles to: - ```Lua - local _var_0 = setmetatable({ }, { - __close = function(self) - end + ```Lua + local a = setmetatable({ }, { + __close = function(self) end }) - local a = _var_0 - local _var_1 - if var then - _var_1 = 123 - else - _var_1 = 'abc' - end - local b = _var_1 + local b = (function() + if var then + return 123 + else + return 'abc' + end + end)() ``` @@ -274,45 +358,45 @@ end):Destroy() ### Added Features * Add macro functions. -```Moonscript --- file 'macro.mp' -export macro config = (debugging = true)-> - global debugMode = debugging == "true" - "" - -export macro asserts = (cond)-> - debugMode and "assert #{cond}" or "" + ```Moonscript + -- file 'macro.mp' + export macro config = (debugging = true)-> + global debugMode = debugging == "true" + "" -export macro assert = (cond)-> - debugMode and "assert #{cond}" or "#{cond}" + export macro asserts = (cond)-> + debugMode and "assert #{cond}" or "" -$config! + export macro assert = (cond)-> + debugMode and "assert #{cond}" or "#{cond}" --- file 'main.mp' -import 'macro' as {:$config, :$assert, :$asserts} + $config! -macro and = (...)-> "#{ table.concat {...}, ' and ' }" + -- file 'main.mp' + import 'macro' as {:$config, :$assert, :$asserts} -$asserts item ~= nil -$config false -value = $assert item + macro and = (...)-> "#{ table.concat {...}, ' and ' }" -if $and f1!, f2!, f3! - print "OK" -``` - Compiles to: -```Lua --- file 'macro.mp' -local _module_0 = { } -return _module_0 + $asserts item ~= nil + $config false + value = $assert item --- file 'main.mp' -assert(item ~= nil) -local value = item -if (f1() and f2() and f3()) then - print("OK") -end -``` + if $and f1!, f2!, f3! + print "OK" + ``` + Compiles to: + ```Lua + -- file 'macro.mp' + local _module_0 = { } + return _module_0 + + -- file 'main.mp' + assert(item ~= nil) + local value = item + if (f1() and f2() and f3()) then + print("OK") + end + ``` @@ -340,70 +424,70 @@ From the original Moonscript compiler: * Add option to compile Yuescript as a Lua C lib. Got Yuescript released to `Luarocks`. * Move old `export` statement functions to `global` statement to match the `local` statement. * Change `export` statement behavior to support module management. Moon codes with `export` statements can not explicitly return values in the root scope. And codes with `export default` can export only one value as the module content. Use cases: -```Moonscript --- file 'Config.mp' -export default {flag:1, value:"x"} - --- file 'Utils.mp' -export map = (items, func)-> [func item for item in *items] -export filter = (items, func)-> [item for item in *items when func item] - --- file 'main.mp' -import 'Config' as {:flag, :value} -import 'Utils' as {:map, :filter} -``` -Compiles to: -```Lua --- file 'Config.mp' -local _module_0 = nil -_module_0 = { - flag = 1, - value = "x" -} -return _module_0 - --- file 'Utils.mp' -local _module_0 = { } -local map -map = function(items, func) - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #items do - local item = items[_index_0] - _accum_0[_len_0] = func(item) - _len_0 = _len_0 + 1 - end - return _accum_0 -end -_module_0["map"] = map -local filter -filter = function(items, func) - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #items do - local item = items[_index_0] - if func(item) then - _accum_0[_len_0] = item + ```Moonscript + -- file 'Config.mp' + export default {flag:1, value:"x"} + + -- file 'Utils.mp' + export map = (items, func)-> [func item for item in *items] + export filter = (items, func)-> [item for item in *items when func item] + + -- file 'main.mp' + import 'Config' as {:flag, :value} + import 'Utils' as {:map, :filter} + ``` + Compiles to: + ```Lua + -- file 'Config.mp' + local _module_0 = nil + _module_0 = { + flag = 1, + value = "x" + } + return _module_0 + + -- file 'Utils.mp' + local _module_0 = { } + local map + map = function(items, func) + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #items do + local item = items[_index_0] + _accum_0[_len_0] = func(item) _len_0 = _len_0 + 1 end + return _accum_0 + end + _module_0["map"] = map + local filter + filter = function(items, func) + local _accum_0 = { } + local _len_0 = 1 + for _index_0 = 1, #items do + local item = items[_index_0] + if func(item) then + _accum_0[_len_0] = item + _len_0 = _len_0 + 1 + end + end + return _accum_0 end - return _accum_0 -end -_module_0["filter"] = filter -return _module_0 - --- file 'main.mp' -local flag, value -do - local _obj_0 = require('Config') - flag, value = _obj_0.flag, _obj_0.value -end -local map, filter -do - local _obj_0 = require('Utils') - map, filter = _obj_0.map, _obj_0.filter -end -``` + _module_0["filter"] = filter + return _module_0 + + -- file 'main.mp' + local flag, value + do + local _obj_0 = require('Config') + flag, value = _obj_0.flag, _obj_0.value + end + local map, filter + do + local _obj_0 = require('Utils') + map, filter = _obj_0.map, _obj_0.filter + end + ``` @@ -425,110 +509,110 @@ Fix issues in original Moonscript compiler: * Multi-line comment support. * Back call features with new operator and syntax. For example: -```Moonscript -{1,2,3} - |> map((x)-> x * 2) - |> filter((x)-> x > 4) - |> reduce(0, (a,b)-> a + b) - |> print - -do - (data) <- http.get "ajaxtest" - body[".result"]\html data - (processed) <- http.post "ajaxprocess", data - body[".result"]\append processed - print "done" -``` -  will be compiled to: -```Lua -print(reduce(filter(map({ - 1, - 2, - 3 -}, function(x) - return x * 2 -end), function(x) - return x > 4 -end), 0, function(a, b) - return a + b -end)) -do - http.get("ajaxtest", function(data) - body[".result"]:html(data) - return http.post("ajaxprocess", data, function(processed) - body[".result"]:append(processed) - return print("done") + ```Moonscript + {1,2,3} + |> map((x)-> x * 2) + |> filter((x)-> x > 4) + |> reduce(0, (a,b)-> a + b) + |> print + + do + (data) <- http.get "ajaxtest" + body[".result"]\html data + (processed) <- http.post "ajaxprocess", data + body[".result"]\append processed + print "done" + ``` + will be compiled to: + ```Lua + print(reduce(filter(map({ + 1, + 2, + 3 + }, function(x) + return x * 2 + end), function(x) + return x > 4 + end), 0, function(a, b) + return a + b + end)) + do + http.get("ajaxtest", function(data) + body[".result"]:html(data) + return http.post("ajaxprocess", data, function(processed) + body[".result"]:append(processed) + return print("done") + end) end) - end) -end -``` + end + ``` * Existential operator support. Generate codes from: -```Moonscript -func?! - -x = tab?.value - -print abc?["hello world"]?.xyz - -if print and x? - print x -``` -  to: -```Lua -if func ~= nil then - func() -end -local x -if tab ~= nil then - x = tab.value -end -print((function() - if abc ~= nil then - local _obj_0 = abc["hello world"] - if _obj_0 ~= nil then - return _obj_0.xyz + ```Moonscript + func?! + + x = tab?.value + + print abc?["hello world"]?.xyz + + if print and x? + print x + ``` + to: + ```Lua + if func ~= nil then + func() + end + local x + if tab ~= nil then + x = tab.value + end + print((function() + if abc ~= nil then + local _obj_0 = abc["hello world"] + if _obj_0 ~= nil then + return _obj_0.xyz + end + return nil end return nil + end)()) + if print and (x ~= nil) then + print(x) end - return nil -end)()) -if print and (x ~= nil) then - print(x) -end -``` + ``` * More usages for `import` keyword. Will compile codes from: -```Moonscript -import 'module' -import "module.part" -import "d-a-s-h-e-s" -import "player" as Player -import "lpeg" as {:C, :Ct, :Cmt} -``` -  to: -```Lua -local module = require('module') -local part = require("module.part") -local d_a_s_h_e_s = require("d-a-s-h-e-s") -local Player = require("player") -local C, Ct, Cmt -do - local _obj_0 = require("lpeg") - C, Ct, Cmt = _obj_0.C, _obj_0.Ct, _obj_0.Cmt -end -``` + ```Moonscript + import 'module' + import "module.part" + import "d-a-s-h-e-s" + import "player" as Player + import "lpeg" as {:C, :Ct, :Cmt} + ``` + to: + ```Lua + local module = require('module') + local part = require("module.part") + local d_a_s_h_e_s = require("d-a-s-h-e-s") + local Player = require("player") + local C, Ct, Cmt + do + local _obj_0 = require("lpeg") + C, Ct, Cmt = _obj_0.C, _obj_0.Ct, _obj_0.Cmt + end + ``` * Can do slash call with Lua keywords. Generate codes from: -```Moonscript -c.repeat.if\then("xyz")\else res -``` -  to: -```Lua -local _call_3 = c["repeat"]["if"] -local _call_4 = _call_3["then"](_call_3, "xyz") -_call_4["else"](_call_4, res) -``` + ```Moonscript + c.repeat.if\then("xyz")\else res + ``` + to: + ```Lua + local _call_3 = c["repeat"]["if"] + local _call_4 = _call_3["then"](_call_3, "xyz") + _call_4["else"](_call_4, res) + ``` @@ -537,110 +621,108 @@ _call_4["else"](_call_4, res) * Left part of update statement will now accept only one assignable expression. * Expression list appears in the middle of the code block is not allowed. For codes like: -```Moonscript --- Moonscript 0.5.0 -f = (x)-> - "abc",123 -- valid meaningless codes - x + 1 -``` - -in original Moonscript compiles to: - -```Lua -local f -f = function(x) - local _ = "abc", 123 -- report error in Yuescript - return x + 1 -end -``` - -This feature may lead to some silenced errors. For example: - -```Moonscript --- expected codes -tree\addChild with Node! - \addChild subNode + ```Moonscript + -- Moonscript 0.5.0 + f = (x)-> + "abc",123 -- valid meaningless codes + x + 1 + ``` + in original Moonscript compiles to: + ```Lua + local f + f = function(x) + local _ = "abc", 123 -- report error in Yuescript + return x + 1 + end + ``` + + This feature may lead to some silenced errors. For example: + + ```Moonscript + -- expected codes + tree\addChild with Node! + \addChild subNode --- in original Moonscript, codes will still run --- after adding a break by mistake -tree\addChild -with Node! - \addChild subNode -``` - -the original Moonscript will compile these codes to: - -```Lua --- expected codes -tree:addChild((function() + -- in original Moonscript, codes will still run + -- after adding a break by mistake + tree\addChild + with Node! + \addChild subNode + ``` + + The original Moonscript will compile these codes to: + + ```Lua + -- expected codes + tree:addChild((function() + do + local _with_0 = Node() + _with_0:addChild(subNode) + return _with_0 + end + end)()) + + -- codes added with a break will still run + local _ -- report error in Yuescript instead of creating + do -- an anonymous function to bind the object method + local _base_0 = tree + local _fn_0 = _base_0.addChild + _ = function(...) + return _fn_0(_base_0, ...) + end + end do local _with_0 = Node() _with_0:addChild(subNode) - return _with_0 - end -end)()) - --- codes added with a break will still run -local _ -- report error in Yuescript instead of creating -do -- an anonymous function to bind the object method - local _base_0 = tree - local _fn_0 = _base_0.addChild - _ = function(...) - return _fn_0(_base_0, ...) end -end -do - local _with_0 = Node() - _with_0:addChild(subNode) -end -``` + ``` * Reusing variables which help generate reduced Lua codes. For example, Yuescript will generate codes from: -```Moonscript -with leaf - .world 1,2,3 - -with leaf - g = .what.is.this - print g - -for x in *something - print x -``` - -  to: - -```Lua -leaf.world(1, 2, 3) -do - local g = leaf.what.is.this - print(g) -end -for _index_0 = 1, #something do - local x = something[_index_0] - print(x) -end -``` - -  instead of: - -```lua -do - local _with_0 = leaf - _with_0.world(1, 2, 3) -end -do - local _with_0 = leaf - local g = _with_0.what.is.this -end -local _list_0 = something -for _index_0 = 1, #_list_0 do - local x = _list_0[_index_0] - print(x) -end -``` + ```Moonscript + with leaf + .world 1,2,3 + + with leaf + g = .what.is.this + print g + + for x in *something + print x + ``` + + to: + + ```Lua + leaf.world(1, 2, 3) + do + local g = leaf.what.is.this + print(g) + end + for _index_0 = 1, #something do + local x = something[_index_0] + print(x) + end + ``` + + instead of: + + ```lua + do + local _with_0 = leaf + _with_0.world(1, 2, 3) + end + do + local _with_0 = leaf + local g = _with_0.what.is.this + end + local _list_0 = something + for _index_0 = 1, #_list_0 do + local x = _list_0[_index_0] + print(x) + end + ``` -- cgit v1.2.3-55-g6feb