moonscript/moon/init.moon

134 lines
2.8 KiB
Plaintext
Raw Normal View History

2011-10-27 07:03:38 +00:00
2011-12-04 19:16:06 +00:00
lua = { :debug, :type }
2015-12-07 02:06:06 +00:00
import getfenv, setfenv, dump from require "moonscript.util"
2011-11-15 03:16:26 +00:00
2013-06-08 06:34:03 +00:00
local *
2011-10-27 07:03:38 +00:00
2011-11-21 01:52:19 +00:00
p = (...) ->
print dump ...
2011-12-04 19:16:06 +00:00
is_object = (value) -> -- is a moonscript object
lua.type(value) == "table" and value.__class
type = (value) -> -- class aware type
base_type = lua.type value
if base_type == "table"
cls = value.__class
return cls if cls
base_type
2011-12-03 22:05:02 +00:00
debug = setmetatable {
2011-11-15 03:16:26 +00:00
upvalue: (fn, k, v) ->
upvalues = {}
i = 1
while true
name = lua.debug.getupvalue(fn, i)
break if name == nil
upvalues[name] = i
i += 1
if not upvalues[k]
error "Failed to find upvalue: " .. tostring k
if not v
_, value = lua.debug.getupvalue fn, upvalues[k]
value
else
lua.debug.setupvalue fn, upvalues[k], v
2011-12-03 22:05:02 +00:00
}, __index: lua.debug
2011-11-15 03:16:26 +00:00
2011-10-27 07:03:38 +00:00
-- run a function with scope injected before its function environment
run_with_scope = (fn, scope, ...) ->
old_env = getfenv fn
env = setmetatable {}, {
__index: (name) =>
val = scope[name]
if val != nil
val
else
old_env[name]
}
setfenv fn, env
fn ...
-- wrap obj such that calls to methods do not need a reference to self
bind_methods = (obj) ->
2011-10-27 07:03:38 +00:00
setmetatable {}, {
__index: (name) =>
val = obj[name]
2011-12-04 19:16:06 +00:00
if val and lua.type(val) == "function"
2011-10-27 07:03:38 +00:00
bound = (...) -> val obj, ...
self[name] = bound
bound
else
val
}
-- use a function to provide default values to table
-- optionally specify a starting table
-- fibanocci table:
-- t = defaultbl {[0]: 0, [1]: 1}, (i) -> self[i - 1] + self[i - 2]
defaultbl = (t, fn) ->
if not fn
fn = t
t = {}
setmetatable t, {
__index: (name) =>
val = fn self, name
rawset self, name, val
val
}
-- chain together tables by __index metatables
extend = (...) ->
tbls = {...}
return if #tbls < 2
for i = 1, #tbls - 1
a = tbls[i]
b = tbls[i + 1]
setmetatable a, __index: b
tbls[1]
2011-10-27 07:03:38 +00:00
-- shallow copy
copy = =>
2011-12-03 19:56:15 +00:00
{key,val for key,val in pairs self}
2011-10-27 07:03:38 +00:00
-- mixin class properties into self, call new
mixin = (cls, ...) =>
2013-06-08 07:06:56 +00:00
for key, val in pairs cls.__base
2011-10-27 07:03:38 +00:00
self[key] = val if not key\match"^__"
cls.__init self, ...
-- mixin methods from an object into self
mixin_object = (object, methods) =>
for name in *methods
self[name] = (parent, ...) ->
object[name](object, ...)
-- mixin table values into self
mixin_table = (tbl, keys) =>
if keys
for key in *keys
self[key] = tbl[key]
else
for key, val in pairs tbl
self[key] = val
2011-12-01 03:26:17 +00:00
fold = (items, fn)->
len = #items
if len > 1
accum = fn items[1], items[2]
for i=3,len
2013-01-10 03:47:02 +00:00
accum = fn accum, items[i]
2011-12-01 03:26:17 +00:00
accum
else
items[1]
2013-06-08 06:34:03 +00:00
{
:dump, :p, :is_object, :type, :debug, :run_with_scope, :bind_methods,
:defaultbl, :extend, :copy, :mixin, :mixin_object, :mixin_table, :fold
}