nomsu/lib/compatibility/compatibility.nom
Bruce Hill a1849da175 Autoformat (mostly just to do with the new
blank-line-after-end-of-multi-indent-block rule
2019-03-27 15:22:46 -07:00

147 lines
5.3 KiB
Plaintext

#!/usr/bin/env nomsu -V7.0.0
###
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 ($ -> ($, 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 #$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:
$v2 = (Ver $v)
if ($v2.lib == $start.lib):
if ($start.version < $v2.version <= $end.version): add $v
]
sort $versions by $ -> ($ as version list)
$curr_version = $start_version
for $ver in $versions:
$tree =
SyntaxTree
{: for ($k = $v) in $tree: add $k = ($v upgraded from $curr_version to $ver)}
if (($tree.type == "Action") and $ACTION_UPGRADES.$ver):
$(upgrade 1) = $ACTION_UPGRADES.$ver.($tree, get stub)
if $(upgrade 1):
$tree = (upgrade $tree)
go to (next version)
if $UPGRADES.$ver:
$tree = ($UPGRADES.$ver $tree $ver)
go to (next version)
--- (next version) ---
$curr_version = $ver
if ($tree.version != $end_version):
$tree = (SyntaxTree {: for ($k = $v) in $tree: add $k = $v})
$tree.version = $end_version
if $tree.shebang:
unless ($end_version is "Text"):
$end_version = ($end_version, joined with ".")
$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)