diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2017-12-13 16:29:15 -0800 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2017-12-13 16:29:15 -0800 |
| commit | 536a3ba64931946f81140e6a6d13f612a47a41d9 (patch) | |
| tree | fdf6975057207af248d5c345671e09be79498318 /lib/operators.nom | |
| parent | 0c1c406ce0d1c19508653181d8cef75f976677a5 (diff) | |
Got it working.
Diffstat (limited to 'lib/operators.nom')
| -rw-r--r-- | lib/operators.nom | 133 |
1 files changed, 67 insertions, 66 deletions
diff --git a/lib/operators.nom b/lib/operators.nom index d9880fe..1fcb42a 100644 --- a/lib/operators.nom +++ b/lib/operators.nom @@ -12,21 +12,21 @@ compile [phi, PHI, golden ratio] to: "((1+math.sqrt(5))/2)" compile [nop, pass] to code: "" # Ternary operator +#.. Note: this uses a function instead of (condition and if_expr or else_expr) + because that breaks if %if_expr is falsey. compile [..] %when_true_expr if %condition else %when_false_expr %when_true_expr if %condition otherwise %when_false_expr %when_false_expr unless %condition else %when_true_expr %when_false_expr unless %condition then %when_true_expr ..to: ".." - #.. Note: this uses a function instead of (condition and if_expr or else_expr) - because that breaks if %if_expr is falsey. - |(function(nomsu, vars) - | if \(%condition as lua) then - | return \(%when_true_expr as lua); - | else - | return \(%when_false_expr as lua); - | end - |end)(nomsu, vars) + (function(nomsu, vars) + if \(%condition as lua) then + return \(%when_true_expr as lua); + else + return \(%when_false_expr as lua); + end + end)(nomsu, vars) # Indexing: compile [%obj'%key, %obj's %key, %obj -> %key] to: "(\(%obj as lua))[\(%key as lua)]" @@ -45,16 +45,17 @@ compile [%var mod= %val] to code: "\(%var as lua) = \(%var as lua) % \(%val as l # Binary Operators lua do> ".." - |local binops = {"-","/","<","<=",">",">=","^",{"===","=="},{"!==","~="},{"mod","%"}}; - |for _,op in ipairs(binops) do - | local nomsu_alias = op; - | if type(op) == 'table' then; - | nomsu_alias, op = unpack(op); - | end - | nomsu:defmacro("%a "..nomsu_alias.." %b", (function(nomsu, vars) - | return "("..nomsu:tree_to_lua(vars.a).." "..op.." "..nomsu:tree_to_lua(vars.b)..")"; - | end), [["(\\(%a) ]]..op..[[ \\(%b))"]]); - |end + local binops = {"-","/","<","<=",">",">=","^",{"===","=="},{"!==","~="},{"mod","%"}}; + for _,op in ipairs(binops) do + local nomsu_alias = op; + if type(op) == 'table' then; + nomsu_alias, op = unpack(op); + end + nomsu:defmacro("%a "..nomsu_alias.." %b", (function(nomsu, vars) + return "("..nomsu:tree_to_lua(vars.a).." "..op.." "..nomsu:tree_to_lua(vars.b)..")"; + end), [["(\\(%a) ]]..op..[[ \\(%b))"]]); + end + # TODO: implement OR, XOR, AND for multiple operands compile [%a OR %b, %a | %b] to: "bit32.bor(\(%a as lua), \(%b as lua))" compile [%a XOR %b] to: "bit32.bxor(\(%a as lua), \(%b as lua))" @@ -70,56 +71,56 @@ compile [%a != %b] to: "(not nomsu.utils.equivalent(\(%a as lua), \(%b as lua))) # Commutative Operators defined for up to 8 operands # TODO: work out solution for commutative operators using more clever macros lua do> ".." - |local max_operands = 8; - |local comops = {"+","*","and","or"}; - |for _,_op in ipairs(comops) do - | local op = _op; - | local spec = "%1 "; - | for n=2,max_operands do - | spec = spec .." "..op.." %"..tostring(n); - | nomsu:defmacro(spec, (function(nomsu, vars) - | local bits = {}; - | for i=1,n do - | table.insert(bits, (nomsu:tree_to_lua(vars[tostring(i)]))); - | end - | return "("..table.concat(bits, " "..op.." ")..")"; - | end)); - | end - |end + local max_operands = 8; + local comops = {"+","*","and","or"}; + for _,_op in ipairs(comops) do + local op = _op; + local spec = "%1 "; + for n=2,max_operands do + spec = spec .." "..op.." %"..tostring(n); + nomsu:defmacro(spec, (function(nomsu, vars) + local bits = {}; + for i=1,n do + table.insert(bits, (nomsu:tree_to_lua(vars[tostring(i)]))); + end + return "("..table.concat(bits, " "..op.." ")..")"; + end)); + end + end # Chained compairsions (e.g. x < y <= z) are defined up to 3 operands lua do> ".." - |local max_operands = 3; - |for _,chainers in ipairs({{"<","<="},{">",">="}}) do - | local function recurse(chainers, chain) - # The 1-op versions are already more efficiently defined, and a 0-op version doesnt make sense - | if #chain >= 2 then; - | local spec = "%1"; - | for i,op in ipairs(chain) do - | spec = spec .. " "..op.." %"..tostring(i+1); - | end - # Chained comparisons need to be functions to avoid re-evaluating their arguments :\ - | nomsu:def(spec, function(nomsu, vars) - | for i,op in ipairs(chain) do - | local a, b, result = vars[i], vars[i+1]; - | if op == "<" then; result = a < b; - | elseif op == "<=" then; result = a <= b; - | elseif op == ">" then; result = a > b; - | elseif op == ">=" then; result = a >= b; end - # Short circuit - | if not result then; return false; end - | end - | end); - | end - | if #chain + 1 >= max_operands then; return; end - | for _,c in ipairs(chainers) do - | table.insert(chain, c); - | recurse(chainers, chain); - | table.remove(chain); - | end - | end - | recurse(chainers, {}); - |end + local max_operands = 3; + for _,chainers in ipairs({{"<","<="},{">",">="}}) do + local function recurse(chainers, chain) + -- The 1-op versions are already more efficiently defined, and a 0-op version doesnt make sense + if #chain >= 2 then; + local spec = "%1"; + for i,op in ipairs(chain) do + spec = spec .. " "..op.." %"..tostring(i+1); + end + -- Chained comparisons need to be functions to avoid re-evaluating their arguments : + nomsu:def(spec, function(nomsu, vars) + for i,op in ipairs(chain) do + local a, b, result = vars[i], vars[i+1]; + if op == "<" then; result = a < b; + elseif op == "<=" then; result = a <= b; + elseif op == ">" then; result = a > b; + elseif op == ">=" then; result = a >= b; end + -- Short circuit + if not result then; return false; end + end + end); + end + if #chain + 1 >= max_operands then; return; end + for _,c in ipairs(chainers) do + table.insert(chain, c); + recurse(chainers, chain); + table.remove(chain); + end + end + recurse(chainers, {}); + end # Unary operators compile [- %] to: "-(\(% as lua))" |
