From 68e167e9f0b90968ea67b7f21fdc50a48d129173 Mon Sep 17 00:00:00 2001 From: Li Jin Date: Tue, 12 Jul 2022 17:41:19 +0800 Subject: add table pattern matching syntax and fix issue #93, remove a confusing default value syntax for destructuring. --- spec/inputs/destructure.yue | 3 + spec/inputs/switch.yue | 86 +++++++++++++- spec/outputs/destructure.lua | 121 ++++++++++++-------- spec/outputs/switch.lua | 264 +++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 416 insertions(+), 58 deletions(-) (limited to 'spec') diff --git a/spec/inputs/destructure.yue b/spec/inputs/destructure.yue index a235abd..3007adf 100644 --- a/spec/inputs/destructure.yue +++ b/spec/inputs/destructure.yue @@ -181,3 +181,6 @@ do do {_, a, _, b} = tb -- list placeholder +do + {x: a.b = 1, y: a.c = 2} = x.x.x + diff --git a/spec/inputs/switch.yue b/spec/inputs/switch.yue index ac3dbea..36f9be6 100644 --- a/spec/inputs/switch.yue +++ b/spec/inputs/switch.yue @@ -58,7 +58,91 @@ switch hi switch hi when 3+1, hello!, (-> 4)! - yello + _ = yello else print "cool" +do + dict = { + {} + {1, 2, 3} + a: b: c: 1 + x: y: z: 1 + } + + switch dict + when { + first + {one, two, three} + a: b: :c + x: y: :z + } + print first, one, two, three, c, z + +do + items = + * x: 100 + y: 200 + * width: 300 + height: 400 + * false + + for item in *items + switch item + when :x, :y + print "Vec2 #{x}, #{y}" + when :width, :height + print "Size #{width}, #{height}" + when false + print "None" + when __class: cls + switch cls + when ClassA + print "Object A" + when ClassB + print "Object B" + when #: mt + print "A table with metatable" + else + print "item not accepted!" + +do + tb = {} + switch tb + when {:a = 1, :b = 2} + print a, b + +do + tb = x: "abc" + switch tb + when :x, :y + print "x: #{x} with y: #{y}" + when :x + print "x: #{x} only" + +do + matched = switch tb + when 1 + "1" + when :x + x + when false + "false" + else + nil + +do + return switch tb + when nil + "invalid" + when :a, :b + "#{a + b}" + when 1, 2, 3, 4, 5 + "number 1 - 5" + when {:alwaysMatch = "fallback"} + alwaysMatch + else + "should not reach here" + +nil + diff --git a/spec/outputs/destructure.lua b/spec/outputs/destructure.lua index 9b16181..2fe4ba9 100644 --- a/spec/outputs/destructure.lua +++ b/spec/outputs/destructure.lua @@ -229,12 +229,12 @@ do 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" + if name == nil then + name = "nameless" + end + if job == nil then + job = "jobless" + end end local request request = function(url, options) @@ -261,29 +261,29 @@ do do local _obj_0 = tb value1, key3 = _obj_0.key1.key2, _obj_0.key3 - end - if value1 == nil then - value1 = 123 - end - if key3 == nil then - key3 = "abc" + if value1 == nil then + value1 = 123 + end + if key3 == nil then + key3 = "abc" + end end local mt, call, add do local _obj_0 = getmetatable(tb) mt, call, add = _obj_0, getmetatable(_obj_0).__call, getmetatable(_obj_0).__add - end - if mt == nil then - mt = { - __index = { - abc = 123 + if mt == nil then + mt = { + __index = { + abc = 123 + } } - } - end - if call == nil then - call = (function() - return { } - end) + end + if call == nil then + call = (function() + return { } + end) + end end local _obj_0 = tb local mtx, y, zItem = getmetatable(_obj_0.x), _obj_0.y, _obj_0.z @@ -296,27 +296,33 @@ do return nil end end - local _obj_1 = getmetatable(tb).func - if _obj_1 == nil then + do + local _tmp_0 do - local _obj_2 = item - if _obj_2 ~= nil then - _obj_1 = _obj_2.defVal + local _obj_1 = getmetatable(tb) + _tmp_0 = _obj_1.func + end + if _tmp_0 == nil then + do + local _obj_1 = item + if _obj_1 ~= nil then + _tmp_0 = _obj_1.defVal + end end end - end - a.b(function() + a.b(function() return 123 - end).c = _obj_1 + end).c = _tmp_0 + end end do local mt, subFunc do local _obj_0 = getmetatable(tb.x) mt, subFunc = _obj_0, _obj_0.__sub - end - if mt == nil then - mt = { } + if mt == nil then + mt = { } + end end end do @@ -324,27 +330,28 @@ do do local _obj_0 = tb mt, subFunc = getmetatable(_obj_0.x), getmetatable(_obj_0.x).__sub - end - if mt == nil then - mt = { } + if mt == nil then + mt = { } + end end end do - local a, b, _obj_0 + local a, b do - local _obj_1 = tb - a, b, _obj_0 = _obj_1[1], _obj_1[2], _obj_1.c[1] - end - if a == nil then - a = 1 - end - if b == nil then - b = 2 - end - if _obj_0 == nil then - _obj_0 = 3 + local _obj_0 = tb + local _tmp_0 + a, b, _tmp_0 = _obj_0[1], _obj_0[2], _obj_0.c[1] + if a == nil then + a = 1 + end + if b == nil then + b = 2 + end + if _tmp_0 == nil then + _tmp_0 = 3 + end + d.e = _tmp_0 end - d.e = _obj_0 local _list_0 = tuples for _index_0 = 1, #_list_0 do local _des_0 = _list_0[_index_0] @@ -365,3 +372,17 @@ do a, b = _obj_0[2], _obj_0[4] end end +do + do + local _obj_0 = x.x.x + local _tmp_0, _tmp_1 = _obj_0.x, _obj_0.y + if _tmp_0 == nil then + _tmp_0 = 1 + end + if _tmp_1 == nil then + _tmp_1 = 2 + end + a.b = _tmp_0 + a.c = _tmp_1 + end +end diff --git a/spec/outputs/switch.lua b/spec/outputs/switch.lua index 81f6d5a..03a0d37 100644 --- a/spec/outputs/switch.lua +++ b/spec/outputs/switch.lua @@ -77,11 +77,261 @@ do local _ = no end end -local _exp_0 = hi -if (3 + 1) == _exp_0 or hello() == _exp_0 or (function() - return 4 -end)() == _exp_0 then - return yello -else - return print("cool") +do + local _exp_0 = hi + if (3 + 1) == _exp_0 or hello() == _exp_0 or (function() + return 4 + end)() == _exp_0 then + local _ = yello + else + print("cool") + end +end +do + local dict = { + { }, + { + 1, + 2, + 3 + }, + a = { + b = { + c = 1 + } + }, + x = { + y = { + z = 1 + } + } + } + do + local _tab_0 = "table" == type(dict) + if _tab_0 then + local first = dict[1] + local one + do + local _obj_0 = dict[2] + if _obj_0 ~= nil then + one = _obj_0[1] + end + end + local two + do + local _obj_0 = dict[2] + if _obj_0 ~= nil then + two = _obj_0[2] + end + end + local three + do + local _obj_0 = dict[2] + if _obj_0 ~= nil then + three = _obj_0[3] + end + end + local c + do + local _obj_0 = dict.a + if _obj_0 ~= nil then + do + local _obj_1 = _obj_0.b + if _obj_1 ~= nil then + c = _obj_1.c + end + end + end + end + local z + do + local _obj_0 = dict.x + if _obj_0 ~= nil then + do + local _obj_1 = _obj_0.y + if _obj_1 ~= nil then + z = _obj_1.z + end + end + end + end + if first ~= nil and one ~= nil and two ~= nil and three ~= nil and c ~= nil and z ~= nil then + print(first, one, two, three, c, z) + end + end + end +end +do + local items = { + { + x = 100, + y = 200 + }, + { + width = 300, + height = 400 + }, + false + } + for _index_0 = 1, #items do + local item = items[_index_0] + do + local _tab_0 = "table" == type(item) + local _match_0 = false + if _tab_0 then + local x = item.x + local y = item.y + if x ~= nil and y ~= nil then + print("Vec2 " .. tostring(x) .. ", " .. tostring(y)) + _match_0 = true + end + end + if not _match_0 then + local _match_1 = false + if _tab_0 then + local width = item.width + local height = item.height + if width ~= nil and height ~= nil then + print("Size " .. tostring(width) .. ", " .. tostring(height)) + _match_1 = true + end + end + if not _match_1 then + if false == item then + print("None") + else + local _match_2 = false + if _tab_0 then + local cls = item.__class + if cls ~= nil then + if ClassA == cls then + print("Object A") + elseif ClassB == cls then + print("Object B") + end + _match_2 = true + end + end + if not _match_2 then + if _tab_0 then + local mt = getmetatable(item) + if mt ~= nil then + print("A table with metatable") + end + else + print("item not accepted!") + end + end + end + end + end + end + end +end +do + local tb = { } + do + local _tab_0 = "table" == type(tb) + if _tab_0 then + local a = tb.a + local b = tb.b + if a == nil then + a = 1 + end + if b == nil then + b = 2 + end + if a ~= nil and b ~= nil then + print(a, b) + end + end + end +end +do + local tb = { + x = "abc" + } + do + local _tab_0 = "table" == type(tb) + local _match_0 = false + if _tab_0 then + local x = tb.x + local y = tb.y + if x ~= nil and y ~= nil then + print("x: " .. tostring(x) .. " with y: " .. tostring(y)) + _match_0 = true + end + end + if not _match_0 then + if _tab_0 then + local x = tb.x + if x ~= nil then + print("x: " .. tostring(x) .. " only") + end + end + end + end +end +do + local matched + do + local _exp_0 = tb + if 1 == _exp_0 then + matched = "1" + else + local _tab_0 = "table" == type(_exp_0) + local _match_0 = false + if _tab_0 then + local x = _exp_0.x + if x ~= nil then + matched = x + _match_0 = true + end + end + if not _match_0 then + if false == _exp_0 then + matched = "false" + else + matched = nil + end + end + end + end +end +do + local _exp_0 = tb + if nil == _exp_0 then + return "invalid" + else + do + local _tab_0 = "table" == type(_exp_0) + local _match_0 = false + if _tab_0 then + local a = _exp_0.a + local b = _exp_0.b + if a ~= nil and b ~= nil then + return tostring(a + b) + _match_0 = true + end + end + if not _match_0 then + if 1 == _exp_0 or 2 == _exp_0 or 3 == _exp_0 or 4 == _exp_0 or 5 == _exp_0 then + return "number 1 - 5" + else + if _tab_0 then + local alwaysMatch = _exp_0.alwaysMatch + if alwaysMatch == nil then + alwaysMatch = "fallback" + end + if alwaysMatch ~= nil then + return alwaysMatch + end + else + return "should not reach here" + end + end + end + end + end end +return nil -- cgit v1.2.3-55-g6feb