aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/control_flow.nom2
-rw-r--r--core/math.nom81
-rw-r--r--core/metaprogramming.nom90
-rw-r--r--core/text.nom4
4 files changed, 110 insertions, 67 deletions
diff --git a/core/control_flow.nom b/core/control_flow.nom
index bbc98f1..a692f95 100644
--- a/core/control_flow.nom
+++ b/core/control_flow.nom
@@ -560,7 +560,7 @@ test:
%lua = (..)
Lua "\
..do
- local \(mangle "stack \(%var.1)") = _List{\(%structure as lua expr)}
+ local \(mangle "stack \(%var.1)") = List{\(%structure as lua expr)}
while #\(mangle "stack \(%var.1)") > 0 do
\(%var as lua expr) = table.remove(\(mangle "stack \(%var.1)"), 1)"
%lua::append "\n "
diff --git a/core/math.nom b/core/math.nom
index 66f5aba..3bad78a 100644
--- a/core/math.nom
+++ b/core/math.nom
@@ -76,27 +76,54 @@ test:
externally (%n to the nearest %rounder) means (..)
=lua "(\%rounder)*math.floor((\%n / \%rounder) + .5)"
-# Any/all/none
+# Any/all
+externally [all of %items, all %items] all mean:
+ for % in %items:
+ unless %: return (no)
+ return (yes)
[all of %items, all %items] all compile to:
unless (%items.type is "List"):
- return (Lua value "utils.all(\(%items as lua expr))")
+ return %tree
%clauses = (((% as lua expr)::text) for % in %items)
return (Lua value "(\(%clauses::joined with " and "))")
-
[not all of %items, not all %items] all parse as (not (all of %items))
+
+externally [any of %items, any %items] all mean:
+ for % in %items:
+ if %: return (yes)
+ return (no)
[any of %items, any %items] all compile to:
unless (%items.type is "List"):
- return (Lua value "utils.any(\(%items as lua expr))")
+ return %tree
%clauses = (((% as lua expr)::text) for % in %items)
return (Lua value "(\(%clauses::joined with " or "))")
-
[none of %items, none %items] all parse as (not (any of %items))
+
+# Sum/product
+externally [sum of %items, sum %items] all mean:
+ %total = 0
+ for % in %items: %total += %
+ return %total
[sum of %items, sum %items] all compile to:
unless (%items.type is "List"):
- return (Lua value "utils.sum(\(%items as lua expr))")
+ return %tree
%clauses = (((% as lua expr)::text) for % in %items)
return (Lua value "(\(%clauses::joined with " + "))")
+externally [product of %items, product %items] all mean:
+ %prod = 1
+ for % in %items: %prod *= %
+ return %prod
+[product of %items, product %items] all compile to:
+ unless (%items.type is "List"):
+ return %tree
+ %clauses = (((% as lua expr)::text) for % in %items)
+ return (Lua value "(\(%clauses::joined with " * "))")
+
+externally [avg of %items, average of %items] all mean (..)
+ (sum of %items) / (size of %items)
+
+# Shorthand for control flow
[if all of %items %body, if all of %items then %body] all parse as (..)
if (all of %items) %body
@@ -136,42 +163,44 @@ externally (%n to the nearest %rounder) means (..)
unless none of %items %body else %else, unless none of %items then %body else %else
..all parse as (if (any of %items) %body else %else)
-[product of %items, product %items] all compile to:
- unless (%items.type is "List"):
- return (Lua value "utils.product(\(%items as lua expr))")
- %clauses = (((% as lua expr)::text) for % in %items)
- return (Lua value "(\(%clauses::joined with " * "))")
-
-externally [avg of %items, average of %items] all mean (..)
- =lua "(utils.sum(\%items)/#\%items)"
-
-[min of %items, smallest of %items, lowest of %items] all compile to (..)
- Lua value "utils.min(\(%items as lua expr))"
-
-[max of %items, biggest of %items, largest of %items, highest of %items] all compile \
-..to (Lua value "utils.max(\(%items as lua expr))")
+# Min/max
+externally [min of %items, smallest of %items, lowest of %items] all mean:
+ %best = (nil)
+ for % in %items:
+ if ((%best == (nil)) or (% < %best)):
+ %best = %
+ return %best
+
+externally [max of %items, biggest of %items, largest of %items, highest of %items] all mean:
+ %best = (nil)
+ for % in %items:
+ if ((%best == (nil)) or (% > %best)):
+ %best = %
+ return %best
test:
assume ((min of [3, -4, 1, 2] by % = (% * %)) == 1)
assume ((max of [3, -4, 1, 2] by % = (% * %)) == -4)
(min of %items by %item = %value_expr) parses as (..)
result of:
- set {%best:nil, %best_key:nil}
+ %best = (nil)
+ %best_key = (nil)
for %item in %items:
%key = %value_expr
if ((%best == (nil)) or (%key < %best_key)):
- set {%best:%item, %best_key:%key}
-
+ %best = %item
+ %best_key = %key
return %best
(max of %items by %item = %value_expr) parses as (..)
result of:
- set {%best:nil, %best_key:nil}
+ %best = (nil)
+ %best_key = (nil)
for %item in %items:
%key = %value_expr
if ((%best == (nil)) or (%key > %best_key)):
- set {%best:%item, %best_key:%key}
-
+ %best = %item
+ %best_key = %key
return %best
# Random functions
diff --git a/core/metaprogramming.nom b/core/metaprogramming.nom
index 61c877f..b104987 100644
--- a/core/metaprogramming.nom
+++ b/core/metaprogramming.nom
@@ -63,29 +63,33 @@ test:
asdf
assume (%tmp is (nil)) or barf "compile to is leaking variables"
lua> "\
- ..COMPILE_ACTIONS["1 compiles to"] = function(nomsu, tree, \%actions, \%body)
- if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
- local \%args = {"nomsu", "tree", unpack(table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):text() end))}
- local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", \%actions[1].stub:as_lua(),
+ ..COMPILE_ACTIONS["1 compiles to"] = function(nomsu, tree, \%action, \%body)
+ local \%args = List{\(\%nomsu), \(\%tree), unpack(\%action:get_args())}
+ local lua = LuaCode(tree.source, "COMPILE_ACTIONS[", \%action.stub:as_lua(),
"] = ", \(what (%args -> %body) compiles to))
+ return lua
+ end"
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+(%actions all compile to %body) compiles to:
+ lua> "\
+ ..if \%actions.type ~= "List" then
+ nomsu:compile_error(\%actions, "This should be a list of actions.")
+ end
+ local lua = LuaCode(tree.source, \(what (%actions.1 compiles to %body) compiles to))
+ local \%args = List{\(\%nomsu), \(\%tree), unpack(\%actions[1]:get_args())}
for i=2,#\%actions do
local alias = \%actions[i]
- local \%alias_args = {"nomsu", "tree", unpack(table.map(alias:get_args(), function(a) return nomsu:compile(a):text() \
- ..end))}
+ local \%alias_args = List{\(\%nomsu), \(\%tree), unpack(alias:get_args())}
lua:append("\\nCOMPILE_ACTIONS[", alias.stub:as_lua(), "] = ")
- if utils.equivalent(\%args, \%alias_args) then
+ if \%alias_args == \%args then
lua:append("COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "]")
else
- lua:append("function(")
- lua:concat_append(\%alias_args, ", ")
- lua:append(")\\n return COMPILE_ACTIONS[", \%actions[1].stub:as_lua(), "](")
- lua:concat_append(\%args, ", ")
- lua:append(")\\nend")
+ lua:append(\(what (%alias_args -> \(what %actions.1 compiles to)) compiles to))
end
end
- return lua
- end
- COMPILE_ACTIONS["1 all compile to"] = COMPILE_ACTIONS["1 compiles to"]"
+ return lua"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -112,27 +116,29 @@ test:
(baz %) parses as (foo %)
assume ((foo 1) == "outer")
-[%actions means %body, %actions all mean %body] all compile to:
+
+(%action means %body) compiles to:
lua> "\
- ..if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
- local fn_name = \%actions[1].stub:as_lua_id()
- local \%args = table.map(\%actions[1]:get_args(), function(a) return nomsu:compile(a):text() end)
+ ..local fn_name = \%action.stub:as_lua_id()
+ local \%args = \%action:get_args()
local lua = LuaCode(tree.source, fn_name, " = ", \(what (%args -> %body) compiles to))
lua:add_free_vars({fn_name})
+ return lua"
+(%actions all mean %body) compiles to:
+ lua> "\
+ ..local fn_name = \%actions[1].stub:as_lua_id()
+ local \%args = List(\%actions[1]:get_args())
+ local lua = LuaCode(tree.source, \(what (%actions.1 means %body) compiles to))
for i=2,#\%actions do
local alias = \%actions[i]
local alias_name = alias.stub:as_lua_id()
lua:add_free_vars({alias_name})
- local \%alias_args = table.map(alias:get_args(), function(a) return nomsu:compile(a):text() end)
+ local \%alias_args = List(alias:get_args())
lua:append("\\n", alias_name, " = ")
- if utils.equivalent(\%args, \%alias_args) then
+ if \%args == \%alias_args then
lua:append(fn_name)
else
- lua:append("function(")
- lua:concat_append(\%alias_args, ", ")
- lua:append(")\\n return ", fn_name, "(")
- lua:concat_append(\%args, ", ")
- lua:append(")\\nend")
+ lua:append(\(what (%alias_args -> %actions.1) compiles to))
end
end
return lua"
@@ -143,10 +149,14 @@ test:
test:
assume ((baz1) == "baz1")
assume ((baz2) == "baz2")
-[externally %actions means %body, externally %actions all mean %body] all compile to:
+(externally %action means %body) compiles to:
+ lua> "\
+ ..local lua = \(what (%action means %body) compiles to)
+ lua:remove_free_vars({\%action.stub:as_lua_id()})
+ return lua"
+(externally %actions all mean %body) compiles to:
lua> "\
- ..local lua = \(what (%actions means %body) compiles to)
- if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
+ ..local lua = \(what (%actions all mean %body) compiles to)
lua:remove_free_vars(table.map(\%actions, function(a) return a.stub:as_lua_id() end))
return lua"
@@ -169,10 +179,12 @@ test:
swap %tmp and %tmp2
assume ((%tmp == 2) and (%tmp2 == 1)) or barf "\
..'parse % as %' variable mangling failed."
-[%actions parses as %body, %actions all parse as %body] all compile to:
+(%actions all parse as %body) compiles to:
lua> "\
..local replacements = {}
- if \%actions.type ~= "List" then \%actions = {\%actions, type="List"} end
+ if \%actions.type ~= "List" then
+ nomsu:compile_error(\%actions, "This should be a list.")
+ end
for i,arg in ipairs(\%actions[1]:get_args()) do
replacements[arg[1]] = nomsu:compile(arg):text()
end
@@ -208,10 +220,12 @@ test:
local \%new_body = LuaCode(\%body.source,
"local mangle = mangler()",
"\\nreturn ", make_tree(\%body))
- local ret = \(what (%actions compiles to %new_body) compiles to)
+ local ret = \(what (%actions all compile to %new_body) compiles to)
return ret"
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+[%action parses as %body] all parse as ([%action] all parse as %body)
# TODO: add check for .is_value
(%tree as lua expr) compiles to (..)
@@ -287,10 +301,10 @@ externally (%tree with vars %replacements) means (..)
externally (match %tree with %patt) means:
lua> "\
- ..if \%patt.type == "Var" then return _Dict{[\%patt[1]]=\%tree} end
+ ..if \%patt.type == "Var" then return Dict{[\%patt[1]]=\%tree} end
if \%patt.type == "Action" and \%patt.stub ~= \%tree.stub then return nil end
if #\%patt ~= #\%tree then return nil end
- local matches = _Dict{}
+ local matches = Dict{}
for \%i=1,#\%patt do
if SyntaxTree:is_instance(\%tree[\%i]) then
local submatch = \(match %tree.%i with %patt.%i)
@@ -341,11 +355,11 @@ externally (type of %) means:
lua> "\
..local lua_type = \(lua type of %)
if lua_type == 'string' then return 'Text'
- elseif lua_type == 'table' then
+ elseif lua_type == 'table' or lua_type == 'userdata' then
local mt = getmetatable(\%)
if mt and mt.__type then return mt.__type end
- return 'Lua table'
- else return lua_type end"
+ end
+ return lua_type"
[% is a %type, % is an %type] all parse as ((type of %) == %type)
[% isn't a %type, % isn't an %type, % is not a %type, % is not an %type] all parse as (..)
diff --git a/core/text.nom b/core/text.nom
index 05ec409..40eb895 100644
--- a/core/text.nom
+++ b/core/text.nom
@@ -22,10 +22,10 @@ test:
assume ("asdf"::uppercase) == "ASDF"
assume ("asdf"::with "s" -> "X") == "aXdf"
assume ("one\ntwo\n"::lines) == ["one", "two", ""]
- (アクション %spec %body) parses as (externally %spec means %body)
+ (%spec とは %body) parses as (%spec means %body)
test:
%こんにちは = "こんにちは"
- アクション [% と言う] "\(%)世界"
+ (% と言う) とは "\(%)世界"
assume (%こんにちは と言う) == "こんにちは世界"
(%expr for %match in %text matching %patt) compiles to (..)
Lua value "\