#!/usr/bin/env nomsu -V4.8.10 # 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.type is "Var"): %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 "\(%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 "\(%t.type){\(%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 = (..) %k = (%v upgraded from %start_version to %end_version) for %k = %v in % set %with_upgraded_args 's metatable to (% 's metatable) return (..) call %ACTION_UPGRADES.%ver.(%.stub) with [%with_upgraded_args, %end_version] if %UPGRADES.%ver: %with_upgraded_args = (..) %k = (%v upgraded from %start_version to %end_version) for %k = %v in %tree set %with_upgraded_args 's metatable to (%tree 's metatable) %tree = (call %UPGRADES.%ver with [%with_upgraded_args, %end_version]) 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 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