diff options
Diffstat (limited to 'core.moon')
| -rwxr-xr-x[-rw-r--r--] | core.moon | 208 |
1 files changed, 143 insertions, 65 deletions
diff --git a/core.moon b/core.moon index d62cf9e..7155829 100644..100755 --- a/core.moon +++ b/core.moon @@ -18,23 +18,52 @@ repr = (x)-> else tostring(x) -game\def {[[print $str]], [[say $str]]}, (locals)=> - with locals - print(repr(.str)) - return nil +game\def {[[print $str]], [[say $str]]}, (args)=> print(repr(args.str)) +game\def {[[printf $str]]}, (args)=> + for s in *args.str do io.write(repr(s)) + io.write("\n") + +game\def [[return $value]], (args)=> args.value + +game\macro [[let $var = $value]], (var, value)-> + "locals[#{var}] = #{value}" + +game\def [[$signature := $body]], (args)=> + invocations = if type(args.signature) == 'table' then args.signature else {args.signature} + for i in *invocations + unless @check_authorization(i) + print "You are not permitted to redefine this function" + return + + @\def args.signature, args.body + print "Defined new rule: \"#{game.repr(args.signature)}\"" + --print debug.getinfo(args.body, "S").source + return nil -game\def [[$invocations := $body]], (locals)=> - game\def locals.invocations, locals.body +game\def [[compile $body]], (args)=> + print debug.getinfo(args.body, "S").source return nil -game\def [[help $invocation]], (locals)=> - with locals - if @rules[.invocation\gsub(" ",";")] - print(@rules[.invocation\gsub(" ",";")]) +game\def [[help $invocation]], (args)=> + print_rule = (invocation, rule)-> + print "\"#{invocation}\" :=" + info = debug.getinfo(rule, "S") + i = 0 + for line in info.source\gmatch("[^\n]+") + i+=1 + if i >= info.linedefined+1 + print(line) + if i >= info.lastlinedefined-1 + return + print " #{info.short_src}:#{info.linedefined}-#{info.lastlinedefined}" + + with args + if rule = @rules[.invocation] + print_rule .invocation, rule return nil words = [w for w in .invocation\gmatch("%S+")] match_count = (i)-> - iws = [w for w in i\gmatch("[^;$]+")] + iws = [w for w in i\gmatch("[^ $]+")] count = 0 for w in *words for iw in *iws @@ -42,26 +71,32 @@ game\def [[help $invocation]], (locals)=> count += 1/#iws return count rules = {} + invocations = {} for i,r in pairs(@rules) - rules[r] = math.max((rules[r] or 0), match_count(i)) + c = match_count(i) + if c > (rules[r] or 0) + rules[r] = c + invocations[r] = i best = [r for r in pairs rules] table.sort best, ((a,b)-> rules[a] > rules[b]) if rules[best[1]] > 0 for r in *best if rules[r] < rules[best[1]] break - print("Closest match for \"#{.invocation}\" is:\n#{r}") + print_rule invocations[r], r return nil - -game\def [[return $retval]], ((locals)=> locals.retval), "... returns the specified value ..." - -game\def {[[true]], [[yes]]}, ((locals)=> true), "... returns true ..." -game\def {[[false]], [[no]]}, ((locals)=> false), "... returns false ..." -game\def {[[nil]], [[None]], [[nop]], [[done]]}, ((locals)=> nil), "... does nothing, returns nil ..." - -game\def {[[$x == $y]], [[equal $x $y]]}, (locals)=> - with locals +game\macro "true", -> "true" +game\macro "yes", -> "true" +game\macro "false", -> "false" +game\macro "no", -> "false" +game\macro "nil", -> "nil" +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 @@ -72,81 +107,124 @@ game\def {[[$x == $y]], [[equal $x $y]]}, (locals)=> if .x[k] != v return false return true - -game\def [[not $x]], (locals)=> not locals.x -game\run [["$x != $y" := {return (not (x == y))}]] -game\def [[$x < $y]], (locals)=> locals.x < locals.y -game\def [[$x <= $y]], (locals)=> locals.x <= locals.y -game\def [[$x > $y]], (locals)=> locals.x > locals.y -game\def [[$x >= $y]], (locals)=> locals.x >= locals.y - -game\def {[[$x + $y]], [[$x plus $y]]}, (locals)=> locals.x + locals.y -game\def {[[$x - $y]], [[$x minus $y]]}, (locals)=> locals.x - locals.y -game\def {[[$x * $y]], [[$x times $y]]}, (locals)=> locals.x * locals.y -game\def {[[$x / $y]], [[$x divided by $y]]}, (locals)=> locals.x / locals.y -game\def {[[$x ^ $y]], [[$x to the power of $y]]}, (locals)=> locals.x ^ locals.y - - -game\def [[if $condition then $body else $else_body]], (locals)=> - with locals +game\run [=[ + ["$x != $y", "$x <> $y", "$x ~= $y"] := {return (not (x == y))} +]=] +game\def [[$x < $y]], (args)=> args.x < args.y +game\def [[$x <= $y]], (args)=> args.x <= args.y +game\def [[$x > $y]], (args)=> args.x > args.y +game\def [[$x >= $y]], (args)=> args.x >= args.y + +game\macro [[$x + $y]], (x,y)-> "(#{x} + #{y})" +game\macro [[$x - $y]], (x,y)-> "(#{x} - #{y})" +game\macro [[$x * $y]], (x,y)-> "(#{x} * #{y})" +game\macro [[$x / $y]], (x,y)-> "(#{x} / #{y})" +game\macro [[$x ^ $y]], (x,y)-> "(#{x} ^ #{y})" + +game\macro [[$x < $y]], (x,y)-> "(#{x} < #{y})" +game\macro [[$x <= $y]], (x,y)-> "(#{x} <= #{y})" +game\macro [[$x > $y]], (x,y)-> "(#{x} > #{y})" +game\macro [[$x >= $y]], (x,y)-> "(#{x} >= #{y})" + +game\macro [[not $x]], (x)-> "(not #{x})" +game\macro [[$x and $y]], (x,y)-> "(#{x} and #{y})" +game\macro [[$x or $y]], (x,y)-> "(#{x} or #{y})" + + +[==[ +game\def [[if $condition $body else $else_body]], (args)=> + with args if .condition - return .body\run(@, locals) - else return .else_body\run(@, locals) + return .body(@, args) + else return .else_body(@, args) -game\run [[ -["if $condition then $body", "when $condition do $body"] := {if $condition then $body else {}} -]] -game\run [[ -["unless $condition do $body"] := {if (not $condition) then $body else {}} -]] -game\run [[ -["unless $condition do $body else $else_body"] := {if (not $condition) then $body else $else_body} -]] +game\run [=[ + ["if $condition $body", "when $condition $body"] := {if $condition $body else {}} + ["unless $condition $body"] := {if (not $condition) $body else {}} + ["unless $condition $body else $else_body"] := {if (not $condition) $body else $else_body} +]=] +]==] +game\def [[random]], -> math.random() -game\def [[sum $items]], (locals)=> +game\def [[sum $items]], (args)=> tot = 0 - for x in *locals.items do tot += x + for x in *args.items do tot += x return tot -game\def {[[average $items]], [[avg $items]]}, (locals)=> +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 *locals.items do tot += x - return tot / #locals.items + for x in *args.items do tot += x + return tot / #args.items -game\def {[[min $items]], [[smallest $items]], [[lowest $items]], [[fewest $items]]}, (locals)=> - with locals +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 -game\def {[[max $items]], [[largest $items]], [[highest $items]], [[most $items]]}, (locals)=> - with locals +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 -game\def {[[argmin $items]]}, (locals)=> - with locals +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 -game\def {[[argmax $items]]}, (locals)=> - with locals +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 -game\def {[[$index st in $list]], [[$index nd in $list]], [[$index rd in $list]], [[$index th in $list]]}, (locals)=> - locals.list[locals.index] +game\def {[[$index st in $list]], [[$index nd in $list]], [[$index rd in $list]], [[$index th in $list]]}, (args)=> + with args + if type(.list) != 'table' + print "Not a list: #{.list}" + return + .list[.index] + +game\def {[[index of $item in $list]]}, (args)=> + with args + if type(.list) != 'table' + print "Not a list: #{.list}" + return + for i,x in ipairs .list + if x == .item + return i + return nil +game\run [=[ + ["$item is in $list", "$list contains $item"] := {(index of $item in $list) != (nil)} +]=] + +game\def {[[# $list]], [[length of $list]], [[size of $list]]}, (args)=> + with args + if type(.list) != 'table' + print "Not a list: #{.list}" + return + #.list + return game |
