aboutsummaryrefslogtreecommitdiff
path: root/builtin_metatables.moon
blob: 430a48ab39d37bbf2afd3f426d0ca4ec0fc30f69 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
-- This file defines some methods on Lua numbers, bools, actions, nil, and coroutines
require "text"

number_mt =
    __type: "a Number"
    as_lua: tostring
    as_nomsu: tostring
    as_text: tostring
    as_a_number: => @
    rounded: => math.floor(@ + .5)
    rounded_down: math.floor
    rounded_up: math.ceil
    to_the_nearest: (rounder)=> rounder * math.floor(@/rounder + 0.5)
    base16: => ("%X")\format(@)
number_mt.__index = number_mt
debug.setmetatable 0, number_mt

bool_mt =
    __type: "a Boolean"
    __len: => @ and 1 or 0
    as_lua: tostring
    as_nomsu: => @ and "yes" or "no"
    as_text: => @ and "yes" or "no"
    _and: (cond)=> @ and cond
    _or: (cond)=> @ or cond
    xor: (cond)=> @ == (not cond)
bool_mt.__index = bool_mt
debug.setmetatable true, bool_mt

fn_mt =
    __type: "an Action"
    as_text: => (tostring(@)\gsub("function", "Action"))
    __add: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...) + other(...))
        elseif type(@) == 'function' then (...)-> (@(...) + other)
        else (...)-> (@ + other(...))
    __sub: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...) - other(...))
        elseif type(@) == 'function' then (...)-> (@(...) - other)
        else (...)-> (@ - other(...))
    __mul: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...) * other(...))
        elseif type(@) == 'function' then (...)-> (@(...) * other)
        else (...)-> (@ * other(...))
    __div: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...)  other(...))
        elseif type(@) == 'function' then (...)-> (@(...)  other)
        else (...)-> (@  other(...))
    __mod: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...) % other(...))
        elseif type(@) == 'function' then (...)-> (@(...) % other)
        else (...)-> (@ % other(...))
    __band: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...) and other(...))
        elseif type(@) == 'function' then (...)-> (@(...) and other)
        else (...)-> (@ and other(...))
    __bor: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...) or other(...))
        elseif type(@) == 'function' then (...)-> (@(...) or other)
        else (...)-> (@ or other(...))
    __bxor: (other)=>
        if type(@) == 'function' and type(other) == 'function'
            (...)-> (@(...) != other(...))
        elseif type(@) == 'function' then (...)-> (@(...) != other)
        else (...)-> (@ != other(...))
fn_mt.__index = fn_mt
debug.setmetatable (->), fn_mt

_last_co_i = setmetatable({}, {__mode:'k'})
local co_mt
co_mt =
    __type: "a Coroutine"
    as_text: => (tostring(@)\gsub("thread", "Coroutine")).." ("..coroutine.status(@)..")"
    __len: => math.huge
    __call: coroutine.resume
    __inext: (k)=>
        ok, val = coroutine.resume(@)
        return if coroutine.status(@) == 'dead'
        if ok then return (k or 0) + 1, val
    __index: (k)=>
        if k == (_last_co_i[@] or 0) + 1
            ret = {coroutine.resume(@, k)}
            _last_co_i[@] = k
            if ret[1]
                return table.unpack(ret, 2)
            else
                return nil
        return co_mt[k]
co_mt.__next = co_mt.__inext
debug.setmetatable(coroutine.create(->), co_mt)

nil_mt =
    __type: "Nil"
    as_lua: => "nil"
    as_nomsu: => "nil"
    as_text: => "nil"
nil_mt.__index = nil_mt
debug.setmetatable nil, nil_mt