aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/collections.nom114
-rw-r--r--lib/control_flow.nom72
-rw-r--r--lib/metaprogramming.nom2
-rw-r--r--lib/operators.nom14
-rw-r--r--lib/scopes.nom2
-rw-r--r--lib/utils2.nom2
6 files changed, 129 insertions, 77 deletions
diff --git a/lib/collections.nom b/lib/collections.nom
index 41710a6..b97c164 100644
--- a/lib/collections.nom
+++ b/lib/collections.nom
@@ -18,15 +18,6 @@ compile [..]
parse [first in %list, first %list] as: 1 st in %list
parse [last in %list, last %list] as: 1 st to last in %list
-# Dict iteration convenience function. This could also be accomplished with: for all (entries in %dict): ...
-compile [for %key = %value in %dict %body] to code: ".."
- do
- for k, v in pairs(\(%dict as lua)) do
- \(%key as lua), \(%value as lua) = k, v;
- \(%body as lua statements)
- end
- end
-
# Membership testing
rule [%item is in %list, %list contains %item, %list has %item] =:
for %key = %value in %list:
@@ -60,7 +51,7 @@ compile [%list ->* %indices] to:
%ret = "\(%list as lua)"
for %index in (%indices's "value"):
%ret join= "[\(%index as lua)]"
- "\(%ret)"
+ "\%ret"
# Assignment
compile [..]
@@ -87,43 +78,16 @@ rule [flatten %lists] =:
add %item to %flat
%flat
-rule [dict from entries %items] =:
+rule [dict %items] =:
%dict = []
for %pair in %items:
%dict -> (%pair -> 1) = (%pair -> 2)
%dict
-compile [dict %items, d %items] to:
- if ((%items's "type") == "Thunk"):
- %item_codes = []
- for %func_call in (%items's "value"):
- assert ((%func_call's "type") == "FunctionCall") ".."
- Invalid format for 'dict' expression. Only literals are allowed.
- %tokens = (%func_call's "value")
- %equals = (%tokens -> 2)
- assert (=lua "#\(%tokens) == 3 and \(%equals) and \(%equals).type == 'Word' and \(%equals).value == '='") ".."
- Invalid format for 'dict' expression. Lines must only have the "% = %" format, not \(%func_call's "src")
- %key = (%tokens -> 1)
- lua> ".."
- if \(%key).type == "Word" and \(%key).value:match("^[a-zA-Z_][a-zA-Z0-9_]*$") then
- \(%key_code) = \(%key).value;
- elseif \(%key).type == "Word" then
- \(%key_code) = "["..nomsu:repr(\(%key).value).."]";
- else
- \(\{%key_code = "[\((%key as lua))]"} as lua statements)
- end
- add "\(%key_code) = \((%tokens -> 3) as lua)" to %item_codes
- return "{\(join %item_codes with glue ",\n")}"
- ..else:
- return (..)
- (..)
- nomsu "replaced_vars" [\(dict from entries %items), =lua "vars"]
- ..as lua
-
rule [entries in %dict] =:
%entries = []
for %k = %v in %dict:
- add (dict {key = %k; value = %v}) to %entries
+ add {key=%k, value=%v} to %entries
%entries
rule [keys in %dict] =:
@@ -137,20 +101,35 @@ rule [values in %dict] =:
%values
# List Comprehension
-compile [%expression for %var in %iterable] to:
- assert ((%var's "type") == "Var") ".."
- List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%var's "type")
+compile [%expression for %item in %iterable] to:
+ assert ((%item's "type") == "Var") ".."
+ List comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
".."
- (function(game, vars);
+ (function(nomsu, vars);
local comprehension = {};
- for i,value in ipairs(\(%iterable as lua)) do;
- \(%var as lua) = value;
+ for i,item in ipairs(\(%iterable as lua)) do;
+ \(%item as lua) = item;
comprehension[i] = \(%expression as lua);
end;
return comprehension;
- end)(game, setmetatable({}, {__index=vars}))
+ end)(nomsu, setmetatable({}, {__index=vars}))
parse [%expression for all %iterable] as: %expression for % in %iterable
+compile [%expression for %key = %value in %iterable] to:
+ assert ((%key's "type") == "Var") ".."
+ List comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%key's "type")
+ assert ((%value's "type") == "Var") ".."
+ List comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%value's "type")
+ ".."
+ (function(nomsu, vars);
+ local comprehension = {};
+ for key,value in pairs(\(%iterable as lua)) do;
+ \(%key as lua), \(%value as lua) = key, value;
+ comprehension[i] = \(%expression as lua);
+ end;
+ return comprehension;
+ end)(nomsu, setmetatable({}, {__index=vars}))
+
rule [%items sorted] =:
%copy = (% for all %items)
sort %copy
@@ -160,7 +139,7 @@ rule [%items sorted by %key] =:
sort %copy by %key
%copy
rule [unique %items] =:
- keys in (dict from entries ([%,yes] for all %items))
+ keys in (dict ([%,yes] for all %items))
# Metatable stuff
compile [counter] to: "setmetatable({}, {__index=function() return 0; end})"
@@ -173,17 +152,42 @@ compile [default dict] to: ".."
rule [chain %dict to %fallback] =:
when (type of %fallback) == ?:
* "table":
- =lua "setmetatable(\(%dict), \(%fallback))"
+ =lua "setmetatable(\%dict, \%fallback)"
* "function":
- =lua "setmetatable(\(%dict), {__index=function(self, key) return (\(%fallback))(nomsu, {['']=key, self=self}); end})"
+ =lua "setmetatable(\%dict, {__index=function(self, key) return (\%fallback)(nomsu, {['']=key, self=self}); end})"
* else:
- =lua "setmetatable(\(%dict), {__index=function(self, key) return (\(%fallback)); end})"
+ =lua "setmetatable(\%dict, {__index=function(self, key) return (\%fallback); end})"
# TODO: maybe make a generator/coroutine?
-#.. Dict comprehensions can be accomplished okay by doing:
- dict ([%'s "key", %'s "value"] for all (entries in %dict))
- or something similar
-# TODO: fix compiler bugs
-pass
+# Dict comprehensions
+compile [%key = %value for %item in %iterable] to:
+ assert ((%item's "type") == "Var") ".."
+ Dict comprehension has the wrong type for the loop variable. Expected Var, but got: \(%item's "type")
+ ".."
+ (function(nomsu, vars);
+ local comprehension = {};
+ for i,value in ipairs(\(%iterable as lua)) do;
+ \(%item as lua) = value;
+ comprehension[\(%key as lua)] = \(%value as lua);
+ end;
+ return comprehension;
+ end)(nomsu, setmetatable({}, {__index=vars}))
+parse [%key = %value for all %iterable] as: %key = %value for % in %iterable
+
+compile [%key = %value for %src_key = %src_value in %iterable] to:
+ assert ((%src_key's "type") == "Var") ".."
+ Dict comprehension has the wrong type for the key loop variable. Expected Var, but got: \(%src_key's "type")
+ assert ((%src_value's "type") == "Var") ".."
+ Dict comprehension has the wrong type for the value loop variable. Expected Var, but got: \(%src_value's "type")
+ ".."
+ (function(nomsu, vars);
+ local comprehension = {};
+ for key,value in pairs(\(%iterable as lua)) do;
+ \(%src_key as lua), \(%src_value as lua) = key, value;
+ comprehension[\(%key as lua)] = \(%value as lua);
+ end;
+ return comprehension;
+ end)(nomsu, setmetatable({}, {__index=vars}))
+
diff --git a/lib/control_flow.nom b/lib/control_flow.nom
index 7658ae1..825e1c2 100644
--- a/lib/control_flow.nom
+++ b/lib/control_flow.nom
@@ -31,8 +31,8 @@ compile [go to %label] to code: ".."
rule [tree %tree has function call %call] =:
lua> ".."
- local target = (\(%call)).stub;
- for subtree,_ in coroutine.wrap(function() nomsu:walk_tree(\(%tree)); end) do
+ local target = (\%call).stub;
+ for subtree,_ in coroutine.wrap(function() nomsu:walk_tree(\%tree); end) do
if type(subtree) == 'table' and subtree.type == "FunctionCall"
and subtree.stub == target then
return true;
@@ -48,12 +48,13 @@ compile [repeat while %condition %body] to code:
"\n::continue_repeat::;" if (tree %body has function call \(do next repeat-loop)) else ""
%code = ".."
while \(%condition as lua) do
- \(%body as lua statements)\(%continue_labels)
+ \(%body as lua statements)\
+ ..\%continue_labels
end --while-loop
if (tree %body has function call \(stop repeat-loop)):
return ".."
do --while-loop label scope
- \(%code)
+ \%code
::stop_repeat::;
end --while-loop label scope
return %code
@@ -76,22 +77,24 @@ compile [..]
%continue_labels = ""
if (tree %body has function call \(do next for-loop)):
%continue_labels join= "\n::continue_for::;"
- if (tree %body has function call (nomsu "replaced_vars" [\(do next %), =lua "{['']=\(%var)}"])):
+ 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 = ".."
for i=\(%start as lua),\(%stop as lua),\(%step as lua) do
\(%var as lua) = i;
- \(%body as lua statements)\(%continue_labels)
+ \(%body as lua statements)\
+ ..\%continue_labels
end --numeric for-loop
%stop_labels = ""
if (tree %body has function call \(stop for-loop)):
%stop_labels join= "\n::stop_for::;"
- if (tree %body has function call (nomsu "replaced_vars" [\(stop %), =lua "{['']=\(%var)}"])):
+ if (tree %body has function call (tree \(stop %) with {""=%var})):
%stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%var])::;"
if (%stop_labels != ""): ".."
do --for-loop label scope
- \(%code)\(%stop_labels)
+ \%code\
+ ..\%stop_labels
end --for-loop label scope
..else: %code
parse [for %var from %start to %stop %body] as: for %var from %start to %stop via 1 %body
@@ -105,26 +108,56 @@ compile [for %var in %iterable %body] to code:
%continue_labels = ""
if (tree %body has function call \(do next for-loop)):
%continue_labels join= "\n::continue_for::;"
- if (tree %body has function call (nomsu "replaced_vars" [\(do next %), =lua "{['']=\(%var)}"])):
+ 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 = ".."
for i,value in ipairs(\(%iterable as lua)) do
\(%var as lua) = value;
- \(%body as lua statements)\(%continue_labels)
+ \(%body as lua statements)\
+ ..\%continue_labels
end --foreach-loop
%stop_labels = ""
if (tree %body has function call \(stop for-loop)):
%stop_labels join= "\n::stop_for::;"
- if (tree %body has function call (nomsu "replaced_vars" [\(stop %), =lua "{['']=\(%var)}"])):
+ if (tree %body has function call (tree \(stop %) with {""=%var})):
%stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%var])::;"
if (%stop_labels != ""): ".."
do --for-loop label scope
- \(%code)\(%stop_labels)
+ \%code\%stop_labels
end --for-loop label scope
..else: %code
parse [for all %iterable %body] as: for % in %iterable %body
+# Dict iteration (lua's "pairs()")
+compile [for %key = %value in %iterable %body] to code:
+ %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})):
+ %continue_labels join= "\n::continue_\(nomsu "var_to_lua_identifier" [%key])::;"
+ 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 = ".."
+ 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 = ""
+ 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})):
+ %stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%key])::;"
+ if (tree %body has function call (tree \(stop %) with {""=%value})):
+ %stop_labels join= "\n::stop_\(nomsu "var_to_lua_identifier" [%value])::;"
+ if (%stop_labels != ""): ".."
+ do --for-loop label scope
+ \%code\
+ ..\%stop_labels
+ end --for-loop label scope
+ ..else: %code
# Switch statement/multi-branch if
compile [when %body] to code:
@@ -160,7 +193,7 @@ compile [when %body] to code:
%condition join= " or \(% as lua)"
%result join= ".."
- \("if" if %first else "elseif") \(%condition) then
+ \("if" if %first else "elseif") \%condition then
\(%action as lua statements)
%fallthroughs = []
@@ -204,7 +237,7 @@ compile [when %branch_value == ? %body] to code:
%condition join= " or (branch_value == \(% as lua))"
%result join= ".."
- \("if" if %first else "elseif") \(%condition) then
+ \("if" if %first else "elseif") \%condition then
\(%action as lua statements)
%fallthroughs = []
@@ -213,7 +246,8 @@ compile [when %branch_value == ? %body] to code:
if (%result != ""):
%result = ".."
do --when == ?
- local branch_value = \(%branch_value as lua);\(%result)
+ local branch_value = \(%branch_value as lua);\
+ ..\%result
end
end --when == ?
%result
@@ -239,11 +273,13 @@ compile [..]
end
end
parse [try %action] as:
- try %action and if it succeeds {pass} or if it fails {pass}
+ try %action and if it succeeds: pass
+ ..or if it fails: pass
parse [try %action and if it fails %fallback] as:
- try %action and if it succeeds {pass} or if it fails %fallback
+ try %action and if it succeeds: pass
+ ..or if it fails %fallback
parse [try %action and if it succeeds %success] as:
- try %action and if it succeeds %success or if it fails {pass}
+ try %action and if it succeeds %success or if it fails: pass
# Do/finally:
compile [do %action then always %final_action] to code: ".."
diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom
index e86b904..b4c1283 100644
--- a/lib/metaprogramming.nom
+++ b/lib/metaprogramming.nom
@@ -107,6 +107,8 @@ rule [%tree as lua statements] =:
compile [nomsu] to: "nomsu"
compile [nomsu's %key] to: "nomsu[\(%key as lua)]"
compile [nomsu %method %args] to: "nomsu[\(%method as lua)](nomsu, unpack(\(%args as lua)))"
+compile [tree %tree with %replacements] to: ".."
+ nomsu:replaced_vars(\(%tree as lua), \(%replacements as lua))
parse [rule %signature] as:
(nomsu's "defs")->(nomsu "get_stub" [\%signature])
diff --git a/lib/operators.nom b/lib/operators.nom
index 1fcb42a..198a8ff 100644
--- a/lib/operators.nom
+++ b/lib/operators.nom
@@ -32,7 +32,17 @@ compile [..]
compile [%obj'%key, %obj's %key, %obj -> %key] to: "(\(%obj as lua))[\(%key as lua)]"
# Variable assignment operator, and += type versions
-compile [%var = %val] to code: "\(%var as lua) = \(%val as lua);"
+compile [%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); end
+ local rhs = {};
+ for i,x in ipairs(\%val.value) do rhs[i] = nomsu:tree_to_lua(x); end
+ return table.concat(lhs, ", ").." = "..table.concat(rhs, ", ")..";";
+ else
+ return \(%var as lua).." = "..\(%val as lua)..";";
+ end
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);"
@@ -53,7 +63,7 @@ lua do> ".."
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), [["(\\%a ]]..op..[[ \\(%b))"]]);
end
# TODO: implement OR, XOR, AND for multiple operands
diff --git a/lib/scopes.nom b/lib/scopes.nom
index 8555287..29a543c 100644
--- a/lib/scopes.nom
+++ b/lib/scopes.nom
@@ -21,7 +21,7 @@ parse [using %scoped do %actions] as:
getmetatable(nomsu.defs["#vars"]).__newindex = getmetatable(nomsu.defs["#vars"]).__index;
do %actions
-parse [scoped %actions] as: using %actions do {pass}
+parse [scoped %actions] as: using %actions do (:pass)
rule [from %filename import %rules] =:
using:
diff --git a/lib/utils2.nom b/lib/utils2.nom
index def8854..cdaf5fa 100644
--- a/lib/utils2.nom
+++ b/lib/utils2.nom
@@ -27,7 +27,7 @@ compile [with %assignments %action] to code:
assert (=lua "vars.eq and vars.eq.type == 'Word' and vars.eq.value == '='") ".."
Invalid format for 'with' statement. List entries must have the form %var = (value)
%value = (%tokens -> 3)
- add (d{i=%i; var=%var; value=%value}) to %data
+ add {i=%i, var=%var, value=%value} to %data
%foo = (..)
join (..)
"local old_value\(%->"i") = \((%->"var") as lua); \((%->"var") as lua) = \((%->"value") as lua);"