More stuff is working more better.

This commit is contained in:
Bruce Hill 2017-09-29 22:04:03 -07:00
parent 723a4c3871
commit e2bbbfe161
9 changed files with 104 additions and 109 deletions

View File

@ -3,7 +3,6 @@ require "lib/permissions.nom"
require "lib/secrets.nom" require "lib/secrets.nom"
require "lib/plurals.nom" require "lib/plurals.nom"
# Users: # Users:
with secrets: with secrets:
secret %users =: lua expr ".." secret %users =: lua expr ".."
@ -11,18 +10,14 @@ with secrets:
| {by_name=function(self, key) return "User<"..key..">" end, | {by_name=function(self, key) return "User<"..key..">" end,
| add=function(self, key) self[key] = self:by_name(key) end} | add=function(self, key) self[key] = self:by_name(key) end}
|}) |})
rule [find user %name] =: rule (find user %name; @%name) =:
lua expr "secrets.users:by_name(vars.name) or nomsu:error('Failed to find user: '..tostring(vars.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)" lua expr "secrets.users:add(vars.name)"
macro [@%name_block] =: rule (everybody; everyone) =:
%name_str =: lua expr "vars.name_block.value.value.src"
".."
|nomsu:call("find user %", \repr %name_str\)
rule [everybody, everyone] =:
(%entry's "key") for %entry in (entries in (secret %users)) (%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: # Inventory:
with secrets: with secrets:
@ -33,57 +28,55 @@ with secrets:
| return t | return t
|end}) |end})
rule [inventory] =: rule (inventory) =: dict:
dict (..)
[%inv's "key", dict (%entry for %entry in (entries in (%inv's "value")))] [%inv's "key", dict (%entry for %entry in (entries in (%inv's "value")))]
..for %inv in (entries in (secret %inventory)) ..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))) dict (%entry for %entry in (entries in ((secret %inventory)->%person)))
rule [%person's stock of %item] =: rule (%person's stock of %item) =:
%item =: canonicalize %item %item =: canonicalize %item
((%person's inventory)->%item) or 0 ((%person's inventory)->%item) or 0
rule [%person's stock of %item as str] =: rule (%person's stock of %item as str) =:
%item =: canonicalize %item %item =: canonicalize %item
%count =: %person's stock of %item %count =: %person's stock of %item
".." ".."
|\%count\ \(singular %item) if (%count == 1) else (plural %item)\ |\(%count) \((singular %item) if (%count == 1) else (plural %item))
rule [give %person %count %item] =: rule (give %person %count %item) =:
%item =: canonicalize %item %item =: canonicalize %item
(%person's inventory)-> %item =: (%person's stock of %item) + %count (%person's inventory)-> %item =: (%person's stock of %item) + %count
rule [give %person %count %item from %donor] =: rule (give %person %count %item from %donor) =:
%item =: canonicalize %item %item =: canonicalize %item
if ((%donor's stock of %item) < %count): if ((%donor's stock of %item) < %count):
say ".." say ".."
|\%donor\ does not have enough \%item\ to transfer |\(%donor) does not have enough \(%item) to transfer
..else: ..else:
(%person's inventory)->%item =: (%person's stock of %item) + %count (%person's inventory)->%item =: (%person's stock of %item) + %count
(%donor's inventory)->%item =: (%donor's stock of %item) - %count (%donor's inventory)->%item =: (%donor's stock of %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 (%person's stock of %item) > 0
rule [rules that change the inventory] =: [..] rule (rules that change the inventory) =: [..]
"give % % %", "give % % % from %" "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" "inventory", "%'s inventory", "%'s stock of %", "%'s stock of % as str"
rule [you] =: rule (you) =:
lua expr "(nomsu.you or 'Anonymous')" lua expr "(nomsu.you or 'Anonymous')"
rule [make %person %action, make %person do %action] =: rule (make %person %action; make %person do %action) =:
lua block ".." lua code ".."
|do
|local old_you = nomsu.you |local old_you = nomsu.you
|nomsu.you = vars.person |nomsu.you = vars.person
| ret = vars.action(nomsu, vars) do %action
lua code ".."
|nomsu.you = old_you |nomsu.you = old_you
|end
say "====================================================" say "===================================================="
say " NEW GAME" say " NEW GAME"
@ -91,27 +84,26 @@ say "===================================================="
# Unanimity for proposals # Unanimity for proposals
with secrets: with secrets:
rule [pending proposal] =: rule (pending proposal) =:
secret %pending secret %pending
rule [propose source %src] =: rule (propose source %src) =:
if (secret %pending): if (secret %pending):
error "A proposal is already pending." error "A proposal is already pending."
secret %pending =: %src secret %pending =: %src
secret %approvals =: [] secret %approvals =: []
say ".." say ".."
|Proposal: |Proposal:
|\%src\ |\(%src)
macro block [propose %action] =: parse (propose %action) as:
%source =: source code from tree %action propose source:
".." source code from tree \%action
|nomsu:call("propose source %", \repr %source\)
rule [with everyone's approval do %action] =: rule (with everyone's approval do %action) =:
run %action run %action
rule [mark %who as approving] =: rule (mark %who as approving) =:
if (not (pending proposal)): if (not (pending proposal)):
say "No action pending" say "No action pending"
return return
@ -128,30 +120,29 @@ with secrets:
secret %pending =: nil secret %pending =: nil
secret %approvals =: nil secret %approvals =: nil
rule [mark %who as rejecting] =: rule (mark %who as rejecting) =:
secret %pending =: nil secret %pending =: nil
secret %approvals =: nil secret %approvals =: nil
rule [approve, vote yes, vote yea] =: rule (approve; vote yes; vote yea) =:
mark (you) as approving mark (you) as approving
rule [reject, vote no, vote nay, veto, disapprove] =: rule (reject; vote no; vote nay; veto; disapprove) =:
mark (you) as rejecting mark (you) as rejecting
restrict "with everyone's approval do %" to within "mark % as approving" restrict "with everyone's approval do %" to within "mark % as approving"
restrict "mark % as approving" to within "approve" restrict "mark % as approving" to within "approve"
restrict "mark % as rejecting" to within "reject" restrict "mark % as rejecting" to within "reject"
rule [join] =: rule (join) =:
add user (you) add user (you)
say ".." say ".."
|Welcome to the game, \you\! |Welcome to the game, \(you)!
restrict (rules that change users) to within "join" restrict (rules that change users) to within "join"
restrict (..) restrict: flatten [..]
flatten [..]
["rule % = %", "make % %", "restrict % to within %"] ["rule % = %", "make % %", "restrict % to within %"]
(rules that change the inventory) (rules that change the inventory)
..to within "with everyone's approval do %" ..to within "with everyone's approval do %"
@ -176,7 +167,7 @@ propose:
approve approve
propose: propose:
rule [fart] =: rule (fart) =:
say "poot" say "poot"
say "fart should have been defined" say "fart should have been defined"
approve approve
@ -185,7 +176,7 @@ fart
propose: propose:
with secrets: with secrets:
rule [open election %candidates %action] =: rule (open election %candidates %action) =:
if (secret %candidates): if (secret %candidates):
error "An election is already in progress." error "An election is already in progress."
..else: ..else:
@ -194,82 +185,85 @@ propose:
secret %action =: %action secret %action =: %action
secret %winner =: nil secret %winner =: nil
rule [close the election] =: rule (close the election) =:
secret %candidates =: nil secret %candidates =: nil
secret %votes =: nil secret %votes =: nil
secret %action =: nil secret %action =: nil
secret %winner =: nil secret %winner =: nil
rule [votes for %candidate] =: rule (votes for %candidate) =:
%votes =: [] %votes =: []
for %entry in (entries in (secret %votes)): for %entry in (entries in (secret %votes)):
if ((%entry's "value") == %candidate): if ((%entry's "value") == %candidate):
add (%entry's "key") to %votes add (%entry's "key") to %votes
%votes %votes
rule [after winning a fair election do %action] =: rule (after winning a fair election do %action) =:
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): for %c in (secret %candidates):
if (%c == %candidate): if (%c == %candidate):
go to %candidate-is-legit go to %candidate-is-legit
error ".." error ".."
|Invalid candidate: \%candidate\ |Invalid candidate: \(%candidate)
-> %candidate-is-legit -> %candidate-is-legit
(secret %votes)->(you) =: %candidate (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 ".." say ".."
|Vote cast. \%candidate\ now has \100 * %vote-percent\% of the votes. |Vote cast. \(%candidate) now has \(100 * %vote-percent)% of the votes.
if (%vote-percent > 0.5): if (%vote-percent > 0.5):
secret %winner =: %candidate secret %winner =: %candidate
after winning a fair election do (secret %action) after winning a fair election do (secret %action)
close the election close the election
rule [rules that change the election] =: [..] rule (rules that change the election) =: [..]
"open election %", "close the election", "vote for %" "open election %", "close the election", "vote for %"
rule [rules that view the election] =: [..] rule (rules that view the election) =: [..]
"votes for %" "votes for %"
approve approve
propose: propose:
rule [as bill %action] =: rule (_as bill %action) =:
if ((you) == "Anonymous"): if ((you) == "Anonymous"):
make "bill" do %action make "bill" do %action
..else: ..else:
say ".." say ".."
|Who do you think you are, \you\? |Who do you think you are, \(you)?
allow ["as bill %"] to use ["make % %"] parse (as bill %) as (_as bill \%)
allow ["_as bill %"] to use ["make % %"]
approve approve
as bill: join as bill: join
propose: propose:
rule [as dave %action] =: rule (_as dave %action) =:
if ((you) == "Anonymous"): if ((you) == "Anonymous"):
make "dave" do %action make "dave" do %action
..else: ..else:
say ".." say ".."
|Who do you think you are, \you\? |Who do you think you are, \(you)?
allow ["as dave %"] to use ["make % %"] parse (as dave %) as (_as dave \%)
allow ["_as dave %"] to use ["make % %"]
approve approve
as bill: approve as bill: approve
as dave: join as dave: join
propose: propose:
rule [declare war] =: say "WAR!!!" rule (declare war) =: say "WAR!!!"
with secrets: with secrets:
secret %president =: nil secret %president =: nil
rule [elect president from %candidates] =: rule (elect president from %candidates) =:
open election %candidates: open election %candidates:
say ".."|Hail to the chief: \the winner\ 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 %" restrict "declare war" to within "as the president do %"
approve approve
@ -284,7 +278,7 @@ as dave:
declare war declare war
propose: propose:
rule [take a shit] =: say "shit taken." rule (take a shit) =: say "shit taken."
approve approve
as bill: approve as bill: approve

View File

@ -40,7 +40,7 @@ compile (continue %var; go to next %var; on to the next %var) to code: ".."
# While loops # While loops
compile (repeat while %condition %body) to block: ".." compile (repeat while %condition %body) to block: ".."
|while \(%condition) do |while \(%condition as lua) do
| \(%body as lua statements) | \(%body as lua statements)
| ::continue_repeat:: | ::continue_repeat::
|end |end
@ -87,8 +87,7 @@ parse (for all %iterable %body) as: for % in %iterable %body
compile (when %body) to block: compile (when %body) to block:
%result =: "" %result =: ""
%fallthroughs =: [] %fallthroughs =: []
for %statement in (%body's "value"): for %func-call in (%body's "value"):
%func-call =: %statement's "value"
assert ((%func-call's "type") == "FunctionCall") ".." assert ((%func-call's "type") == "FunctionCall") ".."
|Invalid format for 'when' statement. Only '*' blocks are allowed. |Invalid format for 'when' statement. Only '*' blocks are allowed.
%tokens =: %func-call's "value" %tokens =: %func-call's "value"
@ -103,7 +102,7 @@ compile (when %body) to block:
%action =: %tokens -> 3 %action =: %tokens -> 3
if (%action == (nil)): if (%action == (nil)):
lua block "table.insert(vars.fallthroughs, vars.condition)" lua block "table.insert(vars.fallthroughs, vars.condition)"
go to next %statement go to next %func-call
if (lua expr "vars.condition.type == 'Word' and vars.condition.value == 'else'"): if (lua expr "vars.condition.type == 'Word' and vars.condition.value == 'else'"):
%result join=: ".." %result join=: ".."
@ -129,10 +128,9 @@ compile (when %body) to block:
# Switch statement # Switch statement
compile (when %branch-value == ? %body) to block: compile (when %branch-value == ? %body) to block:
%result =: "local branch_value = \(%branch-value)" %result =: "local branch_value = \(%branch-value as lua)"
%fallthroughs =: [] %fallthroughs =: []
for %statement in (%body's "value"): for %func-call in (%body's "value"):
%func-call =: %statement's "value"
assert ((%func-call's "type") == "FunctionCall") ".." assert ((%func-call's "type") == "FunctionCall") ".."
|Invalid format for 'when' statement. Only '*' blocks are allowed. |Invalid format for 'when' statement. Only '*' blocks are allowed.
%tokens =: %func-call's "value" %tokens =: %func-call's "value"
@ -147,7 +145,7 @@ compile (when %branch-value == ? %body) to block:
%action =: %tokens -> 3 %action =: %tokens -> 3
if (%action == (nil)): if (%action == (nil)):
lua block "table.insert(vars.fallthroughs, vars.condition)" lua block "table.insert(vars.fallthroughs, vars.condition)"
go to next %statement go to next %func-call
if (lua expr "vars.condition.type == 'Word' and vars.condition.value == 'else'"): if (lua expr "vars.condition.type == 'Word' and vars.condition.value == 'else'"):
%result join=: ".." %result join=: ".."

View File

@ -13,7 +13,7 @@ lua code ".."
|nomsu:def(%s, %s, %s) |nomsu:def(%s, %s, %s)
|]]):format(nomsu:repr(canonical.src), thunk, nomsu:repr(body.src)) |]]):format(nomsu:repr(canonical.src), thunk, nomsu:repr(body.src))
| if #aliases > 1 then | if #aliases > 1 then
| lua = lua .. ([[ | lua = lua .. "\n" .. ([[
|do |do
| local aliased = %s | local aliased = %s
| local src = %s | local src = %s
@ -27,8 +27,7 @@ lua code ".."
|]]):format(nomsu:repr(aliases[i].src), nomsu:repr(canonical.src)) |]]):format(nomsu:repr(aliases[i].src), nomsu:repr(canonical.src))
| end | end
| lua = lua .. [[ | lua = lua .. [[
|end |end]]
|]]
| end | end
| return nil, lua | return nil, lua
|end, "<source can be found in lib/metaprogramming.nom>") |end, "<source can be found in lib/metaprogramming.nom>")
@ -72,6 +71,8 @@ parse (compile %macro_def to block %body) as: escaped compile \%macro_def to cod
| \(%body) | \(%body)
|end |end
rule (do %) =: %
rule (%tree as lua) =: rule (%tree as lua) =:
lua expr "nomsu:tree_to_lua(\(%tree))" lua expr "nomsu:tree_to_lua(\(%tree))"
rule (%tree as value) =: rule (%tree as value) =:

View File

@ -29,11 +29,11 @@ compile (%obj's %key; %obj -> %key) to: "\(%obj as lua)[\(%key as lua)]"
# Variable assignment operator, and += type versions # Variable assignment operator, and += type versions
compile (%var = %val) to code: "\(%var as lua) = \(%val as lua)" compile (%var = %val) to code: "\(%var as lua) = \(%val as lua)"
compile (%var += %val) to code: "\(%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) -= \(%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) *= \(%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) /= \(%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) ^= \(%val as lua)" compile (%var ^= %val) to code: "\(%var as lua) = \(%var as lua) ^ \(%val as lua)"
compile (%var and= %val) to code: "\(%var as lua) = \(%var as lua) and\(%val as lua)" compile (%var and= %val) to code: "\(%var as lua) = \(%var as lua) and\(%val as lua)"
compile (%var or= %val) to code: "\(%var as lua) = \(%var as lua) or \(%val as lua)" compile (%var or= %val) to code: "\(%var as lua) = \(%var as lua) or \(%val as lua)"
compile (%var join= %val) to code: "\(%var as lua) = \(%var as lua) .. \(%val as lua)" compile (%var join= %val) to code: "\(%var as lua) = \(%var as lua) .. \(%val as lua)"

View File

@ -4,17 +4,24 @@ require "lib/operators.nom"
require "lib/collections.nom" require "lib/collections.nom"
# Permission functions # Permission functions
rule (standardize rules %rules) =:
if (lua expr "type(vars.rules) == 'string'"): %rules = [%rules]
(nomsu "get_stub" [%]) for all %rules
rule (restrict %rules to within %elite-rules) =: rule (restrict %rules to within %elite-rules) =:
%rules =: standardize rules %rules
%elite-rules =: standardize rules %elite-rules
say "Restricting \(%rules) to within \(%elite-rules)" say "Restricting \(%rules) to within \(%elite-rules)"
for all (flatten [%elite-rules, %rules]): for all (flatten [%elite-rules, %rules]):
assert ((nomsu's "defs") has key %) "Undefined function: \(%)" assert ((nomsu's "defs") has key %) "Undefined function: \(%)"
for all %rules: for %rule in %rules:
assert (nomsu "check_permission" [%]) ".." assert (nomsu "check_permission" [%]) ".."
|You do not have permission to restrict permissions for function: \(%) |You do not have permission to restrict permissions for function: \(%)
((nomsu) ->* ["defs",%,"whiteset"]) =: ((nomsu) ->* ["defs",%rule,"whiteset"]) =:
dict: [%, yes] for %it in %elite-rules dict: [%, yes] for all %elite-rules
rule (allow %elite-rules to use %rules) =: rule (allow %elite-rules to use %rules) =:
%rules =: standardize rules %rules
%elite-rules =: standardize rules %elite-rules
say "Allowing \(%elite-rules) to use \(%rules)" say "Allowing \(%elite-rules) to use \(%rules)"
for all (flatten [%elite-rules, %rules]): for all (flatten [%elite-rules, %rules]):
assert ((nomsu's "defs") has key %) "Undefined function: \(%)" assert ((nomsu's "defs") has key %) "Undefined function: \(%)"
@ -26,12 +33,14 @@ rule (allow %elite-rules to use %rules) =:
for all %elite-rules: %whiteset -> % = (yes) for all %elite-rules: %whiteset -> % = (yes)
rule (forbid %pleb-rules to use %rules) =: rule (forbid %pleb-rules to use %rules) =:
%rules =: standardize rules %rules
%pleb-rules =: standardize rules %pleb-rules
say "Forbidding \(%pleb-rules) to use \(%rules)" say "Forbidding \(%pleb-rules) to use \(%rules)"
for all (flatten [%pleb-rules, %used]): for all (flatten [%pleb-rules, %used]):
assert ((nomsu's "defs") has key %) "Undefined function: \(%)" assert ((nomsu's "defs") has key %) "Undefined function: \(%)"
for all %rules: for all %rules:
assert (nomsu "check_permission" [%]) ".." assert (nomsu "check_permission" [%]) ".."
|You do not have permission to grant permissions for function: \%it\ |You do not have permission to grant permissions for function: \(%)
%whiteset =: (nomsu) ->* ["defs",%,"whiteset"] %whiteset =: (nomsu) ->* ["defs",%,"whiteset"]
assert %whiteset ".." assert %whiteset ".."
|Cannot individually restrict permissions for \(%) because it is currently |Cannot individually restrict permissions for \(%) because it is currently

View File

@ -18,18 +18,18 @@ with secrets:
| return key | return key
|end}) |end})
rule [the plural of %singular is %plural] =: rule (the plural of %singular is %plural) =:
(secret %plurals)->%singular =: %plural (secret %plurals)->%singular =: %plural
(secret %singulars)->%plural =: %singular (secret %singulars)->%plural =: %singular
(secret %canonicals)->%plural =: %singular (secret %canonicals)->%plural =: %singular
rule [singular %plural] =: rule (singular %plural) =:
%plural in (secret %singulars) %plural in (secret %singulars)
rule [plural %singular] =: rule (plural %singular) =:
%singular in (secret %plurals) %singular in (secret %plurals)
rule [canonicalize %item-name] =: rule (canonicalize %item-name) =:
%item-name in (secret %canonicals) %item-name in (secret %canonicals)
rule [rules that change plurals] =: ["the plural of % is %"] rule (rules that change plurals) =: ["the plural of % is %"]

View File

@ -17,13 +17,4 @@ compile (secret %key = %new_value) to code:
|Wrong type, expected Var, but got: \(%key's "type") |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)"
with secrets: rule (rules about secrecy) =: ["with secrets %"]
secret %foo = 5
rule (plumb %) =:
secret %foo = %
rule (frop) =:
secret %foo
say (frop)
plumb 99
say (frop)

View File

@ -95,7 +95,8 @@ local nomsu = [=[ file <- ({ {| shebang?
word <- ({ !number {%wordchar (!"'" %wordchar)*} }) -> Word word <- ({ !number {%wordchar (!"'" %wordchar)*} }) -> Word
inline_string <- ({ '"' {| inline_string <- ({ '"' {|
({~ (("\\" -> "\") / ('\"' -> '"') / (!string_interpolation [^%nl"]))+ ~} ({~ (("\\" -> "\") / ('\"' -> '"') / ("\n" -> "
") / (!string_interpolation [^%nl"]))+ ~}
/ string_interpolation)* |} '"' }) -> String / string_interpolation)* |} '"' }) -> String
indented_string <- ({ '".."' indent {| indented_string <- ({ '".."' indent {|
indented_string_line (nodent {~ "" -> " indented_string_line (nodent {~ "" -> "

View File

@ -98,7 +98,8 @@ nomsu = [=[
word <- ({ !number {%wordchar (!"'" %wordchar)*} }) -> Word word <- ({ !number {%wordchar (!"'" %wordchar)*} }) -> Word
inline_string <- ({ '"' {| inline_string <- ({ '"' {|
({~ (("\\" -> "\") / ('\"' -> '"') / (!string_interpolation [^%nl"]))+ ~} ({~ (("\\" -> "\") / ('\"' -> '"') / ("\n" -> "
") / (!string_interpolation [^%nl"]))+ ~}
/ string_interpolation)* |} '"' }) -> String / string_interpolation)* |} '"' }) -> String
indented_string <- ({ '".."' indent {| indented_string <- ({ '".."' indent {|
indented_string_line (nodent {~ "" -> " indented_string_line (nodent {~ "" -> "