aboutsummaryrefslogtreecommitdiff
path: root/compatibility/compatibility.nom
blob: e0449c8ce615716917ab25cdfe820b79b6a75583 (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
#!/usr/bin/env nomsu -V6.14
#
    This file contains code for defining ways to upgrade code between different versions
    of Nomsu.
    
use "lib/os"

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

$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, 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

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