aboutsummaryrefslogtreecommitdiff
path: root/lib/operators.nom
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-01-11 18:51:21 -0800
committerBruce Hill <bitbucket@bruce-hill.com>2018-01-11 18:51:21 -0800
commite09f05a50cdb699029e8a4d5bafcfaade34157fd (patch)
treef216e71f7d7797706145f12349b48cd29d7c45ba /lib/operators.nom
parent06bf76f818382cdd33816073866f3cfd41609597 (diff)
Reshuffled all the library code into files that make more sense and
cleaned up some of the library code.
Diffstat (limited to 'lib/operators.nom')
-rw-r--r--lib/operators.nom136
1 files changed, 50 insertions, 86 deletions
diff --git a/lib/operators.nom b/lib/operators.nom
index 9f93a39..89f940e 100644
--- a/lib/operators.nom
+++ b/lib/operators.nom
@@ -1,71 +1,61 @@
+#..
+ This file contains definitions of operators like "+" and "and".
+
use "lib/metaprogramming.nom"
-# Literals
-compile [yes] to: "true"
-compile [no] to: "false"
-compile [nil, null] to: "nil"
-compile [infinity, inf] to: "math.huge"
-compile [not a number, NaN, nan] to: "(0/0)"
-compile [pi, Pi, PI] to: "math.pi"
-compile [tau, Tau, TAU] to: "(2*math.pi)"
-compile [phi, Phi, PHI, golden ratio] to: "((1+math.sqrt(5))/2)"
-compile [do nothing] to code: ""
+# Indexing:
+immediately:
+ compile [%obj'%key, %obj's %key, %obj -> %key] to: "(\(%obj as lua))[\(%key as lua)]"
-# Ternary operator
-#.. Note: this uses a function instead of "(condition and if_expr or else_expr)"
- because that breaks if %if_expr is falsey, e.g. "x < 5 and false or 99"
-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:
- lua> ".."
- local condition = nomsu:tree_to_lua(\%condition).expr;
- local when_true = nomsu:tree_to_lua(\%when_true_expr).expr;
- local when_false = nomsu:tree_to_lua(\%when_false_expr).expr;
- local safe = {Text=true, List=true, Dict=true, Number=true};
- if safe[\%when_true_expr.type] then
- return "("..condition.." and "..when_true.." or "..when_false..")";
- else
- return ([[
- (function(nomsu)
- if %s then
- return %s;
+# Comparison Operators
+immediately:
+ compile [%x < %y] to: "(\(%x as lua) < \(%y as lua))"
+ compile [%x > %y] to: "(\(%x as lua) > \(%y as lua))"
+ compile [%x <= %y] to: "(\(%x as lua) <= \(%y as lua))"
+ compile [%x >= %y] to: "(\(%x as lua) >= \(%y as lua))"
+ compile [%a is %b, %a = %b, %a == %b] to:
+ lua> ".."
+ local safe = {Text=true, Number=true};
+ local a_lua, b_lua = nomsu:tree_to_lua(\%a).expr, nomsu:tree_to_lua(\%b).expr;
+ if safe[\%a.type] or safe[\%b.type] then
+ return "("..a_lua.." == "..b_lua..")";
else
- return %s;
+ return "nomsu.utils.equivalent("..a_lua..", "..b_lua..")";
end
- end)(nomsu)]]):format(condition, when_true, when_false);
- end
-
-# Indexing:
-compile [%obj'%key, %obj's %key, %obj -> %key] to: "(\(%obj as lua))[\(%key as lua)]"
-
-# Substring
-# TODO: improve this syntax
-compile [%str |%start|] to: "\(%str as lua):sub(\(%start as lua), \(%start as lua))"
-compile [%str |%start - %stop|] to: "\(%str as lua):sub(\(%start as lua), \(%stop as lua))"
+ compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to:
+ lua> ".."
+ local safe = {Text=true, Number=true};
+ local a_lua, b_lua = nomsu:tree_to_lua(\%a).expr, nomsu:tree_to_lua(\%b).expr;
+ if safe[\%a.type] or safe[\%b.type] then
+ return "("..a_lua.." ~= "..b_lua..")";
+ else
+ return "(not nomsu.utils.equivalent("..a_lua..", "..b_lua.."))";
+ end
+ # For strict identity checking, use (%x's id) is (%y's id)
+ compile [%'s id, id of %] to: "nomsu.ids[\(% as lua)]"
# Variable assignment operator, and += type versions
-compile [local %vars] to code:
- lua> ".."
- local locals = \%vars.type == "List" and \%vars.value or {\%vars};
- local identifiers = {};
- for i,x in ipairs(locals) do
- identifiers[i] = nomsu:tree_to_lua(x).expr;
- end
- return "local "..table.concat(identifiers, ", ");
-compile [set %var = %val] to code:
- lua> ".."
- if \%var.type == 'List' and \%val.type == 'List' then
- local lhs = {};
- for i,x in ipairs(\%var.value) do lhs[i] = nomsu:tree_to_lua(x).expr; end
- local rhs = {};
- for i,x in ipairs(\%val.value) do rhs[i] = nomsu:tree_to_lua(x).expr; end
+immediately:
+ compile [local %vars] to code:
+ lua> ".."
+ local locals = \%vars.type == "List" and \%vars.value or {\%vars};
+ local identifiers = {};
+ for i,x in ipairs(locals) do
+ identifiers[i] = nomsu:tree_to_lua(x).expr;
+ end
+ return "local "..table.concat(identifiers, ", ");
+ compile [set %var = %val] to code: "\(%var as lua) = \(%val as lua);"
+ compile [set %assignments] to code:
+ assume ((%assignments' "type") is "Dict") or barf "Expected Dict, but got \(%assignments' "type")"
+ lua> ".."
+ local lhs, rhs = {}, {};
+ for i,entry in ipairs(\%assignments.value) do
+ lhs[i] = nomsu:tree_to_lua(entry.dict_key).expr;
+ rhs[i] = nomsu:tree_to_lua(entry.dict_value).expr;
+ end
return table.concat(lhs, ", ").." = "..table.concat(rhs, ", ")..";";
- else
- return \(%var as lua).." = "..\(%val as lua)..";";
- end
+
+# Update assignment operators
compile [%var += %val] to code: "\(%var as lua) = \(%var as lua) + \(%val as lua);"
compile [%var -= %val] to code: "\(%var as lua) = \(%var as lua) - \(%val as lua);"
compile [%var *= %val] to code: "\(%var as lua) = \(%var as lua) * \(%val as lua);"
@@ -84,32 +74,6 @@ compile [%x / %y] to: "(\(%x as lua) / \(%y as lua))"
compile [%x ^ %y] to: "(\(%x as lua) ^ \(%y as lua))"
compile [%x wrapped around %y, %x mod %y] to: "(\(%x as lua) % \(%y as lua))"
-# Comparison Operators
-compile [%x < %y] to: "(\(%x as lua) < \(%y as lua))"
-compile [%x > %y] to: "(\(%x as lua) > \(%y as lua))"
-compile [%x <= %y] to: "(\(%x as lua) <= \(%y as lua))"
-compile [%x >= %y] to: "(\(%x as lua) >= \(%y as lua))"
-compile [%a is %b, %a = %b, %a == %b] to:
- lua> ".."
- local safe = {Text=true, Number=true};
- local a_lua, b_lua = nomsu:tree_to_lua(\%a).expr, nomsu:tree_to_lua(\%b).expr;
- if safe[\%a.type] or safe[\%b.type] then
- return "("..a_lua.." == "..b_lua..")";
- else
- return "nomsu.utils.equivalent("..a_lua..", "..b_lua..")";
- end
-compile [%a isn't %b, %a is not %b, %a not= %b, %a != %b] to:
- lua> ".."
- local safe = {Text=true, Number=true};
- local a_lua, b_lua = nomsu:tree_to_lua(\%a).expr, nomsu:tree_to_lua(\%b).expr;
- if safe[\%a.type] or safe[\%b.type] then
- return "("..a_lua.." ~= "..b_lua..")";
- else
- return "(not nomsu.utils.equivalent("..a_lua..", "..b_lua.."))";
- end
-# For strict identity checking, use (%x's id) is (%y's id)
-compile [%'s id, id of %] to: "nomsu.ids[\(% as lua)]"
-
# 3-part chained comparisons
# (uses a lambda to avoid re-evaluating middle value, while still being an expression)
parse [%x < %y < %z] as: =lua "(function(x,y,z) return x < y and y < z; end)(\%x,\%y,\%z)"