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

use "lib/os.nom"

%UPGRADES = {}
action [upgrade to %version via %upgrade_fn]:
    %UPGRADES.%version = %upgrade_fn

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

parse [upgrade %tree to %version as %body] as (..)
    upgrade to %version via ([%] -> (% with %tree -> %body))

compile [upgrade action %actions to %version as %body] 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.type is "Var"):
                %replacements.(%action.%i.1) = "\(\%tree as lua id)[\%i]"
        
        %needs_mangle = (no)
        local action [make tree %t]:
            when:
                (%t is "Var" syntax tree):
                    if %replacements.(%t.1):
                        return %replacements.(%t.1)
                    ..else:
                        external %needs_mangle = (yes)
                        return ".."
                            \(%t.type){source=\(quote "\(%t.source)"), \(..)
                                quote "\(%t.1) \000\(=lua "string.format('%X', __MANGLE_INDEX)")"
                            ..}
                
                (%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 "\(%t.type){\(%args joined with ", ")}"
                
                else:
                    return (quote %t)
        
        unless ("\%lua" == ""): %lua::append "\n"
        %retval = (make tree %body)
        %lua::append (..)
            Lua ".."
                A_upgrade_action_1_to_2_via_3(\(quote %action.stub), \(%version as lua expr), function(\(..)
                    \%tree as lua id
                ..)
                    \("__MANGLE_INDEX = (__MANGLE_INDEX or 0) + 1\n    " if (%needs_mangle) else "")\
                ..return \%retval
                end)
    
    return %lua

action [..]
    %tree upgraded from %start_version to %end_version
    %tree upgraded to %end_version from %start_version
..:
    local action [%ver as list] ((% 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)):
                        return (call %ACTION_UPGRADES.%ver.(%.stub) with [%])
        
        if %UPGRADES.%ver:
            %tree = (call %UPGRADES.%ver with [%tree])
    
    return %tree

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

parse [%tree upgraded from %start_version] as (..)
    %tree upgraded from %start_version to (Nomsu version)

parse [%tree upgraded to %end_version] as (..)
    %tree upgraded from (%tree.version or (Nomsu version)) to %end_version

parse [%tree upgraded] as (..)
    %tree upgraded from (%tree.version or (Nomsu version)) to (Nomsu version)

action [use %path from version %version]:
    for file %filename in %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