aboutsummaryrefslogtreecommitdiff
path: root/lib/operators.nom
diff options
context:
space:
mode:
Diffstat (limited to 'lib/operators.nom')
-rw-r--r--lib/operators.nom133
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))"