require "lib/core.nom" require "lib/secrets.nom" 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 ..=: lua expr "secrets.users:by_name(vars.name) or compiler:error('Failed to find user: '..tostring(vars.name))" rule: add user %name ..=: lua expr "secrets.users:add(vars.name)" macro: @ %name_block ..=: %name_str =: lua expr "vars.name_block.value.value.src" ".." |compiler:call("find user %", \repr %name_str\) rule: everybody everyone ..=: (%entry's "key") for %entry in (entries in (secret %users)) 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 (..) [%inv's "key", dict (%entry for %entry in (entries in (%inv's "value")))] for %inv in (entries in (secret %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 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 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 rule: %person has %item %person has a %item %person has an %item ..=: (%person's stock of %item) > 0 rule: rules that change the inventory ..=: [..] "give % % %", "give % % % from %" rule: rules that view the inventory ..=: [..] "inventory", "%'s inventory", "%'s stock of %", "%'s stock of % as str" rule: you ..=: lua expr "(compiler.you or 'Anonymous')" rule: make %person %action make %person do %action ..=: lua block ".." |do | local old_you = compiler.you | compiler.you = vars.person | ret = vars.action(compiler, vars) | compiler.you = old_you |end say "====================================================" say " NEW GAME" say "====================================================" # Unanimity for proposals with secrets: rule: pending proposal ..=: secret %pending rule: propose source %src ..=: if (secret %pending): error "A proposal is already pending." secret %pending =: %src secret %approvals =: [] say ".." |Proposal: |\%src\ macro block: propose %action ..=: %source =: source code from tree %action ".." |compiler:call("propose source %", \repr %source\) rule: with everyone's approval do %action ..=: run %action rule: mark %who as approving ..=: if (not (pending proposal)): say "No action pending" return (secret %approvals)-> %who =: yes # Check for uncounted votes: for %user in (everybody): if (not ((secret %approvals)->%user)): return # No one dissents with everyone's approval do (pending proposal) secret %pending =: nil secret %approvals =: nil rule: mark %who as rejecting ..=: secret %pending =: nil secret %approvals =: nil rule: approve vote yes vote yea ..=: mark (you) as approving 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 ..=: 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) ..to within "with everyone's approval do %" say "Rule making is now restricted" join propose: say "Hello world" approve propose: say "Hello world again" approve propose: give "democracy" 1 "possibility" if ("democracy" has "possibility"): say "DEMOCRACY WORKS!!!" ..else: say "democracy has failed :(" approve propose: rule: fart ..=: say "poot" say "fart should have been defined" approve say "doop" fart propose: with secrets: 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 =: [] 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 ..=: do %action rule: the winner ..=: secret %winner rule: vote for %candidate ..=: for %c in (secret %candidates): if (%c == %candidate): go to %candidate-is-legit error ".." |Invalid candidate: \%candidate\ -> %candidate-is-legit (secret %votes)->(you) =: %candidate %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 after winning a fair election do (secret %action) close the election rule: rules that change the election ..=: [..] "open election %", "close the election", "vote for %" rule: rules that view the election ..=: [..] "votes for %" approve propose: rule: as bill %action ..=: if ((you) == "Anonymous"): make "bill" do %action ..else: say ".." |Who do you think you are, \you\? allow ["as bill %"] to use ["make % %"] approve as bill: join propose: rule: as dave %action ..=: if ((you) == "Anonymous"): make "dave" do %action ..else: say ".." |Who do you think you are, \you\? allow ["as dave %"] to use ["make % %"] approve as bill: approve as dave: join propose: rule: declare war ..=: say "WAR!!!" with secrets: secret %president =: nil rule: elect president from %candidates ..=: open election %candidates: say ".."|Hail to the chief: \the winner\ secret %president =: the winner rule: as the president do %action ..=: do %action restrict "declare war" to within "as the president do %" approve as bill: approve as dave: approve elect president from ["tom", "dick", "harry"] vote for "dick" as bill: vote for "dick" as dave: as the president do: declare war propose: rule: take a shit ..=: say "shit taken." approve as bill: approve as dave: approve take a shit say "Done."