aboutsummaryrefslogtreecommitdiff
path: root/nomnom/ast.nom
blob: 816554c3241e16f25fc30c5f3f1964598b471bb0 (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
use "lib/object.nom"

# The types are [..]
    "Number", "Var", "Block", "EscapedNomsu", "Text", "List", "Dict", "DictEntry",
    "IndexChain", "Action", "FileChunks", "Error", "Comment"

object (Syntax Tree):
    my action [set up]:
        if (%me.type == "Action"):
            %stub_bits = []
            %argnum = 1
            for %bit in %me:
                if:
                    (%bit is text): %stub_bits::add %bit
                    (%bit.type != "Comment"):
                        %stub_bits::add "\%argnum"
                        %argnum += 1
            %me.stub = (%stub_bits::joined with " ")
            if (%me.stub == "Lua Code 1 2"):
                lua> "require('ldt').breakpoint()"

    (Syntax Tree).source_code_for_tree = (..)
        {} with fallback % -> (read file %.source.filename)
    
    my action [children]:
        %children = []
        for % in %me:
            if ((% is a "Syntax Tree") and (%.type != "Comment")):
                %children::add %
        if ((%me.type == "Action") and %me.target):
            %children::add %me.target
        return %children

    my action [as lua] (..)
        "Syntax_Tree(\(call ({}'s metatable).as_lua with [%me]))"

    my action [as nomsu] (..)
        "(Syntax Tree \(call ({}'s metatable).as_nomsu with [%me]))"

    my action [as text] (..)
        "(Syntax Tree \(call ({}'s metatable).__tostring with [%me]))"

    my action [get source code] (..)
        (Syntax Tree).source_code_for_tree.%me

    my action [map %fn]:
        %replacement = (call %fn with [%me])
        if %replacement:
            if (%replacement is a "Syntax Tree"):
                %replacement = (%k = %v for %k = %v in %replacement)
                %replacement.source = %me.source
                return (Syntax Tree %replacement)
            return %replacement
        ..else:
            %replacement = {}
            %changes = (no)
            for %k = %v in %me:
                %replacement.%k = %v
                if (%v is a "Syntax Tree"):
                    %r = (%v::map %fn)
                    if ((%r == %v) or (%r == (nil))):
                        do next %k
                    %changes = (yes)
                    %replacement.%k = %r
            unless %changes: return %me
            return (Syntax Tree %replacement)
   
    my action [with %overrides]:
        %new = (%k = %v for %k = %v in %me)
        for %k = %v in %overrides: %new.%k = %v
        return (Syntax Tree %new)

    my action [== %other]:
        unless (..)
            all of [..]
                (type of %me) == (type of %other)
                (%me's metatable) == (%other's metatable)
                (size of %me) == (size of %other)
                %me.type == %other.type
        ..: return (no)
        
        for %item in %me at %i:
            if (%other.%i != %item): return (no)
        if (%me.type == "Action"):
            if (%me.target != %other.target): return (no)
        return (yes)
    
    my action [get args]:
        assume (%me.type == "Action") or barf "Only actions have arguments, not \(%me.type)"
        %args = []
        for % in %me:
            unless ((% is text) or (%.type == "Comment")):
                %args::add %
        return %args

(Syntax Tree).map = (Syntax Tree).map_1