-- case.lua -- Implementing a general case statement in Lua --~ function testcase(k) --~ case (k) --~ is 10,11: return 1 --~ is 12: return 2 --~ is 13 .. 16: return 3 --~ else return 4 --~ endcase --~ end -- --~ function matchcase(s) --~ case(s) --~ matches '^hell': return 5 --~ matches '(%d+)%s+(%d+)',result: --~ return tonumber(result[1])+tonumber(result[2]) --~ else return 0 --~ endcase --~ end local define = macro.define local replace = macro.replace local number = macro.number local name = macro.name local strmatch = string.match local strfind = string.find define('case',{'var'},@ do __case = var; if false then @) define('endcase',nil,@ end; end @) -- looks for the particular pattern {'',r1,'..','',r2} -- and returns r1 and r2 if successful -- There is a _lexical_ gotcha with r1..r2 without whitespace around '..'; Lua regards this as a malformed number local function try_extract_range(arg) if arg[1] == '' and arg[3]=='..' and arg[4]=='' then return arg[2],arg[5] end end define('is',{'value',handle_parms = macro.parameter_grabber(':')}, function(ls,...) local args = {...} local subst,put = macro.subst_putter() put('elseif') for i,arg in ipairs(args) do local r1,r2 = try_extract_range(arg) if r1 then put(replace({'r1','r2'},{number(r1), number(r2)}, @(r1<=__case and r2>=__case)@)) else put(arg); put('=='); put('','__case') end if i < #args then put('or') end end put('then') return subst end ) function __matches(str,pat,res) if not res then return strfind(str,pat) else local tbl = {strmatch(str,pat)} if #tbl > 0 then _G[res] = tbl return true end end end define('matches',{'value',handle_parms = macro.parameter_grabber(':')}, function(ls,...) local args = {...} local subst,put = macro.subst_putter() put('elseif') put('','__matches'); put('('); put('','__case'); put(',') put(args[1]) if #args > 1 then put(',') if args[2][1] ~= '' then macro.error("must supply a variable name to receive captures") end put('',args[2][2]) end put(')') put('then') return subst end )