aboutsummaryrefslogtreecommitdiff
path: root/lib/object.nom
blob: eb9beb8211d04daec3d358ace09fba51421a0364 (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
use "core"

# TODO: make codegen less verbose

lua> "CLASSES = {}"

immediately
    compile [@, me] to: Lua value "self"
action [new %classname %inst]
    =lua "setmetatable(\%inst, CLASSES[\%classname])"
immediately
    parse [new %classname] as: new %classname {}

compile [as %instance %body] to
    Lua ".."
        do
            local self = \(%instance as lua expr)
            local old_self = self.class:set_self(self)
            old_actions, ACTIONS = ACTIONS, self.class.ACTIONS
            old_compile_actions, COMPILE_ACTIONS = COMPILE_ACTIONS, self.class.COMPILE_ACTIONS
            old_arg_orders, ARG_ORDERS = ARG_ORDERS, self.class.ARG_ORDERS
            local fell_through = false
            local ok, ret = pcall(function()
                \(%body as lua statements)
                fell_through = true
            end)
            self.class:set_self(old_self)
            ACTIONS = old_actions
            COMPILE_ACTIONS = old_compile_actions
            ARG_ORDERS = old_arg_orders
            if not ok then error(ret) end
            if not fell_through then return ret end
        end

parse [object %classname %class_body] as
    using
        %cls <- {..}
            name:%classname
            ACTIONS:=lua "ACTIONS", COMPILE_ACTIONS:=lua "COMPILE_ACTIONS"
            ARG_ORDERS:=lua "ARG_ORDERS"
        (=lua "CLASSES").%classname <- %cls
        lua> ".."
            setmetatable(\%cls, {__tostring=function() return \%classname end})
            local self = nil
            \%cls.set_self = function(_, inst)
                local old_self = self
                self = inst
                return old_self
            end
            \%cls.__index = \%cls
            \%cls.class = \%cls
        %class_body
        run ".."
            action [new \%classname %inst]
                say "NEWING"
                return: =lua "setmetatable(\\%inst, \\%cls)"
        lua> ".."
            if ACTIONS["as text"] then
                \%cls.__tostring = ACTIONS["as text"]
            end