aboutsummaryrefslogtreecommitdiff
path: root/lib/compatibility/compatibility.nom
blob: dc21f0b73544c1d1a1f3496321164603ccb3d3ad (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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#!/usr/bin/env nomsu -V6.15.13.8
#
    This file contains code for defining ways to upgrade code between different versions
    of Nomsu.
    
use "filesystem"

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

$UPGRADES = {}
$ACTION_UPGRADES = ({} with fallback $ -> {})
external:
    (upgrade to $version via $upgrade_fn) means:
        $UPGRADES.$version = $upgrade_fn
    
    (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) == "a 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, add "\n"
            
            $retval = (make tree $body)
            $lua, add
                Lua ("
                    upgrade_action_1_to_2_via(\(quote $action.stub), \($version as lua expr), function(\
                    ..\(\$tree as lua id))
                        return \$retval
                    end)
                ")
        return $lua
    
    [
        $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 version list) means:
            if ($ver is "Text"):
                return (($ as number) for $ in $ver matching "[0-9]+")
            return $ver
        (Ver $) means:
            if ($ is "a List"):
                if ($.1 is "Text"):
                    return {.lib = $.1, .version = ($, from 2)}
                return {.version = $}
            [$lib, $ver] = ($, match "(.*)/([0-9.]+)")
            if $lib:
                return {.lib = $lib, .version = ($ver as version list)}
            return {.version = ($ as version list)}
        $start = (Ver $start_version)
        $end = (Ver $end_version)
        $end.lib or= $start.lib
        assume $start.lib == $end.lib
        $seen = {}
        $versions = {}
        for $v = $ in $UPGRADES:
            $versions.$v = (yes)
        
        for $v = $ in $ACTION_UPGRADES:
            $versions.$v = (yes)
        
        $versions = [: for $v = $ in $versions: if ((Ver $v).lib == $start.lib): add $v]
        sort $versions by $ -> ($ as version list)
        for $ver in $versions:
            if (($ver as version list) <= $start.version): do next $ver
            if (($ver as version list) > $end.version): stop $ver
            if $ACTION_UPGRADES.$ver:
                $tree =
                    $tree, with
                        $ ->:
                            if ($ is "Action" syntax tree):
                                $(upgrade 1 to 2) = $ACTION_UPGRADES.$ver.($.stub)
                                if $(upgrade 1 to 2):
                                    $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 (upgrade $with_upgraded_args to $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
    
    ($tree upgraded from $start_version) means
        $tree upgraded from $start_version to $(NOMSU VERSION)
    
    ($tree upgraded to $end_version) means
        $tree upgraded from ($tree.version or $(NOMSU VERSION)) to $end_version
    
    ($tree upgraded) means
        $tree upgraded from ($tree.version or $(NOMSU VERSION)) to $(NOMSU VERSION)