diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2017-10-02 19:00:58 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2017-10-02 19:00:58 -0700 |
| commit | 63ed265157de8ff91dee606b0e61e52214a4083b (patch) | |
| tree | 0b9aa6e920d8ea9a4938a59a0e7b39355b108150 | |
| parent | dcd3391b36c7accc194cfdc8654db085c9bc820e (diff) | |
More progress towards making everything work.
| -rw-r--r-- | examples/parser_tests.nom | 183 | ||||
| -rw-r--r-- | examples/sample_code.nom | 30 | ||||
| -rw-r--r-- | examples/sample_game.nom | 185 | ||||
| -rw-r--r-- | lib/collections.nom | 2 | ||||
| -rw-r--r-- | lib/metaprogramming.nom | 3 | ||||
| -rw-r--r-- | lib/permissions.nom | 2 | ||||
| -rw-r--r-- | lib/secrets.nom | 7 | ||||
| -rw-r--r-- | lib/utils.nom | 2 | ||||
| -rw-r--r-- | nomsu.lua | 194 |
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: ".." @@ -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 |
