aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2017-08-18 21:08:28 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2017-08-18 21:08:28 -0700
commitdc152f88b6ff1d778a8106ee49b8c4e3d902404a (patch)
treedfd2471cab5de49b8b1472f00236b566e169f8b4
parentb2d49dde55522429f805590c40f96a95bfc67106 (diff)
Cleanup and utils file.
-rwxr-xr-xcore.moon104
-rwxr-xr-xgame1.moon21
-rw-r--r--nomic.moon19
-rw-r--r--utils.moon119
4 files changed, 166 insertions, 97 deletions
diff --git a/core.moon b/core.moon
index 7155829..1ea22dc 100755
--- a/core.moon
+++ b/core.moon
@@ -1,26 +1,11 @@
#!/usr/bin/env moon
nomic = require 'nomic'
+utils = require 'utils'
game = nomic()
-is_list = (t)->
- i = 0
- for _ in pairs(t)
- i += 1
- if t[i] == nil then return false
- return true
-
-repr = (x)->
- if type(x) == 'table'
- if is_list x
- "[#{table.concat([repr(i) for i in *x], ", ")}]"
- else
- "{#{table.concat(["#{k}: #{v}" for k,v in pairs x], ", ")}}"
- else
- tostring(x)
-
-game\def {[[print $str]], [[say $str]]}, (args)=> print(repr(args.str))
+game\def {[[print $str]], [[say $str]]}, (args)=> print(utils.repr(args.str))
game\def {[[printf $str]]}, (args)=>
- for s in *args.str do io.write(repr(s))
+ for s in *args.str do io.write(utils.repr(s))
io.write("\n")
game\def [[return $value]], (args)=> args.value
@@ -36,7 +21,7 @@ game\def [[$signature := $body]], (args)=>
return
@\def args.signature, args.body
- print "Defined new rule: \"#{game.repr(args.signature)}\""
+ print "Defined new rule: #{utils.repr(args.signature)}"
--print debug.getinfo(args.body, "S").source
return nil
@@ -78,7 +63,7 @@ game\def [[help $invocation]], (args)=>
rules[r] = c
invocations[r] = i
best = [r for r in pairs rules]
- table.sort best, ((a,b)-> rules[a] > rules[b])
+ utils.sort best, rules
if rules[best[1]] > 0
for r in *best
if rules[r] < rules[best[1]]
@@ -95,18 +80,7 @@ game\macro "None", -> "nil"
game\macro "null", -> "nil"
game\def [[nop]], ((args)=> nil), "... does nothing, returns nil ..."
-game\def [[$x == $y]], (args)=>
- with args
- if .x == .y then return true
- if type(.x) != type(.y) then return false
- if type(.x) != 'table' then return false
- for k,v in pairs(.x)
- if .y[k] != v
- return false
- for k,v in pairs(.y)
- if .x[k] != v
- return false
- return true
+game\def [[$x == $y]], (args)=> utils.equivalent(args.x, args.y)
game\run [=[
["$x != $y", "$x <> $y", "$x ~= $y"] := {return (not (x == y))}
]=]
@@ -147,57 +121,25 @@ game\run [=[
game\def [[random]], -> math.random()
-game\def [[sum $items]], (args)=>
- tot = 0
- for x in *args.items do tot += x
- return tot
-
-game\def [[all $items]], (args)=>
- for x in *args.items
- if not x then return false
- return true
-
-game\def [[any $items]], (args)=>
- for x in *args.items
- if x then return true
- return false
-
-game\def {[[average $items]], [[avg $items]]}, (args)=>
- tot = 0
- for x in *args.items do tot += x
- return tot / #args.items
-
+game\def [[sum $items]], (args)=> utils.sum(args.items)
+game\def [[all $items]], (args)=> utils.all(args.items)
+game\def [[any $items]], (args)=> utils.any(args.items)
+game\def {[[average $items]], [[avg $items]]}, (args)=> utils.sum(items)/#items
game\def {[[min $items]], [[smallest $items]], [[lowest $items]], [[fewest $items]]}, (args)=>
- with args
- min = .items[1]
- for i=2,#.items
- if .items[i] < min
- min = .items[i]
- return min
+ utils.min(args.items)
game\def {[[max $items]], [[largest $items]], [[highest $items]], [[most $items]]}, (args)=>
- with args
- max = .items[1]
- for i=2,#.items
- if .items[i] > max
- max = .items[i]
- return max
+ utils.max(args.items)
game\def {[[argmin $items]]}, (args)=>
- with args
- min = .items[1]
- for i=2,#.items
- if .items[i][2] < min[2]
- min = .items[i]
- return min
-
+ utils.min(args.items, ((i)->i[2]))
game\def {[[argmax $items]]}, (args)=>
- with args
- max = .items[1]
- for i=2,#.items
- if .items[i][2] > max[2]
- max = .items[i]
- return max
+ utils.max(args.items, ((i)->i[2]))
+
+game\def {[[min $items with respect to $keys]]}, (args)=>
+ utils.min(args.items, args.keys)
+game\def {[[max $items with respect to $keys]]}, (args)=>
+ utils.max(args.items, args.keys)
game\def {[[$index st in $list]], [[$index nd in $list]], [[$index rd in $list]], [[$index th in $list]]}, (args)=>
with args
@@ -211,10 +153,8 @@ game\def {[[index of $item in $list]]}, (args)=>
if type(.list) != 'table'
print "Not a list: #{.list}"
return
- for i,x in ipairs .list
- if x == .item
- return i
- return nil
+ utils.key_for(args.list, args.item)
+
game\run [=[
["$item is in $list", "$list contains $item"] := {(index of $item in $list) != (nil)}
]=]
@@ -224,7 +164,7 @@ game\def {[[# $list]], [[length of $list]], [[size of $list]]}, (args)=>
if type(.list) != 'table'
print "Not a list: #{.list}"
return
- #.list
+ return #(.list)
return game
diff --git a/game1.moon b/game1.moon
index 11bc8ce..d3e6a78 100755
--- a/game1.moon
+++ b/game1.moon
@@ -1,4 +1,5 @@
#!/usr/bin/env moon
+utils = require 'utils'
Game = require 'nomic'
core_game = require 'core'
@@ -40,7 +41,7 @@ game\def {"restrict $actions to $whitelist"}, (args)=>
whitelist = @all_aliases(if type(.whitelist) == 'table' then .whitelist else {.whitelist})
@\set_whitelist actions, whitelist
for action in *actions
- print("Restricting #{Game.repr(action)} to #{Game.repr(whitelist)}")
+ print("Restricting #{utils.repr(action)} to #{utils.repr(whitelist)}")
game\def {"permit $whitelist to $actions"}, (args)=>
with args
@@ -50,7 +51,7 @@ game\def {"permit $whitelist to $actions"}, (args)=>
if not @authorized[action]
print "#{action} is already available to everyone."
continue
- print("Permitting #{Game.repr(action)} to #{Game.repr(whitelist)}")
+ print("Permitting #{utils.repr(action)} to #{utils.repr(whitelist)}")
for w in *whitelist
@authorized[action][w] = true
@@ -62,7 +63,7 @@ game\def {"revoke $actions rights from $whitelist"}, (args)=>
if not @authorized[action]
print "#{action} is available to everyone, it can't be restricted."
continue
- print("Revoking the right of #{Game.repr(action)} to use #{Game.repr(whitelist)}")
+ print("Revoking the right of #{utils.repr(action)} to use #{utils.repr(whitelist)}")
for w in *whitelist
@authorized[action][w] = nil
@@ -134,6 +135,10 @@ sudo {
if (everyone approves $pending) {
sudo $pending
unpropose
+ } else {
+ let "approvers" = (# (* $pending = "approved"))
+ let "num-players" = (# (players))
+ printf [$approvers, "/", $num-players, " players have approved"]
}
}
@@ -190,8 +195,10 @@ propose {
"fart" := {
say "poot"
}
+ say "fart should have been defined"
}
approve
+say "doop"
fart
propose {
@@ -311,7 +318,9 @@ approve
arbitrarily define "butts" := {say "BUTTS"}
butts
-arbitrarily define "ass" := {say "ASS"}
-ass
-
]=]
+
+
+
+
+
diff --git a/nomic.moon b/nomic.moon
index 2a03080..0eb9879 100644
--- a/nomic.moon
+++ b/nomic.moon
@@ -4,10 +4,10 @@ moon = require 'moon'
type = moon.type
is_list = (t)->
- i = 0
+ i = 1
for _ in pairs(t)
- i += 1
if t[i] == nil then return false
+ i += 1
return true
repr = (x)->
@@ -105,17 +105,18 @@ FunctionCall = (tokens)->
code = table.concat(ret, "\n")
return code
-Thunk = (lines)->
+Thunk = (statements)->
ret = {}
add_line ret, "function(game, locals)"
indent!
- for i,line in ipairs lines
- if line\match "locals%[\".*\"%] = .*"
- table.insert ret, indent_block(line)
- elseif i == #lines
- table.insert ret, indent_block("return "..line..";")
+ for i,statement in ipairs statements
+ -- TODO: clean up? This is a bit hacky. I should *know* if this is a var assignment.
+ if statement\match "locals%[\".*\"%] = .*"
+ table.insert ret, indent_block(statement)
+ elseif i == #statements
+ table.insert ret, indent_block("return "..statement..";")
else
- table.insert ret, indent_block(line..";")
+ table.insert ret, indent_block(statement..";")
dedent!
add_line ret, "end"
return table.concat(ret, "\n")
diff --git a/utils.moon b/utils.moon
new file mode 100644
index 0000000..069cf4a
--- /dev/null
+++ b/utils.moon
@@ -0,0 +1,119 @@
+local utils
+utils = {
+ is_list: (t)->
+ i = 1
+ for _ in pairs(t)
+ if t[i] == nil then return false
+ i += 1
+ return true
+
+ repr: (x, add_quotes=false)->
+ switch type(x)
+ when 'table'
+ if utils.is_list x
+ "[#{table.concat([utils.repr(i, true) for i in *x], ", ")}]"
+ else
+ "{#{table.concat(["[#{k}]: #{v}" for k,v in pairs x], ", ")}}"
+ when 'string'
+ if not add_quotes
+ x
+ elseif not x\find[["]]
+ "\"#{x}\""
+ elseif not x\find[[']]
+ "\'#{x}\'"
+ else
+ for i=0,math.huge
+ eq = ("=")\rep(i)
+ if not x\find"%[#{eq}%[" and not x\find"%]#{eq}%]"
+ return "[#{eq}[#{x}]#{eq}]"
+ else
+ tostring(x)
+
+ split: (str, sep="%s")->
+ [chunk for chunk in str\gmatch("[^#{sep}]")]
+
+ keys: (t)-> [k for k in pairs(t)]
+ values: (t)-> [v for _,v in pairs(t)]
+
+ sum: (t)->
+ tot = 0
+ for _,x in pairs(t) do tot += x
+ return tot
+
+ all: (t)->
+ for _,x in pairs t
+ if not x then return false
+ return true
+
+ any: (t)->
+ for _,x in pairs t
+ if x then return true
+ return false
+
+ min: (list, keyFn=((x)->x))->
+ assert utils.is_list(list), "min() expects to be operating on a list"
+ best = list[1]
+ if type(keyFn) == 'table'
+ keyTable = keyFn
+ keyFn = (k)->keyTable[k]
+ for i=2,#list
+ if keyFn(list[i]) < keyFn(best)
+ best = list[i]
+ return best
+
+ max: (list, keyFn=((x)->x))->
+ assert utils.is_list(list), "min() expects to be operating on a list"
+ best = list[1]
+ if type(keyFn) == 'table'
+ keyTable = keyFn
+ keyFn = (k)->keyTable[k]
+ for i=2,#list
+ if keyFn(list[i]) > keyFn(best)
+ best = list[i]
+ return best
+
+ sort: (list, keyFn=((x)->x), reverse=false)->
+ assert utils.is_list(list), "min() expects to be operating on a list"
+ if type(keyFn) == 'table'
+ keyTable = keyFn
+ keyFn = (k)->keyTable[k]
+ comparison = if reverse then ((x,y)->(keyFn(x)>keyFn(y))) else ((x,y)->(keyFn(x)<keyFn(y)))
+ table.sort list, comparison
+
+ equivalent: (x,y)->
+ if x == y then return true
+ if type(x) != type(y) then return false
+ if type(x) != 'table' then return false
+ for k,v in pairs(x)
+ if y[k] != v
+ return false
+ for k,v in pairs(y)
+ if x[k] != v
+ return false
+ return true
+
+ key_for: (t, value)->
+ for k,v in pairs(t)
+ if v == value
+ return k
+ return nil
+
+ clamp: (x, min,max)->
+ if x < min then min
+ elseif x > max then max
+ else x
+
+ mix: (min,max, amount)->
+ (1-amount)*min + amount*max
+
+ sign: (x)->
+ if x == 0 then 0
+ elseif x < 0 then -1
+ else 1
+
+ round: (x, increment=1)->
+ if x >= 0 then math.floor(x/increment + .5)*increment
+ else math.ceil(x/increment - .5)*increment
+
+}
+return utils