diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml index be432804ee..9cb858d722 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/nix.yml @@ -20,7 +20,7 @@ jobs: - name: Run test id: run_test # Not running all tests because those outside of hkmc2 are obsolete (will be removed) - run: sbt -J-Xmx4096M -J-Xss8M test + run: sbt -J-Xmx4096M -J-Xss1G test # It's useful to see how the tests fail by seeing the diff through the next step continue-on-error: true - name: Check no changes diff --git a/hkmc2/js/src/main/scala/hkmc2/Compiler.scala b/hkmc2/js/src/main/scala/hkmc2/Compiler.scala index 0c82d968cb..509f53e184 100644 --- a/hkmc2/js/src/main/scala/hkmc2/Compiler.scala +++ b/hkmc2/js/src/main/scala/hkmc2/Compiler.scala @@ -63,7 +63,11 @@ class Compiler(paths: MLsCompiler.Paths)(using cctx: CompilerCtx): perFileDiagnostics @JSExportTopLevel("Paths") -final class Paths(prelude: Str, runtime: Str, term: Str) extends MLsCompiler.Paths: +final class Paths(prelude: Str, runtime: Str, term: Str, block: Str, spHelper: Str, option: Str, ss: Str) extends MLsCompiler.Paths: val preludeFile = Path(prelude) val runtimeFile = Path(runtime) val termFile = Path(term) + val blockFile = Path(block) + val specializeHelpersFile = Path(spHelper) + val optionFile = Path(option) + val shapeSetFile = Path(ss) diff --git a/hkmc2/js/src/test/scala/hkmc2/CompilerTest.scala b/hkmc2/js/src/test/scala/hkmc2/CompilerTest.scala index 9ed0bd1ade..cb5a036247 100644 --- a/hkmc2/js/src/test/scala/hkmc2/CompilerTest.scala +++ b/hkmc2/js/src/test/scala/hkmc2/CompilerTest.scala @@ -21,7 +21,7 @@ class CompilerTest extends AnyFunSuite: None .toMap + ("/std/Prelude.mls" -> node.fs.readFileSync(preludePath, "utf-8")) - private val paths = new Paths("/std/Prelude.mls", "/std/Runtime.mjs", "/std/Term.mjs") + private val paths = new Paths("/std/Prelude.mls", "/std/Runtime.mjs", "/std/Term.mjs", "/std/Block.mls", "/std/SpecializeHelpers.mls", "/std/Option.mls", "/std/ShapeSet.mls") private def createCompiler(): (InMemoryFileSystem, Compiler) = val stdLib = loadStandardLibrary() diff --git a/hkmc2/jvm/src/test/scala/hkmc2/CompileTestRunnerBase.scala b/hkmc2/jvm/src/test/scala/hkmc2/CompileTestRunnerBase.scala index ecaa6bba72..50b4379f64 100644 --- a/hkmc2/jvm/src/test/scala/hkmc2/CompileTestRunnerBase.scala +++ b/hkmc2/jvm/src/test/scala/hkmc2/CompileTestRunnerBase.scala @@ -64,7 +64,11 @@ abstract class CompileTestRunnerBase( paths = new MLsCompiler.Paths: val preludeFile = mainTestDir / "mlscript" / "decls" / "Prelude.mls" val runtimeFile = mainTestDir / "mlscript-compile" / "Runtime.mjs" - val termFile = mainTestDir / "mlscript-compile" / "Term.mjs", + val termFile = mainTestDir / "mlscript-compile" / "Term.mjs" + val blockFile = mainTestDir / "mlscript-compile" / "Block.mjs" + val optionFile = mainTestDir / "mlscript-compile" / "Option.mjs" + val shapeSetFile = mainTestDir / "mlscript-compile" / "ShapeSet.mjs" + val specializeHelpersFile = mainTestDir / "mlscript-compile" / "SpecializeHelpers.mjs", mkRaise = report.mkRaise ) compiler.compileModule(file) diff --git a/hkmc2/shared/src/main/scala/hkmc2/Config.scala b/hkmc2/shared/src/main/scala/hkmc2/Config.scala index a01359c3c9..81aa9db380 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/Config.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/Config.scala @@ -31,6 +31,7 @@ case class Config( etaExpansion: Opt[EtaExpansion], inlining: Opt[Inliner], deadBranchRemoval: Bool, + disableDataFlowAnalysis: Bool, // FIXME: remove it. it now leads to timeout in staged reg exp output qqEnabled: Bool, funcToCls: Bool, commentGeneratedCode: Bool, @@ -73,6 +74,7 @@ object Config: etaExpansion = S(EtaExpansion.default), inlining = S(Inliner(default.inlineThreshold)), deadBranchRemoval = default.deadBranchRemoval, + disableDataFlowAnalysis = false, qqEnabled = false, funcToCls = false, commentGeneratedCode = false, @@ -443,6 +445,10 @@ object ConfigParser: parseBool(value) match case S(v) => _.copy(deadBranchRemoval = v) case N => identity + case "disableDataFlowAnalysis" => + parseBool(value) match + case S(v) => _.copy(disableDataFlowAnalysis = v) + case N => identity case _ => raise(ErrorReport( msg"Unknown config field '${name}'" -> value.toLoc :: Nil, diff --git a/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala b/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala index 9a29b47502..40f244b981 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala @@ -39,6 +39,10 @@ object MLsCompiler: def preludeFile: io.Path def runtimeFile: io.Path def termFile: io.Path + def blockFile: io.Path + def specializeHelpersFile: io.Path + def optionFile: io.Path + def shapeSetFile: io.Path /** * The compiler that compiles MLscript code into JavaScript modules. @@ -103,14 +107,27 @@ class MLsCompiler case Term.Quoted(_) | Term.Unquoted(_) => true case Term.Ref(sym) => sym === State.termSymbol case _ => t.subTerms.exists(findQuote) + def findStage(t: semantics.Statement): Bool = t match + case d: semantics.Definition => d.hasStagedModifier.isDefined + case _ => t.subStatements.exists(findStage) + val hasQuote = findQuote(blk0) + val isStaged = findStage(blk0) + // println(s"yydz: ${blk0.subTerms}") val blk = new Term.Blk( Import(State.runtimeSymbol, runtimeFile.toString, runtimeFile) :: - // Only import `Term.mls` when necessary. + // Only import files when necessary. (if hasQuote then - Import(State.termSymbol, termFile.toString, termFile) :: blk0.stats + Import(State.termSymbol, termFile.toString, termFile) :: Nil else - blk0.stats), + Nil) ::: + (if isStaged then + Import(State.optionSymbol, optionFile.toString, optionFile) :: + Import(State.shapeSetSymbol, shapeSetFile.toString, shapeSetFile) :: + Import(State.blockSymbol, blockFile.toString, blockFile) :: + Import(State.specializeHelpersSymbol, specializeHelpersFile.toString, specializeHelpersFile) :: Nil + else + Nil) ::: blk0.stats, blk0.res ) val low = ltl.givenIn: diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/Block.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/Block.scala index 2f7767d79f..fde588cc7f 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/Block.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/Block.scala @@ -804,17 +804,15 @@ final case class ClsLikeBody( ctor.freeVars ++ methods.flatMap(_.freeVars) lazy val size = 1 + methods.map(_.size).sum + ctor.size -/* object ClsLikeBody: - // TODO rm `empty`? it's currently unused def empty(id: Tree.Ident)(using State) = ClsLikeBody( isym = ModuleOrObjectSymbol(Tree.DummyTypeDef(syntax.Mod), id), methods = Nil, privateFields = Nil, publicFields = Nil, ctor = End(), + annotations = Nil, ) -*/ final case class Handler( sym: BlockMemberSymbol, diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/BlockSimplifier.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/BlockSimplifier.scala index 6fa6c6d278..7fcc869249 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/BlockSimplifier.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/BlockSimplifier.scala @@ -51,10 +51,11 @@ class BlockSimplifier changed ||= dce.changed if dce.changed then log("▶ DCE:\n" + printRes) - val vp = new DataFlowAnalysis(LocalVars.analyze(res.main)) - res = vp.apply(res) - changed ||= vp.changed - if vp.changed then log("▶ VP:\n" + printRes) + if !config.disableDataFlowAnalysis then // FIXME: remove it. it now leads to timeout in staged reg exp output + val vp = new DataFlowAnalysis(LocalVars.analyze(res.main)) + res = vp.apply(res) + changed ||= vp.changed + if vp.changed then log("▶ VP:\n" + printRes) summon[Config].inlining.foreach: cfg => val inl = new Inliner(using cfg) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/FirstClassFunctionTransformer.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/FirstClassFunctionTransformer.scala index 0d61f95059..62f01e3124 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/FirstClassFunctionTransformer.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/FirstClassFunctionTransformer.scala @@ -36,7 +36,8 @@ class FirstClassFunctionTransformer End()), End(), None, None)(N, annotations = Nil) private def getParamList(l: BlockMemberSymbol): Option[ParamList] = funDefns.get(l) match - case Some(fd) => fd.params.headOption + case Some(fd) => fd.params.headOption.map(pl => + ParamList(pl.flags, pl.params.map(p => Param(p.flags, VarSymbol(p.sym.id), p.sign, p.modulefulness)), pl.restParam)) case _ => l.tsym.flatMap(getParamList) private def getParamList(ts: TermSymbol): Option[ParamList] = @@ -111,4 +112,19 @@ class FirstClassFunctionTransformer def transform(b: Block): Block = val desugared = new DesugarMultipleParamList().applyBlock(b) new CollectFunDefns().applyBlock(desugared) - applyBlock(desugared) + new LabelTransformer().applyBlock(applyBlock(desugared)) + + +class LabelTransformer(using State, Raise) extends BlockTransformer(new SymbolSubst()): + private val contMap = HashMap.empty[LabelSymbol, BlockMemberSymbol] + + override def applyBlock(b: Block): Block = b match + case Label(label, false, body, rest) => + val contSym = BlockMemberSymbol("cont$", Nil, false) + val contFun = FunDefn.withFreshSymbol(N, contSym, PlainParamList(Nil) :: Nil, rest)(N, Nil) + contMap.addOne(label -> contSym) + super.applyBlock(Scoped(Set(contSym), Define(contFun, body))) + case Break(label) => contMap.get(label) match + case S(sym) => Return(Call(sym.asPath, Nil ne_:: Nil)(CallMetadata.defaultMlsFun)) + case _ => super.applyBlock(b) + case _ => super.applyBlock(b) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala index ed88ca3b84..3b24393cf4 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala @@ -269,15 +269,13 @@ class Lowering()(using Config, TL, Raise, State, Ctx, SymbolPrinter): mod.classCompanion match case S(comp) => comp.defn.getOrElse(wat("Module companion without definition", mod.companion)) case N => - val stagedAnnots = mod.annotations.collect: - case Annot.Modifier(Keyword.`staged`) => Annot.Modifier(Keyword.`staged`) ClassDef.Plain(mod.owner, syntax.Cls, new ClassSymbol(Tree.DummyTypeDef(syntax.Cls), mod.sym.id), mod.bsym, Nil, N, ObjBody(Blk(Nil, UnitVal())), S(mod.sym), - stagedAnnots, + Nil, Nil, N, ) diff --git a/hkmc2/shared/src/main/scala/hkmc2/codegen/ReflectionInstrumenter.scala b/hkmc2/shared/src/main/scala/hkmc2/codegen/ReflectionInstrumenter.scala index 92b08e9c31..de36528376 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/codegen/ReflectionInstrumenter.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/codegen/ReflectionInstrumenter.scala @@ -4,7 +4,7 @@ package codegen import utils.* import hkmc2.Message.MessageContext -import scala.collection.mutable.HashMap +import scala.collection.mutable.{HashMap, HashSet} import scala.util.chaining.* import hkmc2.utils.*, shorthands.* @@ -13,61 +13,140 @@ import semantics.* import semantics.Elaborator.{State, Ctx, ctx} import syntax.{Keyword, Literal, Tree} +import hkmc2.syntax.Tree.Ident // it should be possible to cache some common constructions (End, Option) into the context // this avoids having to rebuild the same shapes everytime they are needed - -// transform Block to Block IR so that it can be instrumented in mlscript -class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(new SymbolSubst()): - // recover `defn` for when `sym.defn` is `None`, when the definition was generated by other compiler passes - val defnMap = HashMap[Symbol, ClsLikeDefn]() - - type ArgWrappable = Path | ValueSymbol - type Context = HashMap[Path, Path] - // TODO: there could be a fresh scope per function body, instead of a single one for the entire program - val scope = Scope.empty(Scope.Cfg.default) - - def asArg(x: ArgWrappable): Arg = x match - case p: Path => p.asArg - case l: ValueSymbol => l.asPath.asArg - - // null and undefined are missing - def toValue(lit: Str | Int | BigDecimal | Bool): Value = - val l = lit match - case i: Int => Tree.IntLit(i) - case b: Bool => Tree.BoolLit(b) - case s: Str => Tree.StrLit(s) - case n: BigDecimal => Tree.DecLit(n) - Value.Lit(l) - - extension [A, B](ls: Ls[(A => B) => B]) - def collectApply(f: Ls[A] => B): B = - // defer applying k while prepending new elements to the list - ls.foldRight((_: Ls[A] => B)(Nil))((headCont, tailCont) => +// allowMultipleParamList: bypasses error from instrumenting user functions with multiple parameter lists +case class Context(cache: HashMap[Path | Symbol, Path], allowMultipleParamList: Bool = false): + def getCache(p: Path | Symbol): Option[Path] = cache.get(p) + def addCache(p: Path | Symbol, v: Path): Context = Context(cache.clone() += (p -> v), allowMultipleParamList) + def delCache(p: Path | Symbol): Context = Context(cache.clone() -= p, allowMultipleParamList) + override def clone(): Context = Context(cache.clone(), allowMultipleParamList) + +object Context: + def apply(allowMultipleParamList: Bool): Context = Context(new HashMap(), allowMultipleParamList) + +extension [A, B](ls: Iterable[(A => B) => B]) + def collectApply(f: Ls[A] => B): B = + // defer applying k while prepending new elements to the list + ls.foldRight((_: Ls[A] => B)(Nil))((headCont, tailCont) => + k => + headCont: head => + tailCont: tail => + k(head :: tail), + )(f) + +extension [A](xs: Ls[Context => ((A, Context) => Block) => Block]) + def chainContext(using ctx: Context)(k: (Ls[A], Context) => Block): Block = + xs.foldRight((ctx: Context) => (k: (Ls[A], Context) => Block) => k(Nil, ctx))((head, tail) => + ctx => k => - headCont: head => - tailCont: tail => - k(head :: tail) - )(f) - - // helpers for constructing Block - - def assign(res: Result, symName: Str = "tmp")(k: Path => Block): Block = + head(ctx): (head, ctx) => + tail(ctx): (tail, ctx) => + k(head :: tail, ctx), + )(ctx)(k) + +type ArgWrappable = Path | ValueSymbol + +def asArg(x: ArgWrappable): Arg = x match + case p: Path => p.asArg + case l: ValueSymbol => l.asPath.asArg + +// null and undefined are missing +def toValue(lit: Str | Int | BigDecimal | Bool): Value = + val l = lit match + case i: Int => Tree.IntLit(i) + case b: Bool => Tree.BoolLit(b) + case s: Str => Tree.StrLit(s) + case n: BigDecimal => Tree.DecLit(n) + Value.Lit(l) + +// helpers for constructing Block +object Helpers: + def assign(using State)(res: Result, symName: Str = "tmp")(k: Path => Block): Block = // TODO: skip assignment if res: Path? val sym = new TempSymbol(N, symName) Scoped(Set(sym), Assign(sym, res, k(sym.asSimpleRef))) - def tuple(elems: Ls[ArgWrappable], symName: Str = "tmp")(k: Path => Block): Block = + def tuple(using State)(elems: Ls[ArgWrappable], symName: Str = "tmp")(k: Path => Block): Block = assign(Tuple(false, elems.map(asArg)), symName)(k) - // isMlsFun is probably always true? - def call(fun: Path, args: Ls[ArgWrappable], isMlsFun: Bool = true, symName: Str = "tmp")(k: Path => Block): Block = + def ctor(using State)(cls: Path, args: Ls[ArgWrappable], symName: Str = "tmp")(k: Path => Block): Block = + assign(Instantiate(false, cls, Ls(args.map(asArg)))(InstantiateMetadata.empty), symName)(k) + + def call(using State)(fun: Path, args: Ls[ArgWrappable], isMlsFun: Bool = true, symName: Str = "tmp")(k: Path => Block): Block = assign(Call(fun, args.map(asArg) ne_:: Nil)(CallMetadata(isMlsFun, false, Nil)), symName)(k) - // helpers for instrumenting Block +// transform fields of a class from private to public +class DataClassTransformer(using State) extends BlockTransformer(SymbolSubst.Id): + import Helpers._ + + // add val flag to each param + override def applyParamList(ps: ParamList) = + ps.copy(params = ps.params.map(param => param.copy(flags = param.flags.copy(isVal = true)))) + + override def applyClsLikeDefn(defn: ClsLikeDefn)(k: Defn => Block) = + val addSyms = defn.privateFields.map(f => (BlockMemberSymbol(f.name, Nil, false), f)) + val privateFields = addSyms.map({case (b, f) => f.name -> (b, f)}).toMap + + val paramsOpt = defn.paramsOpt.map(applyParamList) + val auxParams = defn.auxParams.map(applyParamList) + + class PrivateFieldDefnRemover extends BlockTransformer(SymbolSubst.Id): + override def applyPath(p: Path)(k: Path => Block) = p match + // remove outdated definition symbols for private fields + case s @ Select(Value.This(cls), Tree.Ident(n)) if cls == defn.isym && privateFields.get(n).isDefined => k(s.copy()(N)) + case _ => k(p) + + // change private field initializations to public + val publicInitTransformer = new PrivateFieldDefnRemover: + override def applyBlock(b: Block) = b match + case AssignField(l @ Value.This(cls), Tree.Ident(n), r, rest) if cls == defn.isym => + privateFields.get(n) match + case S((b, t)) => + applyResult(r): r => + assign(r): p => + Define(ValDefn(t, b, p)(N, Nil), applyBlock(rest)) + case N => super.applyBlock(b) + case _ => super.applyBlock(b) + // only turn AssignField declarations for private fields to ValDefn for public fields + val ctor = publicInitTransformer.applyBlock(defn.ctor) + val methods = defn.methods.map((new PrivateFieldDefnRemover).applyFunDefn) + + val newDefn = defn.copy( + paramsOpt = paramsOpt, + auxParams = auxParams, + publicFields = addSyms ++ defn.publicFields, + privateFields = Nil, + ctor = ctor, + methods = methods, + )(defn.configOverride, defn.annotations) + + k(newDefn) + +// replaces VarSymbols using map +class VarSymSubst(map: Map[VarSymbol, VarSymbol]) extends SymbolSubst: + override def mapVarSym(l: VarSymbol): VarSymbol = map.getOrElse(l, l) + +// transform Block to Block IR so that it can be instrumented in mlscript +class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(SymbolSubst.Id): + import Helpers._ + // scope holds bindings of variables, and the ModuleOrObjectSymbol/ClassSymbols collected are later used for redirection + val scope = Scope.empty(Scope.Cfg.default) + // recover `defn` for when `sym.defn` is `None`, when the definition was generated by other compiler passes + val defnMap = HashMap[DefinitionSymbol[? <: ClassLikeDef], ClsLikeDefn]() + // elaborated path of a BaseTypeSymbol + val baseTypePath = HashMap[BaseTypeSymbol, Path]() + + def getDefn(l: DefinitionSymbol[? <: ClassLikeDef]) = + l.defn.orElse(defnMap.get(l)).get + + // helpers for constructing Block IR def blockMod(name: Str) = summon[State].blockSymbol.asSimpleRef.selSN(name) def optionMod(name: Str) = summon[State].optionSymbol.asSimpleRef.selSN(name) + def helperMod(name: Str) = summon[State].specializeHelpersSymbol.asSimpleRef.selSN(name) def blockCtor(name: Str, args: Ls[ArgWrappable], symName: Str = "tmp")(k: Path => Block): Block = call(blockMod(name), args, true, symName)(k) @@ -82,60 +161,87 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n // linking functions defined in MLscipt def fnPrintCode(p: Path)(k: Block): Block = + val printCodeFun = blockMod("Printer").selSN("class").selSN("default").selSN("printCode") // discard result, we only care about side effect - blockCall("printCode", Ls(p))(_ => k) + call(printCodeFun, Ls(p))(_ => k) def fnConcat(p1: Path, p2: Path, symName: String = "concat")(k: Path => Block): Block = blockCall("concat", Ls(p1, p2), symName)(k) // transformation helpers + // preserveName overrides the renaming of symbols within the function // if sym is ClassSymbol, we may need pOpt to link to the path pointing to the value of the symbol - def transformSymbol(sym: MaybeSymbol, pOpt: Option[Path] = N, symName: Str = "sym")(k: Path => Block): Block = sym match - case t: TermSymbol if t.defn.exists(_.sym.asClsOrMod.isDefined) => - transformSymbol(t.defn.get.sym.asClsOrMod.get, pOpt, symName)(k) - // retain names to built-in functions or function definitions - case t: TermSymbol if t.defn.exists(_.k == syntax.Fun) => - blockCtor("Symbol", Ls(toValue(sym.nme)), symName)(k) - case clsSym: ClassSymbol if ctx.builtins.virtualClasses(clsSym) => - blockCtor("VirtualClassSymbol", Ls(toValue(sym.nme)), symName)(k) - case baseSym: BaseTypeSymbol => - val name = scope.allocateOrGetName(baseSym) - val (owner, bsym, paramsOpt, auxParams) = (baseSym.defn, defnMap.get(baseSym)) match - case (S(defn), _) => (defn.owner, defn.bsym, defn.paramsOpt, defn.auxParams) - case (_, S(defn: ClsLikeDefn)) => (defn.owner, defn.sym, defn.paramsOpt, defn.auxParams) - // FIXME: hack to patch in staging for returning the object Unit. - case _ if baseSym == State.unitSymbol => (N, baseSym, N, Nil) + def transformSymbol(sym: MaybeSymbol, preserveName: Bool = false, pOpt: Option[Path] = N, symName: Str = "sym")(using ctx: Context)(k: (Path, Context) => Block): Block = + sym match + case sym: Symbol => transformSymbol(sym, preserveName, pOpt, symName)(k) + // the symbol will never be referenced, so no need to cache it + case _: NoSymbol => blockCtor("NoSymbol", Nil, symName)(k(_, ctx)) + + def transformSymbol(sym: Symbol, preserveName: Bool, pOpt: Option[Path], symName: Str)(using ctx: Context)(k: (Path, Context) => Block): Block = + def cachedK(p: Path, ctx: Context) = + k(p, ctx.addCache(sym, p)) + def checkMap(mapType: Str, key: Path, p: Path, ctx: Context) = + call(State.runtimeSymbol.asPath.selSN("SymbolMap").selSN(mapType), Ls(key, p))(cachedK(_, ctx)) + ctx.getCache(sym).map(cachedK(_, ctx)).getOrElse: + // reserve name to scope to avoid shadowing by other symbols + val rename = sym match + case _ if pOpt.isDefined => false + case _ if preserveName => scope.allocateOrGetName(sym); false + // non-top-level classes + case c: ClassSymbol if c.defn.exists(_.owner.isDefined) => false + // top-level user-defined staged classes + case c: ClassSymbol if c.defn.exists(defn => defn.owner.isEmpty && defn.hasStagedModifier.isDefined) => false + // avoid name collision + case _: TempSymbol | _: LocalVarSymbol | _: BaseTypeSymbol => true + // FIXME: there may be more types of symbols that need to be renamed during staging + case b: BlockMemberSymbol => + if !b.nameIsMeaningful then scope.allocateOrGetName(sym) + false + case _: BuiltinSymbol => false + case t: TermSymbol if t.defn.exists(_.sym.asTrm.isDefined) && (t.k is syntax.Fun) => false + case _ => false + val name = if rename then scope.allocateOrGetName(sym) else sym.nme + sym match + case t: TermSymbol if t.defn.exists(_.sym.asClsOrMod.isDefined) => + // no need to perform caching for redirecting call + transformSymbol(t.defn.get.sym.asClsOrMod.get, rename, pOpt, symName)(k) + case clsSym: ClassSymbol if Elaborator.ctx.builtins.virtualClasses(clsSym) => + blockCtor("VirtualClassSymbol", Ls(toValue(name)), symName)(checkMap("checkClassMap", toValue(name), _, ctx)) + case baseSym: BaseTypeSymbol => + util.boundary: + val (owner, bsym, paramsOpt, auxParams, ctorSym) = (baseSym.defn, defnMap.get(baseSym)) match + case (S(defn), _) => (defn.owner, defn.bsym, defn.paramsOpt, defn.auxParams, defn.ctorSym) + case (_, S(defn: ClsLikeDefn)) => (defn.owner, defn.sym, defn.paramsOpt, defn.auxParams, defn.ctorSym) + // FIXME: hack to patch in staging for returning the object Unit. + case _ if baseSym == State.unitSymbol => (N, baseSym, N, Nil, N) + case _ => + raise(ErrorReport(msg"Unable to infer parameters from symbol in staged module, which are necessary to reconstruct class instances: ${sym.toString()}" -> baseSym.toLoc :: Nil)) + util.boundary.break(End()) + + val path = (pOpt, owner, ctorSym) match + case (S(p), _, _) => p + case (N, S(owner), _) => owner.asThis.selSN(baseSym.nme) + case (N, N, S(ctorSym)) => bsym.asBlkMember.get.asMemberRef(ctorSym) + case _ => bsym.asBlkMember.get.asMemberRef(baseSym.asClsOrMod.get) + + // store the elaborated path of the symbol + baseTypePath += baseSym -> path + + baseSym match + case _: ClassSymbol => + transformParamsOpt(paramsOpt): (paramsOpt, ctx) => + auxParams.map(ps => ctx => transformParamList(ps)(using ctx)).chainContext: (auxParams, ctx) => + tuple(auxParams): auxParams => + blockCtor("ConcreteClassSymbol", Ls(toValue(name), path, paramsOpt, auxParams, toValue(rename)), symName)(checkMap("checkClassMap", path, _, ctx)) + case _: ModuleOrObjectSymbol => + blockCtor("ModuleSymbol", Ls(toValue(name), path, toValue(rename)), symName)(checkMap("checkModuleMap", path, _, ctx)) case _ => - raise(ErrorReport(msg"Unable to infer parameters from symbol in staged module, which are necessary to reconstruct class instances: ${sym.toString()}" -> baseSym.toLoc :: Nil)) - return End() - - val path: ArgWrappable = pOpt.getOrElse(owner match - case S(owner) => owner.asThis.selSN(sym.nme) - case N => bsym.asBlkMember.get.asMemberRef(baseSym.asClsOrMod.get)) - baseSym match - case _: ClassSymbol => - transformParamsOpt(paramsOpt): paramsOpt => - auxParams.map(ps => transformParamList(ps)).collectApply: auxParams => - tuple(auxParams): auxParams => - blockCtor("ConcreteClassSymbol", Ls(toValue(name), path, paramsOpt, auxParams), symName)(k) - case _: ModuleOrObjectSymbol => - blockCtor("ModuleSymbol", Ls(toValue(name), path), symName)(k) - case NoSymbol => - blockCtor("NoSymbol", Nil, symName)(k) - case sym: LocalVarSymbol => - val name = scope.allocateOrGetName(sym) - blockCtor("Symbol", Ls(toValue(name)), symName)(k) - // preserve names to builtin symbols - case _: BuiltinSymbol => - blockCtor("Symbol", Ls(toValue(sym.nme)), symName)(k) - // FIXME: there may be more types of symbols that need to be renamed during staging - case _ => - blockCtor("Symbol", Ls(toValue(sym.nme)), symName)(k) + blockCtor("Symbol", Ls(toValue(name)), symName)(cachedK(_, ctx)) - def transformOption[A](xOpt: Opt[A], f: A => (Path => Block) => Block)(k: Path => Block): Block = xOpt match - case S(x) => f(x)(optionSome(_)(k)) - case N => optionNone()(k) + def transformOption[A](xOpt: Opt[A], f: A => ((Path, Context) => Block) => Block)(using Context)(k: (Path, Context) => Block): Block = xOpt match + case S(x) => f(x)((p, ctx) => optionSome(p)(k(_, ctx))) + case N => optionNone()(k(_, summon)) // instrumentation rules @@ -145,70 +251,67 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n def ruleBranches(x: Path, p: Path, arms: Ls[Case -> Block], dflt: Opt[Block], symName: String = "branches")(using Context)(k: (Path, Context) => Block): Block = def applyRuleBranch(cse: Case, block: Block)(f: Path => Context => Block)(ctx: Context): Block = transformCase(cse): cse => - transformBlock(block)(using ctx.clone() += p -> x): (y, ctx) => + transformBlock(block)(using ctx.addCache(p, x)): (y, ctx) => blockCtor("Arm", Ls(cse, y)): cde => - f(cde)(ctx.clone() -= p) + f(cde)(ctx.delCache(p)) (arms.map(applyRuleBranch).collectApply(_: Ls[Path] => Context => Block)(summon)): arms => ctx => tuple(arms): arms => ruleEnd(): e => - // TODO: use transformOption here - def dfltStaged(k: (Path, Context) => Block) = - dflt match - case S(dflt) => - transformBlock(dflt)(using ctx.clone() += p -> x): (dflt, ctx) => - optionSome(dflt)(k(_, ctx.clone() -= p)) - case N => optionNone()(k(_, ctx)) + def dfltStaged(k: (Path, Context) => Block) = dflt match + case S(dflt) => + transformBlock(dflt)(using ctx.addCache(p, x)): (dflt, ctx) => + optionSome(dflt)(k(_, ctx.delCache(p))) + case N => optionNone()(k(_, ctx)) dfltStaged: (dflt, ctx) => blockCtor("Match", Ls(x, arms, dflt, e), symName)(k(_, ctx)) // transformations of Block - def transformPath(p: Path)(using ctx: Context)(k: Path => Block): Block = + def transformPath(p: Path)(using ctx: Context)(k: (Path, Context) => Block): Block = // rulePath - ctx.get(p).map(k).getOrElse: + ctx.getCache(p).map(k(_, ctx)).getOrElse: p match case Value.SimpleRef(l) => - transformSymbol(l): sym => - blockCtor("ValueSimpleRef", Ls(sym), "var")(k) + transformSymbol(l): (sym, ctx) => + blockCtor("ValueSimpleRef", Ls(sym), "var")(k(_, ctx)) case Value.MemberRef(bms, disamb) => - transformSymbol(disamb): sym => - blockCtor("ValueMemberRef", Ls(sym), "var")(k) + transformSymbol(disamb): (sym, ctx) => + blockCtor("ValueMemberRef", Ls(sym), "var")(k(_, ctx)) case l: Value.Lit => - blockCtor("ValueLit", Ls(l), "lit")(k) + blockCtor("ValueLit", Ls(l), "lit")(k(_, ctx)) + case Value.This(sym) => + transformSymbol(sym): (sym, ctx) => + blockCtor("ValueThis", Ls(sym))(k(_, ctx)) case s @ Select(p, Tree.Ident(name)) => - transformPath(p): x => - val sym = s.symbol.map(transformSymbol(_, S(s))) - .getOrElse(blockCtor("Symbol", Ls(toValue(name)))) - sym: sym => - blockCtor("Select", Ls(x, sym), "sel")(k) + transformPath(p): (x, ctx) => + s.symbol match + case S(sym) => transformSymbol(sym, true, pOpt = S(s))(using ctx)((sym, ctx) => blockCtor("Select", Ls(x, sym), "sel")(k(_, ctx))) + case N => blockCtor("Symbol", Ls(toValue(name)))(sym => blockCtor("Select", Ls(x, sym), "sel")(k(_, ctx))) case DynSelect(qual, fld, arrayIdx) => - transformPath(qual): x => - transformPath(fld): y => - blockCtor("DynSelect", Ls(x, y, toValue(arrayIdx)), "dynsel")(k) - case _: Value.This => - raise(ErrorReport(msg"Value.This not supported in staged module." -> p.toLoc :: Nil)) - End() + transformPath(qual): (x, ctx) => + transformPath(fld)(using ctx): (y, ctx) => + blockCtor("DynSelect", Ls(x, y, toValue(arrayIdx)), "dynsel")(k(_, ctx)) - def transformResult(r: Result)(using Context)(k: Path => Block): Block = r match + def transformResult(r: Result)(using ctx: Context)(k: (Path, Context) => Block): Block = r match case p: Path => transformPath(p)(k) case Tuple(mut, elems) => - assert(!mut, "mutable tuple not supported") - transformArgs(elems): xs => + if mut then raise(ErrorReport(msg"Mutable tuples not supported in staged module." -> r.toLoc :: Nil)) + transformArgs(elems): (xs, ctx) => tuple(xs.map(_._1)): codes => - blockCtor("Tuple", Ls(codes), "tup")(k) + blockCtor("Tuple", Ls(codes), "tup")(k(_, ctx)) case Instantiate(mut, cls, argss) => - assert(!mut, "mutable instantiation not supported") + if mut then raise(ErrorReport(msg"Mutable instantiations not supported in staged module." -> r.toLoc :: Nil)) argss match case Nil => raise(ErrorReport(msg"Instantiate with no argument lists not supported in staged module." -> r.toLoc :: Nil)) End() case args :: Nil => - transformArgs(args): xs => - transformPath(cls): cls => + transformArgs(args): (xs, ctx) => + transformPath(cls)(using ctx): (cls, ctx) => tuple(xs.map(_._1)): codes => - blockCtor("Instantiate", Ls(cls, codes), "inst")(k) + blockCtor("Instantiate", Ls(cls, codes), "inst")(k(_, ctx)) case args :: restArgss => raise(ErrorReport(msg"Instantiate with multiple argument lists not supported in staged module." -> r.toLoc :: Nil)) End() @@ -216,24 +319,12 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n case Call(fun, Ls(Arg(_, scrut), Arg(_, Value.Lit(Tree.IntLit(idx)))) :: _) if fun == Value.SimpleRef(State.runtimeSymbol).selSN("Tuple").selSN("get") => transformPath(Select(scrut, Tree.Ident(idx.toString()))(N))(k) case Call(fun, argss) => - val stagedFunPath = fun match - case s @ Select(qual, Tree.Ident(name)) => s.symbol.flatMap({ - case t: TermSymbol => t.owner.flatMap({ case sym: DefinitionSymbol[?] => - sym.defn.flatMap(_.hasStagedModifier.map(_ => - Select(qual, Tree.Ident(name + "_gen"))(N) - )) - }) - case _ => N - }) - case _ => N - argss match case args :: Nil => - val newFun = stagedFunPath.getOrElse(fun) - transformPath(newFun): fun => - transformArgs(args): args => + transformPath(fun): (stagedFun, ctx) => + transformArgs(args)(using ctx): (args, ctx) => tuple(args.map(_._1)): tup => - blockCtor("Call", Ls(fun, tup), "app")(k) + blockCtor("Call", Ls(stagedFun, tup), "app")(k(_, ctx)) case args :: restArgss => raise(ErrorReport(msg"Call with multiple argument lists not supported in staged module." -> r.toLoc :: Nil)) End() @@ -241,55 +332,59 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n raise(ErrorReport(msg"Other Results not supported in staged module: ${r.getClass.toString()}" -> r.toLoc :: Nil)) End() - def transformArg(a: Arg)(using Context)(k: ((Path, Bool)) => Block): Block = + def transformArg(a: Arg)(using Context)(k: ((Path, Bool), Context) => Block): Block = val Arg(spread, value) = a - if spread.isDefined then - raise(ErrorReport(msg"Spread parameters are not supported in staged module: ${a.toString()}" -> N :: Nil)) - End() - else - transformPath(value): value => - blockCtor("Arg", Ls(value)): cde => - k(cde, spread.isDefined) - - def transformArgs(args: Ls[Arg])(using Context)(k: Ls[(Path, Bool)] => Block): Block = - args.map(transformArg).collectApply(k) - - def transformParamList(ps: ParamList)(k: Path => Block) = - ps.params.map(p => transformSymbol(p.sym)).collectApply(tuple(_)(k)) - - def transformParamsOpt(pOpt: Opt[ParamList])(k: Path => Block) = + if spread.isDefined then raise(ErrorReport(msg"Spread parameters are not supported in staged module." -> value.toLoc :: Nil)) + transformPath(value): (value, ctx) => + blockCtor("Arg", Ls(value)): cde => + k((cde, spread.isDefined), ctx) + + def transformArgs(args: Ls[Arg])(using Context)(k: (Ls[(Path, Bool)], Context) => Block): Block = + args.map(a => ctx => transformArg(a)(using ctx)).chainContext(k) + + // maintain parameter names in instrumented code + def transformParamList(ps: ParamList)(using ctx: Context)(k: (Path, Context) => Block) = + ps.params.map(p => (ctx: Context) => (k: (Path, Context) => Block) => + transformOption(p.flags.reflConstraint, { + case ReflectionConstraint.Dynamic => k => blockCtor("Dynamic", Nil)(k(_, ctx)) + case ReflectionConstraint.Static => k => blockCtor("Static", Nil)(k(_, ctx)) + })(using ctx): (constraint, ctx) => + transformSymbol(p.sym, true)(using ctx): (sym, ctx) => + blockCtor("Param", Ls(constraint, sym))(k(_, ctx)) + ).chainContext((ps, ctx) => tuple(ps)(k(_, ctx))) + + def transformParamsOpt(pOpt: Opt[ParamList])(using ctx: Context)(k: (Path, Context) => Block) = transformOption(pOpt, transformParamList)(k) + def transformParams(params: Ls[ParamList])(using Context)(k: (Path, Context) => Block) = + params.map(ps => ctx => transformParamList(ps)(using ctx)).chainContext((p, ctx) => tuple(p)(k(_, ctx))) + def transformCase(cse: Case)(using Context)(k: Path => Block): Block = cse match case Case.Lit(lit) => blockCtor("Lit", Ls(Value.Lit(lit)))(k) case Case.Cls(cls, path) => - transformSymbol(cls): cls => - transformPath(path): path => + transformSymbol(cls): (cls, ctx) => + transformPath(path)(using ctx): (path, ctx) => blockCtor("Cls", Ls(cls, path))(k) - case Case.Tup(len, true) => - raise(ErrorReport(msg"Spread parameters are not supported in staged module: ${cse.toString()}" -> N :: Nil)) - End() - case Case.Tup(len, false) => + case Case.Tup(len, inf) => + if inf then raise(ErrorReport(msg"Spread parameters are not supported in staged module: ${cse.toString()}" -> N :: Nil)) blockCtor("Tup", Ls(toValue(len)))(k) case Case.Field(name, safe) => raise(ErrorReport(msg"Case.Field not supported in staged module." -> name.toLoc :: Nil)) End() - def transformBlock(b: Block)(using Context)(k: Path => Block): Block = - transformBlock(b)((p, _) => k(p)) - def transformBlock(b: Block)(using ctx: Context)(k: (Path, Context) => Block): Block = b match case Return(res) => - transformResult(res): x => + transformResult(res): (x, ctx) => blockCtor("Return", Ls(x), "return")(k(_, ctx)) case Assign(x, r, b) => - transformResult(r): y => - transformSymbol(x): xSym => + transformResult(r): (y, ctx) => + transformSymbol(x): (xSym, ctx) => blockCtor("ValueSimpleRef", Ls(xSym)): xStaged => (Assign(x, xStaged, _)): + val nextCtx = ctx.clone() given Context = x match - case NoSymbol => ctx.clone() - case x: ValueSymbol => ctx.clone() += x.asPath -> xStaged + case NoSymbol => nextCtx + case x: ValueSymbol => nextCtx.addCache(x.asPath, xStaged) transformBlock(b): (z, ctx) => blockCtor("Assign", Ls(xSym, y, z), "assign")(k(_, ctx)) case assign @ AssignField(lhs, nme, r, rest) => @@ -297,14 +392,10 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n // Ideally, we should just properly reflect these as the private field assignments they are assign.symbol match case S(ts: TermSymbol) if ts.isPrivate => - transformResult(r): y => - transformSymbol(ts): xSym => + transformResult(r): (y, ctx) => + transformSymbol(ts)(using ctx): (xSym, ctx) => blockCtor("ValueSimpleRef", Ls(xSym)): xStaged => - // * Reflect the binding as the private field assignment it is, so the - // * owned field symbol is selected on its owner rather than emitted as a - // * plain reference (which would otherwise reach `JSBuilder`'s owned-`SimpleRef` path). - ((cont: Block) => AssignField(lhs, nme, xStaged, cont)(S(ts))): - given Context = ctx.clone() += Select(lhs, nme)(S(ts)) -> xStaged + given Context = ctx.addCache(Select(lhs, nme)(S(ts)), xStaged) transformBlock(rest): (z, ctx) => blockCtor("Assign", Ls(xSym, y, z), "assign")(k(_, ctx)) case _ => @@ -313,26 +404,26 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n End() case Define(cls: ClsLikeDefn, rest) => assert(cls.companion.isEmpty, "nested module not supported") - transformBlock(rest): p => - transformSymbol(cls.isym): c => - // staging the methods within the module - cls.methods.map(transformFunDefn).collectApply: methods => - tuple(methods): methods => - optionNone(): none => // TODO: handle companion object - blockCtor("ClsLikeDefn", Ls(c, methods, none)): cls => + transformSymbol(cls.isym): (c, ctx) => + // staging the methods within the module + cls.methods.map(defn => ctx => transformFunDefn(defn)(using ctx)).chainContext(using ctx): (methods, ctx) => + tuple(methods): methods => + optionNone(): none => // TODO: handle companion object + blockCtor("ClsLikeDefn", Ls(c, methods, none)): cls => + transformBlock(rest)(using ctx): (p, ctx) => blockCtor("Define", Ls(cls, p))(k(_, ctx)) case Define(v: ValDefn, rest) => // TODO: only allow ValDefn inside ctors - transformBlock(rest): p => - transformOption(v.tsym.owner, transformSymbol(_)): owner => - transformSymbol(v.sym): sym => - transformPath(v.rhs): rhs => + transformOption(v.tsym.owner, transformSymbol(_)): (owner, ctx) => + transformSymbol(v.sym)(using ctx): (sym, ctx) => + transformPath(v.rhs)(using ctx): (rhs, ctx) => + transformBlock(rest)(using ctx): (p, ctx) => blockCtor("ValDefn", Ls(owner, sym, rhs)): v => blockCtor("Define", Ls(v, p))(k(_, ctx)) case End(_) => ruleEnd()(k(_, ctx)) case Match(p, ks, dflt, rest) => - transformPath(p): x => - ruleBranches(x, p, ks, dflt): (stagedMatch, ctx) => + transformPath(p): (x, ctx) => + ruleBranches(x, p, ks, dflt)(using ctx): (stagedMatch, ctx) => transformBlock(rest)(using ctx): (z, ctx) => fnConcat(stagedMatch, z, "match")(k(_, ctx)) case Begin(sub, rest) => @@ -341,9 +432,9 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n transformBlock(rest)(using ctx): (rest, ctx) => fnConcat(sub, rest)(k(_, ctx)) case Scoped(syms, body) => - syms.toList.sortBy(_.uid).map(transformSymbol(_)).collectApply: symsStaged => + syms.toList.sortBy(_.uid).map(s => ctx => transformSymbol(s)(using ctx)).chainContext(using ctx): (symsStaged, ctx) => tuple(symsStaged): tup => - transformBlock(body): (body, ctx) => + transformBlock(body)(using ctx): (body, ctx) => blockCtor("Scoped", Ls(tup, body))(b => Scoped(syms, k(b, ctx))) case Define(_: FunDefn, _) => raise(ErrorReport(msg"Nested function definitions are not supported in staged modules. Try enabling :ftc." -> N :: Nil)) @@ -355,71 +446,262 @@ class ReflectionInstrumenter(using State, Raise, Ctx) extends BlockTransformer(n raise(ErrorReport(msg"Other Blocks not supported in staged module: ${b.getClass.toString()}" -> N :: Nil)) End() - def transformFunDefn(f: FunDefn)(using Context)(k: Path => Block): Block = - transformBlock(f.body): body => - if f.params.length != 1 then + def transformFunDefn(f: FunDefn)(using Context)(k: (Path, Context) => Block): Block = + // maintain parameter names in instrumented code + transformSymbol(f.sym): (sym, ctx) => + if f.params.length > 1 && !ctx.allowMultipleParamList then raise(ErrorReport(msg":ftc must be enabled to desugar functions with multiple parameter lists." -> f.sym.toLoc :: Nil)) - // maintain parameter names in instrumented code - f.params.map( - _.params.map(p => blockCtor("Symbol", Ls(toValue(p.sym.nme)))).collectApply - ).collectApply: paramListSyms => - blockCtor("Symbol", Ls(toValue(f.sym.nme))): sym => - paramListSyms.map(tuple(_)).collectApply: tups => - tuple(tups): tup => - blockCtor("FunDefn", Ls(sym, tup, body, toValue(true)))(k) - - def applyFunDefnInner(f: FunDefn): (FunDefn, Block => Block) = - val genSymName = f.sym.nme + "_instr" - val genSym = BlockMemberSymbol(genSymName, Nil, false) - val sym = f.owner.get.asThis.selSN(genSymName) + transformParams(f.params)(using ctx): (paramList, ctx) => + transformBlock(f.body)(using ctx): (body, ctx) => + blockCtor("FunDefn", Ls(sym, paramList, body))(k(_, ctx)) + + def stageMethod(f: FunDefn, ctx: Context = Context(false)): FunDefn = + val stageSymName = f.sym.nme + "_instr" + val stageSym = BlockMemberSymbol(stageSymName, Nil, false) // turn into fundefn - val dSym = TermSymbol(f.dSym.k, f.dSym.owner, Tree.Ident(f.sym.nme + "_instr")) + val dSym = TermSymbol(f.dSym.k, f.dSym.owner, Tree.Ident(stageSymName)) val argSyms = f.params.flatMap(_.params).map(_.sym) - val newBody = Scoped(Set(argSyms*), transformFunDefn(f)(using new HashMap)(Return(_))) - - // TODO: remove it. only for test - val debug = (k: Block) => call(sym, Nil)(fnPrintCode(_)(k)) - val newFun = f.copy(sym = genSym, dSym = dSym, params = Ls(PlainParamList(Nil)), body = newBody)(f.configOverride, f.annotations) - (newFun, debug) - - override def applyBlock(b: Block): Block = super.applyBlock(b) match - // find modules with staged annotation - case Define(c: ClsLikeDefn, rest) if c.companion.exists(_.isStaged) => - val sym = c.sym.subst - val companion = c.companion.get - val (stagedMethods, debugPrintCode) = companion.methods - .map(applyFunDefnInner) - .unzip - val ctor = FunDefn.withFreshSymbol(S(companion.isym), BlockMemberSymbol("ctor$", Nil), Ls(PlainParamList(Nil)), companion.ctor)(N, Nil) - val (stagedCtor, ctorPrint) = applyFunDefnInner(ctor) - - val debugBlock = (ctorPrint :: debugPrintCode) - .foldRight(End(): Block)(_(_)) - def debugCont(rest: Block) = - Begin(debugBlock, rest) - // add generator functions for classes within the constructor - val genCls = new BlockTransformer(SymbolSubst.Id): - override def applyBlock(b: Block): Block = super.applyBlock(b) match - case Define(c: ClsLikeDefn, rest) if c.companion.isEmpty => - val (stagedMethods, debugPrintCode) = c.methods - .map(applyFunDefnInner) - .unzip - val newModule = c.copy(methods = c.methods ++ stagedMethods)(c.configOverride, c.annotations.filter: - case Annot.Modifier(Keyword.`staged`) => false - case _ => true) - Define(newModule, rest) - case b => b - val newCtor = genCls.applyBlock(companion.ctor) + val newBody = transformFunDefn(f)(using ctx)((block, _) => Return(block)) + + FunDefn.withFreshSymbol(f.dSym.owner, stageSym, Ls(PlainParamList(Nil)), newBody)(f.configOverride, f.annotations) + + def refreshParamList(ps: ParamList) = + PlainParamList(ps.params.map(p => Param.simple(VarSymbol(Tree.Ident(p.sym.nme))))) + + def genMethod(cache: Path, classFun: Bool)(f: FunDefn, stagedPath: Path) = + val genSymName = f.sym.nme + "_gen" + val sym = BlockMemberSymbol(genSymName, Nil, false) + val dSym = TermSymbol(f.dSym.k, f.dSym.owner, Tree.Ident(genSymName)) + + // refresh parameters + val funParams = f.params.map(refreshParamList) + val params = if classFun then PlainParamList(Param.simple(VarSymbol(Tree.Ident("cls"))) :: Nil) :: funParams else funParams + val body = params.map(ps => tuple(ps.params.map(_.sym))).collectApply: tups => + tuple(tups): args => + call(helperMod("specialize"), Ls(cache, toValue(f.sym.nme), stagedPath, args)): res => + Return(res) + FunDefn.withFreshSymbol(f.dSym.owner, sym, params, body)(f.configOverride, f.annotations) + + def stageCtor(ctorFun: FunDefn): FunDefn = + // refresh VarSymbols for ctor + val paramSymMap = ctorFun.params.map(_.params.map(x => x.sym -> VarSymbol(x.sym.id))).flatten.toMap + // refresh symbols after copying parameter list + val paramRewrite = new BlockTransformer(VarSymSubst(paramSymMap)) + stageMethod(paramRewrite.applyFunDefn(ctorFun), Context(true)) + + case class StagingCfg(ownerSym: DefinitionSymbol[? <: ClassLikeDef] & InnerSymbol, modSym: InnerSymbol, nestedPropagates: Ls[Path], codegenClasses: Ls[BlockMemberSymbol]): + val forClass = ownerSym != modSym + val suffix = "$" + scope.allocateOrGetName(ownerSym) + val cacheNme = (if forClass then "class$" else "") + "cache" + suffix + val generatorMapNme = (if forClass then "class$" else "") + "generatorMap" + suffix + + def stageMethods(cfg: StagingCfg)(methods: Ls[FunDefn]): (FunDefn, Ls[FunDefn], Block => Block) = + import cfg._ + // for storing specialized functions in each staged module + val cacheSym = BlockMemberSymbol(cacheNme, Nil, true) + val cacheTsym = TermSymbol(syntax.ImmutVal, S(modSym), Tree.Ident(cacheNme)) + val cachePath = modSym.asPath.selSN(cacheNme) + val generatorMapSym = BlockMemberSymbol(generatorMapNme, Nil, true) + val generatorMapTsym = TermSymbol(syntax.ImmutVal, S(modSym), Tree.Ident(generatorMapNme)) + + // TODO: remove generator function for ctor, we only need the staged function + val (stagedMethods, generatorMethods, generatorEntries) = methods.map(f => + val staged = stageMethod(f) + val stagedPath = modSym.asPath.selSN(staged.sym.nme) + val gen = genMethod(cachePath, forClass)(f, stagedPath) + + ( + staged, + gen, + tuple(Ls(toValue(f.sym.nme), modSym.asPath.selSN(gen.sym.nme))) + ) + ).unzip3 + val reservedNames = getDefn(ownerSym) match + case ownerDefn: semantics.ClassLikeDef => + val ownerParamNames = (ownerDefn.paramsOpt.toList ++ ownerDefn.auxParams) + .flatMap(_.params.map(_.sym.nme)) + (ownerDefn.body.members.keys.toList ++ ownerParamNames).distinct + case ownerDefn: ClsLikeDefn => + val ownerParamNames = (ownerDefn.paramsOpt.toList ++ ownerDefn.auxParams) + .flatMap(_.params.map(_.sym.nme)) + val ownerFieldNames = ownerDefn.publicFields.map(_._1.nme) ++ ownerDefn.privateFields.map(_.nme) + (ownerDefn.methods.map(_.sym.nme) ++ ownerFieldNames ++ ownerParamNames).distinct + val reservedNameValues = reservedNames.map(name => (k: Path => Block) => k(toValue(name))) + + // initialize cache for the module + def cacheDecl(rest: Block) = + val pOpt = if !forClass then S(ownerSym.asThis) else N + + transformSymbol(ownerSym, pOpt = pOpt)(using Context(false)): (stagedSym, _) => + ctor(State.globalThisSymbol.asPath.selSN("Map"), Nil): cacheMap => + reservedNameValues.collectApply: defs => + tuple(defs): reservedNames => + ctor(State.globalThisSymbol.asPath.selSN("Set"), Ls(reservedNames)): nameSet => + ctor(helperMod("FunCache"), Ls(stagedSym, cacheMap, nameSet)): funCache => + Define(ValDefn(cacheTsym, cacheSym, funCache)(N, Nil), rest) + + def generatorMapDecl(rest: Block) = + generatorEntries.collectApply: defs => + tuple(defs): tup => + ctor(State.globalThisSymbol.asPath.selSN("Map"), Ls(tup)): map => + Define(ValDefn(generatorMapTsym, generatorMapSym, map)(N, Nil), rest) + + val propFunDef = + val sym = BlockMemberSymbol("propagate", Nil) + val params = PlainParamList(Nil) + val body = call(State.shapeSetSymbol.asPath.selSN("mkDyn"), Nil, isMlsFun = true, symName = "tmp_dyn"): dynVal => + def callGenCont(rest: Block) = + generatorMethods.foldRight(rest)((gen, rest) => + val genPath = modSym.asPath.selSN(gen.sym.nme) + val params = gen.params.map(_.params.map(_ => dynVal)) + params.foldRight((_: Path) => rest) + ((args, k) => call(_, args, true, "gen_call")(k)) + (genPath) + ) + nestedPropagates.foldRight(callGenCont(End()))((path, rest) => + call(path.selSN("propagate"), Nil, isMlsFun = true, symName = "tmp")(_ => rest) + ) + FunDefn.withFreshSymbol(S(modSym), sym, params :: Nil, body)(N, Nil) + + def genOutputBody(sourceSym: VarSymbol, psym: VarSymbol) = + call(modSym.asPath.selSN(propFunDef.sym.nme), Nil, true, "tmp"): _ => + tuple(codegenClasses): codegenClasses => + call(blockMod("codegen"), Ls(toValue(modSym.nme), cachePath, sourceSym, psym, codegenClasses), true, "tmp")(_ => End()) + val entryFunDef = + val sym = BlockMemberSymbol("generate", Nil) + val sourceSym = VarSymbol(Ident("source")) + val psym = VarSymbol(Ident("path")) + val params = PlainParamList(Param.simple(sourceSym) :: Param.simple(psym) :: Nil) + FunDefn.withFreshSymbol(S(modSym), sym, params :: Nil, genOutputBody(sourceSym, psym))(N, Nil) + + val toCodeDef = + val sym = BlockMemberSymbol("toCode", Nil) + val params = PlainParamList(Nil) + val body = tuple(codegenClasses): codegenClasses => + call(blockMod("toCode"), Ls(toValue(modSym.nme), cachePath, codegenClasses), true, "tmp")(Return(_)) + FunDefn.withFreshSymbol(S(modSym), sym, params :: Nil, body)(N, Nil) + + // grab all defn seen so far + // TODO: this could be reduced to only contain all the symbols used within the module + val previousStageValues = if forClass then Nil else + scope.getBindings.toList.collect[(ClassSymbol | ModuleOrObjectSymbol, String)]({ // FIXME: this `toList` should be removed, but now we lose some of the values without it. + case (m: ModuleOrObjectSymbol, s) if m != State.unitSymbol && m != ownerSym => (m, s) + case (c: ClassSymbol, s) if !Elaborator.ctx.builtins.virtualClasses(c) && c != ownerSym => (c, s) + }).map((key, nme) => + val name = nme + "$" + scope.allocateOrGetName(ownerSym) + val tsym = TermSymbol(syntax.ImmutVal, S(modSym), Tree.Ident(name)) + val sym = BlockMemberSymbol(name, Nil) + (tsym, sym, baseTypePath.get(key).get) + ) + + def previousStageDecl(b: Block) = + previousStageValues.iterator.foldRight(b)({ case ((tsym, sym, key), acc) => + Define(ValDefn(tsym, sym, key)(N, Nil), acc) + }) + + (entryFunDef, propFunDef :: toCodeDef :: stagedMethods ++ generatorMethods, b => cacheDecl(generatorMapDecl(previousStageDecl(b)))) + + override def applyObjBody(companion: ClsLikeBody) = + if companion.isStaged then + // staged modules + val (sym, ctor, methods) = (companion.isym, companion.ctor, companion.methods) + // avoid name clash of cache and generator map for derived staged classes + val modSym = sym + val ctorFun = FunDefn.withFreshSymbol(S(modSym), BlockMemberSymbol("ctor$", Nil, false), Ls(PlainParamList(Nil)), ctor)(N, Nil) + val newCtorFun = stageCtor(ctorFun) + + // collect top-level staged classes to be printed in the next stage + class UsedStagedClassesCollector extends BlockTraverser: + val used: HashSet[BlockMemberSymbol] = new HashSet() + override def applySymbol(sym: Symbol) = sym match + case c: ClassSymbol if c.defn.exists(defn => defn.hasStagedModifier.isDefined && defn.owner.isEmpty) => + used += c.defn.get.bsym + case _ => () + val collector = (new UsedStagedClassesCollector) + collector.applyCompanionModule(companion) + val codegenClasses = collector.used + + val defn = sym.defn match + case S(defn) => defn + case N => raise(ErrorReport(msg"No definition found for staged module." -> sym.toLoc :: Nil)); return companion + val nestedPropagates = defn.body.blk.stats.collect: + case cls: ClassDef if cls.hasStagedModifier.isDefined => + modSym.asPath.sel(Tree.Ident(cls.sym.nme), cls.sym) + + val cfg = new StagingCfg(companion.isym, modSym, nestedPropagates, codegenClasses.toList) + val (entryFun, newMethods, cont) = stageMethods(cfg)(methods) + + companion.copy( + methods = entryFun :: newCtorFun :: newMethods, + ctor = Begin(applyBlock(companion.ctor), cont(End())), + ) + else super.applyObjBody(companion) + + // lazy is needed for ctx.builtins.Function + lazy val firstClassFunc = State.globalThisSymbol.asThis.sel(Tree.Ident("Function"), ctx.builtins.Function) + + override def applyBlock(b: Block): Block = b match + // Lifter adds private variables after lifting function classes after FirstClassFunctionTransformer, but we need the variables to be public for staging + case Define(defn: ClsLikeDefn, rest) if defn.isStaged && defn.parentPath.exists(_ == firstClassFunc) && !defn.sym.nameIsMeaningful && !defn.privateFields.isEmpty => + (new DataClassTransformer).applyClsLikeDefn(defn): defn => + applyBlock(Define(defn, rest)) + // staged classes + case Define(defn: ClsLikeDefn, rest) if defn.isStaged => + if !defn.privateFields.isEmpty then + raise(ErrorReport(msg"Staged classes with private fields are not supported." -> defn.sym.toLoc :: Nil)) + return End() + + // stage the companion module first, to avoid staging the new functions we add to the companion module + val companion = defn.companion.map(applyObjBody).getOrElse(ClsLikeBody.empty(Tree.Ident(defn.sym.nme))) + + def replaceSuper(parentPath: Path) = new BlockTransformer(SymbolSubst.Id): + override def applyResult(r: Result)(k: Result => Block) = super.applyResult(r): + case Call(Value.SimpleRef(sym: BuiltinSymbol), args) if sym.nme == "super" => k(Call(parentPath, args)(CallMetadata.defaultMlsFun)) + case r => k(r) + val preCtor = defn.parentPath match + case S(parent) => replaceSuper(parent).applyBlock(defn.preCtor) + case N => defn.preCtor + + val (sym, ctor, ctorParams, methods) = + val ctorParams = defn.paramsOpt match + case S(ps) => ps :: defn.auxParams + case N => defn.auxParams + (defn.sym, defn.ctor, ctorParams, defn.methods) + + val modSym = companion.isym + + val preCtorFun = FunDefn.withFreshSymbol(S(modSym), BlockMemberSymbol("preCtor$", Nil, false), ctorParams, preCtor)(N, Nil) + val ctorFun = FunDefn.withFreshSymbol(S(modSym), BlockMemberSymbol("class$ctor$", Nil, false), ctorParams, ctor)(N, Nil) + val newPreCtorFun = stageCtor(preCtorFun) + val newCtorFun = stageCtor(ctorFun) + + val cfg = new StagingCfg(defn.isym, modSym, Nil, Nil) + val (entryFun, newMethods, cont) = stageMethods(cfg)(methods) + val (companionEntryFun, companionMethods) = companion.methods.partition(_.sym.nme == "generate") + val combinedEntryFun: FunDefn = companionEntryFun match + case Nil => entryFun + case companionFun :: Nil => + val symMap = entryFun.params.flatMap(_.params.map(_.sym)) + .zip(companionFun.params.flatMap(_.params.map(_.sym))) + .toMap + val paramRewrite = new BlockTransformer(VarSymSubst(symMap)) + val combinedBody = Begin(companionFun.body, paramRewrite.applyBlock(entryFun.body)) + companionFun.copy(body = combinedBody)(companionFun.configOverride, companionFun.annotations) + case _ => + raise(ErrorReport(msg"There shouldn't be more than one entry function generated in a module." -> N :: Nil)) + entryFun + + // used for staging classes inside modules val newCompanion = companion.copy( - methods = stagedCtor :: companion.methods ++ stagedMethods, - ctor = Begin(newCtor, debugCont(End())), + methods = combinedEntryFun :: newPreCtorFun :: newCtorFun :: newMethods ++ companionMethods, + ctor = Begin(companion.ctor, cont(End())), ) - val newModule = c.copy(sym = sym, companion = S(newCompanion))(c.configOverride, c.annotations.filter: + val newModule = defn.copy(sym = sym, companion = S(newCompanion), ctor = applyBlock(ctor))(defn.configOverride, defn.annotations.filter: case Annot.Modifier(Keyword.`staged`) => false case _ => true) - Define(newModule, rest) - case b => b + Define(newModule, applyBlock(rest)) + case b => super.applyBlock(b) def mkDefnMap(b: Block): Unit = val transformer = new BlockTraverser: diff --git a/hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala b/hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala index f254254000..9c2d16a259 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala @@ -342,6 +342,8 @@ object Elaborator: val prettyPrintSymbol = TempSymbol(N, "prettyPrint") val termSymbol = TempSymbol(N, "Term") val blockSymbol = TempSymbol(N, "Block") + val shapeSetSymbol = TempSymbol(N, "ShapeSet") + val specializeHelpersSymbol = TempSymbol(N, "SpecializeHelpers") val optionSymbol = TempSymbol(N, "option") val wasmSymbol = TempSymbol(N, "wasm") val nonLocalRetHandlerTrm = @@ -1737,9 +1739,9 @@ extends Importer with ucs.SplitElaborator: val allParams = ps.fold(Nil): _.params.flatMap: // Only `pat` flag is `true`. - case p @ Param(flags = FldFlags(false, false, true, false)) => S(p) + case p @ Param(flags = FldFlags(N, false, false, true, false)) => S(p) // All flags are `false`. - case p @ Param(flags = FldFlags(false, false, false, false)) => S(p) + case p @ Param(flags = FldFlags(N, false, false, false, false)) => S(p) case Param(flags, sym, _, _) => raise(ErrorReport(msg"Unexpected pattern parameter ${sym.name} with modifiers: ${flags.show}" -> sym.toLoc :: Nil)) N diff --git a/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala b/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala index 6f1c47265b..911bd8a6b1 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/semantics/Term.scala @@ -1290,11 +1290,17 @@ case class TypeDef( annotations: Ls[Annot], ) extends TypeLikeDef +enum ReflectionConstraint: + case Dynamic, Static + def str: Str = this match + case Dynamic => "@dynamic" + case Static => "@static" // TODO Store optional source locations for the flags instead of booleans -final case class FldFlags(mut: Bool, spec: Bool, pat: Bool, isVal: Bool): +final case class FldFlags(reflConstraint: Opt[ReflectionConstraint], mut: Bool, spec: Bool, pat: Bool, isVal: Bool): def show: Str = val flags = Buffer.empty[String] + reflConstraint.map(flags += _.str) if mut then flags += "mut" if spec then flags += "spec" if pat then flags += "pattern" @@ -1303,7 +1309,7 @@ final case class FldFlags(mut: Bool, spec: Bool, pat: Bool, isVal: Bool): override def toString: String = "‹" + show + "›" object FldFlags: - val empty: FldFlags = FldFlags(false, false, false, false) + val empty: FldFlags = FldFlags(N, false, false, false, false) object benign: // * Some flags like `mut` and `module` are "benign" in the sense that they don't affect code-gen def unapply(flags: FldFlags): Bool = diff --git a/hkmc2/shared/src/main/scala/hkmc2/syntax/Tree.scala b/hkmc2/shared/src/main/scala/hkmc2/syntax/Tree.scala index a51ffe0524..3d2e795e4f 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/syntax/Tree.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/syntax/Tree.scala @@ -9,7 +9,7 @@ import hkmc2.utils.*, shorthands.* import hkmc2.utils.* import hkmc2.Message.MessageContext -import semantics.{FldFlags, TermDefFlags, Modulefulness} +import semantics.{FldFlags, TermDefFlags, Modulefulness, ReflectionConstraint} import semantics.Elaborator.State import Tree._ @@ -382,6 +382,18 @@ enum Tree extends AutoLocated: // fun f(using <...>) case TermDef(Ins, inner, N) => go(inner, flags, modifiers + Ins) + // fun f(@dynamic <...>) + case Annotated(Ident("dynamic"), inner) => + if flags.reflConstraint.isDefined then L: + ErrorReport: + msg"At most one reflection constraint can be added for each parameter." -> t.toLoc :: Nil + else go(inner, flags.copy(reflConstraint = S(ReflectionConstraint.Dynamic)), modifiers) + // fun f(@static <...>) + case Annotated(Ident("static"), inner) => + if flags.reflConstraint.isDefined then L: + ErrorReport: + msg"At most one reflection constraint can be added for each parameter." -> t.toLoc :: Nil + else go(inner, flags.copy(reflConstraint = S(ReflectionConstraint.Static)), modifiers) // * Base Case (for `using` clause) // fun f(using A) diff --git a/hkmc2/shared/src/main/scala/hkmc2/utils/utils.scala b/hkmc2/shared/src/main/scala/hkmc2/utils/utils.scala index 9d579cdb98..d1deb238f2 100644 --- a/hkmc2/shared/src/main/scala/hkmc2/utils/utils.scala +++ b/hkmc2/shared/src/main/scala/hkmc2/utils/utils.scala @@ -74,8 +74,9 @@ class DebugPrinter: val flags = Buffer.empty[Str] if isMethod then flags += "method" flags.mkString("(", ", ", ")") - case FldFlags(mut, spec, pat, value) => + case FldFlags(reflConstraint, mut, spec, pat, value) => val flags = Buffer.empty[Str] + reflConstraint.map(flags += _.str) if mut then flags += "mut" if spec then flags += "spec" if pat then flags += "pat" diff --git a/hkmc2/shared/src/test/mlscript-compile/Block.mls b/hkmc2/shared/src/test/mlscript-compile/Block.mls index e7a6169c42..ec4d7cdb15 100644 --- a/hkmc2/shared/src/test/mlscript-compile/Block.mls +++ b/hkmc2/shared/src/test/mlscript-compile/Block.mls @@ -1,29 +1,76 @@ +#config(liftDefns: None) + import "./Predef.mls" import "./Option.mls" import "./StrOps.mls" import "./Runtime.mls" +import "fs" +import "process" +import "path" +import "url" + open Predef open StrOps open Option module Block with... +module StagingUtility with + let moduleGenMapPrefix = "generatorMap$" + let classGenMapPrefix = "class$generatorMap$" + let moduleCachePrefix = "cache$" + let classCachePrefix = "class$cache$" + + fun isStagedClass(c) = + not (getClassGenMap(c) is undefined) + + fun getGenMapName(name, isClass) = + (if isClass then classGenMapPrefix else moduleGenMapPrefix) + name + + fun getCacheName(name, isClass) = + (if isClass then classCachePrefix else moduleCachePrefix) + name + + fun getActualClass(c) = if not (c."class" is undefined) then c.class else c + + fun legacyName(name) = name + "__Legacy" + + fun getStagedClassInfo(c) = + let actualClass = getActualClass(c) + let clsName = actualClass.(Symbols.definitionMetadata).1 + [actualClass, clsName] + + fun getClassGenMap(c) = + let info = getStagedClassInfo(c) + info.0.(getGenMapName(info.1, true)) + + fun getClassCache(c) = + let info = getStagedClassInfo(c) + info.0.(getCacheName(info.1, true)) + +open StagingUtility {isStagedClass, getClassCache, legacyName} + type Opt[A] = Option[A] // dependancies referenced in Block classes, referencing implementation in Term.mls type Literal = null | undefined | Str | Int | Num | Bool -type ParamList = Array[Symbol] +type ParamList = Array[Param] class Symbol(val name: Str) -// this is so that we're able to retrieve information about the class from the symbol class ClassSymbol(val name: Str) extends Symbol(name) class VirtualClassSymbol(val name: Str) extends ClassSymbol(name) -class ConcreteClassSymbol(val name: Str, val value: Class, val paramsOpt: Opt[ParamList], val auxParams: Array[ParamList]) extends ClassSymbol(name) -class ModuleSymbol(val name: Str, val value: Class) extends Symbol(name) +class ConcreteClassSymbol(val name: Str, val value: Class, val paramsOpt: Opt[ParamList], val auxParams: Array[ParamList], val redirect: Bool) extends ClassSymbol(name) +class ModuleSymbol(val name: Str, val value: Class, val redirect: Bool) extends Symbol(name) class NoSymbol() extends Symbol("$no_symbol$") + +class Constraint with + constructor + Dynamic() + Static() + +class Param(val constraint: Opt[Constraint], val sym: Symbol) class Arm(val cse: Case, val body: Block) fun isPrimitiveType(sym: Symbol) = @@ -42,18 +89,16 @@ fun isPrimitiveTypeOf(sym: Symbol, l: Literal) = ["Bool", b] and b is Bool then true else false - -// Classes defined in Block.scala - +// TODO: spread parameters will be as another field to Arg class Arg(val value: Path) class Case with constructor Lit(val lit: Literal) - Cls(val cls: Symbol, val path: Path) + Cls(val cls: ClassSymbol, val path: Path) Tup(val len: Int) -class Result with +class Result with constructor Call(val _fun: Path, val args: Array[Arg]) Instantiate(val cls: Path, val args: Array[Arg]) // assume immutable @@ -63,9 +108,11 @@ class Path extends Result with constructor Select(val qual: Path, val name: Symbol) DynSelect(val qual: Path, val fld: Path, val arrayIdx: Bool) // is arrayIdx used? + // we use Value as a prefix here to diambiguate from Case.Lit ValueSimpleRef(val l: Symbol) ValueMemberRef(val l: Symbol) ValueLit(val lit: Literal) + ValueThis(val sym: Symbol) class Defn with constructor @@ -85,122 +132,372 @@ class Block with End() fun concat(b1: Block, b2: Block) = if b1 is + Return then b1 + End then b2 Match(scrut, arms, dflt, rest) then Match(scrut, arms, dflt, concat(rest, b2)) - Return(res) then b1 Assign(lhs, rhs, rest) then Assign(lhs, rhs, concat(rest, b2)) Define(defn, rest) then Define(defn, concat(rest, b2)) Scoped(symbols, rest) then Scoped(symbols, concat(rest, b2)) - End() then b2 fun indent(s: Str) = s.replaceAll("\n", "\n ") -fun showLiteral(l: Literal) = - if l is - undefined then "undefined" - null then "null" - Str then "\"" + l.toString() + "\"" - else l.toString() - -fun showSymbol(s: Symbol) = s.name.replaceAll("$", "_") - -fun showPath(p: Path): Str = - if p is - // avoids needing to import the runtime module - Select(ValueSimpleRef(Symbol("runtime")), ModuleSymbol("Unit", Runtime.Unit)) then "()" - Select(qual, name) then showPath(qual) + "." + showSymbol(name) - DynSelect(qual, fld, false) then showPath(qual) + ".(" + showPath(fld) + ")" - DynSelect(qual, fld, true) then showPath(qual) + ".[" + showPath(fld) + "]" - ValueSimpleRef(l) then showSymbol(l) - ValueMemberRef(l) then showSymbol(l) - ValueLit(lit) then showLiteral(lit) - -fun showArg(arg: Arg) = - showPath(arg.value) - -fun showArgs(args: Array[Arg]) = - args.map(showArg).join(", ") - -fun showResult(r: Result): Str = - if r is - Path then showPath(r) - Call(fun_, args) and - // use infix to avoid parsing + and - as taking a unary argument - args is [lhs, rhs] and fun_ is - ValueSimpleRef(Symbol("+")) then showArg(lhs) + " + " + showArg(rhs) - ValueSimpleRef(Symbol("-")) then showArg(lhs) + " - " + showArg(rhs) - else showPath(fun_) + "(" + showArgs(args) + ")" - Instantiate(cls, args) then "new " + showPath(cls) + (if args.length != 0 then "(" + showArgs(args) + ")" else "") - Tuple(elems) then "[" + showArgs(elems) + "]" - _ then "" - -// Case (match arm patterns) -fun showCase(c) = - if c is - Lit(l) then showLiteral(l) - Cls(cls, _) then showSymbol(cls) - Tup(len) then "[" + Array(len).fill("_").join(", ") + "]" - _ then "" - -fun showArm(a) = - showCase(a.cse) + " then" + (if a.body is Return then " " else "\n ") + indent(showBlock(a.body)) - -fun showParams(p: ParamList) = - "(" + p.map(showSymbol(_)).join(", ") + ")" - -fun showParamsOpt(p) = - if p is - Some(s) then showParams(s) - None then "" - -fun showParamList(ps: Array[ParamList]) = - ps.map(showParams).join("") - -fun showDefn(d: Defn): Str = - if d is - FunDefn(sym, ps, body) then - "fun " + showSymbol(sym) + showParamList(ps) + " =" + - (if body is Return | End then " " else "\n ") + indent(showBlock(body)) - ClsLikeDefn(sym, methods, _) then - "class " + showSymbol(sym) + showParamsOpt(sym.paramsOpt) - + indent((if methods is [] then "" else " with\n") + methods.map(showDefn).join("\n")) - // TODO: used to represent assignments in constructors, which still need some adjustments - ValDefn(owner, sym, rhs) then - "val " + showSymbol(sym) + " = " + showPath(rhs) - _ then "" - -fun showBlock(b) = - if b is - Assign(lhs, rhs, rest) then - (if lhs is NoSymbol then "" else showSymbol(lhs) + " = ") - + showResult(rhs) + showRestBlock(rest) - Define(d, rest) then - showDefn(d) + showRestBlock(rest) - Return(res) then - showResult(res) - Match(scrut, arms, dflt, rest) then - "if " + showPath(scrut) + " is" - + indent("\n" + arms.map(showArm).join("\n")) - + if dflt is Some(db) then indent("\nelse" + indent((if db is Return then " " else "\n") + showBlock(db))) else "" - + showRestBlock(rest) - Scoped(symbols, rest) then - // initialize symbols - "let {" + symbols.map(showSymbol).join(", ") + "}" + showRestBlock(rest) - End() then "()" - _ then "" + b - -// removes trailing newline -fun showRestBlock(b : Block): Str = - if b is End then "" else "\n" + showBlock(b) - -fun show(x) = - if x is - Symbol then showSymbol(x) - Path then showPath(x) - Result then showResult(x) - Case then showCase(x) - Defn then showDefn(x) - Block then showBlock(x) - else - "" - -fun printCode(x) = print(show(x)) +// we write .map(f(_)) instead of .map(f) here because of method debinding, see https://github.com/hkust-taco/mlscript/issues/450 +class Printer(val owner: Opt[Symbol]) with + fun showLiteral(l: Literal) = + if l is + undefined then "undefined" + null then "null" + Str then "\"" + l + .replaceAll("\\", "\\\\") + .replaceAll("\"", "\\\"") + .replaceAll("\n", "\\n") + .replaceAll("\t", "\\t") + .replaceAll("\r", "\\r") + + "\"" + else l.toString() + + fun showDefnSymbol(s: Symbol) = + s.name.replaceAll("$", "_") + + fun isGeneratedStagedClass(s: Symbol) = + if s is + ConcreteClassSymbol(_, value, _, _, _) then isStagedClass(value) + else false + + fun showGeneratedStagedClassCache(cache): Str = + cache.printDefinitions() + + fun showSymbol(s: Symbol) = + if s.redirect and owner is + Some(owner) and owner is + ModuleSymbol then // TODO: this must be a top-level module symbol + legacyName(owner.name) + ".\"" + s.name + "$" + owner.name + "\"" + else owner.name + ".\"" + s.name + "$" + owner.name + "\"" + else s.name.replaceAll("$", "_") + + fun showPath(p: Path): Str = + if p is + Select(qual, name) and + qual is + // avoids needing to import the runtime module + ValueMemberRef(Symbol("runtime")) and name is ModuleSymbol("Unit", Runtime.Unit, _) then "()" + // remove selection to owner for values defined within the owner + // TODO: does this pattern exist, or is it replaced by the case below? + ValueMemberRef(sym) and owner is Some(owner) and sym === owner then showSymbol(name) + // NOTE: ValueThis carries information about the class, but the elaborator can infer it for us + ValueThis then showSymbol(name) + else showPath(qual) + "." + showSymbol(name) + DynSelect(qual, fld, false) then showPath(qual) + ".(" + showPath(fld) + ")" + DynSelect(qual, fld, true) then showPath(qual) + ".[" + showPath(fld) + "]" + ValueSimpleRef(l) | ValueMemberRef(l) then showSymbol(l) + ValueLit(lit) then showLiteral(lit) + ValueThis then "this" + + fun showArg(arg: Arg) = + showPath(arg.value) + + fun showArgs(args: Array[Arg]) = + args.map(showArg(_)).join(", ") + + fun hasClassValue(cls: Path) = + if cls is + Select(ValueMemberRef(sym), name) and + owner is Some(owner) and sym == owner and isGeneratedStagedClass(name) then false + ValueMemberRef(ConcreteClassSymbol(_, value, _, _, _)) then not (value."class" is undefined) + Select(_, ConcreteClassSymbol(_, value, _, _, _)) then not (value."class" is undefined) + else false + + fun showInstantiatePath(cls: Path) = + showPath(cls) + (if hasClassValue(cls) then ".class" else "") + + fun showResult(r: Result): Str = + if r is + Path then showPath(r) + Call(fun_, args) and + args is [arg] and fun_ is + ValueSimpleRef(Symbol("!")) then "not " + showArg(arg) + // use infix to avoid parsing + and - as taking a unary argument + args is [lhs, rhs] and fun_ is + ValueSimpleRef(Symbol("+")) then showArg(lhs) + " + " + showArg(rhs) + ValueSimpleRef(Symbol("-")) then showArg(lhs) + " - " + showArg(rhs) + else showPath(fun_) + "(" + showArgs(args) + ")" + Instantiate(cls, args) then + let classPath = showInstantiatePath(cls) + // redirections must be dynamic selections, hence the use of new! is required + // NOTE: noModuleCheck is enabled, so we don't need to switch to new! for dynamic selections from a module + "new " + classPath + "(" + showArgs(args) + ")" + Tuple(elems) then "[" + showArgs(elems) + "]" + _ then "" + + // Case (match arm patterns) + fun showCase(c) = + if c is + Lit(l) then showLiteral(l) + Cls(cls, _) then showSymbol(cls) + Tup(len) then "[" + Array(len).fill("_").join(", ") + "]" + _ then "" + + fun showArm(a) = + showCase(a.cse) + " then" + (if a.body is Return then " " else "\n ") + indent(showBlock(a.body)) + + fun showParams(pl: ParamList) = + // do not print constraints to next stage + "(" + pl.map(p => showSymbol(p.sym)).join(", ") + ")" + + fun showCtorParams(pl: ParamList) = + "(" + pl.map(p => "val " + showSymbol(p.sym)).join(", ") + ")" + + fun showParamsOpt(p) = + if p is + Some(s) then showCtorParams(s) + None then "" + + fun showParamList(ps: Array[ParamList]) = + ps.map(showParams(_)).join("") + + fun collectSymbolName(names: Set[String], sym: Symbol) = + if not sym is NoSymbol do names.add(showSymbol(sym)) + + fun collectParamNames(names: Set[String], ps: Array[ParamList]) = + let printer = this + ps.forEach(pl => pl.forEach(p => printer.collectSymbolName(names, p.sym))) + + fun collectDefnSymbolNames(names: Set[String], d: Defn) = + let printer = this + if d is + FunDefn(_, ps, body) then + printer.collectParamNames(names, ps) + printer.collectBlockSymbolNames(names, body) + ClsLikeDefn(sym, methods, _) then + printer.collectSymbolName(names, sym) + methods.forEach(m => printer.collectDefnSymbolNames(names, m)) + ValDefn(_, sym, _) then printer.collectSymbolName(names, sym) + + fun collectBlockSymbolNames(names: Set[String], b: Block) = + let printer = this + if b is + Assign(lhs, _, rest) then + printer.collectSymbolName(names, lhs) + printer.collectBlockSymbolNames(names, rest) + Define(d, rest) then + printer.collectDefnSymbolNames(names, d) + printer.collectBlockSymbolNames(names, rest) + Match(_, arms, dflt, rest) then + arms.forEach(a => printer.collectBlockSymbolNames(names, a.body)) + if dflt is Some(db) do printer.collectBlockSymbolNames(names, db) + printer.collectBlockSymbolNames(names, rest) + Scoped(symbols, rest) then + symbols.forEach(s => printer.collectSymbolName(names, s)) + printer.collectBlockSymbolNames(names, rest) + Return | End then () + + fun freshSelfSymbol(ps: Array[ParamList], body: Block) = + let names = new Set() + collectParamNames(names, ps) + collectBlockSymbolNames(names, body) + let + base = "self" + idx = 0 + name = base + while names.has(name) do + set + idx += 1 + name = base + idx + Symbol(name) + + fun prependParam(ps: Array[ParamList], p: Param) = + if ps is + [] then [[p]] + [first, ...rest] then [[p, ...first], ...rest] + + fun showFunDefn(prefix: Str, sym: Symbol, ps: Array[ParamList], body: Block): Str = + prefix + "fun " + showDefnSymbol(sym) + showParamList(ps) + " =" + + (if body is Return | End then " " else "\n ") + indent(showBlock(body)) + + fun showDefn(d: Defn): Str = + if d is + FunDefn(sym, ps, body) then + showFunDefn("", sym, ps, body) + ClsLikeDefn(sym, methods, _) and sym is ConcreteClassSymbol(_, v, _, _, _) and + isGeneratedStagedClass(sym) then getClassCache(v).printDefinitions() + else + "class " + showDefnSymbol(sym) + showParamsOpt(sym.paramsOpt) + sym.auxParams.map(showParams(_)).join("") + + indent((if methods is [] then "" else " with\n") + methods.map(showDefn(_)).join("\n")) + // TODO: used to represent assignments in constructors, which still need some adjustments + ValDefn(owner, sym, rhs) then + "val " + showSymbol(sym) + " = " + showPath(rhs) + _ then "" + + fun showPrivateDefn(d: Defn): Str = + if d is + FunDefn(sym, ps, body) then showFunDefn("", sym, ps, body) + else showDefn(d) + + fun showPrivateMethodDefn(d: Defn): Str = + if d is + FunDefn(sym, ps, body) then + let selfSym = freshSelfSymbol(ps, body) + let psWithSelf = prependParam(ps, Param(None, selfSym)) + // substitute `this` with `self` + class SelfPrinter(val selfSym: Symbol) extends Printer(owner) with + fun showPath(p: Path): Str = + if p is + Select(qual, name) and + qual is + // avoids needing to import the runtime module + ValueMemberRef(Symbol("runtime")) and name is ModuleSymbol("Unit", Runtime.Unit, _) then "()" + ValueThis(ConcreteClassSymbol) then this.showSymbol(selfSym) + "." + this.showSymbol(name) + ValueThis then this.showSymbol(name) + ValueMemberRef(sym) and owner is Some(owner) and sym === owner and owner is ConcreteClassSymbol then this.showSymbol(selfSym) + "." + this.showSymbol(name) + ValueMemberRef(sym) and owner is Some(owner) and sym === owner then this.showSymbol(name) + else showPath(qual) + "." + this.showSymbol(name) + DynSelect(qual, fld, false) then showPath(qual) + ".(" + showPath(fld) + ")" + DynSelect(qual, fld, true) then showPath(qual) + ".[" + showPath(fld) + "]" + ValueSimpleRef(l) | ValueMemberRef(l) then this.showSymbol(l) + ValueLit(lit) then this.showLiteral(lit) + ValueThis(ConcreteClassSymbol) then this.showSymbol(selfSym) + SelfPrinter(selfSym).showFunDefn("", sym, psWithSelf, body) + else showPrivateDefn(d) + + fun showBlock(b) = + if b is + Assign(lhs, rhs, rest) then + (if lhs is NoSymbol then "" else showSymbol(lhs) + " = ") + + showResult(rhs) + showRestBlock(rest) + Define(d, rest) then + showDefn(d) + showRestBlock(rest) + Return(res) then showResult(res) + Match(scrut, arms, dflt, rest) then + "if " + showPath(scrut) + " is" + + indent("\n" + arms.map(showArm(_)).join("\n")) + + if dflt is Some(db) then indent("\nelse" + indent((if db is Return then " " else "\n") + showBlock(db))) else "" + + showRestBlock(rest) + Scoped(symbols, rest) then + // but this one must use the function argument instead of a lambda... + "let {" + symbols.map(showSymbol).join(", ") + "}" + showRestBlock(rest) + End() then "()" + _ then "" + + // removes trailing newline + fun showRestBlock(b : Block): Str = + if b is End then "" else "\n" + showBlock(b) + + fun show(x) = + if x is + Symbol then showSymbol(x) + Path then showPath(x) + Result then showResult(x) + Case then showCase(x) + Defn then showDefn(x) + Block then showBlock(x) + else + "" + + fun printCode(x) = + print(show(x)) + + fun printModule(name, methods) = print("module " + name + " with" + indent("\n" + methods.map(showDefn(_)).join("\n"))) + +module Printer with + val default = Printer(None) + +let configs = + let options = [ + "noFreeze: true", + "noModuleCheck: true", + "liftDefns: None", + "disableDataFlowAnalysis: true", // FIXME: remove it. it now leads to timeout in staged reg exp output + "deadParamElim: Some(DeadParamElim(debug: false, mono: true))" + ] + "#config(" + options.join(", ") + ")\n" + +fun mkImport(source, name) = + "import \"" + source + "\" as " + legacyName(name) + +fun printPrivateMember(cache) = + let printer = Printer(Some(cache.owner)) + cache.cache.values().map(e => + if e.isPrivate then + if cache.owner is ConcreteClassSymbol then printer.showPrivateMethodDefn(e.defn) + else printer.showPrivateDefn(e.defn) + else "" + ).toArray().filter(_ != "").sort().join("\n") + +fun collectClassInModule(block) = + if block is + Define(ClsLikeDefn(sym, _, _), rest) and sym is ConcreteClassSymbol(_, value, _, _, _) and isStagedClass(value) then + [printCachedPrivateCode(getClassCache(value)), collectClassInModule(rest)].filter(_ != "").join("\n") + Define(_, rest) then collectClassInModule(rest) + else "" + +fun checkCtor(cache) = + if cache.owner is ModuleSymbol then + let runtimeClass = cache.owner.value + let ctor = runtimeClass."ctor$_instr"() + assert ctor is FunDefn + collectClassInModule(ctor.body) + else "" + +// collect and print private functions & methods in the given cache +fun printCachedPrivateCode(cache) = + [printPrivateMember(cache), checkCtor(cache)].filter(_ != "").join("\n") + +fun printPrivateCodeIn(name, cache, usedStagedClasses) = + let usedCaches = usedStagedClasses.map(getClassCache(_)) + let privateText = [...usedCaches.map(printCachedPrivateCode), printCachedPrivateCode(cache)].filter(_ != "").join("\n") + if privateText == "" then "" else "open " + name + "\n" + privateText + +fun toCode(name, cache, usedStagedClasses) = + let usedCaches = usedStagedClasses.map(getClassCache(_)) + let prefix = usedCaches.map(_.printDefinitions() + "\n").join("") + let publicText = prefix + indent(cache.printDefinitions()) + let privateText = printPrivateCodeIn(name, cache, usedStagedClasses) + publicText + if privateText == "" then "" else "\n" + privateText + +fun codegen(name, cache, source, file, usedStagedClasses) = + let fullpath = path.join of process.cwd(), file + let code = mkImport(source, name) + "\n" + toCode(name, cache, usedStagedClasses) + if not fs.existsSync(fullpath) do + fs.mkdirSync(path.dirname(fullpath), recursive: true) + fs.writeFileSync(fullpath, "", "utf8") + let originData = fs.readFileSync(fullpath, "utf8") + let newData = configs + code + if newData != originData do + fs.writeFileSync(fullpath, newData, "utf8") + +fun generateAll(name, file, ...modules) = + let fullpath = path.join of process.cwd(), file + if not fs.existsSync(fullpath) do + fs.mkdirSync(path.dirname(fullpath), recursive: true) + fs.writeFileSync(fullpath, "", "utf8") + fun splitCodeText(text) = + if text.split("\nopen ") is + [publicText] then [publicText, "", ""] + [publicText, ...privatePieces] then + let privateText = "open " + privatePieces.join("\nopen ") + let privateLines = privateText.split("\n") + [ + publicText, + privateLines.filter(_.startsWith("open ")).join("\n"), + privateLines.filter(l => not l.startsWith("open ")).join("\n"), + ] + let code = fold((res, p) => if p is + [mod, modName, source] then + mod.propagate() + let parts = splitCodeText(mod.toCode()) + [ + res.0 + mkImport(source, modName) + "\n", + res.1 + parts.0 + "\n", + res.2 + parts.1 + "\n", + res.3 + parts.2 + "\n", + ] + )(["", "", "", ""], ...modules) + let originData = fs.readFileSync(fullpath, "utf8") + let publicText = code.1.trim() + let openText = code.2.trim() + let privateText = code.3.trim() + let opens = ["open " + name, openText].filter(_ != "").join("\n") + let privateSuffix = if privateText == "" then "" else "\n" + opens + "\n" + privateText + let newData = configs + code.0 + "\n" + "module " + name + " with" + indent("\n" + publicText) + privateSuffix + if newData != originData do + fs.writeFileSync(fullpath, newData, "utf8") diff --git a/hkmc2/shared/src/test/mlscript-compile/NaiveTransform3D.mls b/hkmc2/shared/src/test/mlscript-compile/NaiveTransform3D.mls new file mode 100644 index 0000000000..255a237d6b --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/NaiveTransform3D.mls @@ -0,0 +1,95 @@ +#config(noFreeze: true) + +module Mx with + fun init(len, dft) = globalThis.Array(len).fill(dft) + fun setAt(a, i, v) = + set a.(i) = v + a + fun len(arr) = arr.length + +module NaiveTransform3D with + class Matrix(val arr, val r, val c) + + fun iter(sum, x, y, colX, i, j, k) = + if k > 0 then iter(sum + x.arr.(i * x.c + colX - k) * y.arr.((colX - k) * y.c + j), x, y, colX, i, j, k - 1) + else sum + + fun iterCol(m, x, y, colX, colY, i, j) = + if j === 0 then m + else iterCol(update(m, i, colY - j, iter(0.0, x, y, colX, i, colY - j, colX)), x, y, colX, colY, i, j - 1) + + fun iterRow(m, x, y, rowX, colX, colY, i) = + if i === 0 then m + else iterRow(iterCol(m, x, y, colX, colY, rowX - i, colY), x, y, rowX, colX, colY, i - 1) + + fun iterID(m, w, i) = + if i === 0 then m + else + iterID(update(m, w - i, w - i, 1), w, i - 1) + + fun zeros(r, c) = new Matrix(Mx.init(r * c, 0), r, c) + + fun multiply(x, y) = + let res = zeros(x.r, y.c) + iterRow(res, x, y, x.r, x.c, y.c, x.r) + + fun ident(w) = + let m = zeros(w, w) + iterID(m, w, w) + + fun update(m, i, j, v) = new Matrix(Mx.setAt(m.arr, i * m.c + j, v), m.r, m.c) + + fun transform(dx, dy, dz) = + update of + update of + update(ident(4), 0, 3, dx), 1, 3, dy + , 2, 3, dz + + fun scale(sx, sy, sz) = + update of + update of + update(ident(4), 0, 0, sx), 1, 1, sy + , 2, 2, sz + + fun rotateX(angle) = + let s = Math.sin(angle) + let c = Math.cos(angle) + update of + update of + update of + update(ident(4), 1, 1, c), 1, 2, -s + , 2, 1, s + , 2, 2, c + + fun rotateY(angle) = + let s = Math.sin(angle) + let c = Math.cos(angle) + update of + update of + update of + update(ident(4), 0, 0, c), 0, 2, s + , 2, 0, -s + , 2, 2, c + + fun rotateZ(angle) = + let s = Math.sin(angle) + let c = Math.cos(angle) + update of + update of + update of + update(ident(4), 0, 0, c), 0, 1, -s + , 1, 0, s + , 1, 1, c + + fun model(local, position, scaling, rotation) = + let rot = multiply of + rotateZ(rotation.2), multiply of + rotateY(rotation.1), multiply of + rotateX(rotation.0), ident(4) + let res = multiply of + transform(position.0, position.1, position.2), multiply of + rot, multiply(scale(scaling.0, scaling.1, scaling.2), new Matrix([local.0, local.1, local.2, 1], 4, 1)) + [res.arr.0, res.arr.1, res.arr.2] + + fun model0(local) = + model(local, [11, 4, 51], [0.4, 0.19, 0.19], [0.8 * 3.14159265, 3.1415926535, 0.0]) diff --git a/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs b/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs index a679e58cd0..6eed318a72 100644 --- a/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs +++ b/hkmc2/shared/src/test/mlscript-compile/Runtime.mjs @@ -5,55 +5,55 @@ import RuntimeJS from "./RuntimeJS.mjs"; import Rendering from "./Rendering.mjs"; import LazyArray from "./LazyArray.mjs"; import Iter from "./Iter.mjs"; -let Runtime1, lambda, lambda1, lambda2, lambda$, lambda$1, Capture$scope291, lambda$2, Capture$scope311, lambda$3; -(class Capture$scope31 { +let Runtime1, lambda, lambda1, lambda2, lambda$, lambda$1, Capture$scope321, lambda$2, Capture$scope341, lambda$3; +(class Capture$scope34 { static { - Capture$scope311 = this + Capture$scope341 = this } constructor(result$0) { this.result$0 = result$0; } toString() { return runtime.render(this); } - static [definitionMetadata] = ["class", "Capture$scope31"]; + static [definitionMetadata] = ["class", "Capture$scope34"]; }); -lambda$3 = (undefined, function (scope31$cap, cont) { +lambda$3 = (undefined, function (scope34$cap, cont) { return (m, marker) => { - return lambda2(scope31$cap, cont, m, marker) + return lambda2(scope34$cap, cont, m, marker) } }); -lambda2 = (undefined, function (scope31$cap, cont, m, marker) { +lambda2 = (undefined, function (scope34$cap, cont, m, marker) { let scrut, tmp, tmp1; scrut = runtime.safeCall(m.has(cont)); if (scrut === true) { tmp = ", " + marker; - tmp1 = scope31$cap.result$0 + tmp; - scope31$cap.result$0 = tmp1; + tmp1 = scope34$cap.result$0 + tmp; + scope34$cap.result$0 = tmp1; return runtime.Unit } return runtime.Unit; }); -(class Capture$scope29 { +(class Capture$scope32 { static { - Capture$scope291 = this + Capture$scope321 = this } constructor(result$0) { this.result$0 = result$0; } toString() { return runtime.render(this); } - static [definitionMetadata] = ["class", "Capture$scope29"]; + static [definitionMetadata] = ["class", "Capture$scope32"]; }); -lambda$2 = (undefined, function (scope29$cap, cont) { +lambda$2 = (undefined, function (scope32$cap, cont) { return (m, marker) => { - return lambda1(scope29$cap, cont, m, marker) + return lambda1(scope32$cap, cont, m, marker) } }); -lambda1 = (undefined, function (scope29$cap, cont, m, marker) { +lambda1 = (undefined, function (scope32$cap, cont, m, marker) { let scrut, tmp, tmp1; scrut = runtime.safeCall(m.has(cont)); if (scrut === true) { tmp = ", " + marker; - tmp1 = scope29$cap.result$0 + tmp; - scope29$cap.result$0 = tmp1; + tmp1 = scope32$cap.result$0 + tmp; + scope32$cap.result$0 = tmp1; return runtime.Unit } return runtime.Unit; @@ -273,6 +273,38 @@ lambda$ = (undefined, function (Runtime2, EffectHandle1, value) { toString() { return runtime.render(this); } static [definitionMetadata] = ["class", "Str"]; }); + (class SymbolMap { + static { + Runtime.SymbolMap = this + } + static { + let tmp, tmp1; + tmp = globalThis.Object.freeze(new globalThis.Map()); + SymbolMap.classMap = tmp; + tmp1 = globalThis.Object.freeze(new globalThis.Map()); + SymbolMap.moduleMap = tmp1; + } + static checkClassMap(key, value) { + let v; + v = runtime.safeCall(SymbolMap.classMap.get(key)); + if (v instanceof Runtime.Unit.class) { + runtime.safeCall(SymbolMap.classMap.set(key, value)); + return value + } + return v; + } + static checkModuleMap(key, value) { + let v; + v = runtime.safeCall(SymbolMap.moduleMap.get(key)); + if (v instanceof Runtime.Unit.class) { + runtime.safeCall(SymbolMap.moduleMap.set(key, value)); + return value + } + return v; + } + toString() { return runtime.render(this); } + static [definitionMetadata] = ["class", "SymbolMap"]; + }); Runtime.render = Rendering.render; (class TraceLogger { static { @@ -905,12 +937,12 @@ lambda$ = (undefined, function (Runtime2, EffectHandle1, value) { return header; } static showFunctionContChain(cont, hl, vis, reps) { - let scrut, scrut1, scrut2, tmp, tmp1, tmp2, tmp3, tmp4, scope29$cap, lambda$here; - scope29$cap = new Capture$scope291(undefined); + let scrut, scrut1, scrut2, tmp, tmp1, tmp2, tmp3, tmp4, scope32$cap, lambda$here; + scope32$cap = new Capture$scope321(undefined); if (cont instanceof Runtime.FunctionContFrame.class) { tmp = cont.constructor.name + "(pc="; - scope29$cap.result$0 = tmp + cont.saved.at(1); - lambda$here = lambda$2(scope29$cap, cont); + scope32$cap.result$0 = tmp + cont.saved.at(1); + lambda$here = lambda$2(scope32$cap, cont); runtime.safeCall(hl.forEach(lambda$here)); scrut = runtime.safeCall(vis.has(cont)); if (scrut === true) { @@ -920,12 +952,12 @@ lambda$ = (undefined, function (Runtime2, EffectHandle1, value) { if (scrut1 === true) { throw runtime.safeCall(globalThis.Error("10 repeated continuation frame (loop?)")) } - tmp2 = scope29$cap.result$0 + ", REPEAT"; - scope29$cap.result$0 = tmp2; + tmp2 = scope32$cap.result$0 + ", REPEAT"; + scope32$cap.result$0 = tmp2; } else { runtime.safeCall(vis.add(cont)); } - tmp3 = scope29$cap.result$0 + ") -> "; + tmp3 = scope32$cap.result$0 + ") -> "; tmp4 = Runtime.showFunctionContChain(cont.next, hl, vis, reps); return tmp3 + tmp4 } @@ -936,11 +968,11 @@ lambda$ = (undefined, function (Runtime2, EffectHandle1, value) { return "(NOT CONT)"; } static showHandlerContChain(cont, hl, vis, reps) { - let scrut, scrut1, scrut2, tmp, tmp1, tmp2, tmp3, scope31$cap, lambda$here; - scope31$cap = new Capture$scope311(undefined); + let scrut, scrut1, scrut2, tmp, tmp1, tmp2, tmp3, scope34$cap, lambda$here; + scope34$cap = new Capture$scope341(undefined); if (cont instanceof Runtime.HandlerContFrame.class) { - scope31$cap.result$0 = cont.handler.constructor.name; - lambda$here = lambda$3(scope31$cap, cont); + scope34$cap.result$0 = cont.handler.constructor.name; + lambda$here = lambda$3(scope34$cap, cont); runtime.safeCall(hl.forEach(lambda$here)); scrut = runtime.safeCall(vis.has(cont)); if (scrut === true) { @@ -950,12 +982,12 @@ lambda$ = (undefined, function (Runtime2, EffectHandle1, value) { if (scrut1 === true) { throw runtime.safeCall(globalThis.Error("10 repeated continuation frame (loop?)")) } - tmp1 = scope31$cap.result$0 + ", REPEAT"; - scope31$cap.result$0 = tmp1; + tmp1 = scope34$cap.result$0 + ", REPEAT"; + scope34$cap.result$0 = tmp1; } else { runtime.safeCall(vis.add(cont)); } - tmp2 = scope31$cap.result$0 + " -> "; + tmp2 = scope34$cap.result$0 + " -> "; tmp3 = Runtime.showFunctionContChain(cont.next, hl, vis, reps); return tmp2 + tmp3 } diff --git a/hkmc2/shared/src/test/mlscript-compile/Runtime.mls b/hkmc2/shared/src/test/mlscript-compile/Runtime.mls index 31e21b9158..39e42df8f9 100644 --- a/hkmc2/shared/src/test/mlscript-compile/Runtime.mls +++ b/hkmc2/shared/src/test/mlscript-compile/Runtime.mls @@ -120,6 +120,24 @@ module Str with @mayNotRaiseEffects fun leave(string, n) = string.slice(n) +// A global map for Symbols defined during reflection instrumentation to ensure uniqueness of symbols across different staged functions and compilation units +// A staged class with no parameters has the same runtime value as its staged companion, +// and this causes an unwated collision when creating a symbol for both the class and the module, +// so we need to split the map into the which type of symbol used. +module SymbolMap with + val classMap = new Map() + val moduleMap = new Map() + + fun checkClassMap(key: Class, value) = if + let v = classMap.get(key) + v is Unit then classMap.set(key, value); value + else v + + fun checkModuleMap(key: Class, value) = if + let v = moduleMap.get(key) + v is Unit then moduleMap.set(key, value); value + else v + // Re-export rendering functions val render = Rendering.render diff --git a/hkmc2/shared/src/test/mlscript-compile/Shape.mls b/hkmc2/shared/src/test/mlscript-compile/Shape.mls index d8a3dcca30..73dee48040 100644 --- a/hkmc2/shared/src/test/mlscript-compile/Shape.mls +++ b/hkmc2/shared/src/test/mlscript-compile/Shape.mls @@ -1,69 +1,84 @@ +#config(liftDefns: None) + import "./Block.mls" import "./Option.mls" +import "./CachedHash.mls" +import "./ShapeSet.mjs" -open Block { Literal, ClassSymbol, showSymbol, isPrimitiveType, isPrimitiveTypeOf } +open Block { Literal, ConcreteClassSymbol, isPrimitiveType, isPrimitiveTypeOf } open Option type Shape = Shape.Shape +type ShSet = ShapeSet.ShapeSet module Shape with... -class Shape with +val printer = Block.Printer(None) + +class Shape extends CachedHash with constructor Dyn() Lit(val l: Literal) - Arr(val shapes: Array[Shape]) - Class(val sym: ClassSymbol, val params: Array[Shape]) + Arr(val shapes: Array[ShSet]) + Class(val sym: ConcreteClassSymbol, val fields: Array[ShSet]) // TODO: track the auxParams as well fun show(s: Shape) = if s is Dyn then "Dyn" - Lit(lit) then "Lit(" + Block.showLiteral(lit) + ")" - Arr(shapes) then "Arr(" + shapes.map(show).join(", ") + ")" - Class(sym, params) then "Class(" + showSymbol(sym) + ", [" + params.map(show).join(", ") + "])" + Lit(lit) then "Lit(" + printer.showLiteral(lit) + ")" + Arr(shapes) then "Arr(" + shapes.map(_.toString()).join(", ") + ")" + Class(sym, fields) then "Class(" + printer.showSymbol(sym) + ", {" + [...fields.entries()].map(e => e.0 + ": " + e.1.toString()).join(", ") + "})" fun sel(s1: Shape, s2: Shape): Array[Shape] = if [s1, s2] is - [Class(sym, params), Lit(n)] and n is Str - and sym.args is Some(args) - and args.find(_ == n) - == () then [] - is i then [params.(i)] - [Dyn, Lit(n)] and n is Str - then [Dyn()] - [Arr(shapes), Lit(n)] and n is Int - then [shapes.(n)] + [Class(ConcreteClassSymbol(_, _, paramsOpt, auxParams, _), params), Lit(n)] and n is Str and paramsOpt is Some(paramsSymb) and + paramsSymb.map(_.sym.name).indexOf(n) is + -1 then [] + n then params.(n).values() + [Class(ConcreteClassSymbol, p), Dyn] then [Dyn()] + [Dyn, Lit(n)] and + n is Str then [Dyn()] + n is Int then [Dyn()] + else throw Error("Unknown selection") + [Arr(shapes), Lit(n)] and // n can be both string or integer + n < shapes.length then shapes.(n).values() // This utilizes the string and number conversion in JS lol + else throw Error("Array out of bound") [Arr(shapes), Dyn] then - shapes - [Dyn, Lit(n)] and n is Int - then [Dyn()] - [Dyn, Dyn] - then [Dyn()] - else [] // TODO: return no possibility instead of err? + shapes.flatMap(_.values()) + [Dyn, Dyn] then [Dyn()] + else [] fun static(s: Shape) = if s is Dyn then false Lit(l) then not (l is Str and isPrimitiveType(l)) // redundant bracket? - Class(_, params) then params.every(static) - Arr(shapes) then shapes.every(static) + Class(_, params) then params.every(_.values() is [v] and static(v)) + Arr(shapes) then shapes.every(_.values() is [v] and static(v)) open Block { Case } fun silh(p: Case): Shape = if p is Block.Lit(l) then Lit(l) - Block.Cls(sym, path) then - val size = if sym.args is Some(i) then i else 0 - Class(sym, Array(size).fill(Dyn)) - Block.Tup(n) then Arr(Array(n).fill(Dyn)) + Block.Cls(clsSymb, path) then + let paramsSize = if clsSymb.paramsOpt is Some(params) then params.length else 0 + Class(clsSymb, Array(paramsSize).fill(ShapeSet.mkDyn())) + Block.Tup(n) then Arr(Array(n).fill(ShapeSet.mkDyn())) + +fun getActualClass(c) = if not (c."class" is undefined) then c.class else c +fun isSubClassOf(d, b) = + let dClass = getActualClass(d) + let bClass = getActualClass(b) + dClass == bClass || bClass.isPrototypeOf(dClass) -// TODO: use Option instead, since all of them return at most one shape fun filter(s: Shape, p: Case): Array[Shape] = if [s, p] is [Lit(l1), Block.Lit(l2)] and l1 == l2 then [s] - [Lit(l), Block.Cls(c, _)] and isPrimitiveTypeOf(c, l) then [s] + [Lit(l), Block.Cls(c, _)] and isPrimitiveTypeOf(c, l) then [s] [Arr(ls), Block.Tup(n)] and ls.length == n then [s] - [Class(c1, _), Block.Cls(c2, _)] and c1.name == c2.name then [s] + [Class(c1, _), Block.Cls(c2, _)] and c1 is ConcreteClassSymbol and c2 is ConcreteClassSymbol and + c1 == c2 then [s] // TODO: is === possible? + [Class(c1, _), Block.Cls(c2, _)] and c1 is ConcreteClassSymbol and c2 is ConcreteClassSymbol and + isSubClassOf(c1.value, c2.value) then [s] [Dyn, _] then [silh(p)] else [] @@ -72,6 +87,10 @@ fun rest(s: Shape, p: Case): Array[Shape] = [Lit(l1), Block.Lit(l2)] and l1 == l2 then [] [Lit(l), Block.Cls(c, _)] and isPrimitiveTypeOf(c, l) then [] [Arr(ls), Block.Tup(n)] and ls.length == n then [] - [Class(c1, _), Block.Cls(c2, _)] and c1.name == c2.name then [] + [Class(c1, _), Block.Cls(c2, _)] and c1 is ConcreteClassSymbol and c2 is ConcreteClassSymbol and + c1 == c2 then [] // TODO: is === possible? + [Class(c1, _), Block.Cls(c2, _)] and c1 is ConcreteClassSymbol and c2 is ConcreteClassSymbol and + isSubClassOf(c1.value, c2.value) then [] + [Class(c1, _), Block.Cls(c2, _)] and c1.name == c2.name then [s] [Dyn, _] then [s] - else [s] \ No newline at end of file + else [s] diff --git a/hkmc2/shared/src/test/mlscript-compile/ShapeSet.mls b/hkmc2/shared/src/test/mlscript-compile/ShapeSet.mls new file mode 100644 index 0000000000..021e733f7a --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/ShapeSet.mls @@ -0,0 +1,210 @@ +#config(liftDefns: None) + +import "./Block.mls" +import "./CachedHash.mls" +import "./Option.mls" +import "./Predef.mls" +import "./Shape.mls" +import "./StrOps.mls" +import "./Runtime.mls" + +open Block {ConcreteClassSymbol, Path, Symbol, Param} +open Shape {Dyn, Lit, Arr, Class} +open Predef +open Option +open StrOps + +type ShapeSet = ShapeSet.ShapeSet + +module ShapeSet with... + +class ShapeSet(val shapeset: Map[String, Shape]) extends CachedHash with + fun keys() = shapeset.keys().toArray().toSorted() + + fun values() = shapeset.values().toArray() + + fun isEmpty() = shapeset.size == 0 + + fun contains(s: Shape) = shapeset.has(s.hash()) + + fun flatMap(f) = liftMany(values().flatMap(f)) + + fun toString() = "{" ~ keys().toSorted().toString() ~ "}" + + fun isDyn() = shapeset.size == 1 and values().0 is Dyn + +module ShapeSet with + fun empty = ShapeSet(new Map) + +fun mkShapeSet(entries) = + let shapeMap = new Map(entries) + let dyn = Dyn() + if shapeMap.has(dyn.hash()) then ShapeSet(new Map([[dyn.hash(), dyn]])) + else ShapeSet(shapeMap) + +fun lift(s: Shape) = mkShapeSet([[s.hash(), s]]) + +fun liftMany(arr: Array[Shape]) = + mkShapeSet(arr.map(s => [s.hash(), s])) + +fun union2(s1: ShapeSet, s2: ShapeSet) = + if s1.isDyn() then s1 + else if s2.isDyn() then s2 + else mkShapeSet([...s1.shapeset, ...s2.shapeset]) + +fun union(...s) = + if s.length is 0 then ShapeSet.empty + else s.reduce((acc, next) => union2(acc, next)) + +fun flat(arr: Array[ShapeSet]) = mkShapeSet(arr.map(_.shapeset.entries().toArray()).flat()) + +fun prod(xs) = xs.reduce((a, b) => a.flatMap(d => b.map(e => [...d, e])), [[]]) + +// lifted constructors + +fun mkBot() = ShapeSet.empty + +fun mkDyn() = lift(Dyn()) + +fun mkLit(l) = lift(Lit(l)) + +fun mkArr(shapes: Array[ShapeSet]) = + lift(Arr(shapes)) + +fun mkClass(sym: ConcreteClassSymbol, params: Array[ShapeSet]) = + lift(Class(sym, params)) + +fun mkClassFromMap(sym: ConcreteClassSymbol, paramsMap: Map[String, ShapeSet], psOpt: Option[Array[Array[Param]]]) = + if sym is ConcreteClassSymbol(name, value, paramsOpt, auxParams, redir) then + let entries = [...paramsMap.entries()] + let keys = entries.map(a => + let s = Symbol(a.0) + if psOpt is Some(pss) then + let found = pss.flat().find(p => p.sym.name === a.0) + if found is Runtime.Unit then Param(None, s) + else found + else Param(None, s) + ) + let params = entries.map(_.1) + let newSym = ConcreteClassSymbol(name, value, Some(keys), auxParams, redir) + lift(Class(newSym, params)) + +fun filterSet(s: ShapeSet, p: Block.Case) = s.flatMap(Shape.filter(_, p)) + +fun restSet(s: ShapeSet, p: Block.Case) = s.flatMap(Shape.rest(_, p)) + +fun isLitShape(s: ShapeSet) = s.values().length is 1 and s.values().0 is Lit(l) +fun isFalseShape(s: ShapeSet) = s.values().length is 1 and s.values().0 is Lit(l) and l is false +fun isTrueShape(s: ShapeSet) = s.values().length is 1 and s.values().0 is Lit(l) and l is true +fun isZeroShape(s: ShapeSet) = s.values().length is 1 and s.values().0 is Lit(l) and l is 0 + +fun binOpSet(op: Str, s1: ShapeSet, s2: ShapeSet) = + if + op is + "&&" and + isFalseShape(s1) then mkLit(false) + isFalseShape(s2) then mkLit(false) + "||" and + isTrueShape(s1) then mkLit(true) + isTrueShape(s2) then mkLit(true) + "*" and + isZeroShape(s1) then mkLit(0) // unsound if user writes 0 * "hello" => NaN + isZeroShape(s2) then mkLit(0) + s1.isDyn() then mkDyn() + s2.isDyn() then mkDyn() + else + let pairs = prod([s1.values(), s2.values()]) + let res = pairs.map(pair => + if pair.0 is Lit(l1) and pair.1 is Lit(l2) and op is + "+" then Lit(l1 + l2) + "-" then Lit(l1 - l2) + "*" then Lit(l1 * l2) + "/" then Lit(l1 / l2) + "%" then Lit(l1 % l2) + "==" then Lit(l1 == l2) + "!=" then Lit(l1 != l2) + "<" then Lit(l1 < l2) + "<=" then Lit(l1 <= l2) + ">" then Lit(l1 > l2) + ">=" then Lit(l1 >= l2) + "===" then Lit(l1 === l2) + "!==" then Lit(l1 !== l2) + "&&" then Lit(l1 && l2) + "||" then Lit(l1 || l2) + else Dyn() + ) + if res.some(_ is Dyn) then mkDyn() + else + let st = liftMany(res) + let isBoolOp = if op is + "==" then true + "!=" then true + "<" then true + "<=" then true + ">" then true + ">=" then true + "===" then true + "!==" then true + "&&" then true + "||" then true + else false + if isBoolOp and st.values().length > 1 then mkDyn() + else st + +fun selSet(s1: ShapeSet, s2: ShapeSet) = + prod([s1.values(), s2.values()]) + .flatMap(pair => Shape.sel(pair.0, pair.1)) + |> liftMany + +fun staticSet(s: ShapeSet) = + let v = s.values() + if v.length == + 1 then Shape.static(v.0) + else false + +fun valOf(s : Shape) = + if s is + Dyn() then throw Error("valOf on Dyn") + Lit(l) then l + Arr(shapes) then shapes.map((x, _, _) => valOfSet(x)) + Class(ConcreteClassSymbol(name, value, paramsOpt, auxParams, _), params) then new! value(...params.map(valOfSet)) + else throw Error("Unknown shape: " + s) + +fun valOfSet(s : ShapeSet) = + if s.values().length == + 1 then valOf(s.values().0) + else throw Error("valOfSet on non-singleton ShapeSet") + +let idCounter = 0 +fun freshId(prefix) = + set idCounter = idCounter + 1 + Block.Symbol(prefix + "_" + idCounter.toString()) + +private fun shape2path(s: Shape, allocs) = + // assert Shape.static(s) + if s is + Lit(l) then [Block.End(), Block.ValueLit(l)] + Arr(v) then + let mapped = v.map(shapeset2path(_, allocs)) + let blocks = mapped.map(_.0) + blocks.reverse() + let paths = mapped.map(_.1) + let tupSym = freshId("tup") + allocs.push(tupSym) + let tupAssign = Block.Assign(tupSym, Block.Tuple(paths.map(Block.Arg(_))), Block.End()) + let fullBlock = foldr((acc, b) => Block.concat(b, acc))(tupAssign, ...blocks) + [fullBlock, Block.ValueSimpleRef(tupSym)] + Class(sym, fields) then + let mapped = fields.map(shapeset2path(_, allocs)) + let blocks = mapped.map(_.0) + blocks.reverse() + let paths = mapped.map(_.1) + let clsSym = freshId("obj") + allocs.push(clsSym) + let clsAssign = Block.Assign(clsSym, Block.Instantiate(Block.ValueMemberRef(sym), paths.map(Block.Arg(_))), Block.End()) + let fullBlock = foldr((acc, b) => Block.concat(b, acc))(clsAssign, ...blocks) + [fullBlock, Block.ValueSimpleRef(clsSym)] + +fun shapeset2path(s: ShapeSet, allocs) = + assert staticSet(s) + shape2path(s.values().0, allocs) diff --git a/hkmc2/shared/src/test/mlscript-compile/SimpleRegExp.mls b/hkmc2/shared/src/test/mlscript-compile/SimpleRegExp.mls new file mode 100644 index 0000000000..4484c434ab --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/SimpleRegExp.mls @@ -0,0 +1,226 @@ +#config(noFreeze: true) + +module SeqHelper with + fun push(arr, ele) = + arr.push(ele) + arr + fun concat(lhs, rhs) = lhs.concat(rhs) + fun has(arr, ele) = arr.includes(ele) + fun len(s) = s.length + fun eq(arr1, arr2) = + arr1.length == arr2.length and arr1.every((v, i) => v == arr2.(i)) + fun setEq(s1, s2) = + s1.slice().sort() + s2.slice().sort() + s1.length == s2.length and s1.every((v, i) => v.eq(s2.(i))) + +module CharSet with + fun alphabet() = [ + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + ] + fun space() = [" ", "\n", "\t", "\r"] + fun digit() = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] + +module SimpleRegExp with + class Some(val x) + class None + + fun len(s) = SeqHelper.len(s) + fun has(arr, ele) = SeqHelper.has(arr, ele) + fun arrEq(arr1, arr2) = SeqHelper.eq(arr1, arr2) + fun push(arr, ele) = SeqHelper.push(arr, ele) + fun concat(lhs, rhs) = SeqHelper.concat(lhs, rhs) + fun setEq(s1, s2) = SeqHelper.setEq(s1, s2) + + class DedupSet(val arr) with + fun addImp(e, i) = + let s = len(arr) + if i == s then new DedupSet(push(arr, e)) + else + let e' = arr.(i) + if e.eq(e') then this else addImp(e, i + 1) + fun add(e) = + addImp(e, 0) + + class RegExp() with + fun derive(c) + fun canBeEmpty() + fun normalize() + fun eq(other) + fun startsWith(c) + + class Nothing() extends RegExp() with + fun derive(c) = this + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = other is Nothing + fun startsWith(c) = false + + class Empty() extends RegExp() with + fun derive(c) = new Nothing() + fun canBeEmpty() = true + fun normalize() = this + fun eq(other) = other is Empty + fun startsWith(c) = false + + class Exact(val ch) extends RegExp() with + fun derive(c) = + if startsWith(c) then new Empty() + else new Nothing() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = + if other is Exact(ch') then ch == ch' else false + fun startsWith(c) = ch == c + + class Any() extends RegExp() with + fun derive(c) = new Empty() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = other is Any() + fun startsWith(c) = true + + class Not(val chars) extends RegExp() with + fun derive(c) = + if startsWith(c) then new Empty() else new Nothing() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = + if other is Not(chars') then arrEq(chars, chars') else false + fun startsWith(c) = not has(chars, c) + + fun notWord() = new Not(CharSet.alphabet()) + fun notSpace() = new Not(CharSet.space()) + fun notDigit() = new Not(CharSet.digit()) + + fun mkUnion(arr, i, s) = + if i == s - 1 then arr.(i) + else + if arr.(i) is + Nothing() then mkUnion(arr, i + 1, s) + else new Union(arr.(i), mkUnion(arr, i + 1, s)) + + class Union(val p1, val p2) extends RegExp() with + fun derive(c) = (new Union(p1.derive(c), p2.derive(c))).normalize() + fun canBeEmpty() = p1.canBeEmpty() || p2.canBeEmpty() + fun flat() = + let p1' = if p1 is Union then p1.flat() else [p1] + let p2' = if p2 is Union then p2.flat() else [p2] + concat(p1', p2') + fun iter(st, arr, i, s) = + if i == s then st + else iter(st.add(arr.(i)), arr, i + 1, s) + fun normalize() = + let p1' = p1.normalize() + let p2' = p2.normalize() + let arr1 = if p1' is Union then p1'.flat() else [p1'] + let arr2 = if p2' is Union then p2'.flat() else [p2'] + let s = iter(new DedupSet(arr1), arr2, 0, len(arr2)) + mkUnion(s.arr, 0, len(s.arr)) + fun eq(other) = + let n = other.normalize() + if n is + Union then setEq(normalize().flat(), n.flat()) + else false + fun startsWith(c) = p1.startsWith(c) || p2.startsWith(c) + + fun question(r) = new Union(r, new Empty()) + + class In(val chars) extends RegExp() with + fun derive(c) = + if startsWith(c) then new Empty() else new Nothing() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = + if other is In(chars') then arrEq(chars, chars') else false + fun startsWith(c) = has(chars, c) + + fun words() = new In(CharSet.alphabet()) + fun spaces() = new In(CharSet.space()) + fun digits() = new In(CharSet.digit()) + + class Concat(val p1, val p2) extends RegExp() with + fun derive(c) = + let p1' = p1.derive(c) + if p1.canBeEmpty() then + (new Union(new Concat(p1', p2), p2.derive(c))).normalize() + else (new Concat(p1', p2)).normalize() + fun canBeEmpty() = p1.canBeEmpty() and p2.canBeEmpty() + fun normalize() = + let p1' = p1.normalize() + if p1' is + Empty() then p2.normalize() + Nothing() then p1' + else new Concat(p1', p2.normalize()) + fun eq(other) = + if other is Concat(p1', p2') then p1.eq(p1') and p2.eq(p2') else false + fun startsWith(c) = p1.startsWith(c) || (p1.canBeEmpty() and p2.startsWith(c)) + + fun nTimes(r, i) = + if i == 1 then r + else new Concat(r, nTimes(r, i - 1)) + + class Star(val p) extends RegExp() with + fun derive(c) = (new Concat(p.derive(c), new Star(p))).normalize() + fun canBeEmpty() = true + fun normalize() = new Star(p.normalize()) + fun eq(other) = + if other is Star(p') then p.eq(p') else false + fun startsWith(c) = p.startsWith(c) + + fun plus(r) = new Concat(r, new Star(r)) + + fun matchImpl(p, s, acc) = if + len(s) == 0 and + p.canBeEmpty() then new Some(acc) + else new None + p is Nothing then new None + let c = s.0 + p.startsWith(c) then matchImpl(p.derive(c), s.slice(1), acc + c) + p.canBeEmpty() then new Some(acc) + else new None + fun match(p, s) = + matchImpl(p, s, "") + + fun matchAllImpl(p, s, res) = + if len(s) == 0 then res + else + if match(p, s) is + Some(ss) then + if len(ss) > 0 then matchAllImpl(p, s.slice(len(ss)), SeqHelper.push(res, ss)) + else matchAllImpl(p, s.slice(1), res) + else matchAllImpl(p, s.slice(1), res) + fun matchAll(p, s) = + matchAllImpl(p, s, []) + + // [\w\.-]+@[\w\.-]+\.[\w\.-]+ + fun matchAllEmail(s) = + let p = plus(new In(SeqHelper.concat(CharSet.alphabet(), ["-", "."]))) + let email = new Concat(p, new Concat(new Exact("@"), new Concat(p, new Concat(new Exact("."), p)))) + matchAll(email, s) + + // \w+://[^/\s?#]+[^\s?#]+(\?[^\s#]*)?(#[^\s]*)? + fun matchAllURI(s) = + let n1 = new Not(["/", "?", "#", " ", "\n", "\t", "\r"]) + let n2 = new Not(["?", "#", " ", "\n", "\t", "\r"]) + let n3 = new Not(["#", " ", "\n", "\t", "\r"]) + let w = words() + let d = digits() + let p = SeqHelper.concat(CharSet.alphabet(), SeqHelper.concat(CharSet.digit(), ["-", "_"])) + let head = new Concat(plus(w), new Concat(new Exact(":"), new Concat(new Exact("/"), new Exact("/")))) + let body = new Concat(plus(n1), plus(n2)) + let params = new Concat(question(new Concat(new Exact("?"), new Star(new In(p)))), question(new Concat(new Exact("#"), new Star(new In(p))))) + let uri = new Concat(head, new Concat(body, params)) + matchAll(uri, s) + + // ((25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9]) + fun matchAllIPv4(s) = + let fo = new In(["0", "1", "2", "3", "4"]) + let fi = new In(["0", "1", "2", "3", "4", "5"]) + let segment = new Union(new Concat(new Exact("2"), new Concat(new Exact("5"), fi)), new Union( + new Concat(new Exact("2"), new Concat(fo, digits())), + new Concat(question(new Exact("1")), new Concat(question(digits()), digits())) + )) + let ipv4 = new Concat(nTimes(new Concat(segment, new Exact(".")), 3), segment) + matchAll(ipv4, s) \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/SpecializeHelpers.mls b/hkmc2/shared/src/test/mlscript-compile/SpecializeHelpers.mls new file mode 100644 index 0000000000..febe2f2e05 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/SpecializeHelpers.mls @@ -0,0 +1,676 @@ +#config(liftDefns: None) + +import "./Block.mls" +import "./Shape.mls" +import "./Option.mls" +import "./ShapeSet.mls" +import "./Predef.mls" +import "./Runtime.mls" + +open Block +open Shape +open Option +open Predef +open ShapeSet + +module SpecializeHelpers with ... +fun wrapScoped(symbols, block) = + if symbols.length is 0 then block + else if block is Scoped(oldSymbols, rest) then Scoped([...symbols, ...oldSymbols], rest) + else Scoped(symbols, block) + +fun showCtxPath(p) = if p is + Select(qual, Symbol(name)) then showCtxPath(qual) + "." + name + DynSelect(qual, fld, _) then showCtxPath(qual) + ".(" + showCtxPath(fld) + ")" + ValueSimpleRef(l) | ValueMemberRef(l) and + l is + ConcreteClassSymbol(n, v, _, _, _) then "ClassSymbol(" + n + ")" + ModuleSymbol(n, v, _) then "ModuleSymbol(" + n + ")" + Symbol(n) then "Symbol(" + n + ")" + else throw Error(l) + ValueLit(lit) then "Lit(" + lit.toString() + ")" + ValueThis then "this" + +fun staticCallKey(f, argShapes) = + showCtxPath(f) + "(" + argShapes.map(_.hash()).join(",") + ")" + +class StaticCallEntry( + val block: Block.Block, + val path: Path, + val shape: ShapeSet, +) + +class Ctx( + // ctx tracks shapes of variables + val ctx: Map[String, ShapeSet], + // valDefnCtx tracks fields defined by ValDefn during shape prop of constructor + val valDefnCtx: Map[String, ShapeSet], + // staticCallCtx tracks results of non-staged calls with static arguments + val staticCallCtx: Map[String, StaticCallEntry], + // allocs tracks the new variables allocated + val allocs: Array[Block.Symbol], + // thisShape stores the shapeset of this, e.g., C1(1) U C1(2) + val thisShape: Option[ShapeSet], +) with + fun get(path) = + let ps = showCtxPath(path) + if ctx.has(ps) then Some(ctx.get(ps)) else None + fun getValDefn(name) = + if valDefnCtx.has(name) then Some(valDefnCtx.get(name)) else None + fun getStaticCall(key) = + if staticCallCtx.has(key) then Some(staticCallCtx.get(key)) else None + fun addStaticCall(key, entry) = + staticCallCtx.set(key, entry) + this + fun clone = Ctx(new Map(ctx), new Map(valDefnCtx), new Map(staticCallCtx), allocs, thisShape) + // For propagation of instantiation of derived class, + // we need to keep track of fields defined in parent class, + // which is stored in valDefnCtx + fun clearCtx = Ctx(new Map(), valDefnCtx, new Map(staticCallCtx), allocs, thisShape) + fun sub(other: Ctx) = + let res = new Map() + fun otherIsBot(ps) = + if other.ctx.has(ps) then other.ctx.get(ps).isEmpty() else false + ctx.forEach((ss, ps, _) => + if not ss.isEmpty() and otherIsBot(ps) do + res.set(ps, ss) + ) + res + fun add(path: Path, ss: ShapeSet) = + let ps = showCtxPath(path) + if ctx.has(ps) then + ctx.set(ps, union2(ctx.get(ps), ss)) + else + ctx.set(ps, ss) + this + fun refine(path: Path, ss: ShapeSet) = + ctx.set(showCtxPath(path), ss) + this + // Later ValDefn (in derived class) shadows earlier ValDefn (in base class) + fun addValDefn(ps: String, ss: ShapeSet) = + valDefnCtx.set(ps, ss) + this +module Ctx with + fun empty() = Ctx(new Map(), new Map(), new Map(), mut [], None) + +class FunEntry( + val defn: FunDefn, + val retShape: ShapeSet, + val isPrivate: Bool, +) + +class FunCache( + val owner: ConcreteClassSymbol | ModuleSymbol, + val cache: Map[Any, FunEntry], + val names: Set[String], +) with + val printer = Printer(Some(owner)) + fun getFun(k) = if cache.has(k) then Some(cache.get(k)) else None + // this will be called at the beginning of specialization to avoid infinite calls when specializing recursive functions + fun setFun(k, v) = cache.set(k, v); v + fun reserveName(name: String) = + names.add(name) + name + fun freshName(funName: String) = + let + prefix = funName + "_" + owner.name + "_sp_" + idx = 0 + name = prefix + idx + while names.has(name) do + set + idx += 1 + name = prefix + idx + reserveName(name) + fun printDefinitions() = + let decl = if owner is + ConcreteClassSymbol then "class " + ModuleSymbol then "module " + let runtimeClass = if owner is + ConcreteClassSymbol(_, _, Some, _, _) then owner.value.class + else owner.value + + let p = printer + let paramText = if owner is + ConcreteClassSymbol and owner.paramsOpt is + Some(ps) then printer.showCtorParams(ps) + owner.auxParams.map(pl => p.showParams(pl)).join("") + else owner.auxParams.map(pl => p.showParams(pl)).join("") + ModuleSymbol then "" + + // process preCtor: inline temp variable when printing + class InlinePrinter(ctx: Map[Symbol, String]) extends Printer(Some(owner)) with + fun showPath(p) = if p is + ValueSimpleRef(s) | ValueMemberRef(s) and ctx.has(s) then ctx.get(s) + Select(qual, name) and qual is + // let elaborator disambiguate ValueThis + ValueThis(_) then this.showSymbol(name) + ValueMemberRef(sym) and sym == owner then this.showSymbol(name) + ValueMemberRef(ModuleSymbol) and this.isGeneratedStagedClass(name) then this.showSymbol(name) + else showPath(qual) + "." + this.showSymbol(name) + DynSelect(qual, fld, false) then showPath(qual) + ".(" + showPath(fld) + ")" + DynSelect(qual, fld, true) then showPath(qual) + ".[" + showPath(fld) + "]" + ValueSimpleRef(s) | ValueMemberRef(s) then this.showSymbol(s) + ValueLit(lit) then this.showLiteral(lit) + + fun inlineResult(ctx: Map[Result, String])(r) = InlinePrinter(ctx).showResult(r) + + fun inlineAssigments(ctx: Map[Symbol, String])(b) = if b is + Return(res) then inlineResult(ctx)(res) + Scoped(syms, rest) then + let ctx = syms.reduce((ctx, sym) => ctx.set(sym, sym.nme), ctx) + inlineAssigments(ctx)(rest) + // print the last call to the parent + Assign(NoSymbol, rhs, End) then inlineResult(ctx)(rhs) + Assign(lhs, rhs, rest) then inlineAssigments(ctx.set(lhs, inlineResult(ctx)(rhs)))(rest) + End then "" + else throw Error("unexpected Block type in constructor: " + b.toString()) + + let extendsClause = if owner is ConcreteClassSymbol then + let preCtor = runtimeClass."preCtor$_instr"().body + assert preCtor is Block.Block + inlineAssigments(new Map())(preCtor) + else "" + + // process ctor: remove ValDefn of parameters defined in paramsOpt + fun removeExtraValDefn(params, block) = if block is + Define(ValDefn(Some, sym, ValueSimpleRef(rhs)), rest) and params.has(rhs) then removeExtraValDefn(params, rest) + // induction + Match(scrut, arms, dflt, rest) then Match(scrut, arms, dflt, removeExtraValDefn(params, rest)) + Assign(lhs, rhs, rest) then Assign(lhs, rhs, removeExtraValDefn(params, rest)) + Define(defn, rest) then Define(defn, removeExtraValDefn(params, rest)) + Scoped(symbols, rest) then Scoped(symbols, removeExtraValDefn(params, rest)) + Return | End then block + + let ctor = runtimeClass.((if owner is ConcreteClassSymbol then "class$" else "") + "ctor$_instr")() + assert ctor is FunDefn + let params = new Set(ctor.params.flat().map(_.sym)) + let ctorBody = removeExtraValDefn(params, ctor.body) + let methodDefns = cache.values().map(e => + if not e.isPrivate then printer.showDefn(e.defn) else "" + ).toArray().filter(_ != "").sort().join("\n") + + decl + owner.name + paramText + + if extendsClause == "" then "" else (" extends " + extendsClause) + + if cache.length == 0 then "" else " with" + + indent("\n" + printer.showBlock(ctorBody)) // TODO: we can skip printing ctor that are just End() + + (if methodDefns == "" then "" else indent("\n" + methodDefns)) + fun toString() = + [printDefinitions(), printCachedPrivateCode(this)].filter(_ != "").join("\n") +module FunCache with + fun empty(owner) = FunCache(owner, new Map(), new Set()) + +open StagingUtility + +// shape of value +fun sov(v): ShapeSet = + if + typeof(v) is "number" | "string" | "boolean" then mkLit(v) + Array.isArray(v) then + mkArr(v.map(sov)) + not (v is undefined) and not (v.constructor is undefined) and not (v.constructor.(Symbols.definitionMetadata) is undefined) and + let meta = v.constructor.(Symbols.definitionMetadata) + let clsName = meta.1 + // if class field is not public, then definitionMetadata in the corresponding field is null + let paramsOpt = if meta.length < 3 + then None + else Some(meta.2.map(p => if p is null then Symbol("") else Symbol(p))) + let classSymbol = Runtime.SymbolMap.classMap.get(v.constructor) + // TODO: non-staged classes not already referenced in staged code will default to dynamic here + classSymbol is Symbol then + let argsMap = new Map() + if not (paramsOpt is None) do + meta.2.forEach((n, _, _) => argsMap.set(n, sov(v.(n)))) + mkClassFromMap(classSymbol, argsMap, None) // FIXME + else mkDyn() // unknown shape of value + +// shape of path +fun sop(ctx, p): ShapeSet = if ctx.get(p) is + Some(s) then s + None and p is + Select(ValueMemberRef(clsSymb), Symbol(name)) and clsSymb is ConcreteClassSymbol then + if ctx.thisShape is Some(thisShape) then // this.name + selSet(thisShape, mkLit(name)) + else if ctx.getValDefn(name) is Some(s) then s // variables defined in valdefn (this is for constructor propagation only) + else throw Error("member not found: " + name) + Select(ValueThis(clsSymb), Symbol(name)) and clsSymb is ConcreteClassSymbol then + if ctx.thisShape is Some(thisShape) then // this.name + selSet(thisShape, mkLit(name)) + else if ctx.getValDefn(name) is Some(s) then s // variables defined in valdefn (this is for constructor propagation only) + else throw Error("member not found: " + name) + Select(qual, Symbol(name)) and // object property + name is "length" and // special handle array .length + let qualShape = sop(ctx, qual) + let vals = qualShape.values() + vals.length > 0 and vals.every(_ is Arr) and + let firstLen = vals.0.shapes.length + vals.every(v => v.shapes.length == firstLen) then + mkLit(firstLen) + else mkDyn() + else selSet(sop(ctx, qual), mkLit(name)) // TODO: any other special function to handle? + DynSelect(qual, fld, _) then + selSet(sop(ctx, qual), sop(ctx, fld)) + ValueLit(lit) then mkLit(lit) + ValueThis(clsSymb) and clsSymb is ConcreteClassSymbol and ctx.thisShape is Some(thisShape) then thisShape + ValueSimpleRef | ValueMemberRef then mkDyn() + +// This sub p.(n) to p.1 if n -> 1 +fun subLitPath(ctx, p) = if p is + DynSelect(qual, fld, b) then DynSelect(subLitPath(ctx, qual), subLitPath(ctx, fld), b) + Select(qual, name) then Select(subLitPath(ctx, qual), name) + ValueSimpleRef | ValueMemberRef and + let s = sop(ctx, p) + s.values() is [Lit(lit)] then ValueLit(lit) + else p + + +// split a shapeset of class symbols into known ones and unknown ones +class SplitResult(val knownMap: Map[Class, [ConcreteClassSymbol, ShapeSet]], val unkShape: ShapeSet) + +fun fsplit(pss) = + let knownMap = new Map() + let unkShape = foldl((acc, s) => if s is + Class(sym, params) and isStagedClass(sym.value) then + let key = getActualClass(sym.value) + if knownMap.has(key) then + let entry = knownMap.get(key) + knownMap.set(key, [entry.0, union2(entry.1, lift(s))]) + else do knownMap.set(key, [sym, lift(s)]) + acc + else union2(acc, mkDyn()) + )(mkBot(), ...pss.values()) + SplitResult(knownMap, unkShape) + +fun lit(l) = [End(), ValueLit(l), mkLit(l)] + + +fun sorInstantiate(ctx, r, cls, args) = + let clsSymb = if cls is + ValueMemberRef(symb) and symb is ConcreteClassSymbol then symb // class defined globally + Select(_, symb) and symb is ConcreteClassSymbol then symb // class defined in a module + else throw Error("Instantiate with non-ClassSymbol in shape propagation: " + cls.toString()) + let argsShape = args.map(a => sop(ctx, a.value)) + if isStagedClass(clsSymb.value) then + let cache = getClassCache(clsSymb.value) + if not (cache is undefined) then + let res = SpecializeHelpers.specializeCtor(clsSymb, argsShape, ctx.clearCtx) + [End(), r, res] + else throw Error("cache not found in staged class") + else [End(), r, mkClass(clsSymb, argsShape)] + +fun sorBuiltinOp(ctx, r, f, name, args) = if args is + [x] and sop(ctx, x.value).values() is [Shape.Lit(l)] and name is + "!" then lit(not l) + "-" then lit(-l) + "+" then lit(+l) + [x, y] then + let s1 = sop(ctx, x.value) + let s2 = sop(ctx, y.value) + let bs = binOpSet(name, s1, s2) + if staticSet(bs) then lit(valOfSet(bs)) + else + let evaledArgs = args.map(a => sor(ctx, a.value)) + let fullBlk = foldl((acc, e) => concat(acc, e.0))(End(), ...evaledArgs) + let newArgs = evaledArgs.map(e => Arg(if e.1 is Path then e.1 else throw Error("expected path"))) + let newArgsWithLit = + if s1.values() is [Shape.Lit(l)] then [Arg(ValueLit(l)), newArgs.1] + else if s2.values() is [Shape.Lit(l)] then [newArgs.0, Arg(ValueLit(l))] + else newArgs + [fullBlk, Call(f, newArgsWithLit), bs] + else + let evaledArgs = args.map(a => sor(ctx, a.value)) + let fullBlk = foldl((acc, e) => concat(acc, e.0))(End(), ...evaledArgs) + let newArgs = evaledArgs.map(e => Arg(if e.1 is Path then e.1 else throw Error("expected path"))) + [fullBlk, Call(f, newArgs), mkDyn()] + +fun sorUnknownCall(ctx, f, args) = + let evaledArgs = args.map(a => sor(ctx, a.value)) + let fullBlk = foldl((acc, e) => concat(acc, e.0))(End(), ...evaledArgs) + let newArgs = evaledArgs.map(e => Arg(if e.1 is Path then e.1 else throw Error("expected path"))) + [fullBlk, Call(f, newArgs), mkDyn()] + +fun sorStaticModuleCall(ctx, f, value, fld, args, argShapes) = + let key = staticCallKey(f, argShapes) + if ctx.getStaticCall(key) is + Some(entry) then [End(), entry.path, entry.shape] + None then + let fimp = value.(fld) + let evaluated = fimp(...argShapes.map(valOfSet)) + let inferredShape = sov(evaluated) + if staticSet(inferredShape) then + let evaluatedPath = shapeset2path(inferredShape, ctx.allocs) + let entry = StaticCallEntry(evaluatedPath.0, evaluatedPath.1, inferredShape) + ctx.addStaticCall(key, entry) + [entry.block, entry.path, entry.shape] + // NOTE: this fallback is for when we are not be able to infer the shape for some runtime values, even when all parameters are static + else sorUnknownCall(ctx, f, args) + +fun sorCall(ctx, r, f, args, argShapes) = if f is + Select(Select(ValueMemberRef(Symbol("runtime")), Symbol("Tuple")), Symbol("get")) // runtime.Tuple.get is generated by the compiler in the IR + and args is [Arg(scrut), Arg(litArg)] then + let recovered = DynSelect(scrut, litArg, false) + [End(), recovered, sop(ctx, recovered)] + Select(Select(ValueMemberRef(Symbol("runtime")), Symbol("Tuple")), Symbol("slice")) then + throw Error("runtime.Tuple.slice not handled in shape propagation") + Select(ValueMemberRef(ModuleSymbol(name, value, _)), clsSymb) and clsSymb is ConcreteClassSymbol then // class within module + [End(), r, mkClass(clsSymb, argShapes)] + Select(ValueThis(ModuleSymbol(name, value, _)), clsSymb) and clsSymb is ConcreteClassSymbol then // class within current module + [End(), r, mkClass(clsSymb, argShapes)] // FIXME + ValueMemberRef(clsSymb) and clsSymb is ConcreteClassSymbol and // top-level class + isStagedClass(clsSymb.value) and + let cache = getClassCache(clsSymb.value) + not (cache is undefined) then + let res = SpecializeHelpers.specializeCtor(clsSymb, argShapes, ctx.clearCtx) + [End(), r, res] + else throw Error("class is staged but cache not found") + else [End(), r, mkClass(clsSymb, argShapes)] + ValueSimpleRef(symb) | ValueMemberRef(symb) then sorBuiltinOp(ctx, r, f, symb.name, args) // built-in or top-level + Select(ValueThis(ModuleSymbol(name, value, redir)), Symbol(fld)) and + let mapPropName = getGenMapName(name, false) + let cachePropName = getCacheName(name, false) + let genMap = value.(mapPropName) + not (genMap is undefined) and + let f_gen = genMap.get(fld) + not (f_gen is Runtime.Unit) then // staged function + let res = f_gen(...argShapes) + [End(), Call(Select(ValueThis(ModuleSymbol(name, value, redir)), Symbol(res.0)), args), res.1] + else + throw Error("module " + name + " is staged but function " + fld + " is not found in generator map") + Select(ValueMemberRef(ModuleSymbol(name, value, redir)), Symbol(fld)) and + let mapPropName = getGenMapName(name, false) + let genMap = value.(mapPropName) + not (genMap is undefined) and + let f_gen = genMap.get(fld) + not (f_gen is Runtime.Unit) then // staged function + let res = f_gen(...argShapes) + let callPath = if res.0 == fld then Select(ValueMemberRef(ModuleSymbol(name, value, redir)), Symbol(res.0)) else ValueSimpleRef(Symbol(res.0)) + [End(), Call(callPath, args), res.1] + else + throw Error("module " + name + " is staged but function " + fld + " is not found in generator map") + argShapes.every(staticSet) then // non staged function and params known + sorStaticModuleCall(ctx, f, value, fld, args, argShapes) + else sorUnknownCall(ctx, f, args) // non staged function and some params unknown + // else throw Error("unknown call in sor: " + r.toString()) + +// shape of result: return [blk, res, s] +// where blk is the block needed to construct the result res (End() if not needed) and s is the shape +fun sor(ctx, r) = if r is + Path then + let s = sop(ctx, r) + [End(), subLitPath(ctx, r), s] + Instantiate(cls, args) then sorInstantiate(ctx, r, cls, args) + Tuple(elems) then [End(), r, mkArr(elems.map(a => sop(ctx, a.value)))] + Call(f, args) then sorCall(ctx, r, f, args, args.map((a, _, _) => sop(ctx, a.value))) + else throw Error("unknown result in sor: " + r.toString()) + +// xOpt stores Some(path) if an Assign block's result is a method call, otherwise it stores None +// implctOpt stores an option of the implct field of return +// p is the path p in p.f() +// f is the symbol f in p.f() +// args are the arguments in p.f(args) +fun dispatchMethodCall(ctx, xOpt, p, f, args) = + let pss = sop(ctx, p) + let argShapes = args.map(a => sop(ctx, a.value)) + let splitRes = fsplit(pss) + let knownMap = splitRes.knownMap + let unkShape = splitRes.unkShape + let knownMapArr = [...knownMap.entries()] + let isRet = xOpt is None + + if knownMap.size is + 0 and + let dfltMatch = Call(Select(p, Symbol(f)), args) + isRet then + [Return(dfltMatch), mkDyn()] + else + let x = if xOpt is Some(x_) then x_ else throw Error("unreachable") + [Assign(x, dfltMatch, End()), mkDyn()] + 1 and unkShape.isEmpty() and + // If the object is certainly a known class, generate the generated method call directly without pattern matching + let C_i = knownMapArr.0.1.0 + let ss_i = knownMapArr.0.1.1 + let genMap = getClassGenMap(C_i.value) + let f_gen = genMap.get(f) + let ret = f_gen(ss_i)(...argShapes) + let retSym = ret.0 + let retShape = ret.1 + let callRes = Call(ValueSimpleRef(Symbol(retSym)), [Arg(p), ...args]) + isRet then + [Return(callRes), retShape] + else + let x = if xOpt is Some(x_) then x_ else throw Error("unreachable") + [Assign(x, callRes, End()), retShape] + else + let armsRet = knownMapArr.map(entry => + let C_i = entry.1.0 + let ss_i = entry.1.1 + let genMap = getClassGenMap(C_i.value) + let f_gen = genMap.get(f) + let retData = f_gen(ss_i)(...argShapes) + let retSym = retData.0 + let retShape = retData.1 + let callRes = Call(ValueSimpleRef(Symbol(retSym)), [Arg(p), ...args]) + if isRet then + [Arm(Cls(C_i, p), Return(callRes)), retShape] + else + let x = if xOpt is Some(x_) then x_ else throw Error("unreachable") + [Arm(Cls(C_i, p), Assign(x, callRes, End())), retShape] + ) + let armsAcc = armsRet.map(_.0) + let totalStagedRetShape = foldl((acc, x) => union2(acc, x.1))(mkBot(), ...armsRet) + let dfltRet = if unkShape.isEmpty() then [None, mkBot()] else + let dfltMatch = Call(Select(p, Symbol(f)), args) + if isRet then + [Some(Return(dfltMatch)), mkDyn()] + else + let x = if xOpt is Some(x_) then x_ else throw Error("unreachable") + [Some(Assign(x, dfltMatch, End())), mkDyn()] + let matchBody = if knownMap.size is 1 and unkShape.isEmpty() then + armsAcc.0.body + else + Match(p, armsAcc, dfltRet.0, End()) + let totalRetShape = union2(totalStagedRetShape, dfltRet.1) + [matchBody, totalRetShape] + +// [retBlock, retShape, canReachEnd] +fun prop(ctx, b) = if b is + End() then [b, mkBot(), true] + Return(Call(Select(p, Symbol(f)), args)) and not (f is "concat") and p is // TODO[later]: Ref -> Path, remove special checks + ValueSimpleRef(symb) | ValueMemberRef(symb) and not symb is ModuleSymbol then + [...dispatchMethodCall(ctx, None, p, f, args), false] + Select(ValueThis(ConcreteClassSymbol), _) then + [...dispatchMethodCall(ctx, None, p, f, args), false] + Select(ValueMemberRef(ConcreteClassSymbol), _) then + [...dispatchMethodCall(ctx, None, p, f, args), false] + Return(res) and sor(ctx, res) is [blk, r1, s1] then + [concat(blk, Return(r1)), s1, false] + Scoped(symbols, rest) then + symbols.forEach(x => ctx.add(ValueSimpleRef(x), mkBot())) + let newAllocs = mut [] + let newCtx = Ctx(new Map(ctx.ctx), ctx.valDefnCtx, new Map(ctx.staticCallCtx), newAllocs, ctx.thisShape) + let res = prop(newCtx, rest) + [wrapScoped([...symbols, ...newAllocs], res.0), res.1, res.2] + Assign(x, Call(Select(p, Symbol(f)), args), restBlock) and p is // TODO Can we deduplicate this? + ValueSimpleRef(symb) | ValueMemberRef(symb) and not (symb is ModuleSymbol) then + let res = dispatchMethodCall(ctx, Some(x), p, f, args) + let b2 = prop(ctx.add(ValueSimpleRef(x), res.1), restBlock) + [concat(res.0, b2.0), b2.1, b2.2] + Select(ValueThis(ConcreteClassSymbol), _) then + let res = dispatchMethodCall(ctx, Some(x), p, f, args) + let b2 = prop(ctx.add(ValueSimpleRef(x), res.1), restBlock) + [concat(res.0, b2.0), b2.1, b2.2] + Select(ValueMemberRef(ConcreteClassSymbol), _) then + let res = dispatchMethodCall(ctx, Some(x), p, f, args) + let b2 = prop(ctx.add(ValueSimpleRef(x), res.1), restBlock) + [concat(res.0, b2.0), b2.1, b2.2] + Define(ValDefn(opt, sym, rhs), restBlock) and + sor(ctx, rhs) is [blk, r1, s1] and + do ctx.addValDefn(sym.name, s1) + prop(ctx, restBlock) is [b2, s2, canReachEnd] then + [concat(blk, Define(ValDefn(opt, sym, r1), b2)), s2, canReachEnd] + Assign(x, r, restBlock) and + sor(ctx, r) is [blk, r1, s1] and + prop(ctx.add(ValueSimpleRef(x), s1), restBlock) is [b2, s2, canReachEnd] then + [concat(blk, Assign(x, r1, b2)), s2, canReachEnd] + Match(p, arms, dflt, restBlock) then + let s = sop(ctx, p) + fun mergeAssigned(acc, assigned) = + assigned.forEach((ss, ps, _) => + if acc.has(ps) then + acc.set(ps, union2(acc.get(ps), ss)) + else + acc.set(ps, ss) + ) + fun propBranch(body, branchShape) = + let branchCtx = ctx.clone + if not p is ValueLit do branchCtx.refine(p, branchShape) + let res = prop(branchCtx, body) + [...res, branchCtx.sub(ctx)] + let filteredArms = foldl((r, arm) => + let fs = filterSet(r.0, arm.cse) + if fs.isEmpty() then r + else + let res = propBranch(arm.body, fs) + mergeAssigned(r.3, res.3) + [restSet(r.0, arm.cse), union2(r.1, res.1), [...r.2, Arm(arm.cse, res.0)], r.3, r.4 || res.2] + )([s, mkBot(), [], new Map(), false], ...arms) + let dfltRes = if filteredArms.0.isEmpty() then [None, mkBot(), new Map(), None] else if dflt is + Some(d) then + let res = propBranch(d, filteredArms.0) + [Some(res.0), res.1, res.3, Some(res.2)] + else [None, mkBot(), new Map(), None] + mergeAssigned(filteredArms.3, dfltRes.2) + filteredArms.3.forEach((ss, ps, _) => + if ctx.ctx.has(ps) then + ctx.ctx.set(ps, union2(ctx.ctx.get(ps), ss)) + else + ctx.ctx.set(ps, ss) + ) + let canReachEnd = filteredArms.4 || (dfltRes.3 is Some(true)) + let restRes = prop(ctx, restBlock) + let retShape = if canReachEnd then union(filteredArms.1, dfltRes.1, restRes.1) + else union(filteredArms.1, dfltRes.1) // every possible branch has a return, so the restBlock cannot be reached + if filteredArms.2.length is + 0 and + canReachEnd and dfltRes.0 is Some(d) then [concat(d, restRes.0), retShape, true] + not canReachEnd and dfltRes.0 is Some(d) and dfltRes.3 is Some(dcanReachEnd) then [d, retShape, dcanReachEnd] // the rest block is unreachable + else restRes // the else block is unreachable + 1 and dfltRes.0 is None then // the else block is unreachable + [concat(filteredArms.2.0.body, restRes.0), retShape, canReachEnd || restRes.2] + else [Match(p, filteredArms.2, dfltRes.0, restRes.0), retShape, canReachEnd || restRes.2] + else [b, mkDyn(), true] + +// TODO: debug only; remove this +fun propStub(ctx, body) = + [body, mkDyn()] + +fun buildShapeName(s: Shape): Str = if s is + Dyn then "Dyn" + Lit(lit) and lit is Str then "Str" + lit + Lit(lit) then "Lit" + lit.toString().replace(".", "_p_") + Arr(shapes) then "Arr_" + shapes.map(buildShapeSetName).join("_") + "_end" + Class(sym, params) and params.length is + 0 then sym.name + else sym.name + "_" + params.map(buildShapeSetName).join("_") + else throw Error("unknown shape when building shape name" + s.toString()) + +fun buildShapeSetName(ss: ShapeSet): Str = + let vals = ss.values() + if vals.length is 1 then buildShapeName(vals.0) + else "Union_" + vals.map(buildShapeName).join("_") + "_end" + +fun specializationParamShapes(isMethod, ps, shapes) = + shapes.map((ss, i, _) => + if isMethod and i is 0 then ss + else ss.map((s, j, _) => + let psIdx = if isMethod then i - 1 else i + if ps.(psIdx).(j).constraint is Some(Dynamic) then mkDyn() else s + ) + ) + +fun hasAllDynamicParams(isMethod, ps, shapes) = + specializationParamShapes(isMethod, ps, shapes).every(_.every(_.isDyn())) + +fun specializeKey(funName, isMethod, ps, shapes) = + let mappedShapes = specializationParamShapes(isMethod, ps, shapes) + if mappedShapes.every(_.every(_.isDyn())) then funName + else funName + "_" + mappedShapes.map(pss => pss.map(buildShapeSetName).join("_")).join("_dot_") + +fun specializeName(cache, funName, isMethod, ps, shapes) = + let mappedShapes = specializationParamShapes(isMethod, ps, shapes) + if mappedShapes.every(_.every(_.isDyn())) then funName + else cache.freshName(funName) + +fun isStaticShapePath(s: Shape) = if s is + Lit(_) then true + // Arr(shapes) then shapes.every(x => x is Lit) + // Class(_, fields) then fields.every(x => x is Lit) + else false + +fun isStaticSetPath(ss: ShapeSet) = + staticSet(ss) and ss.values().every(isStaticShapePath) + +fun isStaticPath(ss: ShapeSet) = + isStaticSetPath(ss) + +fun specialize(cache: FunCache, funName, dflt, shapes) = + // FIXME + // right now the function name depends on the parameter constraints + // so we need to read the constraints by running dflt() anyway + // which prevent the possibilily of not running dflt when specialized function already exists in cache + let defn = dflt() + if defn is FunDefn(Symbol(_), ps, body) then + let isMethod = cache.owner is ConcreteClassSymbol + let specializationKey = specializeKey(funName, isMethod, ps, shapes) + let isPrivate = not hasAllDynamicParams(isMethod, ps, shapes) + if cache.getFun(specializationKey) is + Some(x) then [x.defn.sym.name, x.retShape] + None then + let newName = specializeName(cache, funName, isMethod, ps, shapes) + let paramShapes = if isMethod then shapes.slice(1) else shapes + + let ctx = if isMethod then + let clsSymb = cache.owner + Ctx(new Map(), new Map(), new Map(), mut [], Some(shapes.(0).(0))) + else Ctx.empty() + + ps.forEach((p, i, _) => p.forEach((p2, j, _) => + let shape = if p2.constraint is + Some(Dynamic) then mkDyn() + Some(Static) and not staticSet(paramShapes.(i).(j)) then throw Error("Non-static shape given to static parameter " + p2) + else paramShapes.(i).(j) + ctx.add(ValueSimpleRef(p2.sym), shape) + )) + + cache.setFun(specializationKey, FunEntry(FunDefn(Symbol(newName), ps, body), mkDyn(), isPrivate)) + + let res = prop(ctx, body) + let bodyWithScoped = wrapScoped(ctx.allocs, res.0) + + let actualRetShape = res.1 + + let finalBody = if isStaticPath(actualRetShape) then + let allocs = mut [] + let v2p = shapeset2path(actualRetShape, allocs) + wrapScoped(allocs, concat(v2p.0, Return(v2p.1))) + else bodyWithScoped + + // Update cache with finalized body and actual return shape + let entry = cache.setFun(specializationKey, FunEntry(FunDefn(Symbol(newName), ps, finalBody), actualRetShape, isPrivate)) + + + [entry.defn.sym.name, entry.retShape] + else throw Error("instrumented function is not a FunDefn") + +// this builds the shape of an instantiation of class through shape propagation of constructor +fun specializeCtor(classSymb: ConcreteClassSymbol, argShapes: Array[ShapeSet], ctx: Ctx) = + let actualClass = getActualClass(classSymb.value) + let defn = actualClass."class$ctor$_instr"() + if defn is FunDefn(Symbol(_), ps, body) then + ps.forEach((p, i, _) => p.forEach((p2, j, _) => ctx.add(ValueSimpleRef(p2.sym), argShapes.(j)))) + if not (actualClass."preCtor$_instr" is undefined) and actualClass."preCtor$_instr"() is FunDefn(_, _, preCtorBody) then do + prop(ctx, preCtorBody) + else throw Error("preCtor not found in staged class") + if not (actualClass."class$ctor$_instr" is undefined) and actualClass."class$ctor$_instr"() is FunDefn(_, _, ctorBody) then do + prop(ctx, ctorBody) + else throw Error("ctor not found in staged class") + mkClassFromMap(classSymb, ctx.valDefnCtx, Some(ps)) + else throw Error("instrumented method is not a FunDefn") diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/AdjacentClasses.mls b/hkmc2/shared/src/test/mlscript-compile/staging/AdjacentClasses.mls new file mode 100644 index 0000000000..54c9598cc7 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/AdjacentClasses.mls @@ -0,0 +1,4 @@ +staged module AdjacentClasses with + staged class C(val x) + staged class D() with + fun f() = new C(1) diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/ImportingFiles.mls b/hkmc2/shared/src/test/mlscript-compile/staging/ImportingFiles.mls new file mode 100644 index 0000000000..f507fe6a23 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/ImportingFiles.mls @@ -0,0 +1,10 @@ +#config(noModuleCheck: true) + +import "./SimpleStagedExample.mls" +import "./StagedClass.mls" + +staged module ImportingFiles with + fun f() = SimpleStagedExample.fib(8) // what about importing classes? + // FIXME: import the file "./StagedClass.mls" in next stage + // fun g(x) = (new StagedClass.Bar(x)).f(1, 2) + // val a = StagedClass.Bar diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/Inheritance.mls b/hkmc2/shared/src/test/mlscript-compile/staging/Inheritance.mls new file mode 100644 index 0000000000..0caf4dbb8f --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/Inheritance.mls @@ -0,0 +1,3 @@ +staged module Inheritance with + staged class B(val x) + staged class D(val x) extends B(x + 1) diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/LinkingGeneratedClasses.mls b/hkmc2/shared/src/test/mlscript-compile/staging/LinkingGeneratedClasses.mls new file mode 100644 index 0000000000..8cafed1953 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/LinkingGeneratedClasses.mls @@ -0,0 +1,12 @@ +#config(funcToCls: true) + +class C +staged class S with + fun f(x) = x +staged module LinkingGeneratedClasses with + class D + fun test1 = new C + fun test2(x) = if x then (new S).f(1) else new S + fun test3 = new D + fun f() = x => x + fun g() = x => x + 2 diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/SimpleStagedExample.mls b/hkmc2/shared/src/test/mlscript-compile/staging/SimpleStagedExample.mls new file mode 100644 index 0000000000..906045beae --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/SimpleStagedExample.mls @@ -0,0 +1,28 @@ +#config(noFreeze: true) + +staged module SimpleStagedExample with + fun f(x, y) = x + y + fun fib(n) = if n is + 1 then 1 + 2 then 1 + n then fib(n - 1) + fib(n - 2) + fun foo() = + f(2, 3) + fib(10) + fun spaces() = ["\t", "\n", "\r"] + staged class Bar(val x) with + fun bar() = x + staged class Foo(val x) with + fun foo(b) = + if b is + 1 then x.bar() + 1 + 2 then x.bar() + 2 + else x.bar() + fun baz() = Foo(Bar(1)).foo(1) + fun foobar(x) = + let y = if x is 0 then 1 else 0 + let z = if y is Num then 0 else 1 + y + z + fun bazbaz(x) = not x + + + diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/StagedClass.mls b/hkmc2/shared/src/test/mlscript-compile/staging/StagedClass.mls new file mode 100644 index 0000000000..ae11456ac2 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/StagedClass.mls @@ -0,0 +1,30 @@ +module Helper with + fun foo(x) = x + 1 + +staged module StagedClass with + class Foo + class Bar(val x) with + fun f(y, z) = x + y + z + staged class Baz(val x) + fun foo() = new Foo + fun bar(b) = if b then Bar(0) else new Bar(1) + fun baz(b) = if b then Baz(1) else new Baz(2) + fun f(x) = + if x is + Foo then 0 + Bar(x') then x' + Baz(y) then y + 1 + else -1 + staged class FooBar(val x) + staged class B() + staged class D() extends B() + fun g() = new D() + staged class C() with + fun h() = new D() + staged class X(val x) with + fun f(y) = if x < y then new Bar(x) else new Bar(y) + fun g(y) = Helper.foo(x + y) + fun h(y) = helpFoo(x + y) + fun xx() = new X(0).f(1) + fun helpFoo(x) = Helper.foo(x) + diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/StagedRegExp.mls b/hkmc2/shared/src/test/mlscript-compile/staging/StagedRegExp.mls new file mode 100644 index 0000000000..b797f09a3b --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/StagedRegExp.mls @@ -0,0 +1,226 @@ +#config(noFreeze: true) + +module SeqHelper with + fun push(arr, ele) = + arr.push(ele) + arr + fun concat(lhs, rhs) = lhs.concat(rhs) + fun has(arr, ele) = arr.includes(ele) + fun len(s) = s.length + fun eq(arr1, arr2) = + arr1.length == arr2.length and arr1.every((v, i) => v == arr2.(i)) + fun setEq(s1, s2) = + s1.slice().sort() + s2.slice().sort() + s1.length == s2.length and s1.every((v, i) => v.eq(s2.(i))) + +module CharSet with + fun alphabet() = [ + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + ] + fun space() = [" ", "\n", "\t", "\r"] + fun digit() = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] + +staged module StagedRegExp with + class Some(val x) + class None + + fun len(s) = SeqHelper.len(s) + fun has(arr, ele) = SeqHelper.has(arr, ele) + fun arrEq(arr1, arr2) = SeqHelper.eq(arr1, arr2) + fun push(arr, ele) = SeqHelper.push(arr, ele) + fun concat(lhs, rhs) = SeqHelper.concat(lhs, rhs) + fun setEq(s1, s2) = SeqHelper.setEq(s1, s2) + + staged class DedupSet(val arr) with + fun addImp(e, i) = + let s = len(arr) + if s - i == s then new DedupSet(push(arr, e)) + else + let e' = arr.(s - i) + if e.eq(e') then this else addImp(e, i - 1) + fun add(e) = + addImp(e, len(arr)) + + staged class RegExp() with + fun derive(c) + fun canBeEmpty() + fun normalize() + fun eq(other) + fun startsWith(c) + + staged class Nothing() extends RegExp() with + fun derive(c) = this + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = other is Nothing + fun startsWith(c) = false + + staged class Empty() extends RegExp() with + fun derive(c) = new Nothing() + fun canBeEmpty() = true + fun normalize() = this + fun eq(other) = other is Empty + fun startsWith(c) = false + + staged class Exact(val ch) extends RegExp() with + fun derive(c) = + if startsWith(c) then new Empty() + else new Nothing() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = + if other is Exact(ch') then ch == ch' else false + fun startsWith(c) = ch == c + + staged class Any() extends RegExp() with + fun derive(c) = new Empty() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = other is Any() + fun startsWith(c) = true + + staged class Not(val chars) extends RegExp() with + fun derive(c) = + if startsWith(c) then new Empty() else new Nothing() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = + if other is Not(chars') then arrEq(chars, chars') else false + fun startsWith(c) = not has(chars, c) + + fun notWord() = new Not(CharSet.alphabet()) + fun notSpace() = new Not(CharSet.space()) + fun notDigit() = new Not(CharSet.digit()) + + fun mkUnion(arr, i, s) = + if s - i == s - 1 then arr.(s - i) + else + if arr.(s - i) is + Nothing() then mkUnion(arr, i - 1, s) + else new Union(arr.(s - i), mkUnion(arr, i - 1, s)) + + staged class Union(val p1, val p2) extends RegExp() with + fun derive(c) = (new Union(p1.derive(c), p2.derive(c))).normalize() + fun canBeEmpty() = p1.canBeEmpty() || p2.canBeEmpty() + fun flat() = + let p1' = if p1 is Union then p1.flat() else [p1] + let p2' = if p2 is Union then p2.flat() else [p2] + concat(p1', p2') + fun iter(st, arr, i, s) = + if s - i == s then st + else iter(st.add(arr.(s - i)), arr, i - 1, s) + fun normalize() = + let p1' = p1.normalize() + let p2' = p2.normalize() + let arr1 = if p1' is Union then p1'.flat() else [p1'] + let arr2 = if p2' is Union then p2'.flat() else [p2'] + let s = iter(new DedupSet(arr1), arr2, len(arr2), len(arr2)) + mkUnion(s.arr, len(s.arr), len(s.arr)) + fun eq(other) = + let n = other.normalize() + if n is + Union then setEq(normalize().flat(), n.flat()) + else false + fun startsWith(c) = p1.startsWith(c) || p2.startsWith(c) + + fun question(r) = new Union(r, new Empty()) + + staged class In(val chars) extends RegExp() with + fun derive(c) = + if startsWith(c) then new Empty() else new Nothing() + fun canBeEmpty() = false + fun normalize() = this + fun eq(other) = + if other is In(chars') then arrEq(chars, chars') else false + fun startsWith(c) = has(chars, c) + + fun words() = new In(CharSet.alphabet()) + fun spaces() = new In(CharSet.space()) + fun digits() = new In(CharSet.digit()) + + staged class Concat(val p1, val p2) extends RegExp() with + fun derive(c) = + let p1' = p1.derive(c) + if p1.canBeEmpty() then + (new Union(new Concat(p1', p2), p2.derive(c))).normalize() + else (new Concat(p1', p2)).normalize() + fun canBeEmpty() = p1.canBeEmpty() and p2.canBeEmpty() + fun normalize() = + let p1' = p1.normalize() + if p1' is + Empty() then p2.normalize() + Nothing() then p1' + else new Concat(p1', p2.normalize()) + fun eq(other) = + if other is Concat(p1', p2') then p1.eq(p1') and p2.eq(p2') else false + fun startsWith(c) = p1.startsWith(c) || (p1.canBeEmpty() and p2.startsWith(c)) + + fun nTimes(r, i) = + if i == 1 then r + else new Concat(r, nTimes(r, i - 1)) + + staged class Star(val p) extends RegExp() with + fun derive(c) = (new Concat(p.derive(c), new Star(p))).normalize() + fun canBeEmpty() = true + fun normalize() = new Star(p.normalize()) + fun eq(other) = + if other is Star(p') then p.eq(p') else false + fun startsWith(c) = p.startsWith(c) + + fun plus(r) = new Concat(r, new Star(r)) + + fun matchImpl(p, s, acc) = if + len(s) == 0 and + p.canBeEmpty() then new Some(acc) + else new None + p is Nothing then new None + let c = s.0 + p.startsWith(c) then matchImpl(p.derive(c), s.slice(1), acc + c) + p.canBeEmpty() then new Some(acc) + else new None + fun match(p, s) = + matchImpl(p, s, "") + + fun matchAllImpl(p, s, res) = + if len(s) == 0 then res + else + if match(p, s) is + Some(ss) then + if len(ss) > 0 then matchAllImpl(p, s.slice(len(ss)), SeqHelper.push(res, ss)) + else matchAllImpl(p, s.slice(1), res) + else matchAllImpl(p, s.slice(1), res) + fun matchAll(p, s) = + matchAllImpl(p, s, []) + + // [\w\.-]+@[\w\.-]+\.[\w\.-]+ + fun matchAllEmail(s) = + let p = plus(new In(SeqHelper.concat(CharSet.alphabet(), ["-", "."]))) + let email = new Concat(p, new Concat(new Exact("@"), new Concat(p, new Concat(new Exact("."), p)))) + matchAll(email, s) + + // \w+://[^/\s?#]+[^\s?#]+(\?[^\s#]*)?(#[^\s]*)? + fun matchAllURI(s) = + let n1 = new Not(["/", "?", "#", " ", "\n", "\t", "\r"]) + let n2 = new Not(["?", "#", " ", "\n", "\t", "\r"]) + let n3 = new Not(["#", " ", "\n", "\t", "\r"]) + let w = words() + let d = digits() + let p = SeqHelper.concat(CharSet.alphabet(), SeqHelper.concat(CharSet.digit(), ["-", "_"])) + let head = new Concat(plus(w), new Concat(new Exact(":"), new Concat(new Exact("/"), new Exact("/")))) + let body = new Concat(plus(n1), plus(n2)) + let params = new Concat(question(new Concat(new Exact("?"), new Star(new In(p)))), question(new Concat(new Exact("#"), new Star(new In(p))))) + let uri = new Concat(head, new Concat(body, params)) + matchAll(uri, s) + + // ((25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9]) + fun matchAllIPv4(s) = + let fo = new In(["0", "1", "2", "3", "4"]) + let fi = new In(["0", "1", "2", "3", "4", "5"]) + let segment = new Union(new Concat(new Exact("2"), new Concat(new Exact("5"), fi)), new Union( + new Concat(new Exact("2"), new Concat(fo, digits())), + new Concat(question(new Exact("1")), new Concat(question(digits()), digits())) + )) + let ipv4 = new Concat(nTimes(new Concat(segment, new Exact(".")), 3), segment) + matchAll(ipv4, s) \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/Transform3D.mls b/hkmc2/shared/src/test/mlscript-compile/staging/Transform3D.mls new file mode 100644 index 0000000000..c957ef9fa1 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/Transform3D.mls @@ -0,0 +1,99 @@ +#config(noFreeze: true) + +module Mx with + fun init(len, dft) = globalThis.Array(len).fill(dft) + fun setAt(a, i, v) = + set a.(i) = v + a + fun len(arr) = arr.length + +staged module Transform3D with + class Matrix(val arr, val r, val c) + + fun iter(sum, x, y, colX, i, j, k) = + if k > 0 then iter(sum + x.arr.(i * x.c + colX - k) * y.arr.((colX - k) * y.c + j), x, y, colX, i, j, k - 1) + else sum + + fun iterCol(m, x, y, colX, colY, i, j) = + if j === 0 then m + else iterCol(update(m, i, colY - j, iter(0.0, x, y, colX, i, colY - j, colX)), x, y, colX, colY, i, j - 1) + + fun iterRow(m, x, y, rowX, colX, colY, i) = + if i === 0 then m + else iterRow(iterCol(m, x, y, colX, colY, rowX - i, colY), x, y, rowX, colX, colY, i - 1) + + fun iterID(m, w, i) = + if i === 0 then m + else + iterID(update(m, w - i, w - i, 1), w, i - 1) + + fun zeros(r, c) = new Matrix(Mx.init(r * c, 0), r, c) + + fun multiply(x, y) = + let res = zeros(x.r, y.c) + iterRow(res, x, y, x.r, x.c, y.c, x.r) + + fun ident(w) = + let m = zeros(w, w) + iterID(m, w, w) + + fun update(m, i, j, v) = new Matrix(Mx.setAt(m.arr, i * m.c + j, v), m.r, m.c) + + fun transform(dx, dy, dz) = + update of + update of + update(ident(4), 0, 3, dx), 1, 3, dy + 2, 3, dz + + fun scale(sx, sy, sz) = + update of + update of + update(ident(4), 0, 0, sx), 1, 1, sy + 2, 2, sz + + fun rotateX(angle) = + let s = Math.sin(angle) + let c = Math.cos(angle) + update of + update of + update of + update(ident(4), 1, 1, c), 1, 2, -s + 2, 1, s + 2, 2, c + + fun rotateY(angle) = + let s = Math.sin(angle) + let c = Math.cos(angle) + update of + update of + update of + update(ident(4), 0, 0, c), 0, 2, s + 2, 0, -s + 2, 2, c + + fun rotateZ(angle) = + let s = Math.sin(angle) + let c = Math.cos(angle) + update of + update of + update of + update(ident(4), 0, 0, c), 0, 1, -s + 1, 0, s + 1, 1, c + + fun model(local, position, scaling, rotation) = + let rot = multiply of + rotateZ(rotation.2), multiply of + rotateY(rotation.1), multiply of + rotateX(rotation.0), ident(4) + let res = multiply of + transform(position.0, position.1, position.2), multiply of + rot, multiply(scale(scaling.0, scaling.1, scaling.2), new Matrix([local.0, local.1, local.2, 1], 4, 1)) + [res.arr.0, res.arr.1, res.arr.2] + + fun model0(local) = + model(local, [11, 4, 51], [0.4, 0.19, 0.19], [0.8 * 3.14159265, 3.1415926535, 0.0]) + + fun moveBy(v, dx, dy, dz) = + let m = transform(dx, dy, dz) + multiply(m, new Matrix([v.0, v.1, v.2, 1], 4, 1)) diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/AdjacentClasses.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/AdjacentClasses.mls new file mode 100644 index 0000000000..0cc6e350e4 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/AdjacentClasses.mls @@ -0,0 +1,8 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../AdjacentClasses.mls" as AdjacentClasses__Legacy +module AdjacentClasses with + class C(val x) with + () + class D() with + () + fun f() = new C(1) \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/CombinedModule.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/CombinedModule.mls new file mode 100644 index 0000000000..014e4eec30 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/CombinedModule.mls @@ -0,0 +1,87 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../SimpleStagedExample.mls" as SimpleStagedExample__Legacy +import "../LinkingGeneratedClasses.mls" as LinkingGeneratedClasses__Legacy + +module CombinedModule with + module SimpleStagedExample with + class Bar(val x) with + () + fun bar() = x + class Foo(val x) with + () + fun foo(b) = + let {tmp, tmp1} + if b is + 1 then + tmp = x.bar() + tmp + 1 + 2 then + tmp1 = x.bar() + tmp1 + 2 + else x.bar() + fun baz() = 2 + fun bazbaz(x) = not x + fun f(x, y) = x + y + fun fib(n) = + let {n1, tmp2, tmp3, tmp4, tmp5} + if n is + 1 then 1 + 2 then 1 + else + n1 = n + tmp2 = n1 - 1 + tmp3 = fib(tmp2) + tmp4 = n1 - 2 + tmp5 = fib(tmp4) + tmp3 + tmp5 + fun foo() = 60 + fun foobar(x) = + let {y1, z, tmp10, tmp11} + if x is + 0 then + tmp10 = 1 + else + tmp10 = 0 + y1 = tmp10 + tmp11 = 0 + z = 0 + y1 + 0 + fun spaces() = ["\t", "\n", "\r"] + class S with + () + module LinkingGeneratedClasses with + class D + fun f() = + let {tmp1} + tmp1 = new LinkingGeneratedClasses__Legacy."Function$1$LinkingGeneratedClasses"() + tmp1 + fun g() = + let {tmp2} + tmp2 = new LinkingGeneratedClasses__Legacy."Function$$LinkingGeneratedClasses"() + tmp2 + fun test1 = new LinkingGeneratedClasses__Legacy."C$LinkingGeneratedClasses"() + fun test2(x) = + let {tmp} + if x is + true then + tmp = new S() + f_S_sp_0(tmp, 1) + else new S() + fun test3 = new D() +open CombinedModule +open SimpleStagedExample +open LinkingGeneratedClasses +fun f_SimpleStagedExample_sp_0(x, y) = 5 +fun fib_SimpleStagedExample_sp_0(n) = 55 +fun fib_SimpleStagedExample_sp_1(n) = 34 +fun fib_SimpleStagedExample_sp_2(n) = 21 +fun fib_SimpleStagedExample_sp_3(n) = 13 +fun fib_SimpleStagedExample_sp_4(n) = 8 +fun fib_SimpleStagedExample_sp_5(n) = 5 +fun fib_SimpleStagedExample_sp_6(n) = 3 +fun fib_SimpleStagedExample_sp_7(n) = 2 +fun fib_SimpleStagedExample_sp_8(n) = 1 +fun fib_SimpleStagedExample_sp_9(n) = 1 +fun bar_Bar_sp_0(self) = 1 +fun foo_Foo_sp_0(self, b) = 2 +fun f_S_sp_0(self, x) = 1 \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/ImportingFiles.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/ImportingFiles.mls new file mode 100644 index 0000000000..5c7a62be4e --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/ImportingFiles.mls @@ -0,0 +1,5 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../ImportingFiles.mls" as ImportingFiles__Legacy +module ImportingFiles with + () + fun f() = 21 \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/Inheritance.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/Inheritance.mls new file mode 100644 index 0000000000..262139525b --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/Inheritance.mls @@ -0,0 +1,7 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../Inheritance.mls" as Inheritance__Legacy +module Inheritance with + class B(val x) with + () + class D(val x) extends B(x + 1) with + () \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/LinkingGeneratedClasses.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/LinkingGeneratedClasses.mls new file mode 100644 index 0000000000..55ee4f77e1 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/LinkingGeneratedClasses.mls @@ -0,0 +1,25 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../LinkingGeneratedClasses.mls" as LinkingGeneratedClasses__Legacy +class S with + () +module LinkingGeneratedClasses with + class D + fun f() = + let {tmp1} + tmp1 = new LinkingGeneratedClasses__Legacy."Function$1$LinkingGeneratedClasses"() + tmp1 + fun g() = + let {tmp2} + tmp2 = new LinkingGeneratedClasses__Legacy."Function$$LinkingGeneratedClasses"() + tmp2 + fun test1 = new LinkingGeneratedClasses__Legacy."C$LinkingGeneratedClasses"() + fun test2(x) = + let {tmp} + if x is + true then + tmp = new S() + f_S_sp_0(tmp, 1) + else new S() + fun test3 = new D() +open LinkingGeneratedClasses +fun f_S_sp_0(self, x) = 1 \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/SimpleStagedExample.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/SimpleStagedExample.mls new file mode 100644 index 0000000000..596510f018 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/SimpleStagedExample.mls @@ -0,0 +1,60 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../SimpleStagedExample.mls" as SimpleStagedExample__Legacy +module SimpleStagedExample with + class Bar(val x) with + () + fun bar() = x + class Foo(val x) with + () + fun foo(b) = + let {tmp, tmp1} + if b is + 1 then + tmp = x.bar() + tmp + 1 + 2 then + tmp1 = x.bar() + tmp1 + 2 + else x.bar() + fun baz() = 2 + fun bazbaz(x) = not x + fun f(x, y) = x + y + fun fib(n) = + let {n1, tmp2, tmp3, tmp4, tmp5} + if n is + 1 then 1 + 2 then 1 + else + n1 = n + tmp2 = n1 - 1 + tmp3 = fib(tmp2) + tmp4 = n1 - 2 + tmp5 = fib(tmp4) + tmp3 + tmp5 + fun foo() = 60 + fun foobar(x) = + let {y1, z, tmp10, tmp11} + if x is + 0 then + tmp10 = 1 + else + tmp10 = 0 + y1 = tmp10 + tmp11 = 0 + z = 0 + y1 + 0 + fun spaces() = ["\t", "\n", "\r"] +open SimpleStagedExample +fun f_SimpleStagedExample_sp_0(x, y) = 5 +fun fib_SimpleStagedExample_sp_0(n) = 55 +fun fib_SimpleStagedExample_sp_1(n) = 34 +fun fib_SimpleStagedExample_sp_2(n) = 21 +fun fib_SimpleStagedExample_sp_3(n) = 13 +fun fib_SimpleStagedExample_sp_4(n) = 8 +fun fib_SimpleStagedExample_sp_5(n) = 5 +fun fib_SimpleStagedExample_sp_6(n) = 3 +fun fib_SimpleStagedExample_sp_7(n) = 2 +fun fib_SimpleStagedExample_sp_8(n) = 1 +fun fib_SimpleStagedExample_sp_9(n) = 1 +fun bar_Bar_sp_0(self) = 1 +fun foo_Foo_sp_0(self, b) = 2 \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/StagedClass.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/StagedClass.mls new file mode 100644 index 0000000000..051a586782 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/StagedClass.mls @@ -0,0 +1,69 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../StagedClass.mls" as StagedClass__Legacy +module StagedClass with + class Foo + class Bar(val x) with + fun f(y, z) = + let {tmp} + tmp = x + y + tmp + z + class Baz(val x) with + () + class FooBar(val x) with + () + class B() with + () + class D() extends B() with + () + class C() with + () + fun h() = new D() + class X(val x) with + () + fun f(y) = + let {scrut} + scrut = <(x, y) + if scrut is + true then new Bar(x) + else new Bar(y) + fun g(y) = + let {tmp1} + tmp1 = x + y + X."Helper$X".foo(tmp1) + fun h(y) = + let {tmp2} + tmp2 = x + y + helpFoo(tmp2) + fun bar(b) = + if b is + true then Bar(0) + else new Bar.class(1) + fun baz(b) = + if b is + true then Baz(1) + else new Baz.class(2) + fun f(x) = + let {x__, y4, arg_Baz_0_, arg_Bar_0_} + if x is + Foo then 0 + Bar then + arg_Bar_0_ = x.x + x__ = arg_Bar_0_ + x__ + Baz then + arg_Baz_0_ = x.x + y4 = arg_Baz_0_ + y4 + 1 + else -1 + fun foo() = new Foo() + fun g() = new D() + fun helpFoo(x) = StagedClass__Legacy."Helper$StagedClass".foo(x) + fun xx() = + let {tmp3} + tmp3 = new X(0) + f_X_sp_0(tmp3, 1) +open StagedClass +fun f_X_sp_0(self, y) = + let {scrut} + scrut = true + new Bar(self.x) \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/StagedRegExp.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/StagedRegExp.mls new file mode 100644 index 0000000000..68f5fc1c91 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/StagedRegExp.mls @@ -0,0 +1,2628 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../StagedRegExp.mls" as StagedRegExp__Legacy +module StagedRegExp with + class Some(val x) + class None + class DedupSet(val arr) with + () + fun add(e) = + let {tmp4} + tmp4 = len(arr) + addImp(e, tmp4) + fun addImp(e, i) = + let {s, scrut, e__, scrut1, tmp, tmp1, tmp2, tmp3} + s = len(arr) + tmp = s - i + scrut = ==(tmp, s) + if scrut is + true then + tmp1 = push(arr, e) + new DedupSet(tmp1) + else + tmp2 = s - i + e__ = arr.(tmp2) + scrut1 = e.eq(e__) + if scrut1 is + true then this + else + tmp3 = i - 1 + addImp(e, tmp3) + class RegExp() with + () + class Nothing() extends RegExp() with + () + fun canBeEmpty() = false + fun derive(c) = this + fun eq(other) = + if other is + Nothing then true + else false + fun normalize() = this + fun startsWith(c) = false + class Empty() extends RegExp() with + () + fun canBeEmpty() = true + fun derive(c) = new Nothing() + fun eq(other) = + if other is + Empty then true + else false + fun normalize() = this + fun startsWith(c) = false + class Exact(val ch) extends RegExp() with + () + fun canBeEmpty() = false + fun derive(c) = + let {scrut2} + scrut2 = startsWith(c) + if scrut2 is + true then new Empty() + else new Nothing() + fun eq(other) = + let {ch__, arg_Exact_0_} + if other is + Exact then + arg_Exact_0_ = other.ch + ch__ = arg_Exact_0_ + ==(ch, ch__) + else false + fun normalize() = this + fun startsWith(c) = ==(ch, c) + class Any() extends RegExp() with + () + fun canBeEmpty() = false + fun derive(c) = new Empty() + fun eq(other) = + if other is + Any then true + else false + fun normalize() = this + fun startsWith(c) = true + class Not(val chars) extends RegExp() with + () + fun canBeEmpty() = false + fun derive(c) = + let {scrut3} + scrut3 = startsWith(c) + if scrut3 is + true then new Empty() + else new Nothing() + fun eq(other) = + let {chars__, arg_Not_0_} + if other is + Not then + arg_Not_0_ = other.chars + chars__ = arg_Not_0_ + arrEq(chars, chars__) + else false + fun normalize() = this + fun startsWith(c) = + let {tmp5} + tmp5 = has(chars, c) + not tmp5 + class Union(val p1, val p2) extends RegExp() with + () + fun canBeEmpty() = + let {tmp9} + tmp9 = p1.canBeEmpty() + if tmp9 is + false then p2.canBeEmpty() + else true + fun derive(c) = + let {tmp6, tmp7, tmp8} + tmp6 = p1.derive(c) + tmp7 = p2.derive(c) + tmp8 = new Union(tmp6, tmp7) + normalize_Union_sp_0(tmp8) + fun eq(other) = + let {n, tmp23, tmp24, tmp25} + n = other.normalize() + if n is + Union then + tmp23 = normalize() + tmp24 = tmp23.flat() + tmp25 = flat_Union_sp_0(n) + setEq(tmp24, tmp25) + else false + fun flat() = + let {p1__, scrut4, p2__, scrut5, tmp10, tmp11} + scrut4 = p1 + if scrut4 is + Union then + tmp10 = p1.flat() + else + tmp10 = [p1] + p1__ = tmp10 + scrut5 = p2 + if scrut5 is + Union then + tmp11 = p2.flat() + else + tmp11 = [p2] + p2__ = tmp11 + concat(p1__, p2__) + fun iter(st, arr, i, s) = + let {scrut6, tmp12, tmp13, tmp14, tmp15} + tmp12 = s - i + scrut6 = ==(tmp12, s) + if scrut6 is + true then st + else + tmp13 = s - i + tmp14 = st.add(arr.(tmp13)) + tmp15 = i - 1 + iter(tmp14, arr, tmp15, s) + fun normalize() = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = p1.normalize() + p2__1 = p2.normalize() + if p1__1 is + Union then + tmp16 = flat_Union_sp_0(p1__1) + else + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) + fun startsWith(c) = + let {tmp26} + tmp26 = p1.startsWith(c) + if tmp26 is + false then p2.startsWith(c) + else true + class In(val chars) extends RegExp() with + () + fun canBeEmpty() = false + fun derive(c) = + let {scrut7} + scrut7 = startsWith(c) + if scrut7 is + true then new Empty() + else new Nothing() + fun eq(other) = + let {chars__1, arg_In_0_} + if other is + In then + arg_In_0_ = other.chars + chars__1 = arg_In_0_ + arrEq(chars, chars__1) + else false + fun normalize() = this + fun startsWith(c) = has(chars, c) + class Concat(val p1, val p2) extends RegExp() with + () + fun canBeEmpty() = + let {scrut9, scrut10} + scrut9 = p1.canBeEmpty() + if scrut9 is + true then + scrut10 = p2.canBeEmpty() + if scrut10 is + true then true + else false + else false + fun derive(c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = p1.derive(c) + scrut8 = p1.canBeEmpty() + if scrut8 is + true then + tmp27 = new Concat.class(p1__2, p2) + tmp28 = p2.derive(c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_1(tmp29) + else + tmp30 = new Concat.class(p1__2, p2) + normalize_Concat_sp_0(tmp30) + fun eq(other) = + let {p2__2, p1__4, scrut11, scrut12, arg_Concat_0_, arg_Concat_1_} + if other is + Concat then + arg_Concat_0_ = other.p1 + arg_Concat_1_ = other.p2 + p2__2 = arg_Concat_1_ + p1__4 = arg_Concat_0_ + scrut11 = p1.eq(p1__4) + if scrut11 is + true then + scrut12 = p2.eq(p2__2) + if scrut12 is + true then true + else false + else false + else false + fun normalize() = + let {p1__3, tmp31} + p1__3 = p1.normalize() + if p1__3 is + Empty then p2.normalize() + Nothing then p1__3 + else + tmp31 = p2.normalize() + new Concat.class(p1__3, tmp31) + fun startsWith(c) = + let {scrut13, scrut14, tmp32} + tmp32 = p1.startsWith(c) + if tmp32 is + false then + scrut13 = p1.canBeEmpty() + if scrut13 is + true then + scrut14 = p2.startsWith(c) + if scrut14 is + true then true + else false + else false + else true + class Star(val p) extends RegExp() with + () + fun canBeEmpty() = true + fun derive(c) = + let {tmp33, tmp34, tmp35} + tmp33 = p.derive(c) + tmp34 = new Star.class(p) + tmp35 = new Concat(tmp33, tmp34) + normalize_Concat_sp_1(tmp35) + fun eq(other) = + let {p__, arg_Star_0_} + if other is + Star then + arg_Star_0_ = other.p + p__ = arg_Star_0_ + p.eq(p__) + else false + fun normalize() = + let {tmp36} + tmp36 = p.normalize() + new Star(tmp36) + fun startsWith(c) = p.startsWith(c) + fun arrEq(arr1, arr2) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".eq(arr1, arr2) + fun concat(lhs, rhs) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".concat(lhs, rhs) + fun digits() = + let {tmp51, tup_6} + tup_6 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] + tmp51 = tup_6 + new In(tmp51) + fun has(arr, ele) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".has(arr, ele) + fun len(s) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".len(s) + fun match(p, s) = matchImpl_StagedRegExp_sp_0(p, s, "") + fun matchAll(p, s) = + let {tmp66} + tmp66 = [] + matchAllImpl_StagedRegExp_sp_0(p, s, tmp66) + fun matchAllEmail(s) = + let {p7, email, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tup_7, tup_8} + tup_7 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + tmp67 = tup_7 + tmp68 = ["-", "."] + tup_8 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "-", "."] + tmp69 = tup_8 + tmp70 = new In(tmp69) + p7 = plus_StagedRegExp_sp_0(tmp70) + tmp71 = new Exact("@") + tmp72 = new Exact(".") + tmp73 = new Concat(tmp72, p7) + tmp74 = new Concat(p7, tmp73) + tmp75 = new Concat(tmp71, tmp74) + email = new Concat(p7, tmp75) + matchAll_StagedRegExp_sp_0(email, s) + fun matchAllIPv4(s) = + let {fo, fi, segment, ipv4, tmp102, tmp103, tmp104, tmp105, tmp106, tmp107, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122} + tmp102 = ["0", "1", "2", "3", "4"] + fo = new In(tmp102) + tmp103 = ["0", "1", "2", "3", "4", "5"] + fi = new In(tmp103) + tmp104 = new Exact("2") + tmp105 = new Exact("5") + tmp106 = new Concat(tmp105, fi) + tmp107 = new Concat(tmp104, tmp106) + tmp108 = new Exact("2") + tmp109 = digits() + tmp110 = new Concat(fo, tmp109) + tmp111 = new Concat(tmp108, tmp110) + tmp112 = new Exact("1") + tmp113 = question_StagedRegExp_sp_2(tmp112) + tmp114 = digits() + tmp115 = question_StagedRegExp_sp_3(tmp114) + tmp116 = digits() + tmp117 = new Concat(tmp115, tmp116) + tmp118 = new Concat(tmp113, tmp117) + tmp119 = new Union(tmp111, tmp118) + segment = new Union(tmp107, tmp119) + tmp120 = new Exact(".") + tmp121 = new Concat(segment, tmp120) + tmp122 = nTimes_StagedRegExp_sp_0(tmp121, 3) + ipv4 = new Concat(tmp122, segment) + matchAll_StagedRegExp_sp_2(ipv4, s) + fun matchAllImpl(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl(p, tmp65, res) + fun matchAllURI(s) = + let {n1, n2, n3, w, d, p8, head, body, params, uri, tmp76, tmp77, tmp78, tmp79, tmp80, tmp81, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87, tmp88, tmp89, tmp90, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tup_9, tup_10, tup_11, tup_12} + tmp76 = ["/", "?", "#", " ", "\n", "\t", "\r"] + n1 = new Not(tmp76) + tmp77 = ["?", "#", " ", "\n", "\t", "\r"] + n2 = new Not(tmp77) + tmp78 = ["#", " ", "\n", "\t", "\r"] + n3 = new Not(tmp78) + w = words() + d = digits() + tup_9 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + tmp79 = tup_9 + tup_10 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] + tmp80 = tup_10 + tmp81 = ["-", "_"] + tup_11 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "_"] + tmp82 = tup_11 + tup_12 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "_"] + p8 = tup_12 + tmp83 = plus_StagedRegExp_sp_1(w) + tmp84 = new Exact(":") + tmp85 = new Exact("/") + tmp86 = new Exact("/") + tmp87 = new Concat(tmp85, tmp86) + tmp88 = new Concat(tmp84, tmp87) + head = new Concat(tmp83, tmp88) + tmp89 = plus_StagedRegExp_sp_2(n1) + tmp90 = plus_StagedRegExp_sp_3(n2) + body = new Concat(tmp89, tmp90) + tmp91 = new Exact("?") + tmp92 = new In(p8) + tmp93 = new Star(tmp92) + tmp94 = new Concat(tmp91, tmp93) + tmp95 = question_StagedRegExp_sp_0(tmp94) + tmp96 = new Exact("#") + tmp97 = new In(p8) + tmp98 = new Star(tmp97) + tmp99 = new Concat(tmp96, tmp98) + tmp100 = question_StagedRegExp_sp_1(tmp99) + params = new Concat(tmp95, tmp100) + tmp101 = new Concat(body, params) + uri = new Concat(head, tmp101) + matchAll_StagedRegExp_sp_1(uri, s) + fun matchImpl(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + scrut19 = p.canBeEmpty() + if scrut19 is + true then new Some(acc) + else new None() + else + if p is + Nothing then new None() + else + c18 = s.0 + scrut20 = p.startsWith(c18) + if scrut20 is + true then + tmp56 = p.derive(c18) + tmp57 = s.slice(1) + tmp58 = acc + c18 + matchImpl(tmp56, tmp57, tmp58) + else + scrut21 = p.canBeEmpty() + if scrut21 is + true then new Some(acc) + else new None() + fun mkUnion(arr, i, s) = + let {scrut15, scrut16, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp46, tmp47} + tmp40 = s - i + tmp41 = s - 1 + scrut15 = ==(tmp40, tmp41) + if scrut15 is + true then + tmp42 = s - i + arr.(tmp42) + else + tmp43 = s - i + scrut16 = arr.(tmp43) + if scrut16 is + Nothing then + tmp44 = i - 1 + mkUnion(arr, tmp44, s) + else + tmp45 = s - i + tmp46 = i - 1 + tmp47 = mkUnion(arr, tmp46, s) + new Union(arr.(tmp45), tmp47) + fun nTimes(r, i) = + let {scrut17, tmp52, tmp53} + scrut17 = ==(i, 1) + if scrut17 is + true then r + else + tmp52 = i - 1 + tmp53 = nTimes(r, tmp52) + new Concat(r, tmp53) + fun notDigit() = + let {tmp39, tup_3} + tup_3 = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"] + tmp39 = tup_3 + new Not(tmp39) + fun notSpace() = + let {tmp38, tup_2} + tup_2 = [" ", "\n", "\t", "\r"] + tmp38 = tup_2 + new Not(tmp38) + fun notWord() = + let {tmp37, tup_1} + tup_1 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + tmp37 = tup_1 + new Not(tmp37) + fun plus(r) = + let {tmp54} + tmp54 = new Star(r) + new Concat(r, tmp54) + fun push(arr, ele) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(arr, ele) + fun question(r) = + let {tmp48} + tmp48 = new Empty() + new Union(r, tmp48) + fun setEq(s1, s2) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".setEq(s1, s2) + fun spaces() = + let {tmp50, tup_5} + tup_5 = [" ", "\n", "\t", "\r"] + tmp50 = tup_5 + new In(tmp50) + fun words() = + let {tmp49, tup_4} + tup_4 = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] + tmp49 = tup_4 + new In(tmp49) +open StagedRegExp +fun has_StagedRegExp_sp_0(arr, ele) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".has(arr, ele) +fun has_StagedRegExp_sp_1(arr, ele) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".has(arr, ele) +fun has_StagedRegExp_sp_2(arr, ele) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".has(arr, ele) +fun len_StagedRegExp_sp_0(s) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".len(s) +fun len_StagedRegExp_sp_1(s) = 1 +fun len_StagedRegExp_sp_2(s) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".len(s) +fun len_StagedRegExp_sp_3(s) = 1 +fun len_StagedRegExp_sp_4(s) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".len(s) +fun len_StagedRegExp_sp_5(s) = StagedRegExp__Legacy."SeqHelper$StagedRegExp".len(s) +fun matchAllImpl_StagedRegExp_sp_0(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl_StagedRegExp_sp_0(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl_StagedRegExp_sp_0(p, tmp65, res) +fun matchAllImpl_StagedRegExp_sp_1(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match_StagedRegExp_sp_0(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl_StagedRegExp_sp_2(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl_StagedRegExp_sp_1(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl_StagedRegExp_sp_1(p, tmp65, res) +fun matchAllImpl_StagedRegExp_sp_2(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match_StagedRegExp_sp_0(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl_StagedRegExp_sp_2(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl_StagedRegExp_sp_2(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl_StagedRegExp_sp_2(p, tmp65, res) +fun matchAllImpl_StagedRegExp_sp_3(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match_StagedRegExp_sp_1(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl_StagedRegExp_sp_4(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl_StagedRegExp_sp_3(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl_StagedRegExp_sp_3(p, tmp65, res) +fun matchAllImpl_StagedRegExp_sp_4(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match_StagedRegExp_sp_1(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl_StagedRegExp_sp_4(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl_StagedRegExp_sp_4(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl_StagedRegExp_sp_4(p, tmp65, res) +fun matchAllImpl_StagedRegExp_sp_5(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match_StagedRegExp_sp_2(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl_StagedRegExp_sp_6(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl_StagedRegExp_sp_5(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl_StagedRegExp_sp_5(p, tmp65, res) +fun matchAllImpl_StagedRegExp_sp_6(p, s, res) = + let {scrut22, scrut23, ss, scrut24, tmp59, arg_Some_0_, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65} + tmp59 = len(s) + scrut22 = ==(tmp59, 0) + if scrut22 is + true then res + else + scrut23 = match_StagedRegExp_sp_2(p, s) + if scrut23 is + Some then + arg_Some_0_ = scrut23.x + ss = arg_Some_0_ + tmp60 = len(ss) + scrut24 = >(tmp60, 0) + if scrut24 is + true then + tmp61 = len(ss) + tmp62 = s.slice(tmp61) + tmp63 = StagedRegExp__Legacy."SeqHelper$StagedRegExp".push(res, ss) + matchAllImpl_StagedRegExp_sp_6(p, tmp62, tmp63) + else + tmp64 = s.slice(1) + matchAllImpl_StagedRegExp_sp_6(p, tmp64, res) + else + tmp65 = s.slice(1) + matchAllImpl_StagedRegExp_sp_6(p, tmp65, res) +fun matchAll_StagedRegExp_sp_0(p, s) = + let {tmp66} + tmp66 = [] + matchAllImpl_StagedRegExp_sp_1(p, s, tmp66) +fun matchAll_StagedRegExp_sp_1(p, s) = + let {tmp66} + tmp66 = [] + matchAllImpl_StagedRegExp_sp_3(p, s, tmp66) +fun matchAll_StagedRegExp_sp_2(p, s) = + let {tmp66} + tmp66 = [] + matchAllImpl_StagedRegExp_sp_5(p, s, tmp66) +fun matchImpl_StagedRegExp_sp_0(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + scrut19 = p.canBeEmpty() + if scrut19 is + true then new Some(acc) + else new None() + else + if p is + Nothing then new None() + else + c18 = s.0 + scrut20 = p.startsWith(c18) + if scrut20 is + true then + tmp56 = p.derive(c18) + tmp57 = s.slice(1) + tmp58 = "" + c18 + matchImpl(tmp56, tmp57, tmp58) + else + scrut21 = p.canBeEmpty() + if scrut21 is + true then new Some(acc) + else new None() +fun matchImpl_StagedRegExp_sp_1(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + scrut19 = canBeEmpty_Concat_sp_0(p) + new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_0(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_0(p, c18) + tmp57 = s.slice(1) + tmp58 = "" + c18 + matchImpl_StagedRegExp_sp_2(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_0(p) + new None() +fun matchImpl_StagedRegExp_sp_2(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + if p is + Nothing then + scrut19 = canBeEmpty_Nothing_sp_0(p) + Concat then + scrut19 = canBeEmpty_Concat_sp_2(p) + new None() + else + if p is + Nothing then new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_2(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_2(p, c18) + tmp57 = s.slice(1) + tmp58 = acc + c18 + matchImpl(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_2(p) + new None() +fun matchImpl_StagedRegExp_sp_3(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + scrut19 = canBeEmpty_Concat_sp_4(p) + new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_4(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_4(p, c18) + tmp57 = s.slice(1) + tmp58 = "" + c18 + matchImpl_StagedRegExp_sp_4(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_4(p) + new None() +fun matchImpl_StagedRegExp_sp_4(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + if p is + Nothing then + scrut19 = canBeEmpty_Nothing_sp_0(p) + Concat then + scrut19 = canBeEmpty_Concat_sp_7(p) + new None() + else + if p is + Nothing then new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_7(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_7(p, c18) + tmp57 = s.slice(1) + tmp58 = acc + c18 + matchImpl_StagedRegExp_sp_5(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_7(p) + new None() +fun matchImpl_StagedRegExp_sp_5(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + if p is + Concat then + scrut19 = canBeEmpty_Concat_sp_10(p) + Nothing then + scrut19 = canBeEmpty_Nothing_sp_0(p) + if scrut19 is + true then new Some(acc) + else new None() + else + if p is + Nothing then new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_10(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_10(p, c18) + tmp57 = s.slice(1) + tmp58 = acc + c18 + matchImpl(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_10(p) + if scrut21 is + true then new Some(acc) + else new None() +fun matchImpl_StagedRegExp_sp_6(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + scrut19 = canBeEmpty_Concat_sp_11(p) + new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_11(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_11(p, c18) + tmp57 = s.slice(1) + tmp58 = "" + c18 + matchImpl_StagedRegExp_sp_7(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_11(p) + new None() +fun matchImpl_StagedRegExp_sp_7(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + if p is + Nothing then + scrut19 = canBeEmpty_Nothing_sp_1(p) + Concat then + scrut19 = canBeEmpty_Concat_sp_18(p) + new None() + else + if p is + Nothing then new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_18(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_18(p, c18) + tmp57 = s.slice(1) + tmp58 = acc + c18 + matchImpl_StagedRegExp_sp_8(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_18(p) + new None() +fun matchImpl_StagedRegExp_sp_8(p, s, acc) = + let {scrut18, scrut19, c18, scrut20, scrut21, tmp55, tmp56, tmp57, tmp58} + tmp55 = len(s) + scrut18 = ==(tmp55, 0) + if scrut18 is + true then + if p is + Nothing then + scrut19 = canBeEmpty_Nothing_sp_2(p) + Concat then + scrut19 = canBeEmpty_Concat_sp_21(p) + new None() + else + if p is + Nothing then new None() + else + c18 = s.0 + scrut20 = startsWith_Concat_sp_21(p, c18) + if scrut20 is + true then + tmp56 = derive_Concat_sp_21(p, c18) + tmp57 = s.slice(1) + tmp58 = acc + c18 + matchImpl(tmp56, tmp57, tmp58) + else + scrut21 = canBeEmpty_Concat_sp_21(p) + new None() +fun match_StagedRegExp_sp_0(p, s) = matchImpl_StagedRegExp_sp_1(p, s, "") +fun match_StagedRegExp_sp_1(p, s) = matchImpl_StagedRegExp_sp_3(p, s, "") +fun match_StagedRegExp_sp_2(p, s) = matchImpl_StagedRegExp_sp_6(p, s, "") +fun nTimes_StagedRegExp_sp_0(r, i) = + let {scrut17, tmp52, tmp53} + scrut17 = false + tmp52 = 2 + tmp53 = nTimes_StagedRegExp_sp_1(r, tmp52) + new Concat(r, tmp53) +fun nTimes_StagedRegExp_sp_1(r, i) = + let {scrut17, tmp52, tmp53} + scrut17 = false + tmp52 = 1 + tmp53 = nTimes_StagedRegExp_sp_2(r, tmp52) + new Concat(r, tmp53) +fun nTimes_StagedRegExp_sp_2(r, i) = + let {scrut17, tmp52, tmp53} + scrut17 = true + r +fun plus_StagedRegExp_sp_0(r) = + let {tmp54} + tmp54 = new Star(r) + new Concat(r, tmp54) +fun plus_StagedRegExp_sp_1(r) = + let {tmp54} + tmp54 = new Star(r) + new Concat(r, tmp54) +fun plus_StagedRegExp_sp_2(r) = + let {tmp54} + tmp54 = new Star(r) + new Concat(r, tmp54) +fun plus_StagedRegExp_sp_3(r) = + let {tmp54} + tmp54 = new Star(r) + new Concat(r, tmp54) +fun question_StagedRegExp_sp_0(r) = + let {tmp48} + tmp48 = new Empty() + new Union(r, tmp48) +fun question_StagedRegExp_sp_1(r) = + let {tmp48} + tmp48 = new Empty() + new Union(r, tmp48) +fun question_StagedRegExp_sp_2(r) = + let {tmp48} + tmp48 = new Empty() + new Union(r, tmp48) +fun question_StagedRegExp_sp_3(r) = + let {tmp48} + tmp48 = new Empty() + new Union(r, tmp48) +fun canBeEmpty_Nothing_sp_0(self) = false +fun canBeEmpty_Nothing_sp_1(self) = false +fun canBeEmpty_Nothing_sp_2(self) = false +fun canBeEmpty_Nothing_sp_3(self) = false +fun derive_Nothing_sp_0(self, c) = self +fun derive_Nothing_sp_1(self, c) = self +fun normalize_Nothing_sp_0(self) = self +fun normalize_Nothing_sp_1(self) = self +fun normalize_Nothing_sp_2(self) = self +fun startsWith_Nothing_sp_0(self, c) = false +fun startsWith_Nothing_sp_1(self, c) = false +fun canBeEmpty_Empty_sp_0(self) = true +fun derive_Empty_sp_0(self, c) = new Nothing() +fun normalize_Empty_sp_0(self) = self +fun startsWith_Empty_sp_0(self, c) = false +fun canBeEmpty_Exact_sp_0(self) = false +fun canBeEmpty_Exact_sp_1(self) = false +fun canBeEmpty_Exact_sp_2(self) = false +fun canBeEmpty_Exact_sp_3(self) = false +fun canBeEmpty_Exact_sp_4(self) = false +fun canBeEmpty_Exact_sp_5(self) = false +fun derive_Exact_sp_0(self, c) = + let {scrut2} + scrut2 = self.startsWith(c) + if scrut2 is + true then new Empty() + else new Nothing() +fun derive_Exact_sp_1(self, c) = + let {scrut2} + scrut2 = self.startsWith(c) + if scrut2 is + true then new Empty() + else new Nothing() +fun derive_Exact_sp_2(self, c) = + let {scrut2} + scrut2 = self.startsWith(c) + if scrut2 is + true then new Empty() + else new Nothing() +fun derive_Exact_sp_3(self, c) = + let {scrut2} + scrut2 = self.startsWith(c) + if scrut2 is + true then new Empty() + else new Nothing() +fun derive_Exact_sp_4(self, c) = + let {scrut2} + scrut2 = self.startsWith(c) + if scrut2 is + true then new Empty() + else new Nothing() +fun derive_Exact_sp_5(self, c) = + let {scrut2} + scrut2 = self.startsWith(c) + if scrut2 is + true then new Empty() + else new Nothing() +fun normalize_Exact_sp_0(self) = self +fun normalize_Exact_sp_1(self) = self +fun normalize_Exact_sp_10(self) = self +fun normalize_Exact_sp_2(self) = self +fun normalize_Exact_sp_3(self) = self +fun normalize_Exact_sp_4(self) = self +fun normalize_Exact_sp_5(self) = self +fun normalize_Exact_sp_6(self) = self +fun normalize_Exact_sp_7(self) = self +fun normalize_Exact_sp_8(self) = self +fun normalize_Exact_sp_9(self) = self +fun startsWith_Exact_sp_0(self, c) = ==("@", c) +fun startsWith_Exact_sp_1(self, c) = ==(":", c) +fun startsWith_Exact_sp_2(self, c) = ==("2", c) +fun startsWith_Exact_sp_3(self, c) = ==("2", c) +fun startsWith_Exact_sp_4(self, c) = ==("1", c) +fun startsWith_Exact_sp_5(self, c) = ==(".", c) +fun normalize_Not_sp_0(self) = self +fun normalize_Not_sp_1(self) = self +fun canBeEmpty_Union_sp_0(self) = false +fun canBeEmpty_Union_sp_1(self) = false +fun canBeEmpty_Union_sp_2(self) = true +fun canBeEmpty_Union_sp_3(self) = true +fun derive_Union_sp_0(self, c) = + let {tmp6, tmp7, tmp8} + tmp6 = derive_Concat_sp_14(self.p1, c) + tmp7 = derive_Union_sp_1(self.p2, c) + tmp8 = new Union(tmp6, tmp7) + normalize_Union_sp_11(tmp8) +fun derive_Union_sp_1(self, c) = + let {tmp6, tmp7, tmp8} + tmp6 = derive_Concat_sp_15(self.p1, c) + tmp7 = derive_Concat_sp_16(self.p2, c) + tmp8 = new Union(tmp6, tmp7) + normalize_Union_sp_10(tmp8) +fun derive_Union_sp_2(self, c) = + let {tmp6, tmp7, tmp8} + tmp6 = derive_Exact_sp_4(self.p1, c) + tmp7 = derive_Empty_sp_0(self.p2, c) + tmp8 = new Union(tmp6, tmp7) + normalize_Union_sp_6(tmp8) +fun derive_Union_sp_3(self, c) = + let {tmp6, tmp7, tmp8} + tmp6 = derive_In_sp_2(self.p1, c) + tmp7 = derive_Empty_sp_0(self.p2, c) + tmp8 = new Union(tmp6, tmp7) + normalize_Union_sp_6(tmp8) +fun flat_Union_sp_0(self) = + let {p1__, scrut4, p2__, scrut5, tmp10, tmp11} + scrut4 = self.p1 + if scrut4 is + Union then + tmp10 = self.p1.flat() + else + tmp10 = [self.p1] + p1__ = tmp10 + scrut5 = self.p2 + if scrut5 is + Union then + tmp11 = self.p2.flat() + else + tmp11 = [self.p2] + p2__ = tmp11 + concat(p1__, p2__) +fun normalize_Union_sp_0(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = self.p1.normalize() + p2__1 = self.p2.normalize() + if p1__1 is + Union then + tmp16 = flat_Union_sp_0(p1__1) + else + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_1(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_0(self.p1) + p2__1 = self.p2.normalize() + if p1__1 is + Union then + tmp16 = flat_Union_sp_0(p1__1) + else + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_10(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + if self.p1 is + Concat then + p1__1 = normalize_Concat_sp_45(self.p1) + Nothing then + p1__1 = normalize_Nothing_sp_0(self.p1) + p2__1 = self.p2.normalize() + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_11(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + if self.p1 is + Concat then + p1__1 = normalize_Concat_sp_46(self.p1) + Nothing then + p1__1 = normalize_Nothing_sp_0(self.p1) + p2__1 = self.p2.normalize() + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_12(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_51(self.p1) + p2__1 = normalize_Union_sp_13(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_13(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_52(self.p1) + p2__1 = normalize_Concat_sp_53(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_5(arr2) + tmp20 = len_StagedRegExp_sp_5(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_14(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Exact_sp_10(self.p1) + p2__1 = normalize_Empty_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_1(arr2) + tmp20 = len_StagedRegExp_sp_1(arr2) + s2 = self.iter(tmp18, arr2, 1, 1) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_15(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_47(self.p1) + if self.p2 is + Empty then + p2__1 = normalize_Empty_sp_0(self.p2) + Nothing then + p2__1 = normalize_Nothing_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_4(arr2) + tmp20 = len_StagedRegExp_sp_4(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_16(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_62(self.p1) + p2__1 = self.p2.normalize() + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_17(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_63(self.p1) + p2__1 = self.p2.normalize() + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_2(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_13(self.p1) + if self.p2 is + Concat then + p2__1 = normalize_Concat_sp_10(self.p2) + Nothing then + p2__1 = normalize_Nothing_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_0(arr2) + tmp20 = len_StagedRegExp_sp_0(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_3(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_28(self.p1) + p2__1 = normalize_Empty_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_1(arr2) + tmp20 = len_StagedRegExp_sp_1(arr2) + s2 = self.iter(tmp18, arr2, 1, 1) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_4(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_29(self.p1) + p2__1 = normalize_Empty_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_1(arr2) + tmp20 = len_StagedRegExp_sp_1(arr2) + s2 = self.iter(tmp18, arr2, 1, 1) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_5(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_32(self.p1) + if self.p2 is + Concat then + p2__1 = normalize_Concat_sp_22(self.p2) + Nothing then + p2__1 = normalize_Nothing_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_2(arr2) + tmp20 = len_StagedRegExp_sp_2(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_6(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + if self.p1 is + Empty then + p1__1 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__1 = normalize_Nothing_sp_0(self.p1) + p2__1 = normalize_Nothing_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_3(arr2) + tmp20 = len_StagedRegExp_sp_3(arr2) + s2 = self.iter(tmp18, arr2, 1, 1) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_7(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_42(self.p1) + if self.p2 is + Empty then + p2__1 = normalize_Empty_sp_0(self.p2) + Nothing then + p2__1 = normalize_Nothing_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_4(arr2) + tmp20 = len_StagedRegExp_sp_4(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_8(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_Concat_sp_43(self.p1) + p2__1 = self.p2.normalize() + tmp16 = [p1__1] + arr11 = tmp16 + if p2__1 is + Union then + tmp17 = flat_Union_sp_0(p2__1) + else + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len(arr2) + tmp20 = len(arr2) + s2 = self.iter(tmp18, arr2, tmp19, tmp20) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun normalize_Union_sp_9(self) = + let {p1__1, p2__1, arr11, arr2, s2, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22} + p1__1 = normalize_In_sp_6(self.p1) + p2__1 = normalize_Empty_sp_0(self.p2) + tmp16 = [p1__1] + arr11 = tmp16 + tmp17 = [p2__1] + arr2 = tmp17 + tmp18 = new DedupSet(arr11) + tmp19 = len_StagedRegExp_sp_1(arr2) + tmp20 = len_StagedRegExp_sp_1(arr2) + s2 = self.iter(tmp18, arr2, 1, 1) + tmp21 = len(s2.arr) + tmp22 = len(s2.arr) + mkUnion(s2.arr, tmp21, tmp22) +fun startsWith_Union_sp_0(self, c) = + let {tmp26} + tmp26 = startsWith_Concat_sp_14(self.p1, c) + if tmp26 is + false then startsWith_Union_sp_1(self.p2, c) + else true +fun startsWith_Union_sp_1(self, c) = + let {tmp26} + tmp26 = startsWith_Concat_sp_15(self.p1, c) + if tmp26 is + false then startsWith_Concat_sp_16(self.p2, c) + else true +fun startsWith_Union_sp_2(self, c) = + let {tmp26} + tmp26 = startsWith_Exact_sp_4(self.p1, c) + if tmp26 is + false then startsWith_Empty_sp_0(self.p2, c) + else true +fun startsWith_Union_sp_3(self, c) = + let {tmp26} + tmp26 = startsWith_In_sp_2(self.p1, c) + if tmp26 is + false then startsWith_Empty_sp_0(self.p2, c) + else true +fun canBeEmpty_In_sp_0(self) = false +fun canBeEmpty_In_sp_1(self) = false +fun canBeEmpty_In_sp_2(self) = false +fun derive_In_sp_0(self, c) = + let {scrut7} + scrut7 = self.startsWith(c) + if scrut7 is + true then new Empty() + else new Nothing() +fun derive_In_sp_1(self, c) = + let {scrut7} + scrut7 = self.startsWith(c) + if scrut7 is + true then new Empty() + else new Nothing() +fun derive_In_sp_2(self, c) = + let {scrut7} + scrut7 = self.startsWith(c) + if scrut7 is + true then new Empty() + else new Nothing() +fun normalize_In_sp_0(self) = self +fun normalize_In_sp_1(self) = self +fun normalize_In_sp_2(self) = self +fun normalize_In_sp_3(self) = self +fun normalize_In_sp_4(self) = self +fun normalize_In_sp_5(self) = self +fun normalize_In_sp_6(self) = self +fun startsWith_In_sp_0(self, c) = has_StagedRegExp_sp_0(self.chars, c) +fun startsWith_In_sp_1(self, c) = has_StagedRegExp_sp_1(self.chars, c) +fun startsWith_In_sp_2(self, c) = has_StagedRegExp_sp_2(self.chars, c) +fun canBeEmpty_Concat_sp_0(self) = false +fun canBeEmpty_Concat_sp_1(self) = false +fun canBeEmpty_Concat_sp_10(self) = + let {scrut9, scrut10} + scrut9 = self.p1.canBeEmpty() + if scrut9 is + true then + scrut10 = self.p2.canBeEmpty() + if scrut10 is + true then true + else false + else false +fun canBeEmpty_Concat_sp_11(self) = false +fun canBeEmpty_Concat_sp_12(self) = false +fun canBeEmpty_Concat_sp_13(self) = false +fun canBeEmpty_Concat_sp_14(self) = false +fun canBeEmpty_Concat_sp_15(self) = false +fun canBeEmpty_Concat_sp_16(self) = false +fun canBeEmpty_Concat_sp_17(self) = false +fun canBeEmpty_Concat_sp_18(self) = false +fun canBeEmpty_Concat_sp_19(self) = false +fun canBeEmpty_Concat_sp_2(self) = false +fun canBeEmpty_Concat_sp_20(self) = false +fun canBeEmpty_Concat_sp_21(self) = false +fun canBeEmpty_Concat_sp_22(self) = false +fun canBeEmpty_Concat_sp_23(self) = false +fun canBeEmpty_Concat_sp_3(self) = false +fun canBeEmpty_Concat_sp_4(self) = false +fun canBeEmpty_Concat_sp_5(self) = false +fun canBeEmpty_Concat_sp_6(self) = false +fun canBeEmpty_Concat_sp_7(self) = false +fun canBeEmpty_Concat_sp_8(self) = false +fun canBeEmpty_Concat_sp_9(self) = false +fun derive_Concat_sp_0(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Concat_sp_1(self.p1, c) + scrut8 = canBeEmpty_Concat_sp_1(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_3(tmp30) +fun derive_Concat_sp_1(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_In_sp_0(self.p1, c) + scrut8 = canBeEmpty_In_sp_0(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_2(tmp30) +fun derive_Concat_sp_10(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = self.p1.derive(c) + scrut8 = self.p1.canBeEmpty() + if scrut8 is + true then + tmp27 = new Concat.class(p1__2, self.p2) + tmp28 = self.p2.derive(c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_1(tmp29) + else + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_0(tmp30) +fun derive_Concat_sp_11(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Concat_sp_12(self.p1, c) + scrut8 = canBeEmpty_Concat_sp_12(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_54(tmp30) +fun derive_Concat_sp_12(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Concat_sp_13(self.p1, c) + scrut8 = canBeEmpty_Concat_sp_13(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_48(tmp30) +fun derive_Concat_sp_13(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Union_sp_0(self.p1, c) + scrut8 = canBeEmpty_Union_sp_0(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_47(tmp30) +fun derive_Concat_sp_14(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Exact_sp_2(self.p1, c) + scrut8 = canBeEmpty_Exact_sp_2(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_38(tmp30) +fun derive_Concat_sp_15(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Exact_sp_3(self.p1, c) + scrut8 = canBeEmpty_Exact_sp_3(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_40(tmp30) +fun derive_Concat_sp_16(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Union_sp_2(self.p1, c) + scrut8 = canBeEmpty_Union_sp_2(self.p1) + tmp27 = new Concat.class(p1__2, self.p2) + tmp28 = derive_Concat_sp_17(self.p2, c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_8(tmp29) +fun derive_Concat_sp_17(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Union_sp_3(self.p1, c) + scrut8 = canBeEmpty_Union_sp_3(self.p1) + tmp27 = new Concat.class(p1__2, self.p2) + tmp28 = derive_In_sp_2(self.p2, c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_7(tmp29) +fun derive_Concat_sp_18(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Concat_sp_19(self.p1, c) + scrut8 = canBeEmpty_Concat_sp_19(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_59(tmp30) +fun derive_Concat_sp_19(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + if self.p1 is + Exact then + p1__2 = derive_Exact_sp_5(self.p1, c) + Concat then + p1__2 = derive_Concat_sp_20(self.p1, c) + if self.p1 is + Exact then + scrut8 = canBeEmpty_Exact_sp_5(self.p1) + Concat then + scrut8 = canBeEmpty_Concat_sp_20(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_57(tmp30) +fun derive_Concat_sp_2(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Star_sp_0(self.p1, c) + scrut8 = canBeEmpty_Star_sp_0(self.p1) + tmp27 = new Concat.class(p1__2, self.p2) + tmp28 = derive_Concat_sp_3(self.p2, c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_2(tmp29) +fun derive_Concat_sp_20(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = self.p1.derive(c) + scrut8 = self.p1.canBeEmpty() + if scrut8 is + true then + tmp27 = new Concat.class(p1__2, self.p2) + tmp28 = derive_Exact_sp_5(self.p2, c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_15(tmp29) + else + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_47(tmp30) +fun derive_Concat_sp_21(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + if self.p1 is + Exact then + p1__2 = derive_Exact_sp_5(self.p1, c) + Concat then + p1__2 = derive_Concat_sp_22(self.p1, c) + if self.p1 is + Exact then + scrut8 = canBeEmpty_Exact_sp_5(self.p1) + Concat then + scrut8 = canBeEmpty_Concat_sp_22(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_0(tmp30) +fun derive_Concat_sp_22(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = self.p1.derive(c) + scrut8 = self.p1.canBeEmpty() + if scrut8 is + true then + tmp27 = new Concat.class(p1__2, self.p2) + if self.p2 is + Exact then + tmp28 = derive_Exact_sp_5(self.p2, c) + Nothing then + tmp28 = derive_Nothing_sp_0(self.p2, c) + Concat then + tmp28 = derive_Concat_sp_23(self.p2, c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_17(tmp29) + else + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_63(tmp30) +fun derive_Concat_sp_23(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = self.p1.derive(c) + scrut8 = self.p1.canBeEmpty() + if scrut8 is + true then + tmp27 = new Concat.class(p1__2, self.p2) + if self.p2 is + Exact then + tmp28 = derive_Exact_sp_5(self.p2, c) + Nothing then + tmp28 = derive_Nothing_sp_1(self.p2, c) + Concat then + tmp28 = derive_Concat_sp_20(self.p2, c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_16(tmp29) + else + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_62(tmp30) +fun derive_Concat_sp_3(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Exact_sp_0(self.p1, c) + scrut8 = canBeEmpty_Exact_sp_0(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_9(tmp30) +fun derive_Concat_sp_4(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Concat_sp_5(self.p1, c) + scrut8 = canBeEmpty_Concat_sp_5(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_19(tmp30) +fun derive_Concat_sp_5(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Concat_sp_6(self.p1, c) + scrut8 = canBeEmpty_Concat_sp_6(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_16(tmp30) +fun derive_Concat_sp_6(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_In_sp_1(self.p1, c) + scrut8 = canBeEmpty_In_sp_1(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_15(tmp30) +fun derive_Concat_sp_7(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Concat_sp_8(self.p1, c) + scrut8 = canBeEmpty_Concat_sp_8(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_33(tmp30) +fun derive_Concat_sp_8(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Star_sp_1(self.p1, c) + scrut8 = canBeEmpty_Star_sp_1(self.p1) + tmp27 = new Concat.class(p1__2, self.p2) + tmp28 = derive_Concat_sp_9(self.p2, c) + tmp29 = new Union(tmp27, tmp28) + normalize_Union_sp_5(tmp29) +fun derive_Concat_sp_9(self, c) = + let {p1__2, scrut8, tmp27, tmp28, tmp29, tmp30} + p1__2 = derive_Exact_sp_1(self.p1, c) + scrut8 = canBeEmpty_Exact_sp_1(self.p1) + tmp30 = new Concat.class(p1__2, self.p2) + normalize_Concat_sp_31(tmp30) +fun normalize_Concat_sp_0(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then self.p2.normalize() + Nothing then p1__3 + else + tmp31 = self.p2.normalize() + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_1(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then normalize_Star_sp_0(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_Star_sp_0(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_10(self) = + let {p1__3, tmp31} + p1__3 = normalize_Concat_sp_11(self.p1) + tmp31 = normalize_Concat_sp_12(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_11(self) = + let {p1__3, tmp31} + p1__3 = normalize_In_sp_0(self.p1) + tmp31 = normalize_Star_sp_1(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_12(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_1(self.p1) + tmp31 = normalize_Concat_sp_11(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_13(self) = + let {p1__3, tmp31} + if self.p1 is + Star then + p1__3 = normalize_Star_sp_1(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_14(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_14(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_0(self.p1) + tmp31 = normalize_Concat_sp_10(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_15(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Star_sp_2(self.p2) + Nothing then p1__3 +fun normalize_Concat_sp_16(self) = + let {p1__3, tmp31} + if self.p1 is + Star then + p1__3 = normalize_Star_sp_2(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_17(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_17(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_2(self.p1) + tmp31 = normalize_Concat_sp_18(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_18(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_3(self.p1) + tmp31 = normalize_Exact_sp_3(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_19(self) = + let {p1__3, tmp31} + if self.p1 is + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + Concat then + p1__3 = normalize_Concat_sp_20(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_23(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_2(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Star_sp_1(self.p2) + Nothing then p1__3 +fun normalize_Concat_sp_20(self) = + let {p1__3, tmp31} + p1__3 = normalize_Star_sp_2(self.p1) + tmp31 = normalize_Concat_sp_21(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_21(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_2(self.p1) + tmp31 = normalize_Concat_sp_22(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_22(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_3(self.p1) + tmp31 = normalize_Exact_sp_3(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_23(self) = + let {p1__3, tmp31} + p1__3 = normalize_Concat_sp_24(self.p1) + tmp31 = normalize_Concat_sp_27(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_24(self) = + let {p1__3, tmp31} + p1__3 = normalize_Concat_sp_25(self.p1) + tmp31 = normalize_Concat_sp_26(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_25(self) = + let {p1__3, tmp31} + p1__3 = normalize_Not_sp_0(self.p1) + tmp31 = normalize_Star_sp_3(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_26(self) = + let {p1__3, tmp31} + p1__3 = normalize_Not_sp_1(self.p1) + tmp31 = normalize_Star_sp_4(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_27(self) = + let {p1__3, tmp31} + p1__3 = normalize_Union_sp_3(self.p1) + if p1__3 is + Empty then normalize_Union_sp_4(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_Union_sp_4(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_28(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_4(self.p1) + tmp31 = normalize_Star_sp_5(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_29(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_5(self.p1) + tmp31 = normalize_Star_sp_6(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_3(self) = + let {p1__3, tmp31} + if self.p1 is + Star then + p1__3 = normalize_Star_sp_1(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_4(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_30(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Star_sp_2(self.p2) + Nothing then p1__3 +fun normalize_Concat_sp_31(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Concat_sp_22(self.p2) + Nothing then p1__3 +fun normalize_Concat_sp_32(self) = + let {p1__3, tmp31} + if self.p1 is + Star then + p1__3 = normalize_Star_sp_2(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_21(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_33(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then normalize_Concat_sp_34(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_34(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_34(self) = + let {p1__3, tmp31} + p1__3 = normalize_Concat_sp_35(self.p1) + tmp31 = self.p2.normalize() + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_35(self) = + let {p1__3, tmp31} + p1__3 = normalize_Concat_sp_36(self.p1) + tmp31 = normalize_Concat_sp_37(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_36(self) = + let {p1__3, tmp31} + p1__3 = normalize_Not_sp_0(self.p1) + tmp31 = normalize_Star_sp_3(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_37(self) = + let {p1__3, tmp31} + p1__3 = normalize_Not_sp_1(self.p1) + tmp31 = normalize_Star_sp_4(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_38(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Concat_sp_39(self.p2) + Nothing then p1__3 +fun normalize_Concat_sp_39(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_6(self.p1) + tmp31 = normalize_In_sp_4(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_4(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_0(self.p1) + tmp31 = normalize_Concat_sp_5(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_40(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Concat_sp_41(self.p2) + Nothing then p1__3 +fun normalize_Concat_sp_41(self) = + let {p1__3, tmp31} + p1__3 = normalize_In_sp_5(self.p1) + tmp31 = normalize_In_sp_6(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_42(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then normalize_In_sp_6(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_In_sp_6(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_43(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then normalize_Concat_sp_44(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_44(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_44(self) = + let {p1__3, tmp31} + p1__3 = normalize_Union_sp_9(self.p1) + if p1__3 is + Empty then normalize_In_sp_6(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_In_sp_6(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_45(self) = + let {p1__3, tmp31} + p1__3 = normalize_In_sp_5(self.p1) + tmp31 = normalize_In_sp_6(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_46(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_6(self.p1) + tmp31 = normalize_In_sp_4(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_47(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then normalize_Exact_sp_7(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_Exact_sp_7(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_48(self) = + let {p1__3, tmp31} + if self.p1 is + Exact then + p1__3 = normalize_Exact_sp_7(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + Concat then + p1__3 = normalize_Concat_sp_47(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_49(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_49(self) = + let {p1__3, tmp31} + p1__3 = normalize_Concat_sp_50(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_50(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_5(self) = + let {p1__3, tmp31} + p1__3 = normalize_Concat_sp_6(self.p1) + tmp31 = normalize_Concat_sp_7(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_50(self) = + let {p1__3, tmp31} + p1__3 = normalize_Union_sp_12(self.p1) + if p1__3 is + Empty then normalize_Exact_sp_7(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_Exact_sp_7(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_51(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_8(self.p1) + tmp31 = normalize_Concat_sp_39(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_52(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_9(self.p1) + tmp31 = normalize_Concat_sp_41(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_53(self) = + let {p1__3, tmp31} + p1__3 = normalize_Union_sp_14(self.p1) + if p1__3 is + Empty then normalize_Concat_sp_44(self.p2) + Nothing then p1__3 + else + tmp31 = normalize_Concat_sp_44(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_54(self) = + let {p1__3, tmp31} + if self.p1 is + Nothing then + p1__3 = normalize_Nothing_sp_1(self.p1) + Concat then + p1__3 = normalize_Concat_sp_55(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = normalize_Union_sp_12(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_55(self) = + let {p1__3, tmp31} + if self.p1 is + Exact then + p1__3 = normalize_Exact_sp_7(self.p1) + Concat then + p1__3 = normalize_Concat_sp_47(self.p1) + if p1__3 is + Nothing then p1__3 + else + if self.p2 is + Nothing then + tmp31 = normalize_Nothing_sp_0(self.p2) + Concat then + tmp31 = normalize_Concat_sp_56(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_56(self) = + let {p1__3, tmp31} + if self.p1 is + Exact then + p1__3 = normalize_Exact_sp_7(self.p1) + Concat then + p1__3 = normalize_Concat_sp_47(self.p1) + if p1__3 is + Nothing then p1__3 + else + if self.p2 is + Exact then + tmp31 = normalize_Exact_sp_7(self.p2) + Nothing then + tmp31 = normalize_Nothing_sp_0(self.p2) + Concat then + tmp31 = normalize_Concat_sp_47(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_57(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then + if self.p2 is + Nothing then normalize_Nothing_sp_1(self.p2) + Concat then normalize_Concat_sp_58(self.p2) + Nothing then p1__3 + else + if self.p2 is + Nothing then + tmp31 = normalize_Nothing_sp_1(self.p2) + Concat then + tmp31 = normalize_Concat_sp_58(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_58(self) = + let {p1__3, tmp31} + if self.p1 is + Exact then + p1__3 = normalize_Exact_sp_7(self.p1) + Concat then + p1__3 = normalize_Concat_sp_47(self.p1) + if p1__3 is + Nothing then p1__3 + else + if self.p2 is + Exact then + tmp31 = normalize_Exact_sp_7(self.p2) + Nothing then + tmp31 = normalize_Nothing_sp_1(self.p2) + Concat then + tmp31 = normalize_Concat_sp_47(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_59(self) = + let {p1__3, tmp31} + if self.p1 is + Nothing then + p1__3 = normalize_Nothing_sp_2(self.p1) + Concat then + p1__3 = normalize_Concat_sp_60(self.p1) + if p1__3 is + Nothing then p1__3 + else + tmp31 = self.p2.normalize() + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_6(self) = + let {p1__3, tmp31} + p1__3 = normalize_In_sp_0(self.p1) + tmp31 = normalize_Star_sp_1(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_60(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then + if self.p2 is + Exact then normalize_Exact_sp_7(self.p2) + Nothing then normalize_Nothing_sp_1(self.p2) + Concat then normalize_Concat_sp_61(self.p2) + Nothing then p1__3 + else + if self.p2 is + Exact then + tmp31 = normalize_Exact_sp_7(self.p2) + Nothing then + tmp31 = normalize_Nothing_sp_1(self.p2) + Concat then + tmp31 = normalize_Concat_sp_61(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_61(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then + if self.p2 is + Exact then normalize_Exact_sp_7(self.p2) + Nothing then normalize_Nothing_sp_1(self.p2) + Concat then normalize_Concat_sp_47(self.p2) + Nothing then p1__3 + else + if self.p2 is + Exact then + tmp31 = normalize_Exact_sp_7(self.p2) + Nothing then + tmp31 = normalize_Nothing_sp_1(self.p2) + Concat then + tmp31 = normalize_Concat_sp_47(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_62(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then + if self.p2 is + Exact then normalize_Exact_sp_7(self.p2) + Nothing then normalize_Nothing_sp_1(self.p2) + Concat then normalize_Concat_sp_47(self.p2) + Nothing then p1__3 + else + if self.p2 is + Exact then + tmp31 = normalize_Exact_sp_7(self.p2) + Nothing then + tmp31 = normalize_Nothing_sp_1(self.p2) + Concat then + tmp31 = normalize_Concat_sp_47(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_63(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then + if self.p2 is + Exact then normalize_Exact_sp_7(self.p2) + Nothing then normalize_Nothing_sp_2(self.p2) + Concat then normalize_Concat_sp_64(self.p2) + Nothing then p1__3 + else + if self.p2 is + Exact then + tmp31 = normalize_Exact_sp_7(self.p2) + Nothing then + tmp31 = normalize_Nothing_sp_2(self.p2) + Concat then + tmp31 = normalize_Concat_sp_64(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_64(self) = + let {p1__3, tmp31} + p1__3 = self.p1.normalize() + if p1__3 is + Empty then + if self.p2 is + Exact then normalize_Exact_sp_7(self.p2) + Nothing then normalize_Nothing_sp_1(self.p2) + Concat then normalize_Concat_sp_47(self.p2) + Nothing then p1__3 + else + if self.p2 is + Exact then + tmp31 = normalize_Exact_sp_7(self.p2) + Nothing then + tmp31 = normalize_Nothing_sp_1(self.p2) + Concat then + tmp31 = normalize_Concat_sp_47(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_7(self) = + let {p1__3, tmp31} + p1__3 = normalize_Exact_sp_1(self.p1) + tmp31 = normalize_Concat_sp_6(self.p2) + new Concat.class(p1__3, tmp31) +fun normalize_Concat_sp_8(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Star_sp_1(self.p2) + Nothing then p1__3 +fun normalize_Concat_sp_9(self) = + let {p1__3, tmp31} + if self.p1 is + Empty then + p1__3 = normalize_Empty_sp_0(self.p1) + Nothing then + p1__3 = normalize_Nothing_sp_0(self.p1) + if p1__3 is + Empty then normalize_Concat_sp_10(self.p2) + Nothing then p1__3 +fun startsWith_Concat_sp_0(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Concat_sp_1(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Concat_sp_1(self.p1) + false + else true +fun startsWith_Concat_sp_1(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_In_sp_0(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_In_sp_0(self.p1) + false + else true +fun startsWith_Concat_sp_10(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = self.p1.startsWith(c) + if tmp32 is + false then + scrut13 = self.p1.canBeEmpty() + if scrut13 is + true then + scrut14 = self.p2.startsWith(c) + if scrut14 is + true then true + else false + else false + else true +fun startsWith_Concat_sp_11(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Concat_sp_12(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Concat_sp_12(self.p1) + false + else true +fun startsWith_Concat_sp_12(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Concat_sp_13(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Concat_sp_13(self.p1) + false + else true +fun startsWith_Concat_sp_13(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Union_sp_0(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Union_sp_0(self.p1) + false + else true +fun startsWith_Concat_sp_14(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Exact_sp_2(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Exact_sp_2(self.p1) + false + else true +fun startsWith_Concat_sp_15(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Exact_sp_3(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Exact_sp_3(self.p1) + false + else true +fun startsWith_Concat_sp_16(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Union_sp_2(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Union_sp_2(self.p1) + scrut14 = startsWith_Concat_sp_17(self.p2, c) + if scrut14 is + true then true + else false + else true +fun startsWith_Concat_sp_17(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Union_sp_3(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Union_sp_3(self.p1) + scrut14 = startsWith_In_sp_2(self.p2, c) + if scrut14 is + true then true + else false + else true +fun startsWith_Concat_sp_18(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Concat_sp_19(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Concat_sp_19(self.p1) + false + else true +fun startsWith_Concat_sp_19(self, c) = + let {scrut13, scrut14, tmp32} + if self.p1 is + Exact then + tmp32 = startsWith_Exact_sp_5(self.p1, c) + Concat then + tmp32 = startsWith_Concat_sp_20(self.p1, c) + if tmp32 is + false then + if self.p1 is + Exact then + scrut13 = canBeEmpty_Exact_sp_5(self.p1) + Concat then + scrut13 = canBeEmpty_Concat_sp_20(self.p1) + false + else true +fun startsWith_Concat_sp_2(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Star_sp_0(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Star_sp_0(self.p1) + scrut14 = startsWith_Concat_sp_3(self.p2, c) + if scrut14 is + true then true + else false + else true +fun startsWith_Concat_sp_20(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = self.p1.startsWith(c) + if tmp32 is + false then + scrut13 = self.p1.canBeEmpty() + if scrut13 is + true then + scrut14 = startsWith_Exact_sp_5(self.p2, c) + if scrut14 is + true then true + else false + else false + else true +fun startsWith_Concat_sp_21(self, c) = + let {scrut13, scrut14, tmp32} + if self.p1 is + Exact then + tmp32 = startsWith_Exact_sp_5(self.p1, c) + Concat then + tmp32 = startsWith_Concat_sp_22(self.p1, c) + if tmp32 is + false then + if self.p1 is + Exact then + scrut13 = canBeEmpty_Exact_sp_5(self.p1) + Concat then + scrut13 = canBeEmpty_Concat_sp_22(self.p1) + false + else true +fun startsWith_Concat_sp_22(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = self.p1.startsWith(c) + if tmp32 is + false then + scrut13 = self.p1.canBeEmpty() + if scrut13 is + true then + if self.p2 is + Exact then + scrut14 = startsWith_Exact_sp_5(self.p2, c) + Nothing then + scrut14 = startsWith_Nothing_sp_0(self.p2, c) + Concat then + scrut14 = startsWith_Concat_sp_23(self.p2, c) + if scrut14 is + true then true + else false + else false + else true +fun startsWith_Concat_sp_23(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = self.p1.startsWith(c) + if tmp32 is + false then + scrut13 = self.p1.canBeEmpty() + if scrut13 is + true then + if self.p2 is + Exact then + scrut14 = startsWith_Exact_sp_5(self.p2, c) + Nothing then + scrut14 = startsWith_Nothing_sp_1(self.p2, c) + Concat then + scrut14 = startsWith_Concat_sp_20(self.p2, c) + if scrut14 is + true then true + else false + else false + else true +fun startsWith_Concat_sp_3(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Exact_sp_0(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Exact_sp_0(self.p1) + false + else true +fun startsWith_Concat_sp_4(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Concat_sp_5(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Concat_sp_5(self.p1) + false + else true +fun startsWith_Concat_sp_5(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Concat_sp_6(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Concat_sp_6(self.p1) + false + else true +fun startsWith_Concat_sp_6(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_In_sp_1(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_In_sp_1(self.p1) + false + else true +fun startsWith_Concat_sp_7(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Concat_sp_8(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Concat_sp_8(self.p1) + false + else true +fun startsWith_Concat_sp_8(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Star_sp_1(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Star_sp_1(self.p1) + scrut14 = startsWith_Concat_sp_9(self.p2, c) + if scrut14 is + true then true + else false + else true +fun startsWith_Concat_sp_9(self, c) = + let {scrut13, scrut14, tmp32} + tmp32 = startsWith_Exact_sp_1(self.p1, c) + if tmp32 is + false then + scrut13 = canBeEmpty_Exact_sp_1(self.p1) + false + else true +fun canBeEmpty_Star_sp_0(self) = true +fun canBeEmpty_Star_sp_1(self) = true +fun derive_Star_sp_0(self, c) = + let {tmp33, tmp34, tmp35} + tmp33 = derive_In_sp_0(self.p, c) + tmp34 = new Star.class(self.p) + tmp35 = new Concat(tmp33, tmp34) + normalize_Concat_sp_8(tmp35) +fun derive_Star_sp_1(self, c) = + let {tmp33, tmp34, tmp35} + tmp33 = derive_In_sp_1(self.p, c) + tmp34 = new Star.class(self.p) + tmp35 = new Concat(tmp33, tmp34) + normalize_Concat_sp_30(tmp35) +fun normalize_Star_sp_0(self) = + let {tmp36} + tmp36 = self.p.normalize() + new Star(tmp36) +fun normalize_Star_sp_1(self) = + let {tmp36} + tmp36 = normalize_In_sp_0(self.p) + new Star(tmp36) +fun normalize_Star_sp_2(self) = + let {tmp36} + tmp36 = normalize_In_sp_1(self.p) + new Star(tmp36) +fun normalize_Star_sp_3(self) = + let {tmp36} + tmp36 = normalize_Not_sp_0(self.p) + new Star(tmp36) +fun normalize_Star_sp_4(self) = + let {tmp36} + tmp36 = normalize_Not_sp_1(self.p) + new Star(tmp36) +fun normalize_Star_sp_5(self) = + let {tmp36} + tmp36 = normalize_In_sp_2(self.p) + new Star(tmp36) +fun normalize_Star_sp_6(self) = + let {tmp36} + tmp36 = normalize_In_sp_3(self.p) + new Star(tmp36) +fun startsWith_Star_sp_0(self, c) = startsWith_In_sp_0(self.p, c) +fun startsWith_Star_sp_1(self, c) = startsWith_In_sp_1(self.p, c) \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript-compile/staging/out/Transform3D.mls b/hkmc2/shared/src/test/mlscript-compile/staging/out/Transform3D.mls new file mode 100644 index 0000000000..0445298f56 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript-compile/staging/out/Transform3D.mls @@ -0,0 +1,3918 @@ +#config(noFreeze: true, noModuleCheck: true, liftDefns: None, disableDataFlowAnalysis: true, deadParamElim: Some(DeadParamElim(debug: false, mono: true))) +import "../Transform3D.mls" as Transform3D__Legacy +module Transform3D with + class Matrix(val arr, val r, val c) + fun ident(w) = + let {m3} + m3 = zeros(w, w) + iterID_Transform3D_sp_0(m3, w, w) + fun iter(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = >(k, 0) + if scrut is + true then + tmp = *(i, x.c) + tmp1 = tmp + colX + tmp2 = tmp1 - k + tmp3 = colX - k + tmp4 = *(tmp3, y.c) + tmp5 = tmp4 + j + tmp6 = *(x.arr.(tmp2), y.arr.(tmp5)) + tmp7 = sum + tmp6 + tmp8 = k - 1 + iter(tmp7, x, y, colX, i, j, tmp8) + else sum + fun iterCol(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = ===(j, 0) + if scrut1 is + true then m + else + tmp9 = colY - j + tmp10 = colY - j + tmp11 = iter_Transform3D_sp_0(0, x, y, colX, i, tmp10, colX) + tmp12 = update(m, i, tmp9, tmp11) + tmp13 = j - 1 + iterCol_Transform3D_sp_0(tmp12, x, y, colX, colY, i, tmp13) + fun iterID(m, w, i) = + let {scrut3, tmp17, tmp18, tmp19, tmp20} + scrut3 = ===(i, 0) + if scrut3 is + true then m + else + tmp17 = w - i + tmp18 = w - i + tmp19 = update_Transform3D_sp_1(m, tmp17, tmp18, 1) + tmp20 = i - 1 + iterID_Transform3D_sp_0(tmp19, w, tmp20) + fun iterRow(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = ===(i, 0) + if scrut2 is + true then m + else + tmp14 = rowX - i + tmp15 = iterCol(m, x, y, colX, colY, tmp14, colY) + tmp16 = i - 1 + iterRow(tmp15, x, y, rowX, colX, colY, tmp16) + fun model(local, position, scaling, rotation) = + let {rot, res1, tmp47, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58} + tmp47 = rotateZ(rotation.2) + tmp48 = rotateY(rotation.1) + tmp49 = rotateX(rotation.0) + tmp50 = ident_Transform3D_sp_0(4) + tmp51 = multiply_Transform3D_sp_0(tmp49, tmp50) + tmp52 = multiply_Transform3D_sp_1(tmp48, tmp51) + rot = multiply_Transform3D_sp_1(tmp47, tmp52) + tmp53 = transform(position.0, position.1, position.2) + tmp54 = scale(scaling.0, scaling.1, scaling.2) + tmp55 = [local.0, local.1, local.2, 1] + tmp56 = new Matrix(tmp55, 4, 1) + tmp57 = multiply_Transform3D_sp_2(tmp54, tmp56) + tmp58 = multiply_Transform3D_sp_3(rot, tmp57) + res1 = multiply_Transform3D_sp_3(tmp53, tmp58) + [res1.arr.0, res1.arr.1, res1.arr.2] + fun model0(local) = + let {tmp59, tmp60, tmp61, tmp62} + tmp59 = [11, 4, 51] + tmp60 = [0.4, 0.19, 0.19] + tmp61 = 2.51327412 + tmp62 = [tmp61, 3.1415926535, 0] + model_Transform3D_sp_0(local, tmp59, tmp60, tmp62) + fun moveBy(v, dx, dy, dz) = + let {m5, tmp63, tmp64} + m5 = transform(dx, dy, dz) + tmp63 = [v.0, v.1, v.2, 1] + tmp64 = new Matrix(tmp63, 4, 1) + multiply_Transform3D_sp_2(m5, tmp64) + fun multiply(x, y) = + let {res} + res = zeros(x.r, y.c) + iterRow_Transform3D_sp_0(res, x, y, x.r, x.c, y.c, x.r) + fun rotateX(angle) = + let {s, c2, tmp32, tmp33, tmp34, tmp35, tmp36} + s = Math.sin(angle) + c2 = Math.cos(angle) + tmp32 = ident_Transform3D_sp_0(4) + tmp33 = update_Transform3D_sp_13(tmp32, 1, 1, c2) + tmp34 = -(s) + tmp35 = update_Transform3D_sp_14(tmp33, 1, 2, tmp34) + tmp36 = update_Transform3D_sp_15(tmp35, 2, 1, s) + update_Transform3D_sp_12(tmp36, 2, 2, c2) + fun rotateY(angle) = + let {s1, c3, tmp37, tmp38, tmp39, tmp40, tmp41} + s1 = Math.sin(angle) + c3 = Math.cos(angle) + tmp37 = ident_Transform3D_sp_0(4) + tmp38 = update_Transform3D_sp_10(tmp37, 0, 0, c3) + tmp39 = update_Transform3D_sp_16(tmp38, 0, 2, s1) + tmp40 = -(s1) + tmp41 = update_Transform3D_sp_17(tmp39, 2, 0, tmp40) + update_Transform3D_sp_12(tmp41, 2, 2, c3) + fun rotateZ(angle) = + let {s2, c4, tmp42, tmp43, tmp44, tmp45, tmp46} + s2 = Math.sin(angle) + c4 = Math.cos(angle) + tmp42 = ident_Transform3D_sp_0(4) + tmp43 = update_Transform3D_sp_10(tmp42, 0, 0, c4) + tmp44 = -(s2) + tmp45 = update_Transform3D_sp_18(tmp43, 0, 1, tmp44) + tmp46 = update_Transform3D_sp_19(tmp45, 1, 0, s2) + update_Transform3D_sp_11(tmp46, 1, 1, c4) + fun scale(sx, sy, sz) = + let {tmp29, tmp30, tmp31} + tmp29 = ident_Transform3D_sp_0(4) + tmp30 = update_Transform3D_sp_10(tmp29, 0, 0, sx) + tmp31 = update_Transform3D_sp_11(tmp30, 1, 1, sy) + update_Transform3D_sp_12(tmp31, 2, 2, sz) + fun transform(dx, dy, dz) = + let {tmp26, tmp27, tmp28} + tmp26 = ident_Transform3D_sp_0(4) + tmp27 = update_Transform3D_sp_7(tmp26, 0, 3, dx) + tmp28 = update_Transform3D_sp_8(tmp27, 1, 3, dy) + update_Transform3D_sp_9(tmp28, 2, 3, dz) + fun update(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = *(i, m.c) + tmp24 = tmp23 + j + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, tmp24, v) + new Matrix(tmp25, m.r, m.c) + fun zeros(r, c) = + let {tmp21, tmp22} + tmp21 = *(r, c) + tmp22 = Transform3D__Legacy."Mx$Transform3D".init(tmp21, 0) + new Matrix(tmp22, r, c) +open Transform3D +fun ident_Transform3D_sp_0(w) = + let {m3} + m3 = zeros_Transform3D_sp_0(w, w) + iterID_Transform3D_sp_1(m3, w, w) +fun iterCol_Transform3D_sp_0(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = ===(j, 0) + if scrut1 is + true then m + else + tmp9 = colY - j + tmp10 = colY - j + tmp11 = iter_Transform3D_sp_0(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_0(m, i, tmp9, tmp11) + tmp13 = j - 1 + iterCol_Transform3D_sp_0(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_1(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_1(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_20(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_2(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_10(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_11(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_41(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_17(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_12(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_12(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_46(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_15(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_13(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_13(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_51(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_12(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_14(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_14(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_56(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_9(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_15(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_15(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_16(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_61(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_22(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_17(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_17(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_66(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_23(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_18(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_18(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_71(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_24(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_19(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_19(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_76(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_25(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_20(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_2(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_6(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_18(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_3(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_20(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_21(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_81(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_20(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_22(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_22(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_86(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_18(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_23(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_23(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_91(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_16(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_24(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_24(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_96(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_21(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_25(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_25(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_26(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_101(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_19(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_27(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_27(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_106(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_11(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_28(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_28(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_111(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_14(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_29(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_29(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_116(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_8(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_30(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_3(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_11(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_16(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_4(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_30(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_31(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_121(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_17(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_32(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_32(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_126(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_15(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_33(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_33(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_131(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_12(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_34(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_34(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_136(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_9(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_35(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_35(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_36(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_141(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_22(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_37(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_37(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_146(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_23(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_38(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_38(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_151(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_24(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_39(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_39(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_156(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_25(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_40(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_4(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_16(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_21(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_5(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_40(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_41(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_161(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_26(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_42(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_42(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_43(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_166(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_27(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_44(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_44(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_45(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_171(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_28(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_46(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_46(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_47(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_176(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_29(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_48(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_48(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_49(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_181(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_26(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_50(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_5(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_50(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_51(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_186(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_27(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_52(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_52(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_53(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_191(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_28(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_54(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_54(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_55(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_196(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_29(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_56(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_56(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_57(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_201(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_26(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_58(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_58(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_59(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_206(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_27(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_60(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_6(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_21(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_19(m, i, tmp9, tmp11) + tmp13 = 3 + iterCol_Transform3D_sp_7(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_60(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_61(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_211(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_28(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_62(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_62(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_63(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_216(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_36(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_64(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_64(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_65(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_221(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_26(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_66(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_66(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_67(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_226(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_27(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_68(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_68(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_69(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_231(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_28(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_70(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_7(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 1 + tmp10 = 1 + tmp11 = iter_Transform3D_sp_26(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_11(m, i, tmp9, tmp11) + tmp13 = 2 + iterCol_Transform3D_sp_8(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_70(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_71(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 0 + tmp10 = 0 + tmp11 = iter_Transform3D_sp_236(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_29(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_72(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_72(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = true + m +fun iterCol_Transform3D_sp_8(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 2 + tmp10 = 2 + tmp11 = iter_Transform3D_sp_31(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_14(m, i, tmp9, tmp11) + tmp13 = 1 + iterCol_Transform3D_sp_9(tmp12, x, y, colX, colY, i, tmp13) +fun iterCol_Transform3D_sp_9(m, x, y, colX, colY, i, j) = + let {scrut1, tmp9, tmp10, tmp11, tmp12, tmp13} + scrut1 = false + tmp9 = 3 + tmp10 = 3 + tmp11 = iter_Transform3D_sp_36(0, x, y, colX, i, tmp10, colX) + tmp12 = update_Transform3D_sp_8(m, i, tmp9, tmp11) + tmp13 = 0 + iterCol_Transform3D_sp_10(tmp12, x, y, colX, colY, i, tmp13) +fun iterID_Transform3D_sp_0(m, w, i) = + let {scrut3, tmp17, tmp18, tmp19, tmp20} + scrut3 = ===(i, 0) + if scrut3 is + true then m + else + tmp17 = w - i + tmp18 = w - i + tmp19 = update_Transform3D_sp_2(m, tmp17, tmp18, 1) + tmp20 = i - 1 + iterID_Transform3D_sp_0(tmp19, w, tmp20) +fun iterID_Transform3D_sp_1(m, w, i) = + let {scrut3, tmp17, tmp18, tmp19, tmp20} + scrut3 = false + tmp17 = 0 + tmp18 = 0 + tmp19 = update_Transform3D_sp_3(m, tmp17, tmp18, 1) + tmp20 = 3 + iterID_Transform3D_sp_2(tmp19, w, tmp20) +fun iterID_Transform3D_sp_2(m, w, i) = + let {scrut3, tmp17, tmp18, tmp19, tmp20} + scrut3 = false + tmp17 = 1 + tmp18 = 1 + tmp19 = update_Transform3D_sp_4(m, tmp17, tmp18, 1) + tmp20 = 2 + iterID_Transform3D_sp_3(tmp19, w, tmp20) +fun iterID_Transform3D_sp_3(m, w, i) = + let {scrut3, tmp17, tmp18, tmp19, tmp20} + scrut3 = false + tmp17 = 2 + tmp18 = 2 + tmp19 = update_Transform3D_sp_5(m, tmp17, tmp18, 1) + tmp20 = 1 + iterID_Transform3D_sp_4(tmp19, w, tmp20) +fun iterID_Transform3D_sp_4(m, w, i) = + let {scrut3, tmp17, tmp18, tmp19, tmp20} + scrut3 = false + tmp17 = 3 + tmp18 = 3 + tmp19 = update_Transform3D_sp_6(m, tmp17, tmp18, 1) + tmp20 = 0 + iterID_Transform3D_sp_5(tmp19, w, tmp20) +fun iterID_Transform3D_sp_5(m, w, i) = + let {scrut3, tmp17, tmp18, tmp19, tmp20} + scrut3 = true + m +fun iterRow_Transform3D_sp_0(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = ===(i, 0) + if scrut2 is + true then m + else + tmp14 = rowX - i + tmp15 = iterCol_Transform3D_sp_0(m, x, y, colX, colY, tmp14, colY) + tmp16 = i - 1 + iterRow(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_1(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 0 + tmp15 = iterCol_Transform3D_sp_1(m, x, y, colX, colY, tmp14, colY) + tmp16 = 3 + iterRow_Transform3D_sp_2(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_10(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = true + m +fun iterRow_Transform3D_sp_11(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 0 + tmp15 = iterCol_Transform3D_sp_41(m, x, y, colX, colY, tmp14, colY) + tmp16 = 3 + iterRow_Transform3D_sp_12(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_12(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 1 + tmp15 = iterCol_Transform3D_sp_43(m, x, y, colX, colY, tmp14, colY) + tmp16 = 2 + iterRow_Transform3D_sp_13(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_13(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 2 + tmp15 = iterCol_Transform3D_sp_45(m, x, y, colX, colY, tmp14, colY) + tmp16 = 1 + iterRow_Transform3D_sp_14(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_14(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 3 + tmp15 = iterCol_Transform3D_sp_47(m, x, y, colX, colY, tmp14, colY) + tmp16 = 0 + iterRow_Transform3D_sp_15(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_15(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = true + m +fun iterRow_Transform3D_sp_16(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 0 + tmp15 = iterCol_Transform3D_sp_49(m, x, y, colX, colY, tmp14, colY) + tmp16 = 3 + iterRow_Transform3D_sp_17(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_17(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 1 + tmp15 = iterCol_Transform3D_sp_51(m, x, y, colX, colY, tmp14, colY) + tmp16 = 2 + iterRow_Transform3D_sp_18(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_18(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 2 + tmp15 = iterCol_Transform3D_sp_53(m, x, y, colX, colY, tmp14, colY) + tmp16 = 1 + iterRow_Transform3D_sp_19(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_19(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 3 + tmp15 = iterCol_Transform3D_sp_55(m, x, y, colX, colY, tmp14, colY) + tmp16 = 0 + iterRow_Transform3D_sp_20(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_2(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 1 + tmp15 = iterCol_Transform3D_sp_6(m, x, y, colX, colY, tmp14, colY) + tmp16 = 2 + iterRow_Transform3D_sp_3(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_20(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = true + m +fun iterRow_Transform3D_sp_21(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 0 + tmp15 = iterCol_Transform3D_sp_57(m, x, y, colX, colY, tmp14, colY) + tmp16 = 3 + iterRow_Transform3D_sp_22(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_22(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 1 + tmp15 = iterCol_Transform3D_sp_59(m, x, y, colX, colY, tmp14, colY) + tmp16 = 2 + iterRow_Transform3D_sp_23(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_23(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 2 + tmp15 = iterCol_Transform3D_sp_61(m, x, y, colX, colY, tmp14, colY) + tmp16 = 1 + iterRow_Transform3D_sp_24(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_24(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 3 + tmp15 = iterCol_Transform3D_sp_63(m, x, y, colX, colY, tmp14, colY) + tmp16 = 0 + iterRow_Transform3D_sp_25(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_25(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = true + m +fun iterRow_Transform3D_sp_26(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 0 + tmp15 = iterCol_Transform3D_sp_65(m, x, y, colX, colY, tmp14, colY) + tmp16 = 3 + iterRow_Transform3D_sp_27(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_27(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 1 + tmp15 = iterCol_Transform3D_sp_67(m, x, y, colX, colY, tmp14, colY) + tmp16 = 2 + iterRow_Transform3D_sp_28(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_28(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 2 + tmp15 = iterCol_Transform3D_sp_69(m, x, y, colX, colY, tmp14, colY) + tmp16 = 1 + iterRow_Transform3D_sp_29(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_29(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 3 + tmp15 = iterCol_Transform3D_sp_71(m, x, y, colX, colY, tmp14, colY) + tmp16 = 0 + iterRow_Transform3D_sp_30(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_3(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 2 + tmp15 = iterCol_Transform3D_sp_11(m, x, y, colX, colY, tmp14, colY) + tmp16 = 1 + iterRow_Transform3D_sp_4(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_30(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = true + m +fun iterRow_Transform3D_sp_4(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 3 + tmp15 = iterCol_Transform3D_sp_16(m, x, y, colX, colY, tmp14, colY) + tmp16 = 0 + iterRow_Transform3D_sp_5(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_5(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = true + m +fun iterRow_Transform3D_sp_6(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 0 + tmp15 = iterCol_Transform3D_sp_21(m, x, y, colX, colY, tmp14, colY) + tmp16 = 3 + iterRow_Transform3D_sp_7(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_7(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 1 + tmp15 = iterCol_Transform3D_sp_26(m, x, y, colX, colY, tmp14, colY) + tmp16 = 2 + iterRow_Transform3D_sp_8(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_8(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 2 + tmp15 = iterCol_Transform3D_sp_31(m, x, y, colX, colY, tmp14, colY) + tmp16 = 1 + iterRow_Transform3D_sp_9(tmp15, x, y, rowX, colX, colY, tmp16) +fun iterRow_Transform3D_sp_9(m, x, y, rowX, colX, colY, i) = + let {scrut2, tmp14, tmp15, tmp16} + scrut2 = false + tmp14 = 3 + tmp15 = iterCol_Transform3D_sp_36(m, x, y, colX, colY, tmp14, colY) + tmp16 = 0 + iterRow_Transform3D_sp_10(tmp15, x, y, rowX, colX, colY, tmp16) +fun iter_Transform3D_sp_0(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = >(k, 0) + if scrut is + true then + tmp = *(i, x.c) + tmp1 = tmp + colX + tmp2 = tmp1 - k + tmp3 = colX - k + tmp4 = *(tmp3, y.c) + tmp5 = tmp4 + j + tmp6 = *(x.arr.(tmp2), y.arr.(tmp5)) + tmp7 = 0 + tmp6 + tmp8 = k - 1 + iter(tmp7, x, y, colX, i, j, tmp8) + else 0 +fun iter_Transform3D_sp_1(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(0), 1) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_2(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_10(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_100(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_101(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(4), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_102(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_102(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = *(x.arr.(5), y.arr.(4)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_103(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_103(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = *(x.arr.(6), y.arr.(8)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_104(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_104(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = *(x.arr.(7), y.arr.(12)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_105(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_105(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_106(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = *(x.arr.(4), y.arr.(1)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_107(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_107(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(5), y.arr.(5)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_108(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_108(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = *(x.arr.(6), y.arr.(9)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_109(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_109(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = *(x.arr.(7), y.arr.(13)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_110(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_11(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_12(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_110(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_111(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = *(x.arr.(4), y.arr.(2)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_112(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_112(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = *(x.arr.(5), y.arr.(6)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_113(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_113(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(6), y.arr.(10)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_114(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_114(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = *(x.arr.(7), y.arr.(14)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_115(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_115(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_116(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = *(x.arr.(4), y.arr.(3)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_117(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_117(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = *(x.arr.(5), y.arr.(7)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_118(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_118(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = *(x.arr.(6), y.arr.(11)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_119(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_119(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(7), y.arr.(15)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_120(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_12(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_13(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_120(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_121(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(8), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_122(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_122(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = *(x.arr.(9), y.arr.(4)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_123(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_123(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = *(x.arr.(10), y.arr.(8)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_124(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_124(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = *(x.arr.(11), y.arr.(12)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_125(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_125(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_126(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = *(x.arr.(8), y.arr.(1)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_127(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_127(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(9), y.arr.(5)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_128(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_128(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = *(x.arr.(10), y.arr.(9)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_129(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_129(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = *(x.arr.(11), y.arr.(13)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_130(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_13(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(2), 1) + tmp7 = 0 + tmp6 + tmp8 = 1 + iter_Transform3D_sp_14(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_130(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_131(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = *(x.arr.(8), y.arr.(2)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_132(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_132(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = *(x.arr.(9), y.arr.(6)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_133(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_133(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(10), y.arr.(10)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_134(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_134(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = *(x.arr.(11), y.arr.(14)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_135(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_135(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_136(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = *(x.arr.(8), y.arr.(3)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_137(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_137(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = *(x.arr.(9), y.arr.(7)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_138(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_138(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = *(x.arr.(10), y.arr.(11)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_139(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_139(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(11), y.arr.(15)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_140(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_14(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_15(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_140(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_141(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(12), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_142(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_142(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = *(x.arr.(13), y.arr.(4)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_143(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_143(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = *(x.arr.(14), y.arr.(8)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_144(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_144(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = *(x.arr.(15), y.arr.(12)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_145(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_145(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_146(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = *(x.arr.(12), y.arr.(1)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_147(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_147(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(13), y.arr.(5)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_148(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_148(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = *(x.arr.(14), y.arr.(9)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_149(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_149(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = *(x.arr.(15), y.arr.(13)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_150(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_15(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_150(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_151(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = *(x.arr.(12), y.arr.(2)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_152(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_152(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = *(x.arr.(13), y.arr.(6)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_153(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_153(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(14), y.arr.(10)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_154(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_154(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = *(x.arr.(15), y.arr.(14)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_155(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_155(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_156(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = *(x.arr.(12), y.arr.(3)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_157(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_157(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = *(x.arr.(13), y.arr.(7)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_158(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_158(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = *(x.arr.(14), y.arr.(11)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_159(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_159(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(15), y.arr.(15)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_160(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_16(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_17(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_160(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_161(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(0), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_162(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_162(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(1), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_163(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_163(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(2), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_164(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_164(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(3), 1) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_165(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_165(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_166(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(4), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_167(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_167(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(5), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_168(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_168(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(6), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_169(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_169(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(7), 1) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_170(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_17(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_18(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_170(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_171(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(8), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_172(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_172(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(9), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_173(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_173(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(10), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_174(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_174(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(11), 1) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_175(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_175(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_176(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(12), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_177(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_177(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(13), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_178(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_178(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(14), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_179(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_179(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(15), 1) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_180(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_18(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = 0 + tmp7 = 0 + tmp8 = 1 + iter_Transform3D_sp_19(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_180(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_181(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(0), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_182(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_182(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(1), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_183(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_183(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(2), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_184(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_184(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(3), y.arr.(3)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_185(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_185(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_186(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(4), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_187(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_187(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(5), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_188(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_188(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(6), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_189(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_189(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(7), y.arr.(3)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_190(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_19(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(3), 1) + tmp7 = 0 + tmp6 + tmp8 = 0 + iter_Transform3D_sp_20(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_190(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_191(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(8), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_192(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_192(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(9), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_193(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_193(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(10), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_194(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_194(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(11), y.arr.(3)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_195(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_195(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_196(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(12), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_197(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_197(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(x.arr.(13), y.arr.(1)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_198(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_198(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(x.arr.(14), y.arr.(2)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_199(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_199(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(x.arr.(15), y.arr.(3)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_200(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_2(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 2 + iter_Transform3D_sp_3(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_20(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_200(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_201(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(0.4, y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_202(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_202(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 2 + iter_Transform3D_sp_203(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_203(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_204(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_204(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_205(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_205(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_206(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_207(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_207(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(0.19, y.arr.(1)) + tmp7 = 0 + tmp6 + tmp8 = 2 + iter_Transform3D_sp_208(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_208(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_209(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_209(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_210(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_21(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(4), 1) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_22(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_210(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_211(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_212(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_212(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_213(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_213(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(0.19, y.arr.(2)) + tmp7 = 0 + tmp6 + tmp8 = 1 + iter_Transform3D_sp_214(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_214(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_215(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_215(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_216(sum, x, y, colX, i, j, k) = 1 +fun iter_Transform3D_sp_217(sum, x, y, colX, i, j, k) = 1 +fun iter_Transform3D_sp_218(sum, x, y, colX, i, j, k) = 1 +fun iter_Transform3D_sp_219(sum, x, y, colX, i, j, k) = 1 +fun iter_Transform3D_sp_22(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 2 + iter_Transform3D_sp_23(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_220(sum, x, y, colX, i, j, k) = 1 +fun iter_Transform3D_sp_221(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(1, y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_222(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_222(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 2 + iter_Transform3D_sp_223(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_223(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_224(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_224(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(11, y.arr.(3)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_225(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_225(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_226(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_227(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_227(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = *(1, y.arr.(1)) + tmp7 = 0 + tmp6 + tmp8 = 2 + iter_Transform3D_sp_228(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_228(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_229(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_229(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(4, y.arr.(3)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_230(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_23(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_24(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_230(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_231(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_232(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_232(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_233(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_233(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = *(1, y.arr.(2)) + tmp7 = 0 + tmp6 + tmp8 = 1 + iter_Transform3D_sp_234(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_234(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(51, y.arr.(3)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_235(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_235(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_236(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_237(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_237(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 1 + tmp5 = 1 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_238(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_238(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 2 + tmp5 = 2 + tmp6 = 0 + tmp7 = 0 + tmp8 = 1 + iter_Transform3D_sp_239(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_239(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 3 + tmp5 = 3 + tmp6 = *(1, y.arr.(3)) + tmp7 = 0 + tmp6 + tmp8 = 0 + iter_Transform3D_sp_240(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_24(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_25(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_240(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_25(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_26(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_27(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_27(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(5), 1) + tmp7 = 0 + tmp6 + tmp8 = 2 + iter_Transform3D_sp_28(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_28(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_29(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_29(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_30(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_3(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_4(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_30(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_31(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_32(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_32(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_33(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_33(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(6), 1) + tmp7 = 0 + tmp6 + tmp8 = 1 + iter_Transform3D_sp_34(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_34(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_35(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_35(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_36(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 4 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_37(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_37(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 5 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_38(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_38(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 6 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = 0 + tmp7 = 0 + tmp8 = 1 + iter_Transform3D_sp_39(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_39(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 4 + tmp1 = 8 + tmp2 = 7 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(7), 1) + tmp7 = 0 + tmp6 + tmp8 = 0 + iter_Transform3D_sp_40(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_4(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_5(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_40(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_41(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(8), 1) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_42(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_42(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 2 + iter_Transform3D_sp_43(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_43(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_44(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_44(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_45(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_45(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_46(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_47(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_47(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(9), 1) + tmp7 = 0 + tmp6 + tmp8 = 2 + iter_Transform3D_sp_48(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_48(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_49(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_49(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_50(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_5(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_50(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_51(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_52(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_52(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_53(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_53(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(10), 1) + tmp7 = 0 + tmp6 + tmp8 = 1 + iter_Transform3D_sp_54(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_54(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_55(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_55(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_56(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 8 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_57(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_57(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 9 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_58(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_58(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 10 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = 0 + tmp7 = 0 + tmp8 = 1 + iter_Transform3D_sp_59(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_59(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 8 + tmp1 = 12 + tmp2 = 11 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(11), 1) + tmp7 = 0 + tmp6 + tmp8 = 0 + iter_Transform3D_sp_60(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_6(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_7(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_60(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_61(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(12), 1) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_62(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_62(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 2 + iter_Transform3D_sp_63(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_63(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_64(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_64(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_65(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_65(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_66(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_67(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_67(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(13), 1) + tmp7 = 0 + tmp6 + tmp8 = 2 + iter_Transform3D_sp_68(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_68(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_69(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_69(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_70(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_7(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(1), 1) + tmp7 = 0 + tmp6 + tmp8 = 2 + iter_Transform3D_sp_8(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_70(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_71(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_72(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_72(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_73(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_73(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(14), 1) + tmp7 = 0 + tmp6 + tmp8 = 1 + iter_Transform3D_sp_74(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_74(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_75(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_75(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_76(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 12 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = 0 + tmp7 = 0 + tmp8 = 3 + iter_Transform3D_sp_77(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_77(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 13 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = 0 + tmp7 = 0 + tmp8 = 2 + iter_Transform3D_sp_78(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_78(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 14 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = 0 + tmp7 = 0 + tmp8 = 1 + iter_Transform3D_sp_79(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_79(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 12 + tmp1 = 16 + tmp2 = 15 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(15), 1) + tmp7 = 0 + tmp6 + tmp8 = 0 + iter_Transform3D_sp_80(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_8(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 1 + iter_Transform3D_sp_9(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_80(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_81(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 0 + tmp6 = *(x.arr.(0), y.arr.(0)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_82(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_82(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 4 + tmp6 = *(x.arr.(1), y.arr.(4)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_83(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_83(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 8 + tmp6 = *(x.arr.(2), y.arr.(8)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_84(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_84(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 12 + tmp6 = *(x.arr.(3), y.arr.(12)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_85(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_85(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_86(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 1 + tmp6 = *(x.arr.(0), y.arr.(1)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_87(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_87(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 5 + tmp6 = *(x.arr.(1), y.arr.(5)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_88(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_88(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 9 + tmp6 = *(x.arr.(2), y.arr.(9)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_89(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_89(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = *(x.arr.(3), y.arr.(13)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_90(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_9(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 13 + tmp6 = 0 + tmp7 = sum + 0 + tmp8 = 0 + iter_Transform3D_sp_10(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_90(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_91(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 2 + tmp6 = *(x.arr.(0), y.arr.(2)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_92(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_92(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 6 + tmp6 = *(x.arr.(1), y.arr.(6)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_93(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_93(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 10 + tmp6 = *(x.arr.(2), y.arr.(10)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_94(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_94(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 14 + tmp6 = *(x.arr.(3), y.arr.(14)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_95(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_95(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = false + sum +fun iter_Transform3D_sp_96(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 0 + tmp3 = 0 + tmp4 = 0 + tmp5 = 3 + tmp6 = *(x.arr.(0), y.arr.(3)) + tmp7 = 0 + tmp6 + tmp8 = 3 + iter_Transform3D_sp_97(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_97(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 1 + tmp3 = 1 + tmp4 = 4 + tmp5 = 7 + tmp6 = *(x.arr.(1), y.arr.(7)) + tmp7 = sum + tmp6 + tmp8 = 2 + iter_Transform3D_sp_98(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_98(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 2 + tmp3 = 2 + tmp4 = 8 + tmp5 = 11 + tmp6 = *(x.arr.(2), y.arr.(11)) + tmp7 = sum + tmp6 + tmp8 = 1 + iter_Transform3D_sp_99(tmp7, x, y, colX, i, j, tmp8) +fun iter_Transform3D_sp_99(sum, x, y, colX, i, j, k) = + let {scrut, tmp, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8} + scrut = true + tmp = 0 + tmp1 = 4 + tmp2 = 3 + tmp3 = 3 + tmp4 = 12 + tmp5 = 15 + tmp6 = *(x.arr.(3), y.arr.(15)) + tmp7 = sum + tmp6 + tmp8 = 0 + iter_Transform3D_sp_100(tmp7, x, y, colX, i, j, tmp8) +fun model_Transform3D_sp_0(local, position, scaling, rotation) = + let {rot, res1, tmp47, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58} + tmp47 = rotateZ_Transform3D_sp_0(rotation.2) + tmp48 = rotateY_Transform3D_sp_0(rotation.1) + tmp49 = rotateX_Transform3D_sp_0(rotation.0) + tmp50 = ident_Transform3D_sp_0(4) + tmp51 = multiply_Transform3D_sp_0(tmp49, tmp50) + tmp52 = multiply_Transform3D_sp_1(tmp48, tmp51) + rot = multiply_Transform3D_sp_1(tmp47, tmp52) + tmp53 = transform_Transform3D_sp_0(position.0, position.1, position.2) + tmp54 = scale_Transform3D_sp_0(scaling.0, scaling.1, scaling.2) + tmp55 = [local.0, local.1, local.2, 1] + tmp56 = new Matrix(tmp55, 4, 1) + tmp57 = multiply_Transform3D_sp_4(tmp54, tmp56) + tmp58 = multiply_Transform3D_sp_3(rot, tmp57) + res1 = multiply_Transform3D_sp_5(tmp53, tmp58) + [res1.arr.0, res1.arr.1, res1.arr.2] +fun multiply_Transform3D_sp_0(x, y) = + let {res} + res = zeros_Transform3D_sp_0(x.r, y.c) + iterRow_Transform3D_sp_1(res, x, y, x.r, x.c, y.c, x.r) +fun multiply_Transform3D_sp_1(x, y) = + let {res} + res = zeros_Transform3D_sp_0(x.r, y.c) + iterRow_Transform3D_sp_6(res, x, y, x.r, x.c, y.c, x.r) +fun multiply_Transform3D_sp_2(x, y) = + let {res} + res = zeros_Transform3D_sp_1(x.r, y.c) + iterRow_Transform3D_sp_11(res, x, y, x.r, x.c, y.c, x.r) +fun multiply_Transform3D_sp_3(x, y) = + let {res} + res = zeros_Transform3D_sp_1(x.r, y.c) + iterRow_Transform3D_sp_16(res, x, y, x.r, x.c, y.c, x.r) +fun multiply_Transform3D_sp_4(x, y) = + let {res} + res = zeros_Transform3D_sp_1(x.r, y.c) + iterRow_Transform3D_sp_21(res, x, y, x.r, x.c, y.c, x.r) +fun multiply_Transform3D_sp_5(x, y) = + let {res} + res = zeros_Transform3D_sp_1(x.r, y.c) + iterRow_Transform3D_sp_26(res, x, y, x.r, x.c, y.c, x.r) +fun rotateX_Transform3D_sp_0(angle) = + let {s, c2, tmp32, tmp33, tmp34, tmp35, tmp36} + s = Math.sin(2.51327412) + c2 = Math.cos(2.51327412) + tmp32 = ident_Transform3D_sp_0(4) + tmp33 = update_Transform3D_sp_13(tmp32, 1, 1, c2) + tmp34 = -(s) + tmp35 = update_Transform3D_sp_14(tmp33, 1, 2, tmp34) + tmp36 = update_Transform3D_sp_15(tmp35, 2, 1, s) + update_Transform3D_sp_12(tmp36, 2, 2, c2) +fun rotateY_Transform3D_sp_0(angle) = + let {s1, c3, tmp37, tmp38, tmp39, tmp40, tmp41} + s1 = Math.sin(3.1415926535) + c3 = Math.cos(3.1415926535) + tmp37 = ident_Transform3D_sp_0(4) + tmp38 = update_Transform3D_sp_10(tmp37, 0, 0, c3) + tmp39 = update_Transform3D_sp_16(tmp38, 0, 2, s1) + tmp40 = -(s1) + tmp41 = update_Transform3D_sp_17(tmp39, 2, 0, tmp40) + update_Transform3D_sp_12(tmp41, 2, 2, c3) +fun rotateZ_Transform3D_sp_0(angle) = + let {s2, c4, tmp42, tmp43, tmp44, tmp45, tmp46} + s2 = Math.sin(0) + c4 = Math.cos(0) + tmp42 = ident_Transform3D_sp_0(4) + tmp43 = update_Transform3D_sp_10(tmp42, 0, 0, c4) + tmp44 = -(s2) + tmp45 = update_Transform3D_sp_18(tmp43, 0, 1, tmp44) + tmp46 = update_Transform3D_sp_19(tmp45, 1, 0, s2) + update_Transform3D_sp_11(tmp46, 1, 1, c4) +fun scale_Transform3D_sp_0(sx, sy, sz) = + let {tmp29, tmp30, tmp31} + tmp29 = ident_Transform3D_sp_0(4) + tmp30 = update_Transform3D_sp_33(tmp29, 0, 0, sx) + tmp31 = update_Transform3D_sp_34(tmp30, 1, 1, sy) + update_Transform3D_sp_35(tmp31, 2, 2, sz) +fun transform_Transform3D_sp_0(dx, dy, dz) = + let {tmp26, tmp27, tmp28} + tmp26 = ident_Transform3D_sp_0(4) + tmp27 = update_Transform3D_sp_30(tmp26, 0, 3, dx) + tmp28 = update_Transform3D_sp_31(tmp27, 1, 3, dy) + update_Transform3D_sp_32(tmp28, 2, 3, dz) +fun update_Transform3D_sp_0(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = *(i, m.c) + tmp24 = tmp23 + j + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, tmp24, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_1(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = *(i, m.c) + tmp24 = tmp23 + j + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, tmp24, 1) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_10(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 0 + tmp24 = 0 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 0, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_11(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 4 + tmp24 = 5 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 5, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_12(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 8 + tmp24 = 10 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 10, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_13(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 4 + tmp24 = 5 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 5, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_14(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 4 + tmp24 = 6 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 6, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_15(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 8 + tmp24 = 9 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 9, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_16(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 0 + tmp24 = 2 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 2, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_17(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 8 + tmp24 = 8 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 8, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_18(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 0 + tmp24 = 1 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 1, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_19(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 4 + tmp24 = 4 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 4, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_2(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = *(i, m.c) + tmp24 = tmp23 + j + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, tmp24, 1) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_20(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 0 + tmp24 = 0 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 0, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_21(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 0 + tmp24 = 3 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 3, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_22(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 12 + tmp24 = 12 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 12, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_23(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 12 + tmp24 = 13 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 13, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_24(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 12 + tmp24 = 14 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 14, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_25(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 12 + tmp24 = 15 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 15, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_26(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 0 + tmp24 = 0 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 0, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_27(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 1 + tmp24 = 1 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 1, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_28(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 2 + tmp24 = 2 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 2, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_29(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 3 + tmp24 = 3 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 3, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_3(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_2} + tmp23 = 0 + tmp24 = 0 + tup_2 = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + tmp25 = tup_2 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_30(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_7} + tmp23 = 0 + tmp24 = 3 + tup_7 = [1, 0, 0, 11, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + tmp25 = tup_7 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_31(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_8} + tmp23 = 4 + tmp24 = 7 + tup_8 = [1, 0, 0, 11, 0, 1, 0, 4, 0, 0, 1, 0, 0, 0, 0, 1] + tmp25 = tup_8 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_32(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_9} + tmp23 = 8 + tmp24 = 11 + tup_9 = [1, 0, 0, 11, 0, 1, 0, 4, 0, 0, 1, 51, 0, 0, 0, 1] + tmp25 = tup_9 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_33(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_10} + tmp23 = 0 + tmp24 = 0 + tup_10 = [0.4, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + tmp25 = tup_10 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_34(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_11} + tmp23 = 4 + tmp24 = 5 + tup_11 = [0.4, 0, 0, 0, 0, 0.19, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + tmp25 = tup_11 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_35(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_12} + tmp23 = 8 + tmp24 = 10 + tup_12 = [0.4, 0, 0, 0, 0, 0.19, 0, 0, 0, 0, 0.19, 0, 0, 0, 0, 1] + tmp25 = tup_12 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_36(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 3 + tmp24 = 3 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 3, 1) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_4(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_3} + tmp23 = 4 + tmp24 = 5 + tup_3 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + tmp25 = tup_3 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_5(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_4} + tmp23 = 8 + tmp24 = 10 + tup_4 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0] + tmp25 = tup_4 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_6(m, i, j, v) = + let {tmp23, tmp24, tmp25, tup_5} + tmp23 = 12 + tmp24 = 15 + tup_5 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] + tmp25 = tup_5 + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_7(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 0 + tmp24 = 3 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 3, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_8(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 4 + tmp24 = 7 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 7, v) + new Matrix(tmp25, m.r, m.c) +fun update_Transform3D_sp_9(m, i, j, v) = + let {tmp23, tmp24, tmp25} + tmp23 = 8 + tmp24 = 11 + tmp25 = Transform3D__Legacy."Mx$Transform3D".setAt(m.arr, 11, v) + new Matrix(tmp25, m.r, m.c) +fun zeros_Transform3D_sp_0(r, c) = + let {tmp21, tmp22, tup_1} + tmp21 = 16 + tup_1 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + tmp22 = tup_1 + new Matrix(tmp22, r, c) +fun zeros_Transform3D_sp_1(r, c) = + let {tmp21, tmp22, tup_6} + tmp21 = 4 + tup_6 = [0, 0, 0, 0] + tmp22 = tup_6 + new Matrix(tmp22, r, c) \ No newline at end of file diff --git a/hkmc2/shared/src/test/mlscript/ShapeSetTest.mls b/hkmc2/shared/src/test/mlscript/ShapeSetTest.mls new file mode 100644 index 0000000000..de35ad0c72 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/ShapeSetTest.mls @@ -0,0 +1,74 @@ +:js + +import "../mlscript-compile/ShapeSet.mls" +import "../mlscript-compile/Block.mls" +import "../mlscript-compile/Shape.mls" +import "../mlscript-compile/Option.mls" + +open ShapeSet +open Shape { Lit, Arr, Class, Dyn } +open Option +open Block { Tup, ConcreteClassSymbol, Param, Symbol } + +let x = mkBot() +//│ x = {} + +if x.isEmpty() then 0 +//│ = 0 + +let x = liftMany([Lit(1), Lit(2)]) +let y = liftMany([Arr([Lit(1)]), Arr([Lit(2)])]) +//│ x = {Lit(1),Lit(2)} +//│ y = {Arr([Lit(1)]),Arr([Lit(2)])} + +union2(x, y) +//│ = {Arr([Lit(1)]),Arr([Lit(2)]),Lit(1),Lit(2)} + +union2(mkDyn(), x) +//│ = {Dyn()} + +union(mkLit(1), mkLit(2), mkLit(3)) +//│ = {Lit(1),Lit(2),Lit(3)} + +mkArr([x, y]) +//│ = {Arr([{Lit(1),Lit(2)}, {Arr([Lit(1)]),Arr([Lit(2)])}])} + +class C(val a) +val clsSym = ConcreteClassSymbol("C", C, Some([Param(None, Symbol("a"))]), [], false) +//│ clsSym = ConcreteClassSymbol( +//│ "C", +//│ fun C { class: class C }, +//│ Some([Param(None, Symbol("a"))]), +//│ [], +//│ false +//│ ) + +:fixme +let x = liftMany([Class(clsSym, [mkLit(42)]), Arr([mkLit(1), mkLit("a")])]) +let y = liftMany([Lit(1), Lit("a")]) +selSet(x, y) +//│ ═══[RUNTIME ERROR] Error: Array out of bound +//│ x = {Arr([{Lit(1)}, {Lit("a")}]),Class(ConcreteClassSymbol("C", fun C { class: class C }, Some([Param(None, Symbol("a"))]), [], false), [{Lit(42)}])} +//│ y = {Lit("a"),Lit(1)} + +mkClass(clsSym, [mkLit(1)]) +//│ = {Class(ConcreteClassSymbol("C", fun C { class: class C }, Some([Param(None, Symbol("a"))]), [], false), [{Lit(1)}])} + +filterSet(liftMany([Lit(1), Lit("s"), Arr([Lit(1), Lit(2), Lit(3)])]), Tup(3)) +//│ = {Arr([Lit(1), Lit(2), Lit(3)])} + +let x = mkLit(1) +let y = Block.Cls(Block.Symbol("Bool"), 0) +filterSet(x, y) +//│ = {} +//│ x = {Lit(1)} +//│ y = Cls(Symbol("Bool"), 0) + +Shape.filter(Shape.Lit(1), Block.Lit(1)) +//│ = [Lit(1)] + +[Shape.Lit(1), Block.Lit(1)] is [Shape.Lit(l1), Block.Lit(l2)] +//│ = true + +Shape.silh(Block.Lit(1)) +//│ = Lit(1) diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Classes.mls b/hkmc2/shared/src/test/mlscript/block-staging/Classes.mls new file mode 100644 index 0000000000..97db94f220 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/Classes.mls @@ -0,0 +1,42 @@ +:js +:staging + +import "../../mlscript-compile/Block.mls" + +// TODO: copy C# annotation to Block IR +class C with + fun call(x) = x + 1 +staged module M with + fun f(x) = x.C#call(10) + +staged class A(val a) + +staged module C with + class I + +class C +staged module M with + fun f() = C + +staged class C with + fun f() = 1 + +:e +staged class C(x) +//│ ╔══[COMPILATION ERROR] Staged classes with private fields are not supported. +//│ ║ l.25: staged class C(x) +//│ ╙── ^^^^^^^^^^ + +staged class B(val x) with + fun f(y) = this.x + y +staged class D(val x) extends B(x+1) with + val y = 1 + fun f() = 42 + +class Unstaged +staged class Staged(val x) with + fun inner() = 1 +staged module M with + fun f() = + Unstaged; + Staged diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Functions.mls b/hkmc2/shared/src/test/mlscript/block-staging/Functions.mls index 9f749b55ab..e62c62c9e9 100644 --- a/hkmc2/shared/src/test/mlscript/block-staging/Functions.mls +++ b/hkmc2/shared/src/test/mlscript/block-staging/Functions.mls @@ -2,30 +2,23 @@ :staging :noOpt // To expose the problem -:fixme // TODO: fix IR rebinding issue (each symbol should be bound at most once) :checkIR -staged module Expressions with +staged module Rebinding with fun lit() = let x = 42 x -//│ ╔══[INTERNAL ERROR] [BlockChecker] Invalid IR: symbol x⁰ is bound more than once -//│ ║ l.9: let x = 42 -//│ ╙── ^ -//│ > fun ctor_() = () -//│ > fun lit() = -//│ > let {x} -//│ > x = 42 -//│ > x -let x = [1, 2, 3] +val x = [1, 2, 3] staged module Expressions with - fun lit() = 1 + fun lit(x) = x + x fun assign() = let x = 42 let y = x y fun tup1() = [1, 2] - fun tup2() = [1, x] + fun tup2() = + let x = [1, 2, 3] + [1, x] fun dynsel() = [1].(0) fun match1() = if 9 is @@ -35,50 +28,12 @@ staged module Expressions with 9 then 4 else 0 fun match2() = + let x = [1, 2, 3] if x is [] then 1 [1, 2] then 2 [a, _] then 3 else 0 -//│ > fun ctor_() = () -//│ > fun lit() = 1 -//│ > fun assign() = -//│ > let {x, y} -//│ > x = 42 -//│ > y = x -//│ > y -//│ > fun tup1() = [1, 2] -//│ > fun tup2() = [1, x1] -//│ > fun dynsel() = -//│ > let {tmp} -//│ > tmp = [1] -//│ > tmp.(0) -//│ > fun match1() = -//│ > let {scrut} -//│ > scrut = 9 -//│ > if scrut is -//│ > Bool then 1 -//│ > 8 then 2 -//│ > Int then 3 -//│ > else 0 -//│ > fun match2() = -//│ > let {a, element1_, element0_} -//│ > if x1 is -//│ > [] then 1 -//│ > [_, _] then -//│ > element0_ = x1.0 -//│ > element1_ = x1.1 -//│ > if element0_ is -//│ > 1 then -//│ > if element1_ is -//│ > 2 then 2 -//│ > else -//│ > a = element0_ -//│ > 3 -//│ > else -//│ > a = element0_ -//│ > 3 -//│ > else 0 //│ x = [1, 2, 3] // * LetSplit lowers to a Label/Break pair, which the staged-module @@ -92,82 +47,32 @@ staged module Example with x is 0 and y is 0 and z is 0 then 1 else 2 //│ ═══[COMPILATION ERROR] Other Blocks not supported in staged module: class hkmc2.codegen.Label. -//│ > fun ctor_() = () -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. - -// * LetSplit lowers to a Label/Break pair, which the staged-module -// * compiler (`ReflectionInstrumenter`) doesn't yet understand. With -// * the sharing threshold forced to 1, the shared `else` below would -// * emit exactly that — tracked here as a fixme. -:fixme -:patMatConsequentSharingThreshold 1 -staged module Example with - fun f(x, y, z) = if - x is 0 and y is 0 and z is 0 then 1 - else 2 -//│ ═══[COMPILATION ERROR] Other Blocks not supported in staged module: class hkmc2.codegen.Label. -//│ > fun ctor_() = () -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. -:fixme class Outside(a) staged module ClassInstrumentation with class Inside(a, b) class NoArg - fun inst1() = new Outside(1) + fun inst1() = Outside(1) fun inst2() = new NoArg fun app1() = Outside(1) fun app2() = Inside(1, 2) -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ > fun ctor_() = -//│ > class Inside(a1, b) -//│ > class NoArg -//│ > fun inst1() = new Outside(1) -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. module Nonstaged with fun f() = 1 staged module Staged with fun f() = 1 staged module CallSubst with - fun call() = - 1 + 1 - Nonstaged.f() - Staged.f() -//│ > fun ctor_() = () -//│ > fun f() = 1 -//│ > fun ctor_() = () -//│ > fun call() = -//│ > Nonstaged.f() -//│ > Staged.f_gen() + fun call() = Nonstaged.f() + Staged.f() :ftc staged module Arguments with - fun f(x) = - x = 1 - x + fun f(x) = x fun g(x)(y, z)() = z -//│ > fun ctor_() = () -//│ > fun f(x) = -//│ > x = 1 -//│ > x -//│ > fun g(x) = -//│ > let {tmp} -//│ > tmp = new Function_ -//│ > tmp // :e staged module BadArguments with fun f() = Arguments.g(1)(2, 3) -//│ > fun ctor_() = () -//│ > fun f() = -//│ > let {callPrefix} -//│ > callPrefix = Arguments.g_gen(1) -//│ > callPrefix(2, 3) - -:fixme staged module OtherBlocks with fun scope() = scope.locally of ( @@ -179,51 +84,29 @@ staged module OtherBlocks with 2 then 0 3 then 0 else 0 -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ ╔══[COMPILATION ERROR] No definition found in scope for member 'a' -//│ ╟── which references the symbol introduced here -//│ ║ l.174: let a = 1 -//│ ╙── ^ -//│ > fun ctor_() = () -//│ ═══[RUNTIME ERROR] ReferenceError: a is not defined staged module ClassDefs with class A -//│ > fun ctor_() = -//│ > class A +// TODO: ValDefn in class staged module ValClass with class A(val a) -//│ > fun ctor_() = -//│ > class A(a) -:fixme staged module ClassFunctions with class InnerClass() with fun f() = 1 + Arguments.f(1) fun g() = f() -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. -staged module RetUnit with - fun f() = () -//│ > fun ctor_() = () -//│ > fun f() = () // name collision class A() staged module A with fun f() = 1 -//│ > fun ctor_() = () -//│ > fun f() = 1 // nested module module A with staged module B with fun f() = 1 -//│ > fun ctor_() = () -//│ > fun f() = 1 // FIXME: for g to be defined in the next stage, we need to also print the other ClsLikeDefn/FunDefn nodes when printing the next stage :ftc @@ -231,8 +114,6 @@ staged module NestedFunDefn with fun f() = fun g() = 1 g() -//│ > fun ctor_() = () -//│ > fun f() = g() :todo staged module LabelBreak with @@ -241,16 +122,14 @@ staged module LabelBreak with while x == 1 do set x = x + 1 fun g() = if 1 is - 0 then 2 - 1 then 2 - else 2 + 0 then 1 + 1 + 1 + 1 then 1 + 1 + 1 + else 1 + 1 + 1 //│ ═══[COMPILATION ERROR] Other Blocks not supported in staged module: class hkmc2.codegen.Label. //│ ╔══[COMPILATION ERROR] No definition found in scope for member 'x' //│ ╟── which references the symbol introduced here -//│ ║ l.240: let x = 1 +//│ ║ l.121: let x = 1 //│ ╙── ^ -//│ > fun ctor_() = () -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. :e class C(val a) @@ -260,16 +139,15 @@ staged module A with fun g() = {1 : 2} //│ ═══[COMPILATION ERROR] Field assignment is not supported in staged modules: a //│ ╔══[COMPILATION ERROR] Other Results not supported in staged module: class hkmc2.codegen.Record -//│ ║ l.260: fun g() = {1 : 2} +//│ ║ l.139: fun g() = {1 : 2} //│ ╙── ^ -//│ > fun ctor_() = -//│ > x = C(1) -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. :todo staged module Spread with fun f() = if [1, ..[1, 2]] is [1, ...x] then x else 0 -//│ ═══[COMPILATION ERROR] Spread parameters are not supported in staged module: Arg(Some(Lazy),SimpleRef(tmp:tmp)) +//│ ═══[COMPILATION ERROR] Spread parameters are not supported in staged module. +//│ ═══[COMPILATION ERROR] Spread parameters are not supported in staged module: Tup(1,true) +//│ ═══[COMPILATION ERROR] Unable to infer parameters from symbol in staged module, which are necessary to reconstruct class instances: module:Tuple //│ ═══[COMPILATION ERROR] No definition found in scope for member 'tmp' -//│ > fun ctor_() = () -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. +//│ ═══[COMPILATION ERROR] No definition found in scope for member 'scrut' +//│ ═══[COMPILATION ERROR] No definition found in scope for member 'element0$' diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Generate.mls b/hkmc2/shared/src/test/mlscript/block-staging/Generate.mls new file mode 100644 index 0000000000..ad279faaba --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/Generate.mls @@ -0,0 +1,140 @@ +:js +:staging +:noModuleCheck + +fun gen(M, name) = + M."generate"("../" + name + ".mls", "./hkmc2/shared/src/test/mlscript-compile/staging/out/" + name + ".mls") + +import "../../mlscript-compile/staging/SimpleStagedExample.mls" + +gen(SimpleStagedExample, "SimpleStagedExample") + +import "../../mlscript-compile/staging/out/SimpleStagedExample.mls" + +:expect 60 +SimpleStagedExample.foo() +//│ = 60 + + +:expect 6 +SimpleStagedExample.f(1, 5) +//│ = 6 + + +:expect 5 +SimpleStagedExample.fib(5) +//│ = 5 + +:expect 2 +SimpleStagedExample.baz() +//│ = 2 + + +:expect false +SimpleStagedExample.bazbaz(true) +//│ = false + + +import "../../mlscript-compile/staging/LinkingGeneratedClasses.mls" + +gen(LinkingGeneratedClasses, "LinkingGeneratedClasses") + +import "../../mlscript-compile/staging/out/LinkingGeneratedClasses.mls" + +:expect C +LinkingGeneratedClasses.test1 +//│ = C + +:expect S +LinkingGeneratedClasses.test2(false) +//│ = S + +:expect D +LinkingGeneratedClasses.test3 +//│ = D + +:expect 3 +LinkingGeneratedClasses.f().call(3) +//│ = 3 + +:expect 5 +LinkingGeneratedClasses.g().call(3) +//│ = 5 + +import "../../mlscript-compile/staging/StagedClass.mls" + + +gen(StagedClass, "StagedClass") + + +import "../../mlscript-compile/staging/out/StagedClass.mls" + + +StagedClass.foo() +//│ = Foo + + +StagedClass.bar(false) +//│ = Bar(1) + +StagedClass.bar(true) +//│ = Bar(0) + + +StagedClass.baz(true) +//│ = Baz(1) + +let baz = StagedClass.baz(false) +//│ baz = Baz(2) + + +baz.x +//│ = 2 + +StagedClass.f(baz) +//│ = 3 + + +assert StagedClass.D() is StagedClass.B + +assert StagedClass.g() is StagedClass.D + +assert StagedClass.C().h() is StagedClass.D + +:expect 3 +StagedClass.xx().f(1, 2) +//│ = 3 + + +StagedClass.X(1).f(0) +//│ = Bar(0) + + +assert StagedClass.X(1).f(0) is StagedClass.Bar + + +:fixme we need to support redirection in classes +:expect 2 +StagedClass.X(0).g(1) +//│ ═══[RUNTIME ERROR] TypeError: Cannot read properties of undefined (reading 'foo') +//│ ═══[RUNTIME ERROR] Expected: '2', got: 'undefined' + + +:expect 2 +StagedClass.X(0).h(1) +//│ = 2 + + +import "../../mlscript-compile/staging/ImportingFiles.mls" + +gen(ImportingFiles, "ImportingFiles") + +import "../../mlscript-compile/staging/out/ImportingFiles.mls" + +import "../../mlscript-compile/staging/AdjacentClasses.mls" + +gen(AdjacentClasses, "AdjacentClasses") + +:expect C(1) +AdjacentClasses.D().f() +//│ = C(1) diff --git a/hkmc2/shared/src/test/mlscript/block-staging/GenerateMult.mls b/hkmc2/shared/src/test/mlscript/block-staging/GenerateMult.mls new file mode 100644 index 0000000000..4b8e6a89a0 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/GenerateMult.mls @@ -0,0 +1,32 @@ +:js +:staging +:noModuleCheck + +import "../../mlscript-compile/staging/SimpleStagedExample.mls" +import "../../mlscript-compile/staging/LinkingGeneratedClasses.mls" +import "../../mlscript-compile/Block.mls" + + +Block.generateAll("CombinedModule", "./hkmc2/shared/src/test/mlscript-compile/staging/out/CombinedModule.mls", [SimpleStagedExample, "SimpleStagedExample", "../SimpleStagedExample.mls"], [LinkingGeneratedClasses, "LinkingGeneratedClasses", "../LinkingGeneratedClasses.mls"]) + + +import "../../mlscript-compile/staging/out/CombinedModule.mls" +open CombinedModule + + +SimpleStagedExample.foo() +//│ = 60 + +:expect 6 +SimpleStagedExample.f(1, 5) +//│ = 6 + +:expect 5 +SimpleStagedExample.fib(5) +//│ = 5 + +LinkingGeneratedClasses.test1 +//│ = C + +LinkingGeneratedClasses.test3 +//│ = D diff --git a/hkmc2/shared/src/test/mlscript/block-staging/GeneratorMap.mls b/hkmc2/shared/src/test/mlscript/block-staging/GeneratorMap.mls new file mode 100644 index 0000000000..0e212d632f --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/GeneratorMap.mls @@ -0,0 +1,11 @@ +:js +:staging +:noModuleCheck + +staged module A with + fun f() = 1 + fun g(x) = x + +A."generatorMap$A" +//│ = Map(2) {"f" => fun f_gen, "g" => fun g_gen} + diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Hygiene.mls b/hkmc2/shared/src/test/mlscript/block-staging/Hygiene.mls new file mode 100644 index 0000000000..6913949ef1 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/Hygiene.mls @@ -0,0 +1,25 @@ +:js +:staging +:noModuleCheck + + +import "../../mlscript-compile/ShapeSet.mls" + +open ShapeSet + + +staged module Foo with + fun foo(x) = x + 1 + fun foo_Foo_sp_0(x) = x - 1 + fun foo_Foo_sp_1(x) = x - 2 + + +Foo."foo_gen"(mkLit(0)) +//│ = ["foo_Foo_sp_2", {Lit(1)}] + + +print(Foo."cache$Foo") +//│ > module Foo with +//│ > () +//│ > fun foo_Foo_sp_2(x) = 1 + diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Inheritance.mls b/hkmc2/shared/src/test/mlscript/block-staging/Inheritance.mls new file mode 100644 index 0000000000..8985393d31 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/Inheritance.mls @@ -0,0 +1,12 @@ +:js +:staging +:noModuleCheck + + +fun gen(M, name) = + M."generate"("../" + name + ".mls", "./hkmc2/shared/src/test/mlscript-compile/staging/out/" + name + ".mls") + +import "../../mlscript-compile/staging/Inheritance.mls" + +gen(Inheritance, "Inheritance") + diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Nested.mls b/hkmc2/shared/src/test/mlscript/block-staging/Nested.mls index dd89573888..0c0478451f 100644 --- a/hkmc2/shared/src/test/mlscript/block-staging/Nested.mls +++ b/hkmc2/shared/src/test/mlscript/block-staging/Nested.mls @@ -25,44 +25,71 @@ staged module LiftedNested with //│ define LiftedNested⁰ as class LiftedNested¹ //│ staged module LiftedNested² { //│ constructor { -//│ let tmp, tmp1, tmp2, tmp3; -//│ set tmp2 = LiftedNested².this.ctor$_instr﹖(); -//│ set tmp3 = Block⁰.printCode﹖(tmp2); -//│ set tmp = LiftedNested².this.f_instr﹖(); -//│ set tmp1 = Block⁰.printCode﹖(tmp); +//│ let tmp, tmp1, tmp2, sym, tmp3, tmp4, tmp5, tmp6, tmp7; +//│ set sym = Block⁰.ModuleSymbol﹖("LiftedNested", LiftedNested².this, false); +//│ set tmp3 = runtime⁰.SymbolMap﹖.checkModuleMap﹖(LiftedNested².this, sym); +//│ set tmp4 = new globalThis⁰.Map﹖(); +//│ set tmp5 = ["f"]; +//│ set tmp6 = new globalThis⁰.Set﹖(tmp5); +//│ set tmp7 = new SpecializeHelpers⁰.FunCache﹖(tmp3, tmp4, tmp6); +//│ define cache$LiftedNested⁰ as val cache$LiftedNested¹ = tmp7; +//│ set tmp = ["f", LiftedNested².this.f_gen﹖]; +//│ set tmp1 = [tmp]; +//│ set tmp2 = new globalThis⁰.Map﹖(tmp1); +//│ define generatorMap$LiftedNested⁰ as val generatorMap$LiftedNested¹ = tmp2; +//│ end +//│ } +//│ method generate⁰ = fun generate¹(source, path) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = LiftedNested².this.propagate﹖(); +//│ set tmp1 = []; +//│ set tmp2 = Block⁰.codegen﹖("LiftedNested", LiftedNested².this.cache$LiftedNested﹖, source, path, tmp1); //│ end //│ } //│ method ctor$_instr⁰ = fun ctor$_instr¹() { -//│ let end, tmp, tmp1, tmp2, tmp3; +//│ let sym, tmp, tmp1, end, tmp2; +//│ set sym = Block⁰.Symbol﹖("ctor$"); +//│ set tmp = []; +//│ set tmp1 = [tmp]; //│ set end = Block⁰.End﹖(); -//│ set tmp = Block⁰.Symbol﹖("ctor$"); -//│ set tmp1 = []; -//│ set tmp2 = [tmp1]; -//│ set tmp3 = Block⁰.FunDefn﹖(tmp, tmp2, end, true); -//│ return tmp3 +//│ set tmp2 = Block⁰.FunDefn﹖(sym, tmp1, end); +//│ return tmp2 +//│ } +//│ method propagate⁰ = fun propagate¹() { +//│ let tmp_dyn, gen_call; +//│ set tmp_dyn = ShapeSet⁰.mkDyn﹖(); +//│ set gen_call = LiftedNested².this.f_gen﹖(); +//│ end //│ } -//│ method f⁰ = fun f¹() { -//│ return g⁰() +//│ method toCode⁰ = fun toCode¹() { +//│ let tmp, tmp1; +//│ set tmp = []; +//│ set tmp1 = Block⁰.toCode﹖("LiftedNested", LiftedNested².this.cache$LiftedNested﹖, tmp); +//│ return tmp1 //│ } //│ method f_instr⁰ = fun f_instr¹() { -//│ let sym, var1, tmp, app, return1, tmp1, tmp2, tmp3, tmp4; -//│ set sym = Block⁰.Symbol﹖("g"); -//│ set var1 = Block⁰.ValueMemberRef﹖(sym); +//│ let sym, tmp, tmp1, sym1, var1, tmp2, app, return1, tmp3; +//│ set sym = Block⁰.Symbol﹖("f"); //│ set tmp = []; -//│ set app = Block⁰.Call﹖(var1, tmp); -//│ set return1 = Block⁰.Return﹖(app); -//│ set tmp1 = Block⁰.Symbol﹖("f"); +//│ set tmp1 = [tmp]; +//│ set sym1 = Block⁰.Symbol﹖("g"); +//│ set var1 = Block⁰.ValueMemberRef﹖(sym1); //│ set tmp2 = []; -//│ set tmp3 = [tmp2]; -//│ set tmp4 = Block⁰.FunDefn﹖(tmp1, tmp3, return1, true); -//│ return tmp4 +//│ set app = Block⁰.Call﹖(var1, tmp2); +//│ set return1 = Block⁰.Return﹖(app); +//│ set tmp3 = Block⁰.FunDefn﹖(sym, tmp1, return1); +//│ return tmp3 +//│ } +//│ method f_gen⁰ = fun f_gen¹() { +//│ let tmp, tmp1, tmp2; +//│ set tmp = []; +//│ set tmp1 = [tmp]; +//│ set tmp2 = SpecializeHelpers⁰.specialize﹖(LiftedNested².this.cache$LiftedNested﹖, "f", LiftedNested².this.f_instr﹖, tmp1); +//│ return tmp2 //│ } //│ }; //│ end //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— -//│ > fun ctor_() = () -//│ > fun f() = g() - staged module LiftedLambda with fun foo(x) = y => x + y @@ -72,80 +99,243 @@ staged module LiftedLambda with //│ define lambda as staged fun lambda⁰(x, y) { //│ return +⁰(x, y) //│ }; -//│ @staged -//│ define Function$ as staged class Function$⁰ extends globalThis⁰.Function⁰ { -//│ private val x⁰; +//│ define Function$ as class Function$⁰ extends globalThis⁰.Function⁰ { +//│ val x⁰; //│ constructor(x) { //│ do super⁰(); //│ end; -//│ set Function$⁰.this.x⁰ = x; +//│ let tmp; +//│ set tmp = x; +//│ define x⁰ as val x¹ = tmp; //│ end //│ } //│ method call⁰ = fun call¹(y) { -//│ return lambda⁰(Function$⁰.this.x⁰, y) +//│ return lambda⁰(Function$⁰.this.x﹖, y) +//│ } +//│ } +//│ module Function$¹ { +//│ constructor { +//│ let tmp, tmp1, tmp2, tmp3, tmp4, sym, tmp5, tmp6, tmp7, sym1, tmp8, tmp9, tmp10, tmp11, tmp12; +//│ set tmp3 = option⁰.None﹖; +//│ set tmp4 = option⁰.None﹖; +//│ set sym = Block⁰.Symbol﹖("x"); +//│ set tmp5 = Block⁰.Param﹖(tmp4, sym); +//│ set tmp6 = [tmp5]; +//│ set tmp7 = [tmp6]; +//│ set sym1 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$⁰, tmp3, tmp7, true); +//│ set tmp8 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$⁰, sym1); +//│ set tmp9 = new globalThis⁰.Map﹖(); +//│ set tmp10 = ["call", "x"]; +//│ set tmp11 = new globalThis⁰.Set﹖(tmp10); +//│ set tmp12 = new SpecializeHelpers⁰.FunCache﹖(tmp8, tmp9, tmp11); +//│ define class$cache$Function$⁰ as val class$cache$Function$¹ = tmp12; +//│ set tmp = ["call", Function$¹.this.call_gen﹖]; +//│ set tmp1 = [tmp]; +//│ set tmp2 = new globalThis⁰.Map﹖(tmp1); +//│ define class$generatorMap$Function$⁰ as val class$generatorMap$Function$¹ = tmp2; +//│ end +//│ } +//│ method generate² = fun generate³(source, path) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = Function$¹.this.propagate﹖(); +//│ set tmp1 = []; +//│ set tmp2 = Block⁰.codegen﹖("Function$", Function$¹.this.class$cache$Function$﹖, source, path, tmp1); +//│ end +//│ } +//│ method preCtor$_instr⁰ = fun preCtor$_instr¹() { +//│ let sym, tmp, sym1, tmp1, tmp2, tmp3, sym2, tmp4, tmp5, tmp6, sym3, tmp7, sel, tmp8, app, sym4, tmp9, end, assign, tmp10; +//│ set sym = Block⁰.Symbol﹖("preCtor$"); +//│ set tmp = option⁰.None﹖; +//│ set sym1 = Block⁰.Symbol﹖("x"); +//│ set tmp1 = Block⁰.Param﹖(tmp, sym1); +//│ set tmp2 = [tmp1]; +//│ set tmp3 = [tmp2]; +//│ set sym2 = Block⁰.Symbol﹖("globalThis"); +//│ set tmp4 = Block⁰.ValueThis﹖(sym2); +//│ set tmp5 = option⁰.None﹖; +//│ set tmp6 = []; +//│ set sym3 = Block⁰.ConcreteClassSymbol﹖("Function", globalThis⁰.Function⁰, tmp5, tmp6, false); +//│ set tmp7 = runtime⁰.SymbolMap﹖.checkClassMap﹖(globalThis⁰.Function⁰, sym3); +//│ set sel = Block⁰.Select﹖(tmp4, tmp7); +//│ set tmp8 = []; +//│ set app = Block⁰.Call﹖(sel, tmp8); +//│ set sym4 = Block⁰.NoSymbol﹖(); +//│ set tmp9 = Block⁰.ValueSimpleRef﹖(sym4); +//│ set end = Block⁰.End﹖(); +//│ set assign = Block⁰.Assign﹖(sym4, app, end); +//│ set tmp10 = Block⁰.FunDefn﹖(sym, tmp3, assign); +//│ return tmp10 +//│ } +//│ method class$ctor$_instr⁰ = fun class$ctor$_instr¹() { +//│ let tmp, sym, tmp1, sym1, tmp2, tmp3, tmp4, sym2, tmp5, var1, tmp6, tmp7, tmp8, sym3, tmp9, tmp10, tmp11, sym4, tmp12, tmp13, sym5, end, tmp14, tmp15, assign, tmp16, tmp17; +//│ set sym = Block⁰.Symbol﹖("class$ctor$"); +//│ set tmp1 = option⁰.None﹖; +//│ set sym1 = Block⁰.Symbol﹖("x"); +//│ set tmp2 = Block⁰.Param﹖(tmp1, sym1); +//│ set tmp3 = [tmp2]; +//│ set tmp4 = [tmp3]; +//│ set sym2 = Block⁰.Symbol﹖("tmp"); +//│ set tmp5 = [sym2]; +//│ set var1 = Block⁰.ValueSimpleRef﹖(sym1); +//│ set tmp6 = Block⁰.ValueSimpleRef﹖(sym2); +//│ set tmp = tmp6; +//│ set tmp7 = option⁰.None﹖; +//│ set tmp8 = option⁰.None﹖; +//│ set sym3 = Block⁰.Symbol﹖("x"); +//│ set tmp9 = Block⁰.Param﹖(tmp8, sym3); +//│ set tmp10 = [tmp9]; +//│ set tmp11 = [tmp10]; +//│ set sym4 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$⁰, tmp7, tmp11, true); +//│ set tmp12 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$⁰, sym4); +//│ set tmp13 = option⁰.Some﹖(tmp12); +//│ set sym5 = Block⁰.Symbol﹖("x"); +//│ set end = Block⁰.End﹖(); +//│ set tmp14 = Block⁰.ValDefn﹖(tmp13, sym5, tmp6); +//│ set tmp15 = Block⁰.Define﹖(tmp14, end); +//│ set assign = Block⁰.Assign﹖(sym2, var1, tmp15); +//│ set tmp16 = Block⁰.Scoped﹖(tmp5, assign); +//│ set tmp17 = Block⁰.FunDefn﹖(sym, tmp4, tmp16); +//│ return tmp17 +//│ } +//│ method propagate² = fun propagate³() { +//│ let tmp_dyn, gen_call, gen_call1; +//│ set tmp_dyn = ShapeSet⁰.mkDyn﹖(); +//│ set gen_call = Function$¹.this.call_gen﹖(tmp_dyn); +//│ set gen_call1 = gen_call(tmp_dyn); +//│ end +//│ } +//│ method toCode² = fun toCode³() { +//│ let tmp, tmp1; +//│ set tmp = []; +//│ set tmp1 = Block⁰.toCode﹖("Function$", Function$¹.this.class$cache$Function$﹖, tmp); +//│ return tmp1 +//│ } +//│ method call_instr⁰ = fun call_instr¹() { +//│ let sym, tmp, sym1, tmp1, tmp2, tmp3, sym2, var1, tmp4, tmp5, sym3, tmp6, tmp7, tmp8, sym4, tmp9, tmp10, tmp11, sel, tmp12, var2, tmp13, tmp14, app, return1, tmp15; +//│ set sym = Block⁰.Symbol﹖("call"); +//│ set tmp = option⁰.None﹖; +//│ set sym1 = Block⁰.Symbol﹖("y"); +//│ set tmp1 = Block⁰.Param﹖(tmp, sym1); +//│ set tmp2 = [tmp1]; +//│ set tmp3 = [tmp2]; +//│ set sym2 = Block⁰.Symbol﹖("lambda"); +//│ set var1 = Block⁰.ValueMemberRef﹖(sym2); +//│ set tmp4 = option⁰.None﹖; +//│ set tmp5 = option⁰.None﹖; +//│ set sym3 = Block⁰.Symbol﹖("x"); +//│ set tmp6 = Block⁰.Param﹖(tmp5, sym3); +//│ set tmp7 = [tmp6]; +//│ set tmp8 = [tmp7]; +//│ set sym4 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$⁰, tmp4, tmp8, true); +//│ set tmp9 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$⁰, sym4); +//│ set tmp10 = Block⁰.ValueThis﹖(tmp9); +//│ set tmp11 = Block⁰.Symbol﹖("x"); +//│ set sel = Block⁰.Select﹖(tmp10, tmp11); +//│ set tmp12 = Block⁰.Arg﹖(sel); +//│ set var2 = Block⁰.ValueSimpleRef﹖(sym1); +//│ set tmp13 = Block⁰.Arg﹖(var2); +//│ set tmp14 = [tmp12, tmp13]; +//│ set app = Block⁰.Call﹖(var1, tmp14); +//│ set return1 = Block⁰.Return﹖(app); +//│ set tmp15 = Block⁰.FunDefn﹖(sym, tmp3, return1); +//│ return tmp15 +//│ } +//│ method call_gen⁰ = fun call_gen¹(cls)(y) { +//│ let tmp, tmp1, tmp2, tmp3; +//│ set tmp = [cls]; +//│ set tmp1 = [y]; +//│ set tmp2 = [tmp, tmp1]; +//│ set tmp3 = SpecializeHelpers⁰.specialize﹖(Function$¹.this.class$cache$Function$﹖, "call", Function$¹.this.call_instr﹖, tmp2); +//│ return tmp3 //│ } //│ }; //│ define LiftedLambda⁰ as class LiftedLambda¹ //│ staged module LiftedLambda² { //│ constructor { -//│ let tmp, tmp1, tmp2, tmp3; -//│ set tmp2 = LiftedLambda².this.ctor$_instr﹖(); -//│ set tmp3 = Block⁰.printCode﹖(tmp2); -//│ set tmp = LiftedLambda².this.foo_instr﹖(); -//│ set tmp1 = Block⁰.printCode﹖(tmp); +//│ let tmp, tmp1, tmp2, sym, tmp3, tmp4, tmp5, tmp6, tmp7; +//│ set sym = Block⁰.ModuleSymbol﹖("LiftedLambda", LiftedLambda².this, false); +//│ set tmp3 = runtime⁰.SymbolMap﹖.checkModuleMap﹖(LiftedLambda².this, sym); +//│ set tmp4 = new globalThis⁰.Map﹖(); +//│ set tmp5 = ["foo"]; +//│ set tmp6 = new globalThis⁰.Set﹖(tmp5); +//│ set tmp7 = new SpecializeHelpers⁰.FunCache﹖(tmp3, tmp4, tmp6); +//│ define cache$LiftedLambda⁰ as val cache$LiftedLambda¹ = tmp7; +//│ set tmp = ["foo", LiftedLambda².this.foo_gen﹖]; +//│ set tmp1 = [tmp]; +//│ set tmp2 = new globalThis⁰.Map﹖(tmp1); +//│ define generatorMap$LiftedLambda⁰ as val generatorMap$LiftedLambda¹ = tmp2; +//│ define Function$$LiftedLambda⁰ as val Function$$LiftedLambda¹ = Function$⁰; +//│ end +//│ } +//│ method generate⁴ = fun generate⁵(source, path) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = LiftedLambda².this.propagate﹖(); +//│ set tmp1 = []; +//│ set tmp2 = Block⁰.codegen﹖("LiftedLambda", LiftedLambda².this.cache$LiftedLambda﹖, source, path, tmp1); //│ end //│ } //│ method ctor$_instr² = fun ctor$_instr³() { -//│ let end, tmp, tmp1, tmp2, tmp3; +//│ let sym, tmp, tmp1, end, tmp2; +//│ set sym = Block⁰.Symbol﹖("ctor$"); +//│ set tmp = []; +//│ set tmp1 = [tmp]; //│ set end = Block⁰.End﹖(); -//│ set tmp = Block⁰.Symbol﹖("ctor$"); -//│ set tmp1 = []; -//│ set tmp2 = [tmp1]; -//│ set tmp3 = Block⁰.FunDefn﹖(tmp, tmp2, end, true); -//│ return tmp3 +//│ set tmp2 = Block⁰.FunDefn﹖(sym, tmp1, end); +//│ return tmp2 //│ } -//│ method foo⁰ = fun foo¹(x) { -//│ let tmp; -//│ set tmp = new Function$⁰(x); -//│ return tmp +//│ method propagate⁴ = fun propagate⁵() { +//│ let tmp_dyn, gen_call; +//│ set tmp_dyn = ShapeSet⁰.mkDyn﹖(); +//│ set gen_call = LiftedLambda².this.foo_gen﹖(tmp_dyn); +//│ end +//│ } +//│ method toCode⁴ = fun toCode⁵() { +//│ let tmp, tmp1; +//│ set tmp = []; +//│ set tmp1 = Block⁰.toCode﹖("LiftedLambda", LiftedLambda².this.cache$LiftedLambda﹖, tmp); +//│ return tmp1 //│ } //│ method foo_instr⁰ = fun foo_instr¹() { -//│ let x, tmp, sym, tmp1, sym1, var1, tmp2, tmp3, sym2, tmp4, tmp5, sym3, var2, tmp6, inst, sym4, tmp7, return1, assign, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13; -//│ set sym = Block⁰.Symbol﹖("tmp"); -//│ set tmp1 = [sym]; +//│ let tmp, sym, tmp1, sym1, tmp2, tmp3, tmp4, sym2, tmp5, var1, tmp6, tmp7, tmp8, sym3, tmp9, tmp10, tmp11, sym4, tmp12, var2, tmp13, inst, tmp14, return1, assign, tmp15, tmp16; +//│ set sym = Block⁰.Symbol﹖("foo"); +//│ set tmp1 = option⁰.None﹖; //│ set sym1 = Block⁰.Symbol﹖("x"); +//│ set tmp2 = Block⁰.Param﹖(tmp1, sym1); +//│ set tmp3 = [tmp2]; +//│ set tmp4 = [tmp3]; +//│ set sym2 = Block⁰.Symbol﹖("tmp1"); +//│ set tmp5 = [sym2]; //│ set var1 = Block⁰.ValueSimpleRef﹖(sym1); -//│ set tmp2 = Block⁰.Arg﹖(var1); -//│ set tmp3 = option⁰.None﹖; -//│ set sym2 = Block⁰.Symbol﹖("x1"); -//│ set tmp4 = [sym2]; -//│ set tmp5 = [tmp4]; -//│ set sym3 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$⁰, tmp3, tmp5); -//│ set var2 = Block⁰.ValueMemberRef﹖(sym3); -//│ set tmp6 = [tmp2]; -//│ set inst = Block⁰.Instantiate﹖(var2, tmp6); -//│ set sym4 = Block⁰.Symbol﹖("tmp"); -//│ set tmp7 = Block⁰.ValueSimpleRef﹖(sym4); -//│ set tmp = tmp7; -//│ set return1 = Block⁰.Return﹖(tmp7); -//│ set assign = Block⁰.Assign﹖(sym4, inst, return1); -//│ set tmp8 = Block⁰.Scoped﹖(tmp1, assign); -//│ set tmp9 = Block⁰.Symbol﹖("x"); -//│ set tmp10 = Block⁰.Symbol﹖("foo"); -//│ set tmp11 = [tmp9]; -//│ set tmp12 = [tmp11]; -//│ set tmp13 = Block⁰.FunDefn﹖(tmp10, tmp12, tmp8, true); -//│ return tmp13 +//│ set tmp6 = Block⁰.Arg﹖(var1); +//│ set tmp7 = option⁰.None﹖; +//│ set tmp8 = option⁰.None﹖; +//│ set sym3 = Block⁰.Symbol﹖("x"); +//│ set tmp9 = Block⁰.Param﹖(tmp8, sym3); +//│ set tmp10 = [tmp9]; +//│ set tmp11 = [tmp10]; +//│ set sym4 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$⁰, tmp7, tmp11, true); +//│ set tmp12 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$⁰, sym4); +//│ set var2 = Block⁰.ValueMemberRef﹖(tmp12); +//│ set tmp13 = [tmp6]; +//│ set inst = Block⁰.Instantiate﹖(var2, tmp13); +//│ set tmp14 = Block⁰.ValueSimpleRef﹖(sym2); +//│ set tmp = tmp14; +//│ set return1 = Block⁰.Return﹖(tmp14); +//│ set assign = Block⁰.Assign﹖(sym2, inst, return1); +//│ set tmp15 = Block⁰.Scoped﹖(tmp5, assign); +//│ set tmp16 = Block⁰.FunDefn﹖(sym, tmp4, tmp15); +//│ return tmp16 +//│ } +//│ method foo_gen⁰ = fun foo_gen¹(x) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = [x]; +//│ set tmp1 = [tmp]; +//│ set tmp2 = SpecializeHelpers⁰.specialize﹖(LiftedLambda².this.cache$LiftedLambda﹖, "foo", LiftedLambda².this.foo_instr﹖, tmp1); +//│ return tmp2 //│ } //│ }; //│ end //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— -//│ > fun ctor_() = () -//│ > fun foo(x) = -//│ > let {tmp} -//│ > tmp = new Function_(x) -//│ > tmp - staged module LiftedMultParams with fun foo(x)(y) = x + y @@ -155,76 +345,240 @@ staged module LiftedMultParams with //│ define lambda$ as staged fun lambda$⁰(x, y) { //│ return +⁰(x, y) //│ }; -//│ @staged -//│ define Function$ as staged class Function$¹ extends globalThis⁰.Function⁰ { -//│ private val x¹; +//│ define Function$ as class Function$² extends globalThis⁰.Function⁰ { +//│ val x²; //│ constructor(x) { //│ do super⁰(); //│ end; -//│ set Function$¹.this.x¹ = x; +//│ let tmp; +//│ set tmp = x; +//│ define x² as val x³ = tmp; //│ end //│ } //│ method call² = fun call³(y) { -//│ return lambda$⁰(Function$¹.this.x¹, y) +//│ return lambda$⁰(Function$².this.x﹖, y) +//│ } +//│ } +//│ module Function$³ { +//│ constructor { +//│ let tmp, tmp1, tmp2, tmp3, tmp4, sym, tmp5, tmp6, tmp7, sym1, tmp8, tmp9, tmp10, tmp11, tmp12; +//│ set tmp3 = option⁰.None﹖; +//│ set tmp4 = option⁰.None﹖; +//│ set sym = Block⁰.Symbol﹖("x"); +//│ set tmp5 = Block⁰.Param﹖(tmp4, sym); +//│ set tmp6 = [tmp5]; +//│ set tmp7 = [tmp6]; +//│ set sym1 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$², tmp3, tmp7, true); +//│ set tmp8 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$², sym1); +//│ set tmp9 = new globalThis⁰.Map﹖(); +//│ set tmp10 = ["call", "x"]; +//│ set tmp11 = new globalThis⁰.Set﹖(tmp10); +//│ set tmp12 = new SpecializeHelpers⁰.FunCache﹖(tmp8, tmp9, tmp11); +//│ define class$cache$Function$² as val class$cache$Function$³ = tmp12; +//│ set tmp = ["call", Function$³.this.call_gen﹖]; +//│ set tmp1 = [tmp]; +//│ set tmp2 = new globalThis⁰.Map﹖(tmp1); +//│ define class$generatorMap$Function$² as val class$generatorMap$Function$³ = tmp2; +//│ end +//│ } +//│ method generate⁶ = fun generate⁷(source, path) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = Function$³.this.propagate﹖(); +//│ set tmp1 = []; +//│ set tmp2 = Block⁰.codegen﹖("Function$", Function$³.this.class$cache$Function$﹖, source, path, tmp1); +//│ end +//│ } +//│ method preCtor$_instr² = fun preCtor$_instr³() { +//│ let sym, tmp, sym1, tmp1, tmp2, tmp3, sym2, tmp4, tmp5, tmp6, sym3, tmp7, sel, tmp8, app, sym4, tmp9, end, assign, tmp10; +//│ set sym = Block⁰.Symbol﹖("preCtor$"); +//│ set tmp = option⁰.None﹖; +//│ set sym1 = Block⁰.Symbol﹖("x"); +//│ set tmp1 = Block⁰.Param﹖(tmp, sym1); +//│ set tmp2 = [tmp1]; +//│ set tmp3 = [tmp2]; +//│ set sym2 = Block⁰.Symbol﹖("globalThis"); +//│ set tmp4 = Block⁰.ValueThis﹖(sym2); +//│ set tmp5 = option⁰.None﹖; +//│ set tmp6 = []; +//│ set sym3 = Block⁰.ConcreteClassSymbol﹖("Function", globalThis⁰.Function⁰, tmp5, tmp6, false); +//│ set tmp7 = runtime⁰.SymbolMap﹖.checkClassMap﹖(globalThis⁰.Function⁰, sym3); +//│ set sel = Block⁰.Select﹖(tmp4, tmp7); +//│ set tmp8 = []; +//│ set app = Block⁰.Call﹖(sel, tmp8); +//│ set sym4 = Block⁰.NoSymbol﹖(); +//│ set tmp9 = Block⁰.ValueSimpleRef﹖(sym4); +//│ set end = Block⁰.End﹖(); +//│ set assign = Block⁰.Assign﹖(sym4, app, end); +//│ set tmp10 = Block⁰.FunDefn﹖(sym, tmp3, assign); +//│ return tmp10 +//│ } +//│ method class$ctor$_instr² = fun class$ctor$_instr³() { +//│ let tmp, sym, tmp1, sym1, tmp2, tmp3, tmp4, sym2, tmp5, var1, tmp6, tmp7, tmp8, sym3, tmp9, tmp10, tmp11, sym4, tmp12, tmp13, sym5, end, tmp14, tmp15, assign, tmp16, tmp17; +//│ set sym = Block⁰.Symbol﹖("class$ctor$"); +//│ set tmp1 = option⁰.None﹖; +//│ set sym1 = Block⁰.Symbol﹖("x"); +//│ set tmp2 = Block⁰.Param﹖(tmp1, sym1); +//│ set tmp3 = [tmp2]; +//│ set tmp4 = [tmp3]; +//│ set sym2 = Block⁰.Symbol﹖("tmp"); +//│ set tmp5 = [sym2]; +//│ set var1 = Block⁰.ValueSimpleRef﹖(sym1); +//│ set tmp6 = Block⁰.ValueSimpleRef﹖(sym2); +//│ set tmp = tmp6; +//│ set tmp7 = option⁰.None﹖; +//│ set tmp8 = option⁰.None﹖; +//│ set sym3 = Block⁰.Symbol﹖("x"); +//│ set tmp9 = Block⁰.Param﹖(tmp8, sym3); +//│ set tmp10 = [tmp9]; +//│ set tmp11 = [tmp10]; +//│ set sym4 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$², tmp7, tmp11, true); +//│ set tmp12 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$², sym4); +//│ set tmp13 = option⁰.Some﹖(tmp12); +//│ set sym5 = Block⁰.Symbol﹖("x"); +//│ set end = Block⁰.End﹖(); +//│ set tmp14 = Block⁰.ValDefn﹖(tmp13, sym5, tmp6); +//│ set tmp15 = Block⁰.Define﹖(tmp14, end); +//│ set assign = Block⁰.Assign﹖(sym2, var1, tmp15); +//│ set tmp16 = Block⁰.Scoped﹖(tmp5, assign); +//│ set tmp17 = Block⁰.FunDefn﹖(sym, tmp4, tmp16); +//│ return tmp17 +//│ } +//│ method propagate⁶ = fun propagate⁷() { +//│ let tmp_dyn, gen_call, gen_call1; +//│ set tmp_dyn = ShapeSet⁰.mkDyn﹖(); +//│ set gen_call = Function$³.this.call_gen﹖(tmp_dyn); +//│ set gen_call1 = gen_call(tmp_dyn); +//│ end +//│ } +//│ method toCode⁶ = fun toCode⁷() { +//│ let tmp, tmp1; +//│ set tmp = []; +//│ set tmp1 = Block⁰.toCode﹖("Function$", Function$³.this.class$cache$Function$﹖, tmp); +//│ return tmp1 +//│ } +//│ method call_instr² = fun call_instr³() { +//│ let sym, tmp, sym1, tmp1, tmp2, tmp3, sym2, var1, tmp4, tmp5, sym3, tmp6, tmp7, tmp8, sym4, tmp9, tmp10, tmp11, sel, tmp12, var2, tmp13, tmp14, app, return1, tmp15; +//│ set sym = Block⁰.Symbol﹖("call"); +//│ set tmp = option⁰.None﹖; +//│ set sym1 = Block⁰.Symbol﹖("y"); +//│ set tmp1 = Block⁰.Param﹖(tmp, sym1); +//│ set tmp2 = [tmp1]; +//│ set tmp3 = [tmp2]; +//│ set sym2 = Block⁰.Symbol﹖("lambda$"); +//│ set var1 = Block⁰.ValueMemberRef﹖(sym2); +//│ set tmp4 = option⁰.None﹖; +//│ set tmp5 = option⁰.None﹖; +//│ set sym3 = Block⁰.Symbol﹖("x"); +//│ set tmp6 = Block⁰.Param﹖(tmp5, sym3); +//│ set tmp7 = [tmp6]; +//│ set tmp8 = [tmp7]; +//│ set sym4 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$², tmp4, tmp8, true); +//│ set tmp9 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$², sym4); +//│ set tmp10 = Block⁰.ValueThis﹖(tmp9); +//│ set tmp11 = Block⁰.Symbol﹖("x"); +//│ set sel = Block⁰.Select﹖(tmp10, tmp11); +//│ set tmp12 = Block⁰.Arg﹖(sel); +//│ set var2 = Block⁰.ValueSimpleRef﹖(sym1); +//│ set tmp13 = Block⁰.Arg﹖(var2); +//│ set tmp14 = [tmp12, tmp13]; +//│ set app = Block⁰.Call﹖(var1, tmp14); +//│ set return1 = Block⁰.Return﹖(app); +//│ set tmp15 = Block⁰.FunDefn﹖(sym, tmp3, return1); +//│ return tmp15 +//│ } +//│ method call_gen² = fun call_gen³(cls)(y) { +//│ let tmp, tmp1, tmp2, tmp3; +//│ set tmp = [cls]; +//│ set tmp1 = [y]; +//│ set tmp2 = [tmp, tmp1]; +//│ set tmp3 = SpecializeHelpers⁰.specialize﹖(Function$³.this.class$cache$Function$﹖, "call", Function$³.this.call_instr﹖, tmp2); +//│ return tmp3 //│ } //│ }; //│ define LiftedMultParams⁰ as class LiftedMultParams¹ //│ staged module LiftedMultParams² { //│ constructor { -//│ let tmp, tmp1, tmp2, tmp3; -//│ set tmp2 = LiftedMultParams².this.ctor$_instr﹖(); -//│ set tmp3 = Block⁰.printCode﹖(tmp2); -//│ set tmp = LiftedMultParams².this.foo_instr﹖(); -//│ set tmp1 = Block⁰.printCode﹖(tmp); +//│ let tmp, tmp1, tmp2, sym, tmp3, tmp4, tmp5, tmp6, tmp7; +//│ set sym = Block⁰.ModuleSymbol﹖("LiftedMultParams", LiftedMultParams².this, false); +//│ set tmp3 = runtime⁰.SymbolMap﹖.checkModuleMap﹖(LiftedMultParams².this, sym); +//│ set tmp4 = new globalThis⁰.Map﹖(); +//│ set tmp5 = ["foo"]; +//│ set tmp6 = new globalThis⁰.Set﹖(tmp5); +//│ set tmp7 = new SpecializeHelpers⁰.FunCache﹖(tmp3, tmp4, tmp6); +//│ define cache$LiftedMultParams⁰ as val cache$LiftedMultParams¹ = tmp7; +//│ set tmp = ["foo", LiftedMultParams².this.foo_gen﹖]; +//│ set tmp1 = [tmp]; +//│ set tmp2 = new globalThis⁰.Map﹖(tmp1); +//│ define generatorMap$LiftedMultParams⁰ as val generatorMap$LiftedMultParams¹ = tmp2; +//│ define Function$$LiftedMultParams⁰ as val Function$$LiftedMultParams¹ = Function$²; +//│ end +//│ } +//│ method generate⁸ = fun generate⁹(source, path) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = LiftedMultParams².this.propagate﹖(); +//│ set tmp1 = []; +//│ set tmp2 = Block⁰.codegen﹖("LiftedMultParams", LiftedMultParams².this.cache$LiftedMultParams﹖, source, path, tmp1); //│ end //│ } //│ method ctor$_instr⁴ = fun ctor$_instr⁵() { -//│ let end, tmp, tmp1, tmp2, tmp3; +//│ let sym, tmp, tmp1, end, tmp2; +//│ set sym = Block⁰.Symbol﹖("ctor$"); +//│ set tmp = []; +//│ set tmp1 = [tmp]; //│ set end = Block⁰.End﹖(); -//│ set tmp = Block⁰.Symbol﹖("ctor$"); -//│ set tmp1 = []; -//│ set tmp2 = [tmp1]; -//│ set tmp3 = Block⁰.FunDefn﹖(tmp, tmp2, end, true); -//│ return tmp3 +//│ set tmp2 = Block⁰.FunDefn﹖(sym, tmp1, end); +//│ return tmp2 //│ } -//│ method foo² = fun foo³(x) { -//│ let tmp; -//│ set tmp = new Function$¹(x); -//│ return tmp +//│ method propagate⁸ = fun propagate⁹() { +//│ let tmp_dyn, gen_call; +//│ set tmp_dyn = ShapeSet⁰.mkDyn﹖(); +//│ set gen_call = LiftedMultParams².this.foo_gen﹖(tmp_dyn); +//│ end +//│ } +//│ method toCode⁸ = fun toCode⁹() { +//│ let tmp, tmp1; +//│ set tmp = []; +//│ set tmp1 = Block⁰.toCode﹖("LiftedMultParams", LiftedMultParams².this.cache$LiftedMultParams﹖, tmp); +//│ return tmp1 //│ } //│ method foo_instr² = fun foo_instr³() { -//│ let x, tmp, sym, tmp1, sym1, var1, tmp2, tmp3, sym2, tmp4, tmp5, sym3, var2, tmp6, inst, sym4, tmp7, return1, assign, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13; -//│ set sym = Block⁰.Symbol﹖("tmp"); -//│ set tmp1 = [sym]; +//│ let tmp, sym, tmp1, sym1, tmp2, tmp3, tmp4, sym2, tmp5, var1, tmp6, tmp7, tmp8, sym3, tmp9, tmp10, tmp11, sym4, tmp12, var2, tmp13, inst, tmp14, return1, assign, tmp15, tmp16; +//│ set sym = Block⁰.Symbol﹖("foo"); +//│ set tmp1 = option⁰.None﹖; //│ set sym1 = Block⁰.Symbol﹖("x"); +//│ set tmp2 = Block⁰.Param﹖(tmp1, sym1); +//│ set tmp3 = [tmp2]; +//│ set tmp4 = [tmp3]; +//│ set sym2 = Block⁰.Symbol﹖("tmp1"); +//│ set tmp5 = [sym2]; //│ set var1 = Block⁰.ValueSimpleRef﹖(sym1); -//│ set tmp2 = Block⁰.Arg﹖(var1); -//│ set tmp3 = option⁰.None﹖; -//│ set sym2 = Block⁰.Symbol﹖("x1"); -//│ set tmp4 = [sym2]; -//│ set tmp5 = [tmp4]; -//│ set sym3 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$¹, tmp3, tmp5); -//│ set var2 = Block⁰.ValueMemberRef﹖(sym3); -//│ set tmp6 = [tmp2]; -//│ set inst = Block⁰.Instantiate﹖(var2, tmp6); -//│ set sym4 = Block⁰.Symbol﹖("tmp"); -//│ set tmp7 = Block⁰.ValueSimpleRef﹖(sym4); -//│ set tmp = tmp7; -//│ set return1 = Block⁰.Return﹖(tmp7); -//│ set assign = Block⁰.Assign﹖(sym4, inst, return1); -//│ set tmp8 = Block⁰.Scoped﹖(tmp1, assign); -//│ set tmp9 = Block⁰.Symbol﹖("x"); -//│ set tmp10 = Block⁰.Symbol﹖("foo"); -//│ set tmp11 = [tmp9]; -//│ set tmp12 = [tmp11]; -//│ set tmp13 = Block⁰.FunDefn﹖(tmp10, tmp12, tmp8, true); -//│ return tmp13 +//│ set tmp6 = Block⁰.Arg﹖(var1); +//│ set tmp7 = option⁰.None﹖; +//│ set tmp8 = option⁰.None﹖; +//│ set sym3 = Block⁰.Symbol﹖("x"); +//│ set tmp9 = Block⁰.Param﹖(tmp8, sym3); +//│ set tmp10 = [tmp9]; +//│ set tmp11 = [tmp10]; +//│ set sym4 = Block⁰.ConcreteClassSymbol﹖("Function$", Function$², tmp7, tmp11, true); +//│ set tmp12 = runtime⁰.SymbolMap﹖.checkClassMap﹖(Function$², sym4); +//│ set var2 = Block⁰.ValueMemberRef﹖(tmp12); +//│ set tmp13 = [tmp6]; +//│ set inst = Block⁰.Instantiate﹖(var2, tmp13); +//│ set tmp14 = Block⁰.ValueSimpleRef﹖(sym2); +//│ set tmp = tmp14; +//│ set return1 = Block⁰.Return﹖(tmp14); +//│ set assign = Block⁰.Assign﹖(sym2, inst, return1); +//│ set tmp15 = Block⁰.Scoped﹖(tmp5, assign); +//│ set tmp16 = Block⁰.FunDefn﹖(sym, tmp4, tmp15); +//│ return tmp16 +//│ } +//│ method foo_gen² = fun foo_gen³(x) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = [x]; +//│ set tmp1 = [tmp]; +//│ set tmp2 = SpecializeHelpers⁰.specialize﹖(LiftedMultParams².this.cache$LiftedMultParams﹖, "foo", LiftedMultParams².this.foo_instr﹖, tmp1); +//│ return tmp2 //│ } //│ }; //│ end //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— -//│ > fun ctor_() = () -//│ > fun foo(x) = -//│ > let {tmp} -//│ > tmp = new Function_(x) -//│ > tmp diff --git a/hkmc2/shared/src/test/mlscript/block-staging/PathStaging.mls b/hkmc2/shared/src/test/mlscript/block-staging/PathStaging.mls new file mode 100644 index 0000000000..939eb7a43b --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/PathStaging.mls @@ -0,0 +1,11 @@ +:js +:staging + +staged class M() with + fun f() = 1 +staged module M with + fun g() = 1 + +module N with + staged class NM() + staged module NM diff --git a/hkmc2/shared/src/test/mlscript/block-staging/PrintCode.mls b/hkmc2/shared/src/test/mlscript/block-staging/PrintCode.mls index 621c69fca0..d12936bb2f 100644 --- a/hkmc2/shared/src/test/mlscript/block-staging/PrintCode.mls +++ b/hkmc2/shared/src/test/mlscript/block-staging/PrintCode.mls @@ -1,5 +1,5 @@ -:staging :js +:staging import "../../mlscript-compile/Block.mls" import "../../mlscript-compile/Option.mls" @@ -7,7 +7,9 @@ import "../../mlscript-compile/Option.mls" open Block open Option -printCode(FunDefn(Symbol("f"), [[Symbol("x")]], Return(ValueLit(1)))) +fun printCode(x) = Printer.default.printCode(x) + +printCode(FunDefn(Symbol("f"), [[Param(None, Symbol("x"))]], Return(ValueLit(1)))) //│ > fun f(x) = 1 printCode(ValueLit(true)) @@ -30,26 +32,26 @@ printCode(DynSelect(ValueSimpleRef(Symbol("p")), ValueSimpleRef(Symbol("field")) //│ > p.(field) :silent -class A(val x)(y) class B -let aSym = ConcreteClassSymbol("A", A, Some([Symbol("x")]), [[Symbol("y")]]) -let bSym = ConcreteClassSymbol("B", B, None, []) +class D(val x)(y) extends B +let bSym = ConcreteClassSymbol("B", B, None, [], false) +let dSym = ConcreteClassSymbol("D", D, Some([Param(None, Symbol("x"))]), [[Param(None, Symbol("y"))]], false) printCode(Call(ValueSimpleRef(Symbol("f")), [Arg(ValueLit(3))])) -printCode(Instantiate(ValueMemberRef(aSym), [Arg(ValueLit(0))])) +printCode(Instantiate(ValueMemberRef(dSym), [Arg(ValueLit(0))])) printCode(Tuple([Arg(ValueSimpleRef(Symbol("x"))), Arg(ValueSimpleRef(Symbol("y")))])) //│ > f(3) -//│ > new A(0) +//│ > new D.class(0) //│ > [x, y] :silent -let f = FunDefn(Symbol("f"), [[Symbol("x")]], Return(ValueLit(1))) +let f = FunDefn(Symbol("f"), [[Param(None, Symbol("x"))]], Return(ValueLit(1))) printCode(f) -printCode(ClsLikeDefn(aSym, [f], None)) -printCode(ClsLikeDefn(bSym, [], None)) +printCode(ClsLikeDefn(dSym, [f], [])) +printCode(ClsLikeDefn(bSym, [], [])) //│ > fun f(x) = 1 -//│ > class A(x) with +//│ > class D(val x)(y) with //│ > fun f(x) = 1 //│ > class B @@ -58,15 +60,16 @@ printCode(Scoped([Symbol("x"), Symbol("y")], Assign(Symbol("x"), ValueLit(4.2), //│ > x = 4.2 //│ > x -printCode(Define(ValDefn(Some(aSym), Symbol("x"), ValueLit(1)), End())) -printCode(Define(ValDefn(None, Symbol("a"), ValueLit(1)), End())) +printCode(Define(ValDefn(Some(dSym), Symbol("x"), ValueLit(1)), End())) //│ > val x = 1 + +printCode(Define(ValDefn(None, Symbol("a"), ValueLit(1)), End())) //│ > val a = 1 -printCode(Match(ValueSimpleRef(Symbol("x")), [Arm(Lit(1), Return(ValueLit(2))), Arm(Cls(aSym, ValueMemberRef(aSym)), Return(ValueLit(3)))], Some(Return(ValueSimpleRef(Symbol("x")))), End())) +printCode(Match(ValueSimpleRef(Symbol("x")), [Arm(Lit(1), Return(ValueLit(2))), Arm(Cls(bSym, ValueMemberRef(bSym)), Return(ValueLit(3)))], Some(Return(ValueSimpleRef(Symbol("x")))), End())) //│ > if x is //│ > 1 then 2 -//│ > A then 3 +//│ > B then 3 //│ > else x printCode(Scoped([Symbol("y")], Match( @@ -80,7 +83,7 @@ printCode(Scoped([Symbol("y")], Match( //│ > else 1 //│ > y -printCode(Scoped([Symbol("y")], Match( +printCode(Scoped([Symbol("y")], Match( ValueLit(1), [Arm(Lit(1), Assign(Symbol("y"), ValueLit(1), Return(ValueSimpleRef(Symbol("y")))))], Some(Assign(Symbol("y"), ValueLit(2), Return(ValueSimpleRef(Symbol("y"))))), @@ -117,3 +120,6 @@ printCode(Scoped([Symbol("y")], Match( //│ > else //│ > y = 3 //│ > y + +Printer(Some(dSym)).printCode(Select(ValueSimpleRef(dSym), Symbol("x"))) +//│ > D.x diff --git a/hkmc2/shared/src/test/mlscript/block-staging/PrintingTest.mls b/hkmc2/shared/src/test/mlscript/block-staging/PrintingTest.mls new file mode 100644 index 0000000000..b2a8c125c1 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/PrintingTest.mls @@ -0,0 +1,9 @@ +:js +:staging + +fun f(_) = 1 +class C(val x) + +staged class D(val x)(val y, val z)(val a) extends C([2, z + f(z)]."0") with + val b = z + z + fun f() = a + x diff --git a/hkmc2/shared/src/test/mlscript/block-staging/ShapeProp.mls b/hkmc2/shared/src/test/mlscript/block-staging/ShapeProp.mls new file mode 100644 index 0000000000..c62f52ee05 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/ShapeProp.mls @@ -0,0 +1,374 @@ +:js +:staging +:noFreeze +:noModuleCheck +:noSanityCheck + +import "../../mlscript-compile/ShapeSet.mls" +open ShapeSet +module NonStaged with + fun sq(x) = x * x + +staged module Staged with + fun sq(x) = x * x + fun fib(n) = if n is + 1 then 1 + 2 then 1 + n then fib(n - 1) + fib(n - 2) + +staged module Simple with + fun f(x, y) = x + y + 1 - 1 + fun fib(n) = if n is + 1 then 1 + 2 then 1 + n then fib(n - 1) + fib(n - 2) + fun pyth(x, y) = NonStaged.sq(x) + NonStaged.sq(y) + fun pyth2(x, y) = Staged.sq(x) + Staged.sq(y) + fun test() = + let four = f(2, 2) + let three = fib(four) + let two = Staged.fib(three) + pyth(two, 4) + fun test2(n) = + let dyn = pyth(n, 2) + fib(dyn * 2) + +Simple."test_gen"() +Simple."test2_gen"(mkDyn()) +print(Simple."cache$Simple") +//│ > module Simple with +//│ > () +//│ > fun fib(n) = +//│ > let {n1, tmp2, tmp3, tmp4, tmp5} +//│ > if n is +//│ > 1 then 1 +//│ > 2 then 1 +//│ > else +//│ > n1 = n +//│ > tmp2 = n1 - 1 +//│ > tmp3 = fib(tmp2) +//│ > tmp4 = n1 - 2 +//│ > tmp5 = fib(tmp4) +//│ > tmp3 + tmp5 +//│ > fun test() = 20 +//│ > fun test2(n) = +//│ > let {dyn, tmp10} +//│ > dyn = pyth_Simple_sp_1(n, 2) +//│ > tmp10 = *(dyn, 2) +//│ > fib(tmp10) +//│ > fun f_Simple_sp_0(x, y) = 4 +//│ > fun fib_Simple_sp_0(n) = 3 +//│ > fun fib_Simple_sp_1(n) = 2 +//│ > fun fib_Simple_sp_2(n) = 1 +//│ > fun fib_Simple_sp_3(n) = 1 +//│ > fun pyth_Simple_sp_0(x, y) = 20 +//│ > fun pyth_Simple_sp_1(x, y) = +//│ > let {tmp6, tmp7} +//│ > tmp6 = Simple__Legacy."NonStaged$Simple".sq(x) +//│ > tmp7 = 4 +//│ > tmp6 + 4 + +class C(val x) + +staged module If with + fun f(x) = if x is + C(2) then "C(2) " + C then "C " + else "else " + fun test() = + f(C(2)) + f(C(3)) + f(2) + fun test2(x, y) = + if x is 1 and + y is 1 then + return 1 + else + 2 + else + 3 + 4 + +If."test_gen"() +//│ = ["test", {Lit("C(2) C else ")}] + +If."test2_gen"(mkLit(1), mkDyn()) +//│ = ["test2_If_sp_0", {Lit(1),Lit(4)}] + +print(If."cache$If") +//│ > module If with +//│ > () +//│ > fun test() = "C(2) C else " +//│ > fun f_If_sp_0(x) = "C(2) " +//│ > fun f_If_sp_1(x) = "C " +//│ > fun f_If_sp_2(x) = "else " +//│ > fun test2_If_sp_0(x, y) = +//│ > let {tmp6} +//│ > if y is +//│ > 1 then 1 +//│ > else +//│ > tmp6 = 2 +//│ > 4 + +class C(val n) +staged module If2 with + fun f(x) = + let y + if x is C then + y = x.n + else + y = 0 + y + 1 + fun test() = f(C(2)) + fun test2(dyn) = f(C(dyn)) + fun test3() = f(0) + +If2."test_gen"() +If2."test2_gen"(mkDyn()) +If2."test3_gen"() +print(If2."cache$If2") +//│ > module If2 with +//│ > () +//│ > fun test() = 3 +//│ > fun test2(dyn) = +//│ > let {tmp2} +//│ > tmp2 = If2__Legacy."C$If2"(dyn) +//│ > f_If2_sp_1(tmp2) +//│ > fun test3() = 1 +//│ > fun f_If2_sp_0(x) = 3 +//│ > fun f_If2_sp_1(x) = +//│ > let {y, tmp} +//│ > y = x.n +//│ > tmp = runtime.Unit +//│ > y + 1 +//│ > fun f_If2_sp_2(x) = 1 + +staged module LinearAlgebra with + fun _dot(v1, v2, n, acc) = + if n == + v1.length then acc + else _dot(v1, v2, n + 1, v1.(n) * v2.(n) + acc) + fun dot(v1, v2) = _dot(v1, v2, 0, 0) + fun test(x) = dot([x, 1, 2], [3, 4, 1]) + +LinearAlgebra."test_gen"(mkDyn()) +print(LinearAlgebra."cache$LinearAlgebra") +//│ > module LinearAlgebra with +//│ > () +//│ > fun test(x) = +//│ > let {tmp3, tmp4} +//│ > tmp3 = [x, 1, 2] +//│ > tmp4 = [3, 4, 1] +//│ > dot_LinearAlgebra_sp_0(tmp3, tmp4) +//│ > fun _dot_LinearAlgebra_sp_0(v1, v2, n, acc) = +//│ > let {scrut, tmp, tmp1, tmp2} +//│ > scrut = false +//│ > tmp = 1 +//│ > tmp1 = *(v1.(0), 3) +//│ > tmp2 = tmp1 + 0 +//│ > _dot_LinearAlgebra_sp_1(v1, v2, tmp, tmp2) +//│ > fun _dot_LinearAlgebra_sp_1(v1, v2, n, acc) = +//│ > let {scrut, tmp, tmp1, tmp2} +//│ > scrut = false +//│ > tmp = 2 +//│ > tmp1 = 4 +//│ > tmp2 = 4 + acc +//│ > _dot_LinearAlgebra_sp_2(v1, v2, tmp, tmp2) +//│ > fun _dot_LinearAlgebra_sp_2(v1, v2, n, acc) = +//│ > let {scrut, tmp, tmp1, tmp2} +//│ > scrut = false +//│ > tmp = 3 +//│ > tmp1 = 2 +//│ > tmp2 = 2 + acc +//│ > _dot_LinearAlgebra_sp_3(v1, v2, tmp, tmp2) +//│ > fun _dot_LinearAlgebra_sp_3(v1, v2, n, acc) = +//│ > let {scrut, tmp, tmp1, tmp2} +//│ > scrut = true +//│ > acc +//│ > fun dot_LinearAlgebra_sp_0(v1, v2) = _dot_LinearAlgebra_sp_0(v1, v2, 0, 0) + +staged class L1(val y) with + fun call(x) = x + 2 + y +staged class L2(val y) with + fun call(x) = x + y +staged class L3(val y) with + fun call(x) = x * 2 + y +class L4(val y) with + fun call(x) = x + y + +staged module Dispatching with + fun twice(f, x) = f.call(f.call(x)) + fun pick(x, y, b) = if b then x else y + fun test(b) = + let y = twice(new L1(1), 5) + let m = pick(new L2(2), new L3(3), b) + twice(m, 5) + +Dispatching."test_gen"(mkLit(true)) +//│ = ["test_Dispatching_sp_0", {Lit(9)}] + +Dispatching."test_gen"(mkLit(false)) +//│ = ["test_Dispatching_sp_1", {Lit(29)}] + +Dispatching."test_gen"(mkDyn()) +//│ = ["test", {Lit(15),Lit(17),Lit(29),Lit(9)}] + +print(Dispatching."cache$Dispatching") +//│ > module Dispatching with +//│ > () +//│ > fun test(b) = +//│ > let {y1, m, tmp1, tmp2, tmp3} +//│ > tmp1 = new L1.class(1) +//│ > y1 = twice_Dispatching_sp_0(tmp1, 5) +//│ > tmp2 = new L2.class(2) +//│ > tmp3 = new L3.class(3) +//│ > m = pick_Dispatching_sp_2(tmp2, tmp3, b) +//│ > twice_Dispatching_sp_3(m, 5) +//│ > fun pick_Dispatching_sp_0(x, y, b) = x +//│ > fun pick_Dispatching_sp_1(x, y, b) = y +//│ > fun pick_Dispatching_sp_2(x, y, b) = +//│ > if b is +//│ > true then x +//│ > else y +//│ > fun test_Dispatching_sp_0(b) = 9 +//│ > fun test_Dispatching_sp_1(b) = 29 +//│ > fun twice_Dispatching_sp_0(f, x) = 11 +//│ > fun twice_Dispatching_sp_1(f, x) = 9 +//│ > fun twice_Dispatching_sp_2(f, x) = 29 +//│ > fun twice_Dispatching_sp_3(f, x) = +//│ > let {tmp} +//│ > if f is +//│ > L2 then +//│ > tmp = call_L2_sp_0(f, x) +//│ > L3 then +//│ > tmp = call_L3_sp_0(f, x) +//│ > if f is +//│ > L2 then call_L2_sp_2(f, tmp) +//│ > L3 then call_L3_sp_2(f, tmp) + +print(L1.class."class$cache$L1") +print(L2.class."class$cache$L2") +print(L3.class."class$cache$L3") +//│ > class L1(val y) with +//│ > () +//│ > fun call_L1_sp_0(self, x) = 8 +//│ > fun call_L1_sp_1(self, x) = 11 +//│ > class L2(val y) with +//│ > () +//│ > fun call_L2_sp_0(self, x) = 7 +//│ > fun call_L2_sp_1(self, x) = 9 +//│ > fun call_L2_sp_2(self, x) = x + 2 +//│ > class L3(val y) with +//│ > () +//│ > fun call_L3_sp_0(self, x) = 13 +//│ > fun call_L3_sp_1(self, x) = 29 +//│ > fun call_L3_sp_2(self, x) = +//│ > let {tmp1} +//│ > tmp1 = *(x, 2) +//│ > tmp1 + 3 + +staged class Bar(val x) with + fun bar() = x +staged class Foo(val x) with + fun foo(b) = + if b is + 1 then x.bar() + 1 + 2 then x.bar() + 2 + else x.bar() + +staged module Dispatching2 with + fun baz(b) = Foo(Bar(1)).foo(b) + +Dispatching2."baz_gen"(mkDyn()) +//│ = ["baz", {Lit(1),Lit(2),Lit(3)}] + +staged class A(val x: Int) with + fun f(y: Int) = x + y +staged class B(val x: Int) with + fun f(y: A) = x + y.f(x) + +staged module This with + fun test(x) = B(x).f(A(1)) + fun test2(y) = B(1).x + y + +This."test_gen"(mkLit(1)) +This."test2_gen"(mkLit(1)) +print(This."cache$This") +//│ > module This with +//│ > () +//│ > fun test2_This_sp_0(y) = 2 +//│ > fun test_This_sp_0(x) = 3 + +print(A.class."class$cache$A") +print(B.class."class$cache$B") +//│ > class A(val x) with +//│ > () +//│ > fun f_A_sp_0(self, y) = 2 +//│ > class B(val x) with +//│ > () +//│ > fun f_B_sp_0(self, y) = 3 + +staged class B(val x, val y) with + val z = x + y + +staged class D(val x, val y) extends B(x + 1, x + 2) + +staged module Inheritance with + fun test() = + let d = D(1, 2) + if d is + B then d.z + else "not B" + +Inheritance."test_gen"() +//│ = ["test", {Lit(5)}] + +staged module NonTermination with + fun f(x, y) = if y + == x then 0 + else f(x, y + 1) + +:re +// NonTermination."f_gen"(mkDyn(), mkLit(0)) + +fun g(x, y) = x + y + +staged module GlobalFunction with + fun test(x) = g(x, x) + +GlobalFunction."test_gen"(mkLit(1)) +//│ = ["test_GlobalFunction_sp_0", {Dyn()}] + +staged module Comparison with + fun test(x) = x < 5 + +Comparison."test_gen"(union(mkLit(3), mkLit(4))) +//│ = ["test_Comparison_sp_0", {Lit(true)}] + +Comparison."test_gen"(union(mkLit(4), mkLit(6))) +//│ = ["test_Comparison_sp_1", {Dyn()}] + +class C +module Opaque with + fun f() = new C +staged module M with + fun f() = Opaque.f() +M."f_gen"() +//│ = ["f", {Dyn()}] + +staged module M with + fun f(x, y) = x * y + fun g(y) = f(2, y) + +M."propagate"() + +M."cache$M" +//│ = module M with \ +//│ () \ +//│ fun f(x, y) = *(x, y) \ +//│ fun g(y) = f_M_sp_0(2, y) \ +//│ fun f_M_sp_0(x, y) = *(2, y) + +staged module M with + fun f(x) = x.2 + +M."f_gen"(mkArr([mkLit(1), mkDyn(), mkLit(2)])) +//│ = ["f_M_sp_0", {Lit(2)}] diff --git a/hkmc2/shared/src/test/mlscript/block-staging/ShapeSetHelpers.mls b/hkmc2/shared/src/test/mlscript/block-staging/ShapeSetHelpers.mls new file mode 100644 index 0000000000..4dffa66f62 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/ShapeSetHelpers.mls @@ -0,0 +1,621 @@ +:js + +import "../../mlscript-compile/Block.mls" +import "../../mlscript-compile/Shape.mls" +import "../../mlscript-compile/ShapeSet.mls" +import "../../mlscript-compile/Option.mls" +import "../../mlscript-compile/CachedHash.mls" +import "../../mlscript-compile/SpecializeHelpers.mls" +import "../../mlscript-compile/Runtime.mls" +open Option +open Block { Param, Symbol, ConcreteClassSymbol, Tup, Case, Printer } +open Shape { Arr, Class, Dyn, Lit } +open ShapeSet +open SpecializeHelpers { sov } + +fun printCode(b) = Printer.default.printCode(b) + +mkBot() +//│ = {} + +mkLit(0) +//│ = {Lit(0)} + +mkDyn() +//│ = {Dyn()} + +mkDyn() == mkDyn() +//│ = false + +mkArr([mkLit(0)]) +//│ = {Arr([{Lit(0)}])} + +assert(mkBot().isEmpty()) + +Shape.static(Shape.Lit("Hi")) +//│ = true + +// valOf +:re +valOf(Dyn()) +//│ ═══[RUNTIME ERROR] Error: valOf on Dyn + +valOf(Arr([mkLit(1), lift(Arr([mkLit(2), mkLit(3)]))])) +//│ = [1, [2, 3]] + +:re +valOf(mkDyn()) +//│ ═══[RUNTIME ERROR] Error: Unknown shape: {Dyn()} + +valOfSet(mkLit(0)) +//│ = 0 + +// sel + +let arrSp = mkArr([mkLit(0), mkDyn()]) +//│ arrSp = {Arr([{Lit(0)}, {Dyn()}])} + +selSet(arrSp, mkLit(0)) +//│ = {Lit(0)} + +selSet(arrSp, mkLit(1)) +//│ = {Dyn()} + +selSet(mkDyn(), mkLit(5)) +//│ = {Dyn()} + +:silent +class A(val a, val b) +let aSym = ConcreteClassSymbol("A", A, Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), [], false) + +let a = Class(aSym, [mkLit(42), mkLit("c")]) +let x = liftMany([Dyn(), a, Arr([mkLit(100), mkLit(false), mkLit(undefined)])]) +selSet(x, union(mkLit("a"), mkLit(2))) +//│ = {Dyn()} +//│ a = Class( +//│ ConcreteClassSymbol( +//│ "A", +//│ fun A { class: class A }, +//│ Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), +//│ [], +//│ false +//│ ), +//│ [{Lit(42)}, {Lit("c")}] +//│ ) +//│ x = {Dyn()} + +selSet(lift(Arr([mkDyn(), mkLit(1), lift(a)])), mkLit(1)) +//│ = {Lit(1)} + +// union +mkClass(aSym, [union2(mkLit(42), mkLit(43)), union2(mkLit("c"), mkLit("d"))]) +//│ = {Class(ConcreteClassSymbol("A", fun A { class: class A }, Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), [], false), [{Lit(42),Lit(43)}, {Lit("c"),Lit("d")}])} + +mkArr([union2(mkLit(42), mkLit(43)), union2(mkLit("c"), mkLit("d"))]) +//│ = {Arr([{Lit(42),Lit(43)}, {Lit("c"),Lit("d")}])} + + +let x = liftMany([Lit(1), Lit(2)]) +let y = liftMany([Arr([mkLit(2)]), Lit(1), Arr([mkLit(1)])]) +union(x, y) +//│ = {Arr([{Lit(1)}]),Arr([{Lit(2)}]),Lit(1),Lit(2)} +//│ x = {Lit(1),Lit(2)} +//│ y = {Arr([{Lit(1)}]),Arr([{Lit(2)}]),Lit(1)} + +// filterSet + +filterSet(mkDyn(), Block.Lit("a")) +//│ = {Lit("a")} + +filterSet(mkDyn(), Block.Tup(2)) +//│ = {Arr([{Dyn()}, {Dyn()}])} + +let filterShapes = liftMany([Lit(1), Lit(null), Arr([mkDyn()]), Arr([mkLit(1), mkLit(2), mkLit(3)]), a]) +//│ filterShapes = {Arr([{Dyn()}]),Arr([{Lit(1)}, {Lit(2)}, {Lit(3)}]),Class(ConcreteClassSymbol("A", fun A { class: class A }, Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), [], false), [{Lit(42)}, {Lit("c")}]),Lit(1),Lit(null)} + +// wildcard is represented as dflt in Match + +filterSet(filterShapes, Block.Lit(1)) +//│ = {Lit(1)} + +assert(filterSet(filterShapes, Block.Lit(2)).isEmpty()) + +filterSet(filterShapes, Block.Cls(aSym, undefined)) +//│ = {Class(ConcreteClassSymbol("A", fun A { class: class A }, Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), [], false), [{Lit(42)}, {Lit("c")}])} + +filterSet(filterShapes, Block.Cls(Symbol("Int"), undefined)) +//│ = {Lit(1)} + +filterSet(filterShapes, Tup(3)) +//│ = {Arr([{Lit(1)}, {Lit(2)}, {Lit(3)}])} + +filterSet(filterShapes, Tup(4)) +//│ = {} + +assert(filterSet(filterShapes, Tup(0)).isEmpty()) + +open Block +open SpecializeHelpers { Ctx, sop, sor, prop } + +// Ctx + +let ctx = Ctx.empty() +let x = ValueSimpleRef(Symbol("x")) +//│ ctx = Ctx(Map(0) {}, Map(0) {}, Map(0) {}, [], None) +//│ x = ValueSimpleRef(Symbol("x")) + +ctx.add(x, mkLit(1)) +ctx.get(x) +//│ = Some({Lit(1)}) + +ctx.add(x, mkLit(2)) +ctx.get(x) +//│ = Some({Lit(1),Lit(2)}) + +let y = ValueSimpleRef(Symbol("y")) +ctx.add(y, mkLit("a")) +ctx.get(y) +//│ = Some({Lit("a")}) +//│ y = ValueSimpleRef(Symbol("y")) + +let ctx2 = ctx.clone +ctx2.add(y, mkLit("b")) +ctx2.get(y) +//│ = Some({Lit("a"),Lit("b")}) +//│ ctx2 = Ctx( +//│ Map(2) {"Symbol(x)" => {Lit(1),Lit(2)}, "Symbol(y)" => {Lit("a"),Lit("b")}}, +//│ Map(0) {}, +//│ Map(0) {}, +//│ [], +//│ None +//│ ) + +ctx.get(y) +//│ = Some({Lit("a")}) + + +// DefCtx + + +// Cache + + +// sop + +sop(Ctx.empty(), ValueLit(42)) +//│ = {Lit(42)} + +sop(Ctx.empty(), ValueLit(false)) +//│ = {Lit(false)} + +sop(Ctx.empty().add(ValueSimpleRef(Symbol("x")), mkBot()), ValueSimpleRef(Symbol("x"))) +//│ = {} + + +val x = Symbol("x") +val C = ConcreteClassSymbol("C", undefined, Some([Param(None, "a")]), [], false) +val selPath = DynSelect(ValueSimpleRef(x), ValueLit("a"), false) +let ctx = Ctx.empty() +ctx.add(ValueSimpleRef(x), mkClass(C, [mkLit("pass")])) +sop(ctx, selPath) +//│ = {} +//│ C = ConcreteClassSymbol("C", undefined, Some([Param(None, "a")]), [], false) +//│ ctx = Ctx( +//│ Map(1) { +//│ "Symbol(x)" => {Class(ConcreteClassSymbol("C", undefined, Some([Param(None, "a")]), [], false), [{Lit("pass")}])} +//│ }, +//│ Map(0) {}, +//│ Map(0) {}, +//│ [], +//│ None +//│ ) +//│ selPath = DynSelect(ValueSimpleRef(Symbol("x")), ValueLit("a"), false) +//│ x = Symbol("x") + +// sor + +val tup = Tuple([Arg(ValueLit(1)), Arg(ValueLit(true))]) +sor(Ctx.empty(), tup) +//│ = [ +//│ End(), +//│ Tuple([Arg(ValueLit(1)), Arg(ValueLit(true))]), +//│ {Arr([{Lit(1)}, {Lit(true)}])} +//│ ] +//│ tup = Tuple([Arg(ValueLit(1)), Arg(ValueLit(true))]) + +class C(val p) +let c = ConcreteClassSymbol("C", C, Some([Symbol("p")]), [], false) +let inst = Instantiate(ValueMemberRef(c), [Arg(ValueLit(123))]) +sor(Ctx.empty(), inst) +//│ = [ +//│ End(), +//│ Instantiate( +//│ ValueMemberRef( +//│ ConcreteClassSymbol( +//│ "C", +//│ fun C { class: class C }, +//│ Some([Symbol("p")]), +//│ [], +//│ false +//│ ) +//│ ), +//│ [Arg(ValueLit(123))] +//│ ), +//│ {Class(ConcreteClassSymbol("C", fun C { class: class C }, Some([Symbol("p")]), [], false), [{Lit(123)}])} +//│ ] +//│ c = ConcreteClassSymbol( +//│ "C", +//│ fun C { class: class C }, +//│ Some([Symbol("p")]), +//│ [], +//│ false +//│ ) +//│ inst = Instantiate( +//│ ValueMemberRef( +//│ ConcreteClassSymbol( +//│ "C", +//│ fun C { class: class C }, +//│ Some([Symbol("p")]), +//│ [], +//│ false +//│ ) +//│ ), +//│ [Arg(ValueLit(123))] +//│ ) + +fun testBinOp(op, v1, v2) = + let args = [Arg(ValueLit(v1)), Arg(ValueLit(v2))] + let c = Call(ValueSimpleRef(Symbol(op)), args) + sor(Ctx.empty(), c).1.lit + +:expect 12 +testBinOp("+", 10, 2) +//│ = 12 + +:expect true +testBinOp("==", 10, 10) +//│ = true + +:expect false +testBinOp("===", 10, "10") +//│ = false + +:expect false +testBinOp("&&", true, false) +//│ = false + +fun testUnaryOp(op, v) = + let args = [Arg(ValueLit(v))] + let c = Call(ValueSimpleRef(Symbol(op)), args) + sor(Ctx.empty(), c).1.lit + +:expect -10 +testUnaryOp("-", 10) +//│ = -10 + +:expect false +testUnaryOp("!", true) +//│ = false + +:re +testUnaryOp("~", 10) +//│ ═══[RUNTIME ERROR] Error: Access to required field 'lit' yielded 'undefined' + +// prop + +let x = Symbol("x") +let y = Symbol("y") +let z = Symbol("z") +let plus = ValueSimpleRef(Symbol("+")) +//│ plus = ValueSimpleRef(Symbol("+")) +//│ x = Symbol("x") +//│ y = Symbol("y") +//│ z = Symbol("z") + +// let x +// x = 1 + 1 +// x + 1 +let c = Scoped([x], Assign(x, Call(plus, [Arg(ValueLit(1)), Arg(ValueLit(1))]), Return(Call(plus, [Arg(ValueSimpleRef(x)), Arg(ValueLit(1))])))) +prop(Ctx.empty(), c) +//│ = [ +//│ Scoped( +//│ [Symbol("x")], +//│ Assign(Symbol("x"), ValueLit(2), Return(ValueLit(3))) +//│ ), +//│ {Lit(3)}, +//│ false +//│ ] +//│ c = Scoped( +//│ [Symbol("x")], +//│ Assign( +//│ Symbol("x"), +//│ Call(ValueSimpleRef(Symbol("+")), [Arg(ValueLit(1)), Arg(ValueLit(1))]), +//│ Return( +//│ Call( +//│ ValueSimpleRef(Symbol("+")), +//│ [Arg(ValueSimpleRef(Symbol("x"))), Arg(ValueLit(1))] +//│ ) +//│ ) +//│ ) +//│ ) + +let c = Scoped([x], Assign(x, ValueLit(9), Match(ValueSimpleRef(x), [Arm(Cls(VirtualClassSymbol("Bool"), Select(ValueMemberRef(Symbol("runtime")), Symbol("unreachable"))), Return(ValueLit(1))), Arm(Lit(8), Return(ValueLit(2))), Arm(Cls(VirtualClassSymbol("Int"), Select(ValueMemberRef(Symbol("runtime")), Symbol("unreachable"))), Return(ValueLit(3)))], Some(Return(ValueLit(0))), End()))) +prop(Ctx.empty(), c) +//│ = [ +//│ Scoped( +//│ [Symbol("x")], +//│ Assign(Symbol("x"), ValueLit(9), Return(ValueLit(3))) +//│ ), +//│ {Lit(3)}, +//│ true +//│ ] +//│ c = Scoped( +//│ [Symbol("x")], +//│ Assign( +//│ Symbol("x"), +//│ ValueLit(9), +//│ Match( +//│ ValueSimpleRef(Symbol("x")), +//│ [ +//│ Arm( +//│ Cls( +//│ VirtualClassSymbol("Bool"), +//│ Select(ValueMemberRef(Symbol("runtime")), Symbol("unreachable")) +//│ ), +//│ Return(ValueLit(1)) +//│ ), +//│ Arm(Lit(8), Return(ValueLit(2))), +//│ Arm( +//│ Cls( +//│ VirtualClassSymbol("Int"), +//│ Select(ValueMemberRef(Symbol("runtime")), Symbol("unreachable")) +//│ ), +//│ Return(ValueLit(3)) +//│ ) +//│ ], +//│ Some(Return(ValueLit(0))), +//│ End() +//│ ) +//│ ) +//│ ) + +fun f_gen(args) = + [mkLit(24), Symbol("f1")] // A stub for the actual f_gen + +module M with + fun f(args) = 24 + +:ignore +val MSym = ValueMemberRef(ModuleSymbol("M", M, false)) +//│ ╔══[COMPILATION ERROR] Unexpected moduleful reference of type M. +//│ ║ l.389: val MSym = ValueMemberRef(ModuleSymbol("M", M, false)) +//│ ║ ^ +//│ ╙── Module argument passed to a non-module parameter. +//│ MSym = ValueMemberRef(ModuleSymbol("M", class M, false)) + +val fSym = Symbol("f") +val fPath = Select(MSym, fSym) +//│ fPath = Select(ValueMemberRef(ModuleSymbol("M", class M, false)), Symbol("f")) +//│ fSym = Symbol("f") + +val callF = Call(fPath, [Arg(ValueLit(12))]) +sor(Ctx.empty(), callF) +//│ = [End(), ValueLit(24), {Lit(24)}] +//│ callF = Call( +//│ Select(ValueMemberRef(ModuleSymbol("M", class M, false)), Symbol("f")), +//│ [Arg(ValueLit(12))] +//│ ) + +val ctxXY = Ctx.empty() + .add(ValueSimpleRef(x), mkLit(10)) + .add(ValueSimpleRef(y), mkLit(32)) +//│ ctxXY = Ctx( +//│ Map(2) {"Symbol(x)" => {Lit(10)}, "Symbol(y)" => {Lit(32)}}, +//│ Map(0) {}, +//│ Map(0) {}, +//│ [], +//│ None +//│ ) + +// x + y +val blockAdd = Return(Call(plus, [Arg(ValueSimpleRef(x)), Arg(ValueSimpleRef(y))])) +printCode(blockAdd) +prop(ctxXY, blockAdd) +//│ > x + y +//│ = [Return(ValueLit(42)), {Lit(42)}, false] +//│ blockAdd = Return( +//│ Call( +//│ ValueSimpleRef(Symbol("+")), +//│ [Arg(ValueSimpleRef(Symbol("x"))), Arg(ValueSimpleRef(Symbol("y")))] +//│ ) +//│ ) + +val blockBranch = Scoped([z], Match(ValueLit(1), [Arm(Lit(1), Assign(z, ValueLit(1), End())), Arm(Lit(2), Assign(z, ValueLit(2), End()))], Some(Assign(z, ValueLit(3), End())), Return(ValueSimpleRef(z)))) +printCode(blockBranch) +prop(Ctx.empty(), blockBranch) +//│ > let {z} +//│ > if 1 is +//│ > 1 then +//│ > z = 1 +//│ > 2 then +//│ > z = 2 +//│ > else +//│ > z = 3 +//│ > z +//│ = [ +//│ Scoped( +//│ [Symbol("z")], +//│ Assign(Symbol("z"), ValueLit(1), Return(ValueLit(1))) +//│ ), +//│ {Lit(1)}, +//│ true +//│ ] +//│ blockBranch = Scoped( +//│ [Symbol("z")], +//│ Match( +//│ ValueLit(1), +//│ [ +//│ Arm(Lit(1), Assign(Symbol("z"), ValueLit(1), End())), +//│ Arm(Lit(2), Assign(Symbol("z"), ValueLit(2), End())) +//│ ], +//│ Some(Assign(Symbol("z"), ValueLit(3), End())), +//│ Return(ValueSimpleRef(Symbol("z"))) +//│ ) +//│ ) + +val earlyRetBlock = Scoped([x, y], Assign(x, ValueLit(false), Match(ValueSimpleRef(x), [Arm(Lit(true), Return(ValueLit(10))), Arm(Lit(false), Assign(y, ValueLit(20), End()))], End(), Return(ValueSimpleRef(y))))) +printCode(earlyRetBlock) +prop(Ctx.empty(), earlyRetBlock) +//│ > let {x, y} +//│ > x = false +//│ > if x is +//│ > true then 10 +//│ > false then +//│ > y = 20 +//│ > y +//│ = [ +//│ Scoped( +//│ [Symbol("x"), Symbol("y")], +//│ Assign( +//│ Symbol("x"), +//│ ValueLit(false), +//│ Assign(Symbol("y"), ValueLit(20), Return(ValueLit(20))) +//│ ) +//│ ), +//│ {Lit(20)}, +//│ true +//│ ] +//│ earlyRetBlock = Scoped( +//│ [Symbol("x"), Symbol("y")], +//│ Assign( +//│ Symbol("x"), +//│ ValueLit(false), +//│ Match( +//│ ValueSimpleRef(Symbol("x")), +//│ [ +//│ Arm(Lit(true), Return(ValueLit(10))), +//│ Arm(Lit(false), Assign(Symbol("y"), ValueLit(20), End())) +//│ ], +//│ End(), +//│ Return(ValueSimpleRef(Symbol("y"))) +//│ ) +//│ ) +//│ ) + +:silent +val nestedBlock = Scoped([x, y], Assign(x, ValueLit(true), Assign(y, ValueLit(false), Match(ValueSimpleRef(x), [Arm(Lit(true), Match(ValueSimpleRef(y), [Arm(Lit(true), Return(ValueLit(1)))], Some(Return(ValueLit(2))), End()))], Some(Return(ValueLit(3))), Return(ValueLit(4)))))) +val res = prop(Ctx.empty(), nestedBlock) +printCode(nestedBlock) +printCode(res.0) +//│ > let {x, y} +//│ > x = true +//│ > y = false +//│ > if x is +//│ > true then +//│ > if y is +//│ > true then 1 +//│ > else 2 +//│ > else 3 +//│ > 4 +//│ > let {x, y} +//│ > x = true +//│ > y = false +//│ > 2 + +val res = prop(Ctx.empty(), nestedBlock) +//│ res = [ +//│ Scoped( +//│ [Symbol("x"), Symbol("y")], +//│ Assign( +//│ Symbol("x"), +//│ ValueLit(true), +//│ Assign(Symbol("y"), ValueLit(false), Return(ValueLit(2))) +//│ ) +//│ ), +//│ {Lit(2)}, +//│ false +//│ ] + +:expect {Lit(2)} +res.1 +//│ = {Lit(2)} + +shapeset2path(sov(1), mut[]) +//│ = [End(), ValueLit(1)] + +shapeset2path(sov([1, 2, 3]), mut []) +//│ = [ +//│ Assign( +//│ Symbol("tup_1"), +//│ Tuple([Arg(ValueLit(1)), Arg(ValueLit(2)), Arg(ValueLit(3))]), +//│ End() +//│ ), +//│ ValueSimpleRef(Symbol("tup_1")) +//│ ] + +class TestClass(val a, val b) +val sym = ConcreteClassSymbol("TestClass", TestClass, Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), [], false) +//│ sym = ConcreteClassSymbol( +//│ "TestClass", +//│ fun TestClass { class: class TestClass }, +//│ Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), +//│ [], +//│ false +//│ ) + +Runtime.SymbolMap.classMap.set(TestClass.class, sym) +//│ = Map(1) { +//│ class TestClass => ConcreteClassSymbol( +//│ "TestClass", +//│ fun TestClass { class: class TestClass }, +//│ Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), +//│ [], +//│ false +//│ ) +//│ } + +shapeset2path(sov(TestClass(1, 2)), mut []) +//│ = [ +//│ Assign( +//│ Symbol("obj_2"), +//│ Instantiate( +//│ ValueMemberRef( +//│ ConcreteClassSymbol( +//│ "TestClass", +//│ fun TestClass { class: class TestClass }, +//│ Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), +//│ [], +//│ false +//│ ) +//│ ), +//│ [Arg(ValueLit(1)), Arg(ValueLit(2))] +//│ ), +//│ End() +//│ ), +//│ ValueSimpleRef(Symbol("obj_2")) +//│ ] + +shapeset2path(sov(TestClass(1, [1,2])), mut []) +//│ = [ +//│ Assign( +//│ Symbol("tup_3"), +//│ Tuple([Arg(ValueLit(1)), Arg(ValueLit(2))]), +//│ Assign( +//│ Symbol("obj_4"), +//│ Instantiate( +//│ ValueMemberRef( +//│ ConcreteClassSymbol( +//│ "TestClass", +//│ fun TestClass { class: class TestClass }, +//│ Some([Param(None, Symbol("a")), Param(None, Symbol("b"))]), +//│ [], +//│ false +//│ ) +//│ ), +//│ [Arg(ValueLit(1)), Arg(ValueSimpleRef(Symbol("tup_3")))] +//│ ), +//│ End() +//│ ) +//│ ), +//│ ValueSimpleRef(Symbol("obj_4")) +//│ ] diff --git a/hkmc2/shared/src/test/mlscript/block-staging/SimpleRegExpTest.mls b/hkmc2/shared/src/test/mlscript/block-staging/SimpleRegExpTest.mls new file mode 100644 index 0000000000..e1eb578a40 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/SimpleRegExpTest.mls @@ -0,0 +1,159 @@ +:js +:staging +:noModuleCheck + +import "../../mlscript-compile/SimpleRegExp.mls" + +open SimpleRegExp + +match(Exact("x"), "x") +//│ = Some("x") + +match(Exact("x"), "") +//│ = None + +match(Exact("x"), "xyz") +//│ = Some("x") + + +match(Any(), "x") +//│ = Some("x") + +match(Any(), "") +//│ = None + +match(Any(), "xyz") +//│ = Some("x") + + +match(Not(["x", "y", "z"]), "xyz") +//│ = None + +match(Not(["x", "y", "z"]), "w") +//│ = Some("w") + + +match(Union(Union(Exact("x"), Exact("y")), Exact("z")), "z") +//│ = Some("z") + +match(Union(Union(Exact("x"), Exact("y")), Exact("z")), "y") +//│ = Some("y") + +match(Union(Union(Exact("x"), Exact("y")), Exact("z")), "w") +//│ = None + + +match(question(Exact("x")), "x") +//│ = Some("x") + +match(question(Exact("x")), "y") +//│ = Some("") + +match(question(Exact("x")), "xx") +//│ = Some("x") + +match(question(Any()), "y") +//│ = Some("y") + + +match(new Concat(new Exact("x"), new Concat(new Exact("y"), new Not(["z"]))), "xyy") +//│ = Some("xyy") + +match(new Concat(new Exact("x"), new Concat(new Exact("y"), new Not(["z"]))), "xyz") +//│ = None + +match(new Concat(new Exact("x"), new Concat(new Exact("y"), new Not(["z"]))), "yyy") +//│ = None + + +// x{3}, equivalent to xxx +match(nTimes(Exact("x"), 3), "xxx") +//│ = Some("xxx") + +match(nTimes(Exact("x"), 3), "xxy") +//│ = None + +match(nTimes(Exact("x"), 3), "xx") +//│ = None + + +match(Concat(Star(Exact("x")), Exact("y")), "x") +//│ = None + +match(Concat(Star(Exact("x")), Exact("y")), "y") +//│ = Some("y") + +match(Concat(Star(Exact("x")), Exact("y")), "xxxxxy") +//│ = Some("xxxxxy") + +match(Concat(Star(Exact("x")), Exact("y")), "xyyyy") +//│ = Some("xy") + + +match(plus(Exact("x")), "") +//│ = None + +match(plus(Exact("x")), "x") +//│ = Some("x") + + +match(plus(Exact("x")), "y") +//│ = None + + +match(plus(Exact("x")), "xxx") +//│ = Some("xxx") + + +match(plus(Exact("x")), "xxxy") +//│ = Some("xxx") + + +:silent +let p = Concat(In(["T", "t"]), Concat(Star(words()), notWord())) + + +matchAll(p, "To be or not to be, that is the question.") +//│ = ["To ", "t ", "to ", "that ", "the ", "tion."] + + +matchAllEmail("foo@bar.baz") +//│ = ["foo@bar.baz"] + +matchAllEmail("foo-foo@bar.baz") +//│ = ["foo-foo@bar.baz"] + +matchAllEmail("a.b.c.d@e-f.g.h") +//│ = ["a.b.c.d@e-f.g.h"] + +matchAllEmail("a-b.c.d@e-f.g.h") +//│ = ["a-b.c.d@e-f.g.h"] + +matchAllEmail("foo@bar@baz") +//│ = [] + +matchAllEmail("f@a") +//│ = [] + + +matchAllURI("http://foo.bar.com") +//│ = ["http://foo.bar.com"] + + +matchAllURI("http://foo.bar.com?xxx") +//│ = ["http://foo.bar.com?xxx"] + + +matchAllURI("http://foo.bar.com?xxx#42") +//│ = ["http://foo.bar.com?xxx#42"] + + +matchAllURI("http://foo.bar.com#42") +//│ = ["http://foo.bar.com#42"] + + +matchAllIPv4("8.8.8.8") +//│ = ["8.8.8.8"] + +matchAllIPv4("192.168.1.1") +//│ = ["192.168.1.1"] diff --git a/hkmc2/shared/src/test/mlscript/block-staging/SpecializeTest.mls b/hkmc2/shared/src/test/mlscript/block-staging/SpecializeTest.mls new file mode 100644 index 0000000000..09175c2221 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/SpecializeTest.mls @@ -0,0 +1,39 @@ +:js +:staging +:noModuleCheck + +import "../../mlscript-compile/ShapeSet.mls" + +open ShapeSet + +staged module M with + fun f(x) = + let y = x * 2 + y + fun f_gen + +M.f_gen(mkDyn()) +//│ = ["f", {Dyn()}] + + +M.f_gen(mkLit(2)) +//│ = ["f_M_sp_0", {Lit(4)}] + + +print(M."cache$M") +//│ > module M with +//│ > () +//│ > fun f(x) = +//│ > let {y} +//│ > y = *(x, 2) +//│ > y +//│ > fun f_M_sp_0(x) = 4 + + +staged module Clash with + fun f(x) = x + fun f_gen + fun f_Clash_sp_0() = 0 + +Clash.f_gen(mkLit(1)) +//│ = ["f_Clash_sp_1", {Lit(1)}] diff --git a/hkmc2/shared/src/test/mlscript/block-staging/StageSymbols.mls b/hkmc2/shared/src/test/mlscript/block-staging/StageSymbols.mls index 1a253abb56..05872a845a 100644 --- a/hkmc2/shared/src/test/mlscript/block-staging/StageSymbols.mls +++ b/hkmc2/shared/src/test/mlscript/block-staging/StageSymbols.mls @@ -1,14 +1,11 @@ :js :staging +:noModuleCheck -:fixme staged module M with class C with fun f() = 1 fun g() = f() -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. staged module A with fun f() = 1 @@ -19,74 +16,76 @@ staged module D with class E fun f() = A.f() - B.f() + B.f is Bool fun matching() = 1 is Int 1 is C -//│ > fun ctor_() = () -//│ > fun f() = 1 -//│ > fun ctor_() = -//│ > class E -//│ > fun f() = -//│ > A.f_gen() -//│ > B.f() -//│ > fun matching() = -//│ > let {scrut, scrut1, tmp} -//│ > scrut = 1 -//│ > if scrut is -//│ > Int then -//│ > tmp = true -//│ > else -//│ > tmp = false -//│ > scrut1 = 1 -//│ > if scrut1 is -//│ > C then true -//│ > else false -:fixme module A with module B with class C(a) staged module M with class E fun f() = - D.E - A.B.C - A.B.C(1) + let x = D.E + x = A.B.C + A.B.C(2) E -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ > fun ctor_() = -//│ > class E -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. :e staged module M with fun g()() = 1 //│ ╔══[COMPILATION ERROR] :ftc must be enabled to desugar functions with multiple parameter lists. -//│ ║ l.64: fun g()() = 1 +//│ ║ l.37: fun g()() = 1 //│ ╙── ^^^^^^^^^^^^^ -//│ > fun ctor_() = () -//│ > fun g()() = 1 :ftc staged module M with fun f() = x => x fun g()() = 1 -//│ > fun ctor_() = () -//│ > fun f() = -//│ > let {tmp} -//│ > tmp = new Function_ -//│ > tmp -//│ > fun g() = -//│ > let {tmp1} -//│ > tmp1 = new Function_1 -//│ > tmp1 -// TODO: these need to be printed, somehow: :noModuleCheck -let x = M."f_instr"().body.rest.rhs.cls.l.value -let y = M."g_instr"().body.rest.rhs.cls.l.value -//│ x = class Function$ -//│ y = class Function$ -(new x).call(2) -//│ = 2 +:silent +let x = M."f_instr"().body.rest.rhs.cls.l +let y = M."g_instr"().body.rest.rhs.cls.l +assert x.value != y.value +// check that the two functions will be printed differently +assert x.name != y.name + +staged module Shadowing with + fun f(x, x) = x + +staged module RetUnit with + fun f() = () + +// should use same symbol across compilation units +import "../../mlscript-compile/Runtime.mls" +module M with + fun f() = 1 + +staged module One with + fun f() = M.f() + +staged module Two with + fun f() = M.f() + +:silent +let x = One."f_instr"().body.res._fun.qual.l +let y = Two."f_instr"().body.res._fun.qual.l +assert x === y + +:fixme Array should be skipped for redirection +staged module M with + val a = Math.cos(1) is Array // doesn't handle Array +//│ ╔══[COMPILATION ERROR] No definition found in scope for member 'Array' +//│ ╟── which references the symbol introduced here +//│ ║ l.105: declare class Array[T] +//│ ╙── ^^^^^^^^ +//│ ╔══[COMPILATION ERROR] No definition found in scope for member 'Array' +//│ ╟── which references the symbol introduced here +//│ ║ l.105: declare class Array[T] +//│ ╙── ^^^^^^^^ +//│ ╔══[COMPILATION ERROR] No definition found in scope for member 'Array' +//│ ╟── which references the symbol introduced here +//│ ║ l.105: declare class Array[T] +//│ ╙── ^^^^^^^^ diff --git a/hkmc2/shared/src/test/mlscript/block-staging/StageWtihCompanion.mls b/hkmc2/shared/src/test/mlscript/block-staging/StageWtihCompanion.mls new file mode 100644 index 0000000000..d391fc981e --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/StageWtihCompanion.mls @@ -0,0 +1,16 @@ +:js +:staging + +staged class M with + fun f() = 1 +staged module M with + fun g() = 2 + +staged class B +module B with + fun f() = 1 + +// keep original functions of module +:expect 1 +B.f() +//│ = 1 diff --git a/hkmc2/shared/src/test/mlscript/block-staging/StagedRegExpTest.mls b/hkmc2/shared/src/test/mlscript/block-staging/StagedRegExpTest.mls new file mode 100644 index 0000000000..b3ac103000 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/StagedRegExpTest.mls @@ -0,0 +1,156 @@ +:js +:staging +:noModuleCheck + +import "../../mlscript-compile/staging/StagedRegExp.mls" + + +StagedRegExp."generate"("../StagedRegExp.mls", "./hkmc2/shared/src/test/mlscript-compile/staging/out/StagedRegExp.mls") + + +import "../../mlscript-compile/staging/out/StagedRegExp.mls" + +open StagedRegExp + +match(Exact("x"), "x") +//│ = Some("x") + +match(Exact("x"), "x") +//│ = Some("x") + + +match(Exact("x"), "") +//│ = None + + +match(Exact("x"), "xyz") +//│ = Some("x") + +match(Any(), "x") +//│ = Some("x") + + +match(Any(), "") +//│ = None + + +match(Any(), "xyz") +//│ = Some("x") + + +match(Not(["x", "y", "z"]), "xyz") +//│ = None + + +match(Not(["x", "y", "z"]), "w") +//│ = Some("w") + +match(Union(Union(Exact("x"), Exact("y")), Exact("z")), "z") +//│ = Some("z") + +match(Union(Union(Exact("x"), Exact("y")), Exact("z")), "y") +//│ = Some("y") + +match(Union(Union(Exact("x"), Exact("y")), Exact("z")), "w") +//│ = None + +match(question(Exact("x")), "x") +//│ = Some("x") + +match(question(Exact("x")), "y") +//│ = Some("") + +match(question(Exact("x")), "xx") +//│ = Some("x") + +match(question(Any()), "y") +//│ = Some("y") + +match(Concat(Star(Exact("x")), Exact("y")), "x") +//│ = None + +match(Concat(Star(Exact("x")), Exact("y")), "y") +//│ = Some("y") + +match(Concat(Star(Exact("x")), Exact("y")), "xxxxxy") +//│ = Some("xxxxxy") + +match(Concat(Star(Exact("x")), Exact("y")), "xyyyy") +//│ = Some("xy") + + +match(plus(Exact("x")), "") +//│ = None + +match(plus(Exact("x")), "x") +//│ = Some("x") + + +match(plus(Exact("x")), "y") +//│ = None + +match(plus(Exact("x")), "xxx") +//│ = Some("xxx") + +match(plus(Exact("x")), "xxxy") +//│ = Some("xxx") + +// x{3}, equivalent to xxx +match(nTimes(Exact("x"), 3), "xxx") +//│ = Some("xxx") + +match(nTimes(Exact("x"), 3), "xxy") +//│ = None + +match(nTimes(Exact("x"), 3), "xx") +//│ = None + + +:silent +let p = Concat(In(["T", "t"]), Concat(Star(words()), notWord())) + +matchAll(p, "To be or not to be, that is the question.") +//│ = ["To ", "t ", "to ", "that ", "the ", "tion."] + + +matchAllEmail("foo@bar.baz") +//│ = ["foo@bar.baz"] + +matchAllEmail("foo-foo@bar.baz") +//│ = ["foo-foo@bar.baz"] + +matchAllEmail("a.b.c.d@e-f.g.h") +//│ = ["a.b.c.d@e-f.g.h"] + +matchAllEmail("a-b.c.d@e-f.g.h") +//│ = ["a-b.c.d@e-f.g.h"] + +matchAllEmail("foo@bar@baz") +//│ = [] + +matchAllEmail("f@a") +//│ = [] + + +matchAllURI("http://foo.bar.com") +//│ = ["http://foo.bar.com"] + + +matchAllURI("http://foo.bar.com?xxx") +//│ = ["http://foo.bar.com?xxx"] + + +matchAllURI("http://foo.bar.com?xxx#42") +//│ = ["http://foo.bar.com?xxx#42"] + + +matchAllURI("http://foo.bar.com#42") +//│ = ["http://foo.bar.com#42"] + + + +matchAllIPv4("8.8.8.8") +//│ = ["8.8.8.8"] + +matchAllIPv4("192.168.1.1") +//│ = ["192.168.1.1"] diff --git a/hkmc2/shared/src/test/mlscript/block-staging/SymbolMap.mls b/hkmc2/shared/src/test/mlscript/block-staging/SymbolMap.mls new file mode 100644 index 0000000000..adfb8135e5 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/SymbolMap.mls @@ -0,0 +1,9 @@ +:js +:staging + +class C(val x) + +staged module A with + fun g() = C(1) + fun h() = C(2) + diff --git a/hkmc2/shared/src/test/mlscript/block-staging/SymbolRenaming.mls b/hkmc2/shared/src/test/mlscript/block-staging/SymbolRenaming.mls index bf2f4c6fee..720531ee6f 100644 --- a/hkmc2/shared/src/test/mlscript/block-staging/SymbolRenaming.mls +++ b/hkmc2/shared/src/test/mlscript/block-staging/SymbolRenaming.mls @@ -2,19 +2,13 @@ :staging staged module TempVariable with - fun f() = + fun f(x, x) = let x let x x -//│ > fun ctor_() = () -//│ > fun f() = -//│ > let {x, x1} -//│ > x1 staged module DupeFunctionName with fun f() = 1 -//│ > fun ctor_() = () -//│ > fun f() = 1 class C(val x) @@ -22,21 +16,7 @@ staged module Selection with fun f(x) = x.call() C(1).x is Bool -//│ > fun ctor_() = () -//│ > fun f(x) = -//│ > let {scrut, tmp} -//│ > x.call() -//│ > tmp = C(1) -//│ > scrut = tmp.x -//│ > if scrut is -//│ > Bool then true -//│ > else false -:fixme staged module DupeClass with class C(val y) fun f() = C(1).y -//│ ═══[COMPILATION ERROR] Value.This not supported in staged module. -//│ > fun ctor_() = -//│ > class C(y) -//│ ═══[RUNTIME ERROR] Error: MLscript call unexpectedly returned `undefined`, the forbidden value. diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Syntax.mls b/hkmc2/shared/src/test/mlscript/block-staging/Syntax.mls index 767ab21e60..1d7a85132e 100644 --- a/hkmc2/shared/src/test/mlscript/block-staging/Syntax.mls +++ b/hkmc2/shared/src/test/mlscript/block-staging/Syntax.mls @@ -8,11 +8,11 @@ staged module A //│ k = Mod //│ head = Ident of "A" +staged class Foo + // TODO: reject these annotations? staged object Foo -staged class Foo - staged fun f() = 0 :js @@ -23,21 +23,61 @@ staged module A //│ define A⁰ as class A¹ //│ staged module A² { //│ constructor { -//│ let tmp, tmp1; -//│ set tmp = A².this.ctor$_instr﹖(); -//│ set tmp1 = Block⁰.printCode﹖(tmp); +//│ let tmp, tmp1, sym, tmp2, tmp3, tmp4, tmp5, tmp6; +//│ set sym = Block⁰.ModuleSymbol﹖("A", A².this, false); +//│ set tmp2 = runtime⁰.SymbolMap﹖.checkModuleMap﹖(A².this, sym); +//│ set tmp3 = new globalThis⁰.Map﹖(); +//│ set tmp4 = []; +//│ set tmp5 = new globalThis⁰.Set﹖(tmp4); +//│ set tmp6 = new SpecializeHelpers⁰.FunCache﹖(tmp2, tmp3, tmp5); +//│ define cache$A⁰ as val cache$A¹ = tmp6; +//│ set tmp = []; +//│ set tmp1 = new globalThis⁰.Map﹖(tmp); +//│ define generatorMap$A⁰ as val generatorMap$A¹ = tmp1; +//│ end +//│ } +//│ method generate⁰ = fun generate¹(source, path) { +//│ let tmp, tmp1, tmp2; +//│ set tmp = A².this.propagate﹖(); +//│ set tmp1 = []; +//│ set tmp2 = Block⁰.codegen﹖("A", A².this.cache$A﹖, source, path, tmp1); //│ end //│ } //│ method ctor$_instr⁰ = fun ctor$_instr¹() { -//│ let end, tmp, tmp1, tmp2, tmp3; +//│ let sym, tmp, tmp1, end, tmp2; +//│ set sym = Block⁰.Symbol﹖("ctor$"); +//│ set tmp = []; +//│ set tmp1 = [tmp]; //│ set end = Block⁰.End﹖(); -//│ set tmp = Block⁰.Symbol﹖("ctor$"); -//│ set tmp1 = []; -//│ set tmp2 = [tmp1]; -//│ set tmp3 = Block⁰.FunDefn﹖(tmp, tmp2, end, true); -//│ return tmp3 +//│ set tmp2 = Block⁰.FunDefn﹖(sym, tmp1, end); +//│ return tmp2 +//│ } +//│ method propagate⁰ = fun propagate¹() { +//│ let tmp_dyn; +//│ set tmp_dyn = ShapeSet⁰.mkDyn﹖(); +//│ end +//│ } +//│ method toCode⁰ = fun toCode¹() { +//│ let tmp, tmp1; +//│ set tmp = []; +//│ set tmp1 = Block⁰.toCode﹖("A", A².this.cache$A﹖, tmp); +//│ return tmp1 //│ } //│ }; //│ end //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— -//│ > fun ctor_() = () + +:el +fun f(@dynamic x) = x +//│ Elab: { fun member:f(@dynamicx) = x⁰; } + +fun g(@static x) = x + +:e +fun h(@dynamic @static x) = x +//│ ╔══[COMPILATION ERROR] At most one reflection constraint can be added for each parameter. +//│ ║ l.77: fun h(@dynamic @static x) = x +//│ ╙── ^^^^^^^^^ +//│ ╔══[COMPILATION ERROR] Name not found: x +//│ ║ l.77: fun h(@dynamic @static x) = x +//│ ╙── ^ diff --git a/hkmc2/shared/src/test/mlscript/block-staging/Transform3DTest.mls b/hkmc2/shared/src/test/mlscript/block-staging/Transform3DTest.mls new file mode 100644 index 0000000000..6d8ed0de99 --- /dev/null +++ b/hkmc2/shared/src/test/mlscript/block-staging/Transform3DTest.mls @@ -0,0 +1,223 @@ +:js +:staging +:noModuleCheck + + +import "../../mlscript-compile/NaiveTransform3D.mls" + +let x = new NaiveTransform3D.Matrix([1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 3) +let y = new NaiveTransform3D.Matrix([9, 8, 7, 6, 5, 4, 3, 2, 1], 3, 3) +//│ x = Matrix([1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 3) +//│ y = Matrix([9, 8, 7, 6, 5, 4, 3, 2, 1], 3, 3) + +NaiveTransform3D.multiply of x, y +//│ = Matrix([30, 24, 18, 84, 69, 54, 138, 114, 90], 3, 3) + + +NaiveTransform3D.ident(4) +//│ = Matrix([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 4, 4) + + +NaiveTransform3D.update(NaiveTransform3D.ident(3), 1, 2, 5) +//│ = Matrix([1, 0, 0, 0, 1, 5, 0, 0, 1], 3, 3) + +NaiveTransform3D.transform(1, 2, 3) +//│ = Matrix([1, 0, 0, 1, 0, 1, 0, 2, 0, 0, 1, 3, 0, 0, 0, 1], 4, 4) + + +NaiveTransform3D.scale(2, 2, 2) +//│ = Matrix([2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1], 4, 4) + + +NaiveTransform3D.rotateX(3.1415 / 2) +//│ = Matrix( +//│ [ +//│ 1, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 0.00004632679487995776, +//│ -0.999999998926914, +//│ 0, +//│ 0, +//│ 0.999999998926914, +//│ 0.00004632679487995776, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1 +//│ ], +//│ 4, +//│ 4 +//│ ) + + +NaiveTransform3D.rotateY(3.1415 / 2) +//│ = Matrix( +//│ [ +//│ 0.00004632679487995776, +//│ 0, +//│ 0.999999998926914, +//│ 0, +//│ 0, +//│ 1, +//│ 0, +//│ 0, +//│ -0.999999998926914, +//│ 0, +//│ 0.00004632679487995776, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1 +//│ ], +//│ 4, +//│ 4 +//│ ) + + +NaiveTransform3D.rotateZ(3.1415 / 2) +//│ = Matrix( +//│ [ +//│ 0.00004632679487995776, +//│ -0.999999998926914, +//│ 0, +//│ 0, +//│ 0.999999998926914, +//│ 0.00004632679487995776, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1 +//│ ], +//│ 4, +//│ 4 +//│ ) + + +NaiveTransform3D.model([[10], [0], [0]], [5, 0, 0], [0.5, 0.5, 0.5], [0, 0, 3.1415926535 / 2.0]) +//│ = [5.000000000224483, 5, 0] + + +NaiveTransform3D.model0([[10], [0], [0]]) +//│ = [7, 4, 50.99999999964083] + + +import "../../mlscript-compile/staging/Transform3D.mls" + +Transform3D."generate"("../Transform3D.mls", "./hkmc2/shared/src/test/mlscript-compile/staging/out/Transform3D.mls") + +import "../../mlscript-compile/staging/out/Transform3D.mls" + +let x = new Transform3D.Matrix([1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 3) +let y = new Transform3D.Matrix([9, 8, 7, 6, 5, 4, 3, 2, 1], 3, 3) +//│ x = Matrix([1, 2, 3, 4, 5, 6, 7, 8, 9], 3, 3) +//│ y = Matrix([9, 8, 7, 6, 5, 4, 3, 2, 1], 3, 3) + +Transform3D.multiply of x, y +//│ = Matrix([30, 24, 18, 84, 69, 54, 138, 114, 90], 3, 3) + + +Transform3D.ident(4) +//│ = Matrix([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 4, 4) + + +Transform3D.update(Transform3D.ident(3), 1, 2, 5) +//│ = Matrix([1, 0, 0, 0, 1, 5, 0, 0, 1], 3, 3) + + +Transform3D.transform(1, 2, 3) +//│ = Matrix([1, 0, 0, 1, 0, 1, 0, 2, 0, 0, 1, 3, 0, 0, 0, 1], 4, 4) + + +Transform3D.scale(2, 2, 2) +//│ = Matrix([2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1], 4, 4) + + +Transform3D.rotateX(3.1415 / 2) +//│ = Matrix( +//│ [ +//│ 1, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 0.00004632679487995776, +//│ -0.999999998926914, +//│ 0, +//│ 0, +//│ 0.999999998926914, +//│ 0.00004632679487995776, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1 +//│ ], +//│ 4, +//│ 4 +//│ ) + +Transform3D.rotateY(3.1415 / 2) +//│ = Matrix( +//│ [ +//│ 0.00004632679487995776, +//│ 0, +//│ 0.999999998926914, +//│ 0, +//│ 0, +//│ 1, +//│ 0, +//│ 0, +//│ -0.999999998926914, +//│ 0, +//│ 0.00004632679487995776, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1 +//│ ], +//│ 4, +//│ 4 +//│ ) + +Transform3D.rotateZ(3.1415 / 2) +//│ = Matrix( +//│ [ +//│ 0.00004632679487995776, +//│ -0.999999998926914, +//│ 0, +//│ 0, +//│ 0.999999998926914, +//│ 0.00004632679487995776, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1, +//│ 0, +//│ 0, +//│ 0, +//│ 0, +//│ 1 +//│ ], +//│ 4, +//│ 4 +//│ ) + +Transform3D.model([[10], [0], [0]], [5, 0, 0], [0.5, 0.5, 0.5], [0, 0, 3.1415926535 / 2.0]) +//│ = [5.000000000224483, 5, 0] + + +Transform3D.model0([[10], [0], [0]]) +//│ = [7, 4, 50.99999999964083] diff --git a/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls b/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls index 9063397d01..5a17e02924 100644 --- a/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls +++ b/hkmc2/shared/src/test/mlscript/codegen/ConfigDirective.mls @@ -195,11 +195,11 @@ fun applyTwice(f, x) = f(x) + f(x) applyTwice(fst, Pair(1, 2)) //│ deforest > >>> non-affine syms >>> //│ deforest > cap_ub_(term:fst,0)_for_fst@35 -//│ deforest > f_for_applyTwice@23 -//│ deforest > f_for_applyTwice@54 +//│ deforest > f_for_applyTwice@24 +//│ deforest > f_for_applyTwice@55 //│ deforest > fst_for_fst@32 //│ deforest > tmp@1 -//│ deforest > x_for_applyTwice@24 -//│ deforest > x_for_applyTwice@55 +//│ deforest > x_for_applyTwice@23 +//│ deforest > x_for_applyTwice@54 //│ deforest > <<< non-affine syms <<< //│ = 2 diff --git a/hkmc2/shared/src/test/mlscript/codegen/FirstClassFunctionTransform.mls b/hkmc2/shared/src/test/mlscript/codegen/FirstClassFunctionTransform.mls index 4afcac5fd3..05a0c9cae0 100644 --- a/hkmc2/shared/src/test/mlscript/codegen/FirstClassFunctionTransform.mls +++ b/hkmc2/shared/src/test/mlscript/codegen/FirstClassFunctionTransform.mls @@ -31,16 +31,13 @@ x => x //│ —————————————————| Output |————————————————————————————————————————————————————————————————————————— //│ = class anonymous -:fixme // TODO: fix IR rebinding issue (each symbol should be bound at most once) :checkIR :noInline x => x -//│ ╔══[INTERNAL ERROR] [BlockChecker] Invalid IR: symbol x⁰ is bound more than once -//│ ║ l.37: x => x -//│ ╙── ^ //│ = class anonymous + fun f(x, y, b) = aux(z => x + z) * aux(z => if b then y + z else y - z) @@ -96,12 +93,12 @@ let f = foo in bar(f) bar([foo].0) bar([foo, x => x].1) //│ ╔══[COMPILATION ERROR] Cannot determine if 0 is a function. -//│ ║ l.96: bar([foo].0) +//│ ║ l.93: bar([foo].0) //│ ╙── ^^ //│ ═══[COMPILATION ERROR] Cannot determine if 0$__checkNotMethod is a function. //│ ═══[COMPILATION ERROR] Cannot determine if Error is a function. //│ ╔══[COMPILATION ERROR] Cannot determine if 1 is a function. -//│ ║ l.97: bar([foo, x => x].1) +//│ ║ l.94: bar([foo, x => x].1) //│ ╙── ^^ //│ ═══[COMPILATION ERROR] Cannot determine if 1$__checkNotMethod is a function. //│ ═══[COMPILATION ERROR] Cannot determine if Error is a function. @@ -118,7 +115,7 @@ bar([foo, x => x].(i)) :ge [foo, x => x].(i)(0) //│ ╔══[COMPILATION ERROR] Cannot determine if the dynamic selection is a function object. -//│ ║ l.119: [foo, x => x].(i)(0) +//│ ║ l.116: [foo, x => x].(i)(0) //│ ╙── ^ @@ -132,10 +129,10 @@ let foo = Foo() foo.("f")(0) foo.("h")(1) //│ ╔══[COMPILATION ERROR] Cannot determine if the dynamic selection is a function object. -//│ ║ l.132: foo.("f")(0) +//│ ║ l.129: foo.("f")(0) //│ ╙── ^^^^^^^^ //│ ╔══[COMPILATION ERROR] Cannot determine if the dynamic selection is a function object. -//│ ║ l.133: foo.("h")(1) +//│ ║ l.130: foo.("h")(1) //│ ╙── ^^^^^^^^ //│ = 0 //│ foo = Foo() @@ -283,7 +280,7 @@ y => x + y //│ let lambda, Function$, tmp; //│ @private //│ define lambda as fun lambda⁵(y) { -//│ return +⁰(x¹, y) +//│ return +⁰(x⁰, y) //│ }; //│ define Function$ as class Function$⁵ extends globalThis⁰.Function⁰ { //│ method call¹⁰ = fun call¹¹(y) { return lambda⁵(y) } @@ -380,7 +377,7 @@ foo.Foo#x :ge foo.f(0) //│ ╔══[COMPILATION ERROR] Cannot determine if f is a function object. -//│ ║ l.381: foo.f(0) +//│ ║ l.378: foo.f(0) //│ ╙── ^^^^^ //│ = 1 @@ -398,7 +395,7 @@ foo.Foo#f(0) :ge foo.x(0) //│ ╔══[COMPILATION ERROR] Cannot determine if x is a function object. -//│ ║ l.399: foo.x(0) +//│ ║ l.396: foo.x(0) //│ ╙── ^^^^^ @@ -471,15 +468,15 @@ fun foo(x)(y) = x + y //│ return +⁰(x, y) //│ }; //│ define Function$ as class Function$⁶ extends globalThis⁰.Function⁰ { -//│ private val x²; +//│ private val x¹; //│ constructor(x) { //│ do super⁰(); //│ end; -//│ set Function$⁶.this.x² = x; +//│ set Function$⁶.this.x¹ = x; //│ end //│ } //│ method call¹² = fun call¹³(y) { -//│ return lambda$⁰(Function$⁶.this.x², y) +//│ return lambda$⁰(Function$⁶.this.x¹, y) //│ } //│ }; //│ define foo⁵ as fun foo⁶(x) { let tmp; set tmp = new Function$⁶(x); return tmp }; @@ -516,7 +513,7 @@ print("abc") :e foo(print) //│ ╔══[COMPILATION ERROR] Cannot get print's parameter list. -//│ ║ l.517: foo(print) +//│ ║ l.514: foo(print) //│ ╙── ^^^^^ //│ ═══[RUNTIME ERROR] Error: Function 'call' expected 0 arguments but got 1 @@ -528,7 +525,7 @@ foo(print(_)) :expect ["abc"] foo(tuple) //│ ╔══[COMPILATION ERROR] Cannot get tuple's parameter list. -//│ ║ l.529: foo(tuple) +//│ ║ l.526: foo(tuple) //│ ╙── ^^^^^ //│ ———————————————| Lowered IR |——————————————————————————————————————————————————————————————————————— //│ let Function$, tmp; diff --git a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls index 37d9b9fa66..110b137c39 100644 --- a/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls +++ b/hkmc2/shared/src/test/mlscript/deforest/fusibility.mls @@ -125,7 +125,7 @@ apply(c, AA(3)) fun c(k, x) = if k is AA(_) then x.AA#x + x.AA#x + x.AA#x c(AA(0), AA(3)) //│ deforest > >>> non-affine syms >>> -//│ deforest > tmp@1 +//│ deforest > tmp@2 //│ deforest > x_for_c@17 //│ deforest > x_for_c@31 //│ deforest > <<< non-affine syms <<< diff --git a/hkmc2DiffTests/src/test/scala/hkmc2/JSBackendDiffMaker.scala b/hkmc2DiffTests/src/test/scala/hkmc2/JSBackendDiffMaker.scala index 743c18e8c1..e1ba7a93e7 100644 --- a/hkmc2DiffTests/src/test/scala/hkmc2/JSBackendDiffMaker.scala +++ b/hkmc2DiffTests/src/test/scala/hkmc2/JSBackendDiffMaker.scala @@ -41,9 +41,12 @@ abstract class JSBackendDiffMaker extends MLsDiffMaker: val termNme = baseScp.allocateName(Elaborator.State.termSymbol)(using throw _) val blockNme = baseScp.allocateName(Elaborator.State.blockSymbol)(using throw _) val optionNme = baseScp.allocateName(Elaborator.State.optionSymbol)(using throw _) + val shapeSetNme = baseScp.allocateName(Elaborator.State.shapeSetSymbol)(using throw _) + val specializationHelpersNme = baseScp.allocateName(Elaborator.State.specializeHelpersSymbol)(using throw _) val definitionMetadataNme = baseScp.allocateName(Elaborator.State.definitionMetadataSymbol)(using throw _) val prettyPrintNme = baseScp.allocateName(Elaborator.State.prettyPrintSymbol)(using throw _) + val ltl = new TraceLogger: override def doTrace = debugLowering.isSet || scope.exists: showUCS.get.getOrElse(Set.empty).contains @@ -73,6 +76,8 @@ abstract class JSBackendDiffMaker extends MLsDiffMaker: if stageCode.isSet then importRuntimeModule(blockNme, blockFile) importRuntimeModule(optionNme, optionFile) + importRuntimeModule(shapeSetNme, shapeSetFile) + importRuntimeModule(specializationHelpersNme, specializeHelpersFile) h private var hostCreated = false diff --git a/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala b/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala index 44db4d7882..ea02639aed 100644 --- a/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala +++ b/hkmc2DiffTests/src/test/scala/hkmc2/MLsDiffMaker.scala @@ -20,6 +20,8 @@ abstract class MLsDiffMaker extends DiffMaker: val termFile: io.Path = predefFile.up / "Term.mjs" // * Contains MLscript runtime term definitions val blockFile: io.Path = predefFile.up / "Block.mjs" // * Contains MLscript runtime block definitions val optionFile: io.Path = predefFile.up / "Option.mjs" // * Contains MLscipt runtime option definition + val shapeSetFile: io.Path = predefFile.up / "ShapeSet.mjs" // * Contains MLscript runtime shapeset definitions + val specializeHelpersFile: io.Path = predefFile.up / "SpecializeHelpers.mjs" // * Contains MLscipt runtime specialization helpers val wd = file.up @@ -182,6 +184,7 @@ abstract class MLsDiffMaker extends DiffMaker: inlining = Opt.when(!noInlineOpt.isSet)(Config.Inliner(inlineThreshold = inlineThreshold.get.getOrElse(Config.default.inlineThreshold))), deadBranchRemoval = Config.default.deadBranchRemoval, + disableDataFlowAnalysis = false, qqEnabled = importQQ.isSet, funcToCls = funcToCls.isSet, commentGeneratedCode = debug.isSet, @@ -464,4 +467,3 @@ abstract class MLsDiffMaker extends DiffMaker: doc" #{ ${trm.showTopLevel(using flowScp)} #} \nwhere #{ ${floan.showFlows(using flowScp)} #} ".mkString() - diff --git a/hkmc2DiffTests/src/test/scala/hkmc2/Watcher.scala b/hkmc2DiffTests/src/test/scala/hkmc2/Watcher.scala index 1ca3e16cd4..c4508a973b 100644 --- a/hkmc2DiffTests/src/test/scala/hkmc2/Watcher.scala +++ b/hkmc2DiffTests/src/test/scala/hkmc2/Watcher.scala @@ -111,7 +111,11 @@ class Watcher(dirs: Ls[File]): paths = new MLsCompiler.Paths: val preludeFile = preludePath val runtimeFile = testBasePath/"mlscript-compile"/"Runtime.mjs" - val termFile = testBasePath/"mlscript-compile"/"Term.mjs", + val termFile = testBasePath/"mlscript-compile"/"Term.mjs" + val blockFile = testBasePath/"mlscript-compile"/"Block.mjs" + val specializeHelpersFile = testBasePath/"mlscript-compile"/"SpecializeHelpers.mjs" + val optionFile = testBasePath/"mlscript-compile"/"Option.mjs" + val shapeSetFile = testBasePath/"mlscript-compile"/"ShapeSet.mjs", mkRaise = ReportFormatter(System.out.println, colorize = true).mkRaise ).compileModule(path) else