aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/parser_tests.nom183
-rw-r--r--examples/sample_code.nom30
-rw-r--r--examples/sample_game.nom185
-rw-r--r--lib/collections.nom2
-rw-r--r--lib/metaprogramming.nom3
-rw-r--r--lib/permissions.nom2
-rw-r--r--lib/secrets.nom7
-rw-r--r--lib/utils.nom2
-rw-r--r--nomsu.lua194
9 files changed, 230 insertions, 378 deletions
diff --git a/examples/parser_tests.nom b/examples/parser_tests.nom
deleted file mode 100644
index 25d7e99..0000000
--- a/examples/parser_tests.nom
+++ /dev/null
@@ -1,183 +0,0 @@
-require "lib/core.nom"
-require "lib/testing.nom"
-
-test: say "foo"
-..yields ".."
- |FunctionCall:
- | Word:
- | "say"
- | String:
- | "foo"
-
-test: say (foo)
-..yields ".."
- |FunctionCall:
- | Word:
- | "say"
- | FunctionCall:
- | Word:
- | "foo"
-
-test:
- rule (fart) =: say "poot"
-..yields ".."
- |Call [rule % = %]:
- | List:
- | Call [fart]:
- | Block:
- | Call [say %]:
- | "poot"
-
-test: say (subexpressions work)
-..yields ".."
- |Call [say %]:
- | Call [subexpressions work]:
-
-test: say ["lists", "work"]
-..yields ".."
- |Call [say %]:
- | List:
- | "lists"
- | "work"
-
-test (say []) yields ".."
- |Call [say %]:
- | List:
-
-test:
- say [..]
- 1, 2
- 3
-..yields ".."
- |Call [say %]:
- | List:
- | 1
- | 2
- | 3
-
-test:
- say both [..]
- 1,2
- ..and [..]
- 3,4
-..yields ".."
- |Call [say both % and %]:
- | List:
- | 1
- | 2
- | List:
- | 3
- | 4
-
-
-test:
- if 1: yes
- ..else: no
-..yields ".."
- |Call [if % % else %]:
- | 1
- | Block:
- | Call [yes]:
- | Block:
- | Call [no]:
-
-test:
- if 1 (yes) else: no
-..yields ".."
- |Call [if % % else %]:
- | 1
- | Block:
- | Call [yes]:
- | Block:
- | Call [no]:
-
-test: say (do (return 5))
-..yields ".."
- |Call [say %]:
- | Call [do %]:
- | Block:
- | Call [return %]:
- | 5
-
-test:
- say:
- fn call
-..yields ".."
- |Call [say %]:
- | Call [fn call]:
-
-test:
- do: say "one liner"
- ..also: say "another one liner"
-..yields ".."
- |Call [do % also %]:
- | Block:
- | Call [say %]:
- | "one liner"
- | Block:
- | Call [say %]:
- | "another one liner"
-
-test:
- say:
- do:
- say "hi"
- return 5
- say "bye"
-..yields ".."
- |Call [say %]:
- | Call [do %]:
- | Block:
- | Call [say %]:
- | "hi"
- | Call [return %]:
- | 5
- | Call [say %]:
- | "bye"
-
-
-test: say (1 + (-(2 * 3)))
-..yields ".."
- |Call [say %]:
- | Call [% + %]:
- | 1
- | Call [- %]:
- | Call [% * %]:
- | 2
- | 3
-
-test:
- if %x:
- x
- ..else:
- if %y:
- y
- ..else:
- z
-..yields ".."
- |Call [if % % else %]:
- | Var["x"]
- | Block:
- | Call [x]:
- | Block:
- | Call [if % % else %]:
- | Var["y"]
- | Block:
- | Call [y]:
- | Block:
- | Call [z]:
-
-
-test:
- don't fuck this up
-..yields ".."
- |Call [don 't fuck this up]:
-
-test:
- %Brian's hat
-..yields ".."
- |Call [% 's hat]:
- | Var["Brian"]
-
-say "All tests passed!"
-
diff --git a/examples/sample_code.nom b/examples/sample_code.nom
index fe73ec7..1e1ccc6 100644
--- a/examples/sample_code.nom
+++ b/examples/sample_code.nom
@@ -34,7 +34,7 @@ say ".."
|^and trailing spaces
|
-say ".."|Longstrings have interpolation: \1 + 2\ <- like that
+say "Strings have interpolation: \(1 + 2) <- like that"
rule [doublefart] =: # this farts twice
say "poot"
@@ -76,9 +76,9 @@ say both
if 1: yes
..else: no
-if 1 (:yes) else (:no)
+if 1 {yes} else {no}
-say (do: return 5)
+say (do {return 5})
# Some variables
rule [do %one also %two] =:
@@ -88,7 +88,7 @@ rule [do %one also %two] =:
do: say "one liner"
..also: say "another one liner"
-say (do: return "wow")
+say (do {return "wow"})
say (1 + (-(2 * 3)))
@@ -97,21 +97,21 @@ say (..)
3 * 4
when:
- ? %x == 1:
+ * (%x == 1):
say "one"
- ? %x == 2:
+ * (%x == 2):
say "two"
- ? %x:
+ * %x:
say "nonzero"
- ?:
+ * else:
say "???"
-when %x:
- == 1:
+when %x == ?:
+ * 1:
say "one"
- == 2:
+ * 2:
say "two"
- ==:
+ * else:
say "???"
@@ -134,7 +134,7 @@ rule [%n bottles] =:
lua block ".."
|do
| print("running raw lua code...")
- | for i=\%n\,1,-1 do
+ | for i=\(%n),1,-1 do
| print(tostring(i).." bottles of beer on the wall. Take one down, pass it around,")
| end
| print("no more bottles of beer on the wall.")
@@ -143,9 +143,9 @@ rule [%n bottles] =:
9 bottles
rule [dumsum %nums] =:
- %sum =: 0
+ %sum = 0
for %n in %nums:
- %sum +=: %n
+ %sum += %n
return %sum
say (dumsum [1,2,3])
diff --git a/examples/sample_game.nom b/examples/sample_game.nom
index 3f9d6bc..95e5c26 100644
--- a/examples/sample_game.nom
+++ b/examples/sample_game.nom
@@ -5,72 +5,73 @@ require "lib/plurals.nom"
# Users:
with secrets:
- secret %users =: lua expr ".."
- |setmetatable({}, {__index=
- | {by_name=function(self, key) return "User<"..key..">" end,
- | add=function(self, key) self[key] = self:by_name(key) end}
- |})
- rule (find user %name; @%name) =:
+ secret %users = (..)
+ lua expr ".."
+ |setmetatable({}, {__index={
+ | by_name=function(self, key) return "User<"..key..">"; end,
+ | add=function(self, key) self[key] = self:by_name(key); end,
+ |}})
+ rule [find user %name, @%name] =:
lua expr "secrets.users:by_name(vars.name) or nomsu:error('Failed to find user: '..tostring(vars.name))"
- rule (add user %name) =:
+ rule [add user %name] =:
lua expr "secrets.users:add(vars.name)"
- rule (everybody; everyone) =:
+ rule [everybody, everyone] =:
(%entry's "key") for %entry in (entries in (secret %users))
- rule (rules that change users) =: ["add user %"]
+ rule [rules that change users] =: ["add user %"]
# Inventory:
with secrets:
- secret %inventory =: lua expr ".."
- |setmetatable({}, {__index=function(self,key)
- | local t = {}
- | self[key] = t
- | return t
- |end})
-
- rule (inventory) =: dict:
+ secret %inventory = (..)
+ lua expr ".."
+ |setmetatable({}, {__index=function(self,key)
+ | local t = setmetatable({}, {__index=function() return 0; end});
+ | self[key] = t;
+ | return t;
+ |end});
+
+ rule [inventory] =: dict:
[%inv's "key", dict (%entry for %entry in (entries in (%inv's "value")))]
..for %inv in (entries in (secret %inventory))
- rule (%person's inventory) =:
+ rule [%person's inventory] =:
dict (%entry for %entry in (entries in ((secret %inventory)->%person)))
- rule (%person's stock of %item) =:
- %item =: canonicalize %item
- ((%person's inventory)->%item) or 0
+ rule [%person's stock of %item] =:
+ %item = (canonicalize %item)
+ (((secret %inventory) -> %person) -> %item)
- rule (%person's stock of %item as str) =:
- %item =: canonicalize %item
- %count =: %person's stock of %item
- ".."
- |\(%count) \((singular %item) if (%count == 1) else (plural %item))
+ rule [%person's stock of %item as str] =:
+ %item = (canonicalize %item)
+ %count = (%person's stock of %item)
+ "\(%count) \((singular %item) if (%count == 1) else (plural %item))"
- rule (give %person %count %item) =:
- %item =: canonicalize %item
- (%person's inventory)-> %item =: (%person's stock of %item) + %count
+ rule [give %person %count %item] =:
+ %item = (canonicalize %item)
+ (((secret %inventory) -> %person) -> %item) += %count
- rule (give %person %count %item from %donor) =:
- %item =: canonicalize %item
+ rule [give %person %count %item from %donor] =:
+ %item = (canonicalize %item)
if ((%donor's stock of %item) < %count):
say ".."
|\(%donor) does not have enough \(%item) to transfer
..else:
- (%person's inventory)->%item =: (%person's stock of %item) + %count
- (%donor's inventory)->%item =: (%donor's stock of %item) - %count
+ (((secret %inventory) -> %person) -> %item) += %count
+ (((secret %inventory) -> %donor) -> %item) -= %count
- rule (%person has %item; %person has a %item; %person has an %item) =:
+ rule [%person has %item, %person has a %item, %person has an %item] =:
(%person's stock of %item) > 0
- rule (rules that change the inventory) =: [..]
+ rule [rules that change the inventory] =: [..]
"give % % %", "give % % % from %"
- rule (rules that view the inventory) =: [..]
+ rule [rules that view the inventory] =: [..]
"inventory", "%'s inventory", "%'s stock of %", "%'s stock of % as str"
-rule (you) =:
+rule [you] =:
lua expr "(nomsu.you or 'Anonymous')"
-rule (make %person %action; make %person do %action) =:
+rule [make %person %action, make %person do %action] =:
lua code ".."
|local old_you = nomsu.you
|nomsu.you = vars.person
@@ -84,31 +85,31 @@ say "===================================================="
# Unanimity for proposals
with secrets:
- rule (pending proposal) =:
+ rule [pending proposal] =:
secret %pending
- rule (propose source %src) =:
+ rule [propose source %src] =:
if (secret %pending):
error "A proposal is already pending."
- secret %pending =: %src
- secret %approvals =: []
+ secret %pending = %src
+ secret %approvals = []
say ".."
|Proposal:
|\(%src)
- parse (propose %action) as:
- propose source:
+ parse [propose %action] as:
+ propose source (..)
source code from tree \%action
- rule (with everyone's approval do %action) =:
+ rule [with everyone's approval do %action] =:
run %action
- rule (mark %who as approving) =:
+ rule [mark %who as approving] =:
if (not (pending proposal)):
say "No action pending"
return
- (secret %approvals)-> %who =: yes
+ (secret %approvals)-> %who = (yes)
# Check for uncounted votes:
for %user in (everybody):
@@ -117,34 +118,34 @@ with secrets:
# No one dissents
with everyone's approval do (pending proposal)
- secret %pending =: nil
- secret %approvals =: nil
+ secret %pending = (nil)
+ secret %approvals = (nil)
- rule (mark %who as rejecting) =:
- secret %pending =: nil
- secret %approvals =: nil
+ rule [mark %who as rejecting] =:
+ secret %pending = (nil)
+ secret %approvals = (nil)
- rule (approve; vote yes; vote yea) =:
+ rule [approve, vote yes, vote yea] =:
mark (you) as approving
- rule (reject; vote no; vote nay; veto; disapprove) =:
+ rule [reject, vote no, vote nay, veto, disapprove] =:
mark (you) as rejecting
restrict "with everyone's approval do %" to within "mark % as approving"
restrict "mark % as approving" to within "approve"
restrict "mark % as rejecting" to within "reject"
-rule (join) =:
+rule [join] =:
add user (you)
say ".."
|Welcome to the game, \(you)!
restrict (rules that change users) to within "join"
-
-restrict: flatten [..]
- ["rule % = %", "make % %", "restrict % to within %"]
- (rules that change the inventory)
+restrict (..)
+ flatten [..]
+ ["rule % = %", "make % %", "restrict % to within %"]
+ (rules that change the inventory)
..to within "with everyone's approval do %"
say "Rule making is now restricted"
@@ -167,7 +168,7 @@ propose:
approve
propose:
- rule (fart) =:
+ rule [fart] =:
say "poot"
say "fart should have been defined"
approve
@@ -176,34 +177,34 @@ fart
propose:
with secrets:
- rule (open election %candidates %action) =:
+ rule [open election %candidates %action] =:
if (secret %candidates):
error "An election is already in progress."
..else:
- secret %candidates =: %candidates
- secret %votes =: []
- secret %action =: %action
- secret %winner =: nil
-
- rule (close the election) =:
- secret %candidates =: nil
- secret %votes =: nil
- secret %action =: nil
- secret %winner =: nil
-
- rule (votes for %candidate) =:
- %votes =: []
+ secret %candidates = %candidates
+ secret %votes = []
+ secret %action = %action
+ secret %winner = (nil)
+
+ rule [close the election] =:
+ secret %candidates = (nil)
+ secret %votes = (nil)
+ secret %action = (nil)
+ secret %winner = (nil)
+
+ rule [votes for %candidate] =:
+ %votes = []
for %entry in (entries in (secret %votes)):
if ((%entry's "value") == %candidate):
add (%entry's "key") to %votes
%votes
- rule (after winning a fair election do %action) =:
+ rule [after winning a fair election do %action] =:
do %action
- rule (the winner) =: secret %winner
+ rule [the winner] =: secret %winner
- rule (vote for %candidate) =:
+ rule [vote for %candidate] =:
for %c in (secret %candidates):
if (%c == %candidate):
go to %candidate-is-legit
@@ -212,58 +213,56 @@ propose:
-> %candidate-is-legit
(secret %votes)->(you) =: %candidate
- %vote-percent =: (number of (votes for %candidate)) / (number of (everyone))
+ %vote-percent = ((number of (votes for %candidate)) / (number of (everyone)))
say ".."
|Vote cast. \(%candidate) now has \(100 * %vote-percent)% of the votes.
if (%vote-percent > 0.5):
- secret %winner =: %candidate
+ secret %winner = %candidate
after winning a fair election do (secret %action)
close the election
- rule (rules that change the election) =: [..]
+ rule [rules that change the election] =: [..]
"open election %", "close the election", "vote for %"
- rule (rules that view the election) =: [..]
+ rule [rules that view the election] =: [..]
"votes for %"
approve
propose:
- rule (_as bill %action) =:
+ rule [as bill %action] =:
if ((you) == "Anonymous"):
make "bill" do %action
..else:
say ".."
|Who do you think you are, \(you)?
- parse (as bill %) as (_as bill \%)
- allow ["_as bill %"] to use ["make % %"]
+ allow ["as bill %"] to use ["make % %"]
approve
as bill: join
propose:
- rule (_as dave %action) =:
+ rule [as dave %action] =:
if ((you) == "Anonymous"):
make "dave" do %action
..else:
say ".."
|Who do you think you are, \(you)?
- parse (as dave %) as (_as dave \%)
- allow ["_as dave %"] to use ["make % %"]
+ allow ["as dave %"] to use ["make % %"]
approve
as bill: approve
as dave: join
propose:
- rule (declare war) =: say "WAR!!!"
+ rule [declare war] =: say "WAR!!!"
with secrets:
- secret %president =: nil
- rule (elect president from %candidates) =:
+ secret %president = (nil)
+ rule [elect president from %candidates] =:
open election %candidates:
say ".."
|Hail to the chief: \(the winner)
- secret %president =: the winner
+ secret %president = (the winner)
- rule (as the president do %action) =: do %action
+ rule [as the president do %action] =: do %action
restrict "declare war" to within "as the president do %"
approve
@@ -278,7 +277,7 @@ as dave:
declare war
propose:
- rule (take a shit) =: say "shit taken."
+ rule [take a shit] =: say "shit taken."
approve
as bill: approve
diff --git a/lib/collections.nom b/lib/collections.nom
index 61ae71d..43dfb08 100644
--- a/lib/collections.nom
+++ b/lib/collections.nom
@@ -67,7 +67,7 @@ compile [..]
%index rd in %list = %new_value, %index th in %list = %new_value, %index in %list = %new_value
%list -> %index = %new_value
..to code:
- "(\(%list as lua))[\(%index as lua)] = \(%new_value as lua)"
+ "(\(%list as lua))[\(%index as lua)] = \(%new_value as lua);"
compile [append %item to %list, add %item to %list] to:
"table.insert(\(%list as lua), \(%item as lua))"
diff --git a/lib/metaprogramming.nom b/lib/metaprogramming.nom
index 12144b4..4924e78 100644
--- a/lib/metaprogramming.nom
+++ b/lib/metaprogramming.nom
@@ -44,7 +44,8 @@ rule [escaped compile %macro_def to code %body] =:
parse [compile %macro_def to %body] as: escaped compile \%macro_def to \%body
parse [compile %macro_def to code %body] as: escaped compile \%macro_def to code \%body
-rule [do %] =: %
+rule [do %] =:
+ lua expr "\(%)(nomsu, vars)"
rule [%tree as lua] =:
lua expr "nomsu:tree_to_lua(\(%tree))"
diff --git a/lib/permissions.nom b/lib/permissions.nom
index a2fffff..bb39ac9 100644
--- a/lib/permissions.nom
+++ b/lib/permissions.nom
@@ -17,7 +17,7 @@ rule [restrict %rules to within %elite-rules] =:
assert (nomsu "check_permission" [%]) ".."
|You do not have permission to restrict permissions for function: \(%)
((nomsu) ->* ["defs",%rule,"whiteset"]) = (..)
- dict: [%, yes] for all %elite-rules
+ dict ([%, yes] for all %elite-rules)
rule [allow %elite-rules to use %rules] =:
%rules = (standardize rules %rules)
diff --git a/lib/secrets.nom b/lib/secrets.nom
index 4c3dca6..76bf6b3 100644
--- a/lib/secrets.nom
+++ b/lib/secrets.nom
@@ -2,14 +2,14 @@ require "lib/core.nom"
compile [with secrets %block] to code: ".."
|do;
- | local secrets = {}
+ | local secrets = {};
| \(%block as lua statements)
|end;
# Access the lua variable that should be within scope
compile [secrets] to: "secrets"
-compile [secret %key; secret value of %key; secret value for %key] to:
+compile [secret %key, secret value of %key, secret value for %key] to:
assert ((%key's "type") == "Var") ".."
|Wrong type, expected Var, but got: \(%key's "type")
"secrets[\(repr (%key's "value"))]"
@@ -17,6 +17,7 @@ compile [secret %key; secret value of %key; secret value for %key] to:
compile [secret %key = %new_value] to code:
assert ((%key's "type") == "Var") ".."
|Wrong type, expected Var, but got: \(%key's "type")
- "secrets[\(repr (%key's "value"))] = \(%new_value as lua)"
+ "secrets[\(repr (%key's "value"))] = \(%new_value as lua);"
rule [rules about secrecy] =: ["with secrets %"]
+
diff --git a/lib/utils.nom b/lib/utils.nom
index 02d3732..608e72f 100644
--- a/lib/utils.nom
+++ b/lib/utils.nom
@@ -23,7 +23,7 @@ compile [capitalize %str, %str capitalized] to:
"(\(%str as lua)):gsub('%l', string.upper, 1)"
compile [say %str] to: ".."
- |nomsu:writeln(\(%str as lua))
+ |nomsu:writeln(nomsu.utils.repr_if_not_string(\(%str as lua)))
# Number ranges
compile [%start to %stop by %step, %start to %stop via %step] to: ".."
diff --git a/nomsu.lua b/nomsu.lua
index 82a8b8f..36eeeba 100644
--- a/nomsu.lua
+++ b/nomsu.lua
@@ -66,20 +66,25 @@ local nomsu = [=[ file <- ({ {| shebang?
noeol_statement <- noeol_functioncall / noeol_expression
inline_statement <- inline_functioncall / inline_expression
- inline_block <- ({ {| "(" inline_statements ")" |} }) -> Block
- eol_block <- ({ {| ":" %ws? noeol_statements eol |} }) -> Block
- indented_block <- ({ {| (":" / "(..)") indent
+ inline_thunk <- ({ {| "{" inline_statements "}" |} }) -> Thunk
+ eol_thunk <- ({ {| ":" %ws? noeol_statements eol |} }) -> Thunk
+ indented_thunk <- ({ {| (":" / "{..}") indent
statements (nodent statements)*
- (dedent / (({.+} ("" -> "Error while parsing block")) => error))
- |} }) -> Block
+ (dedent / (({.+} ("" -> "Error while parsing thunk")) => error))
+ |} }) -> Thunk
inline_nomsu <- ({ ("\" inline_expression) }) -> Nomsu
eol_nomsu <- ({ ("\" noeol_expression) }) -> Nomsu
indented_nomsu <- ({ ("\" expression) }) -> Nomsu
- inline_expression <- number / variable / inline_string / inline_list / inline_block / inline_nomsu
- noeol_expression <- indented_string / indented_block / indented_nomsu / indented_list / inline_expression
- expression <- eol_block / eol_nomsu / noeol_expression
+ inline_expression <- number / variable / inline_string / inline_list / inline_nomsu
+ / inline_thunk / ("(" inline_statement ")")
+ noeol_expression <- indented_string / indented_nomsu / indented_list / indented_thunk
+ / ("(..)" indent
+ statement
+ (dedent / (({.+} ("" -> "Error while parsing indented expression"))))
+ ) / inline_expression
+ expression <- eol_thunk / eol_nomsu / noeol_expression
-- Function calls need at least one word in them
inline_functioncall <- ({ {|
@@ -104,7 +109,7 @@ local nomsu = [=[ file <- ({ {| shebang?
|} (dedent / (({.+} ("" -> "Error while parsing String")) => error))
}) -> String
indented_string_line <- "|" ({~ (("\\" -> "\") / (!string_interpolation [^%nl]))+ ~} / string_interpolation)*
- string_interpolation <- "\" (inline_block / indented_block / dotdot)
+ string_interpolation <- "\" ((noeol_expression dotdot?) / dotdot)
number <- ({ (("-"? (([0-9]+ "." [0-9]+) / ("." [0-9]+) / ([0-9]+)))-> tonumber) }) -> Number
@@ -196,38 +201,44 @@ do
self:write(...)
return self:write("\n")
end,
- def = function(self, invocation, thunk, src)
- local stub, arg_names = self:get_stub(invocation)
- assert(stub, "NO STUB FOUND: " .. tostring(repr(invocation)))
- if self.debug then
- self:writeln(tostring(colored.bright("DEFINING RULE:")) .. " " .. tostring(colored.underscore(colored.magenta(repr(stub)))) .. " " .. tostring(colored.bright("WITH ARGS")) .. " " .. tostring(colored.dim(repr(arg_names))))
+ def = function(self, signature, thunk, src, is_macro)
+ if is_macro == nil then
+ is_macro = false
end
- for i = 1, #arg_names - 1 do
- for j = i + 1, #arg_names do
- if arg_names[i] == arg_names[j] then
- self:error("Duplicate argument in function " .. tostring(stub) .. ": '" .. tostring(arg_names[i]) .. "'")
+ assert(type(thunk) == 'function', "Bad thunk: " .. tostring(repr(thunk)))
+ local canonical_args = nil
+ local _list_0 = self:get_stubs(signature)
+ for _index_0 = 1, #_list_0 do
+ local _des_0 = _list_0[_index_0]
+ local stub, arg_names
+ stub, arg_names = _des_0[1], _des_0[2]
+ assert(stub, "NO STUB FOUND: " .. tostring(repr(signature)))
+ if self.debug then
+ self:writeln(tostring(colored.bright("DEFINING RULE:")) .. " " .. tostring(colored.underscore(colored.magenta(repr(stub)))) .. " " .. tostring(colored.bright("WITH ARGS")) .. " " .. tostring(colored.dim(repr(arg_names))))
+ end
+ for i = 1, #arg_names - 1 do
+ for j = i + 1, #arg_names do
+ if arg_names[i] == arg_names[j] then
+ self:error("Duplicate argument in function " .. tostring(stub) .. ": '" .. tostring(arg_names[i]) .. "'")
+ end
end
end
- end
- do
- local _with_0 = {
+ if canonical_args then
+ assert(utils.equivalent(utils.set(arg_names), canonical_args), "Mismatched args")
+ else
+ canonical_args = utils.set(arg_names)
+ end
+ self.defs[stub] = {
thunk = thunk,
- invocation = invocation,
+ stub = stub,
arg_names = arg_names,
src = src,
- is_macro = false
+ is_macro = is_macro
}
- self.defs[stub] = _with_0
- local _ = nil
- return _with_0
end
end,
- defmacro = function(self, invocation, thunk, src)
- do
- local _with_0 = self:def(invocation, thunk, src)
- _with_0.is_macro = true
- return _with_0
- end
+ defmacro = function(self, signature, thunk, src)
+ return self:def(signature, thunk, src, true)
end,
call = function(self, stub, ...)
local def = self.defs[stub]
@@ -336,14 +347,21 @@ do
end
local code_for_statement = ([[ return (function(nomsu, vars)
%s
- return %s
- end)]]):format(statements or "", expr or "")
+ return %s;
+ end);]]):format(statements or "", expr or "ret")
if self.debug then
self:writeln(tostring(colored.bright("RUNNING LUA:")) .. "\n" .. tostring(colored.blue(colored.bright(code_for_statement))))
end
local lua_thunk, err = load(code_for_statement)
if not lua_thunk then
- error("Failed to compile generated code:\n" .. tostring(colored.bright(colored.blue(code_for_statement))) .. "\n\n" .. tostring(err) .. "\n\nProduced by statement:\n" .. tostring(colored.bright(colored.yellow(statement.src))))
+ local n = 1
+ local fn
+ fn = function()
+ n = n + 1
+ return ("\n%-3d|"):format(n)
+ end
+ local code = "1 |" .. code_for_statement:gsub("\n", fn)
+ error("Failed to compile generated code:\n" .. tostring(colored.bright(colored.blue(code))) .. "\n\n" .. tostring(err) .. "\n\nProduced by statement:\n" .. tostring(colored.bright(colored.yellow(statement.src))))
end
local run_statement = lua_thunk()
local ret
@@ -353,19 +371,20 @@ do
end
if not ok then
self:writeln(tostring(colored.red("Error occurred in statement:")) .. "\n" .. tostring(colored.yellow(statement.src)))
- self:error(repr(return_value))
+ self:writeln(debug.traceback())
+ self:error(ret)
end
insert(buffer, tostring(statements or '') .. "\n" .. tostring(expr and "ret = " .. tostring(expr) or ''))
end
- local lua_code = ([[ return function(nomsu, vars)
- local ret
+ local lua_code = ([[ return (function(nomsu, vars)
+ local ret;
%s
- return ret
- end]]):format(concat(buffer, "\n"))
+ return ret;
+ end);]]):format(concat(buffer, "\n"))
return return_value, lua_code
end,
tree_to_value = function(self, tree, vars)
- local code = "return (function(nomsu, vars)\nreturn " .. tostring(self:tree_to_lua(tree)) .. "\nend)"
+ local code = "return (function(nomsu, vars)\nreturn " .. tostring(self:tree_to_lua(tree)) .. ";\nend);"
if self.debug then
self:writeln(tostring(colored.bright("RUNNING LUA TO GET VALUE:")) .. "\n" .. tostring(colored.blue(colored.bright(code))))
end
@@ -387,33 +406,6 @@ do
elseif "Nomsu" == _exp_0 then
return repr(tree.value), nil
elseif "Thunk" == _exp_0 then
- local _, body = self:tree_to_lua(tree.value)
- return ([[ (function(nomsu, vars)
- local ret
- %s
- return ret
- end)]]):format(body), nil
- elseif "Block" == _exp_0 then
- if #tree.value == 0 then
- return "nil", nil
- end
- if #tree.value == 1 then
- local expr, statement = self:tree_to_lua(tree.value[1])
- if not statement then
- return expr, nil
- end
- end
- local thunk_lua = self:tree_to_lua({
- type = "Thunk",
- value = {
- type = "Statements",
- value = tree.value,
- src = tree.src
- },
- src = tree.src
- })
- return ("%s(nomsu, vars)"):format(thunk_lua), nil
- elseif "Statements" == _exp_0 then
local lua_bits = { }
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
@@ -423,10 +415,14 @@ do
insert(lua_bits, statement)
end
if expr then
- insert(lua_bits, "ret = " .. tostring(expr))
+ insert(lua_bits, "ret = " .. tostring(expr) .. ";")
end
end
- return nil, concat(lua_bits, "\n")
+ return ([[ (function(nomsu, vars)
+ local ret;
+ %s
+ return ret;
+ end)]]):format(concat(lua_bits, "\n"))
elseif "FunctionCall" == _exp_0 then
local stub = self:get_stub(tree)
if self.defs[stub] and self.defs[stub].is_macro then
@@ -532,7 +528,7 @@ do
return
end
local _exp_0 = tree.type
- if "List" == _exp_0 or "File" == _exp_0 or "Block" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
+ if "List" == _exp_0 or "File" == _exp_0 or "Thunk" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
local _list_0 = tree.value
for _index_0 = 1, #_list_0 do
local v = _list_0[_index_0]
@@ -578,7 +574,7 @@ do
if vars[tree.value] ~= nil then
tree = vars[tree.value]
end
- elseif "File" == _exp_0 or "Nomsu" == _exp_0 or "Thunk" == _exp_0 or "Block" == _exp_0 or "List" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
+ elseif "File" == _exp_0 or "Nomsu" == _exp_0 or "Thunk" == _exp_0 or "List" == _exp_0 or "FunctionCall" == _exp_0 or "String" == _exp_0 then
local new_value = self:replaced_vars(tree.value, vars)
if new_value ~= tree.value then
do
@@ -645,11 +641,49 @@ do
end
end
return concat(stub, " "), arg_names, args
- elseif "Block" == _exp_0 then
- self:writeln(debug.traceback())
- return self:error("Please pass in a single line from a block, not the whole thing:\n" .. tostring(self:tree_to_str(x)))
+ else
+ return self:error("Unsupported get stub type: " .. tostring(x.type))
end
end,
+ get_stubs = function(self, x)
+ if type(x) ~= 'table' then
+ return {
+ {
+ self:get_stub(x)
+ }
+ }
+ end
+ local _exp_0 = x.type
+ if nil == _exp_0 then
+ local _accum_0 = { }
+ local _len_0 = 1
+ for _index_0 = 1, #x do
+ local i = x[_index_0]
+ _accum_0[_len_0] = {
+ self:get_stub(i)
+ }
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ elseif "List" == _exp_0 then
+ local _accum_0 = { }
+ local _len_0 = 1
+ local _list_0 = x.value
+ for _index_0 = 1, #_list_0 do
+ local i = _list_0[_index_0]
+ _accum_0[_len_0] = {
+ self:get_stub(i)
+ }
+ _len_0 = _len_0 + 1
+ end
+ return _accum_0
+ end
+ return {
+ {
+ self:get_stub(x)
+ }
+ }
+ end,
var_to_lua_identifier = function(self, var)
if type(var) == 'table' and var.type == "Var" then
var = var.value
@@ -803,12 +837,12 @@ if arg and arg[1] then
else
output = io.open(arg[2], 'w')
end
- output:write(([[ local NomsuCompiler = require('nomsu')
- local c = NomsuCompiler()
- local run = function(nomsu, vars)
+ output:write(([[ local NomsuCompiler = require('nomsu');
+ local c = NomsuCompiler();
+ local run = (function(nomsu, vars)
%s
- end
- return run(c, {})
+ end);
+ return run(c, {});
]]):format(code))
end
elseif arg then