aboutsummaryrefslogtreecommitdiff
path: root/compatibility/compatibility.nom
blob: 4d96d890b097732ca84ba09ebbef169cf8e3ceac (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
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env nomsu -V4.11.12.8
#
    This file contains code for defining ways to upgrade code between different versions
    of Nomsu.
    
use "lib/os.nom"

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

%UPGRADES = {}
externally (upgrade to %version via %upgrade_fn) means:
    %UPGRADES.%version = %upgrade_fn
%ACTION_UPGRADES = ({} with fallback % -> {})
externally (upgrade action %stub to %version via %upgrade_fn) means:
    %ACTION_UPGRADES.%version.%stub = %upgrade_fn

(upgrade %tree to %version as %body) parses as (..)
    upgrade to %version via ((% %end_version) -> (% with %tree -> %body))

(upgrade action %actions to %version as %body) compiles to:
    if (%actions is "Action" syntax tree):
        %actions = \[%actions]
    %lua = (Lua "")
    for %action in %actions:
        %replacements = {}
        for %i in 1 to (size of %action):
            if (%action.%i is "Var" syntax tree):
                %replacements.(%action.%i.1) = "\(\%tree as lua id)[\%i]"
        define mangler
        (make tree %t) means:
            when:
                (%t is "Var" syntax tree):
                    if %replacements.(%t.1):
                        return %replacements.(%t.1)
                    ..else:
                        external %needs_mangle = (yes)
                        return "SyntaxTree{type=\(quote %t.type), source=\(quote "\(%t.source)"), \(quote (mangle %t.1))}"
                
                (%t is syntax tree):
                    %args = []
                    for %k = %v in %t:
                        if ((type of %k) == "number"):
                            %args::add (make tree %v)
                        ..else:
                            %args::add "\(%k)=\(make tree %v)"
                    return "SyntaxTree{\(%args::joined with ", ")}"
                
                else:
                    return (quote %t)
        
        unless ("\%lua" == ""):
            %lua::append "\n"
        
        %retval = (make tree %body)
        %lua::append (..)
            Lua "\
                ..upgrade_action_1_to_2_via(\(quote %action.stub), \(%version as lua expr), function(\(\%tree as lua id))
                    return \%retval
                end)"
    return %lua

externally [..]
    %tree upgraded from %start_version to %end_version
    %tree upgraded to %end_version from %start_version
..all mean:
    unless (%tree is syntax tree): return %tree
    (%ver as list) means ((% as number) for % in %ver matching "[0-9]+")
    %versions = {}
    for %v = % in %UPGRADES:
        %versions.%v = (yes)
    
    for %v = % in %ACTION_UPGRADES:
        %versions.%v = (yes)
    
    %versions = ((keys in %versions) sorted by % -> (% as list))
    for %ver in %versions:
        if ((%ver as list) <= (%start_version as list)): do next %ver
        if ((%ver as list) > (%end_version as list)): stop %ver
        if %ACTION_UPGRADES.%ver:
            %tree = (..)
                %tree with % ->:
                    if ((% is "Action" syntax tree) and %ACTION_UPGRADES.%ver.(%.stub)):
                        %with_upgraded_args = {..}
                            : for %k = %v in %: add %k = (%v upgraded from %start_version to %end_version)
                        set %with_upgraded_args's metatable to (%'s metatable)
                        return (%ACTION_UPGRADES.%ver.(%.stub) %with_upgraded_args %end_version)
        
        if %UPGRADES.%ver:
            %with_upgraded_args = {..}
                :
                    for %k = %v in %tree:
                        add %k = (%v upgraded from %start_version to %end_version)
            set %with_upgraded_args's metatable to (%tree's metatable)
            %tree = (%UPGRADES.%ver %with_upgraded_args %end_version)
    if (%tree.version != %end_version):
        %tree = (SyntaxTree {: for %k = %v in %tree: add %k = %v})
        %tree.version = %end_version
        if %tree.shebang:
            %tree.shebang = "#!/usr/bin/env nomsu -V\%end_version\n"
    return %tree

externally (%tree upgraded from %start_version) means (..)
    %tree upgraded from %start_version to (Nomsu version)

externally (%tree upgraded to %end_version) means (..)
    %tree upgraded from (%tree.version or (Nomsu version)) to %end_version

externally (%tree upgraded) means (..)
    %tree upgraded from (%tree.version or (Nomsu version)) to (Nomsu version)

externally (use %path from version %version) means:
    for %filename in (files for %path):
        if (=lua "LOADED[\%filename]"):
            do next %filename
        %file = (read file %filename)
        %tree = (parse %file from %filename)
        %tree = (upgrade %tree from %version)
        run tree %tree