aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/collections.nom22
-rw-r--r--lib/control_flow.nom66
-rw-r--r--lib/operators.nom27
-rw-r--r--lib/utils2.nom12
4 files changed, 66 insertions, 61 deletions
diff --git a/lib/collections.nom b/lib/collections.nom
index 3d87924..fb66468 100644
--- a/lib/collections.nom
+++ b/lib/collections.nom
@@ -48,7 +48,7 @@ compile [length of %list, size of %list, size %list, number of %list, len %list]
compile [%list ->* %indices] to:
assert ((%indices's "type") == "List") ".."
Expected List for chained lookup, not \(%indices's "type")
- %ret = "\(%list as lua)"
+ set %ret = "\(%list as lua)"
for %index in (%indices's "value"):
%ret join= "[\(%index as lua)]"
return "\%ret"
@@ -72,33 +72,23 @@ compile [remove index %index from %list] to:
action [flatten %lists]:
- %flat = []
+ set %flat = []
for %list in %lists:
for %item in %list:
add %item to %flat
return %flat
action [dict %items]:
- %dict = []
- for %pair in %items:
- %dict -> (%pair -> 1) = (%pair -> 2)
- return %dict
+ {(%->1)=(%->2) for all %items}
action [entries in %dict]:
- %entries = []
- for %k = %v in %dict:
- add {key=%k, value=%v} to %entries
- return %entries
+ [{key=%k, value=%v} for %k=%v in %dict]
action [keys in %dict]:
- %keys = []
- for %k = %v in %dict: add %k to %keys
- return %keys
+ [%k for %k=%v in %dict]
action [values in %dict]:
- %values = []
- for %k = %v in %dict: add %v to %values
- return %values
+ [%v for %k=%v in %dict]
# List Comprehension
compile [%expression for %item in %iterable] to:
diff --git a/lib/control_flow.nom b/lib/control_flow.nom
index 5adcbd5..d06de4f 100644
--- a/lib/control_flow.nom
+++ b/lib/control_flow.nom
@@ -55,9 +55,9 @@ immediately:
compile [do next repeat-loop] to code: "goto continue_repeat;"
compile [stop repeat-loop] to code: "goto stop_repeat;"
compile [repeat while %condition %body] to code:
- %continue_labels = (..)
+ set %continue_labels = (..)
"\n::continue_repeat::;" if (tree %body has function call \(do next repeat-loop)) else ""
- %code = ".."
+ set %code = ".."
while \(%condition as lua) do
\(%body as lua statements)\
..\%continue_labels
@@ -92,19 +92,19 @@ immediately:
for %var from %start to %stop via %step %body
..to code:
lua> "local \%continue_labels, \%code, \%stop_labels"
- %continue_labels = ""
+ set %continue_labels = ""
if (tree %body has function call \(do next for-loop)):
%continue_labels join= "\n::continue_for::;"
if (tree %body has function call (tree \(do next %) with {""=%var})):
%continue_labels join= "\n::continue_\(nomsu "var_to_lua_identifier" [%var])::;"
# This trashes the loop variables, just like in Python.
- %code = ".."
+ set %code = ".."
for i=\(%start as lua),\(%stop as lua),\(%step as lua) do
\(%var as lua) = i;
\(%body as lua statements)\
..\%continue_labels
end --numeric for-loop
- %stop_labels = ""
+ set %stop_labels = ""
if (tree %body has function call \(stop for-loop)):
%stop_labels join= "\n::stop_for::;"
if (tree %body has function call (tree \(stop %) with {""=%var})):
@@ -128,25 +128,25 @@ immediately:
immediately:
compile [for %var in %iterable %body] to code:
lua> "local \%continue_labels, \%stop_labels, \%code, \%stop_labels"
- %continue_labels = ""
+ set %continue_labels = ""
if (tree %body has function call \(do next for-loop)):
%continue_labels join= "\n::continue_for::;"
if (tree %body has function call (tree \(do next %) with {""=%var})):
%continue_labels join= "\n::continue_\(nomsu "var_to_lua_identifier" [%var])::;"
# This trashes the loop variables, just like in Python.
- %code = ".."
+ set %code = ".."
for i,value in ipairs(\(%iterable as lua)) do
\(%var as lua) = value;
\(%body as lua statements)\
..\%continue_labels
end --foreach-loop
- %stop_labels = ""
+ set %stop_labels = ""
if (tree %body has function call \(stop for-loop)):
%stop_labels join= "\n::stop_for::;"
if (tree %body has function call (tree \(stop %) with {""=%var})):
%stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%var])::;"
if %stop_labels != "":
- %code = ".."
+ set %code = ".."
do --for-loop label scope
\%code\%stop_labels
end --for-loop label scope
@@ -156,7 +156,7 @@ immediately:
# Dict iteration (lua's "pairs()")
immediately:
compile [for %key = %value in %iterable %body] to code:
- %continue_labels = ""
+ set %continue_labels = ""
if (tree %body has function call \(do next for-loop)):
%continue_labels join= "\n::continue_for::;"
if (tree %body has function call (tree \(do next %x) with {x=%key})):
@@ -164,13 +164,13 @@ immediately:
if (tree %body has function call (tree \(do next %) with {""=%value})):
%continue_labels join= "\n::continue_\(nomsu "var_to_lua_identifier" [%value])::;"
# This trashes the loop variables, just like in Python.
- %code = ".."
+ set %code = ".."
for key,value in ipairs(\(%iterable as lua)) do
\(%key as lua), \(%value as lua) = key, value;
\(%body as lua statements)\
..\%continue_labels
end --foreach-loop
- %stop_labels = ""
+ set %stop_labels = ""
if (tree %body has function call \(stop for-loop)):
%stop_labels join= "\n::stop_for::;"
if (tree %body has function call (tree \(stop %) with {""=%key})):
@@ -189,23 +189,23 @@ immediately:
immediately:
compile [when %body] to code:
lua> "local \%result, \%fallthroughs, \%first"
- %result = ""
- %fallthroughs = []
- %first = (yes)
+ set %result = ""
+ set %fallthroughs = []
+ set %first = (yes)
for %func_call in (%body's "value"):
lua> "local \%tokens, \%star, \%condition, \%action"
assert ((%func_call's "type") == "FunctionCall") ".."
Invalid format for 'when' statement. Only '*' blocks are allowed.
- %tokens = (%func_call's "value")
- %star = (%tokens -> 1)
+ set %tokens = (%func_call's "value")
+ set %star = (%tokens -> 1)
assert (=lua "\%star and \%star.type == 'Word' and \%star.value == '*'") ".."
Invalid format for 'when' statement. Lines must begin with '*'
- %condition = (%tokens -> 2)
+ set %condition = (%tokens -> 2)
assert %condition ".."
Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else"
- %action = (%tokens -> 3)
+ set %action = (%tokens -> 3)
if (%action == (nil)):
lua do> "table.insert(\%fallthroughs, \%condition)"
do next %func_call
@@ -217,7 +217,7 @@ immediately:
\(%action as lua statements)
stop for-loop
..else:
- %condition = (%condition as lua)
+ set %condition = (%condition as lua)
for all %fallthroughs:
%condition join= " or \(% as lua)"
%result join= ".."
@@ -225,8 +225,8 @@ immediately:
\("if" if %first else "elseif") \%condition then
\(%action as lua statements)
- %fallthroughs = []
- %first = (no)
+ set %fallthroughs = []
+ set %first = (no)
if (%result != ""):
%result join= "\nend"
@@ -235,22 +235,22 @@ immediately:
# Switch statement
immediately:
compile [when %branch_value == ? %body] to code:
- %result = ""
- %fallthroughs = []
- %first = (yes)
+ set %result = ""
+ set %fallthroughs = []
+ set %first = (yes)
for %func_call in (%body's "value"):
assert ((%func_call's "type") == "FunctionCall") ".."
Invalid format for 'when' statement. Only '*' blocks are allowed.
- %tokens = (%func_call's "value")
- %star = (%tokens -> 1)
+ set %tokens = (%func_call's "value")
+ set %star = (%tokens -> 1)
assert (=lua "\%star and \%star.type == 'Word' and \%star.value == '*'") ".."
Invalid format for 'when' statement. Lines must begin with '*'
- %condition = (%tokens -> 2)
+ set %condition = (%tokens -> 2)
assert %condition ".."
Invalid format for 'when' statement. Lines must begin with '*' and have a condition or the word "else"
- %action = (%tokens -> 3)
+ set %action = (%tokens -> 3)
if (%action == (nil)):
lua> "table.insert(\%fallthroughs, \%condition)"
do next %func_call
@@ -262,7 +262,7 @@ immediately:
\(%action as lua statements)
stop for-loop
..else:
- %condition = "branch_value == (\(%condition as lua))"
+ set %condition = "branch_value == (\(%condition as lua))"
for all %fallthroughs:
%condition join= " or (branch_value == \(% as lua))"
%result join= ".."
@@ -270,11 +270,11 @@ immediately:
\("if" if %first else "elseif") \%condition then
\(%action as lua statements)
- %fallthroughs = []
- %first = (no)
+ set %fallthroughs = []
+ set %first = (no)
if (%result != ""):
- %result = ".."
+ set %result = ".."
do --when == ?
local branch_value = \(%branch_value as lua);\
..\%result
diff --git a/lib/operators.nom b/lib/operators.nom
index 95441ea..f576e40 100644
--- a/lib/operators.nom
+++ b/lib/operators.nom
@@ -57,7 +57,7 @@ compile [%str |%start|] to: "\(%str as lua):sub(\(%start as lua), \(%start as lu
compile [%str |%start - %stop|] to: "\(%str as lua):sub(\(%start as lua), \(%stop as lua))"
# Variable assignment operator, and += type versions
-compile [%var = %val] to code:
+compile [set %var = %val] to code:
lua> ".."
if \%var.type == 'List' and \%val.type == 'List' then
local lhs = {};
@@ -92,11 +92,26 @@ 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))"
# == and != do equivalence checking, rather than identity checking
-compile [%a == %b] to: "nomsu.utils.equivalent(\(%a as lua), \(%b as lua))"
-compile [%a != %b] to: "(not nomsu.utils.equivalent(\(%a as lua), \(%b as lua)))"
-# For strict identity checking:
-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 != %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)
diff --git a/lib/utils2.nom b/lib/utils2.nom
index b0b9dd9..c8fa3b4 100644
--- a/lib/utils2.nom
+++ b/lib/utils2.nom
@@ -15,16 +15,16 @@ compile [do %action] to code:
# With statement
compile [with %assignments %action] to code:
- %data = []
+ set %data = []
for %i = %assignment in (%assignments' "value"):
- %tokens = (%assignment's "value")
- %var = (%tokens -> 1)
- %eq = (%tokens -> 2)
+ set %tokens = (%assignment's "value")
+ set %var = (%tokens -> 1)
+ set %eq = (%tokens -> 2)
assert (=lua "\%eq and \%eq.type == 'Word' and \%eq.value == '='") ".."
Invalid format for 'with' statement. List entries must have the form %var = (value)
- %value = (%tokens -> 3)
+ set %value = (%tokens -> 3)
add {i=%i, var=%var, value=%value} to %data
- %setup = (..)
+ set %setup = (..)
join (..)
"local old_value\(%->"i") = \((%->"var") as lua); \((%->"var") as lua) = \((%->"value") as lua);"
..for all %data