From e4a948ba947da01b95e329cd797f3e13975faf08 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Sun, 22 Jun 2025 19:42:25 -0400 Subject: [PATCH] maybe actually fix the loop stuff; lots of QOL improvements --- sandbox.ld | 25 +- sandbox_run.txt | 2379 +++++++++++++++++++++++++++++++++++++++++++++++ src/chunk.rs | 86 ++ src/compiler.rs | 166 ++-- src/op.rs | 226 +++++ src/vm.rs | 14 +- 6 files changed, 2825 insertions(+), 71 deletions(-) create mode 100644 sandbox_run.txt create mode 100644 src/chunk.rs create mode 100644 src/op.rs diff --git a/sandbox.ld b/sandbox.ld index 20417b4..69b5ec9 100644 --- a/sandbox.ld +++ b/sandbox.ld @@ -1,13 +1,14 @@ -let test = 2 +let test = 3 -loop ([1, 2, 3]) with { +let quux = loop ([1, 2]) with { ([]) -> false ([x]) -> eq? (x, test) ([x, ...xs]) -> if eq? (x, test) - then true + then :yes else recur (xs) } + let foo = :bar fn not { @@ -16,11 +17,15 @@ fn not { (_) -> false } -& loop ([1, 2, 3]) with { -& ([]) -> false -& ([y]) -> eq? (y, test) -& ([y, ...ys]) -> if not (eq? (y, test)) -& then recur (ys) -& else true -& } +let frob = loop ([1, 2, 3]) with { + ([]) -> false + ([y]) -> eq? (y, test) + ([y, ...ys]) -> if not (eq? (y, test)) + then recur (ys) + else true +} + +[quux, frob] + + diff --git a/sandbox_run.txt b/sandbox_run.txt new file mode 100644 index 0000000..7065810 --- /dev/null +++ b/sandbox_run.txt @@ -0,0 +1,2379 @@ +{ + + let test = 3 + let quux = loop ([1, 2]) with { + ([]) -> false + ([x]) -> eq? (x, test) + ([x, ...xs]) -> if eq? (x, test) + then :yes + else recur (xs) +} + let foo = :bar + fn not { + (false) -> true + (nil) -> true + (_) -> false +} + let frob = loop ([1, 2, 3]) with { + ([]) -> false + ([y]) -> eq? (y, test) + ([y, ...ys]) -> if not (eq? (y, test) ) + then recur (ys) + else true +} + [quux, frob] +} +binding `base` in prelude +stack depth: 1; match depth: 0 +at stack index: 0 +new locals: base@0//-1 +binding `eq?` in prelude +stack depth: 2; match depth: 0 +at stack index: 1 +new locals: base@0//-1|eq?@1//0 +***function clause matching: : (x, y) +binding `x` in eq? +stack depth: 2; match depth: 1 +at stack index: 0 +new locals: x@0//0 +binding `y` in eq? +stack depth: 2; match depth: 0 +at stack index: 1 +new locals: x@0//0|y@1//0 +***accessing keyword: base :eq? stack depth: 2 +resolving binding `base` in eq? +locals: x@0//0|y@1//0 +as enclosing upvalue 0 +***after keyword access stack depth: 3 +resolving binding `x` in eq? +locals: x@0//0|y@1//0 +at locals position 0 +resolving binding `y` in eq? +locals: x@0//0|y@1//0 +at locals position 1 +resolving binding `base` in prelude +locals: base@0//-1|eq?@1//0 +at locals position 0 +binding `first` in prelude +stack depth: 3; match depth: 0 +at stack index: 2 +new locals: base@0//-1|eq?@1//0|first@2//0 +***function clause matching: : ([]) +***function clause matching: : (xs as :list) +binding `xs` in first +stack depth: 1; match depth: 0 +at stack index: 0 +new locals: xs@0//0 +***accessing keyword: base :first stack depth: 1 +resolving binding `base` in first +locals: xs@0//0 +as enclosing upvalue 0 +***after keyword access stack depth: 2 +resolving binding `xs` in first +locals: xs@0//0 +at locals position 0 +resolving binding `base` in prelude +locals: base@0//-1|eq?@1//0|first@2//0 +at locals position 0 +binding `rest` in prelude +stack depth: 4; match depth: 0 +at stack index: 3 +new locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0 +***function clause matching: : ([]) +***function clause matching: : (xs as :list) +binding `xs` in rest +stack depth: 1; match depth: 0 +at stack index: 0 +new locals: xs@0//0 +***accessing keyword: base :rest stack depth: 1 +resolving binding `base` in rest +locals: xs@0//0 +as enclosing upvalue 0 +***after keyword access stack depth: 2 +resolving binding `xs` in rest +locals: xs@0//0 +at locals position 0 +resolving binding `base` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0 +at locals position 0 +binding `inc` in prelude +stack depth: 5; match depth: 0 +at stack index: 4 +new locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0 +***function clause matching: : (x as :number) +binding `x` in inc +stack depth: 1; match depth: 0 +at stack index: 0 +new locals: x@0//0 +***accessing keyword: base :inc stack depth: 1 +resolving binding `base` in inc +locals: x@0//0 +as enclosing upvalue 0 +***after keyword access stack depth: 2 +resolving binding `x` in inc +locals: x@0//0 +at locals position 0 +resolving binding `base` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0 +at locals position 0 +binding `append` in prelude +stack depth: 6; match depth: 0 +at stack index: 5 +new locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0 +***function clause matching: : () +***function clause matching: : (xs as :list) +binding `xs` in append +stack depth: 1; match depth: 0 +at stack index: 0 +new locals: xs@0//0 +resolving binding `xs` in append +locals: xs@0//0 +at locals position 0 +***function clause matching: : (xs as :list, x) +binding `xs` in append +stack depth: 2; match depth: 1 +at stack index: 0 +new locals: xs@0//0 +binding `x` in append +stack depth: 2; match depth: 0 +at stack index: 1 +new locals: xs@0//0|x@1//0 +***accessing keyword: base :append stack depth: 2 +resolving binding `base` in append +locals: xs@0//0|x@1//0 +as enclosing upvalue 0 +***after keyword access stack depth: 3 +resolving binding `xs` in append +locals: xs@0//0|x@1//0 +at locals position 0 +resolving binding `x` in append +locals: xs@0//0|x@1//0 +at locals position 1 +resolving binding `base` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0 +at locals position 0 +binding `fold` in prelude +stack depth: 7; match depth: 0 +at stack index: 6 +new locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0 +***function clause matching: : (f as :fn, []) +binding `f` in fold +stack depth: 2; match depth: 1 +at stack index: 0 +new locals: f@0//0 +***function clause matching: : (f as :fn, xs as :list) +binding `f` in fold +stack depth: 2; match depth: 1 +at stack index: 0 +new locals: f@0//0 +binding `xs` in fold +stack depth: 2; match depth: 0 +at stack index: 1 +new locals: f@0//0|xs@1//0 +***calling function fold stack depth: 2 +resolving binding `f` in fold +locals: f@0//0|xs@1//0 +at locals position 0 +resolving binding `xs` in fold +locals: f@0//0|xs@1//0 +at locals position 1 +***calling function f stack depth: 4 +resolving binding `f` in fold +locals: f@0//0|xs@1//0 +at locals position 0 +***after 0 args stack depth: 5 +resolving binding `fold` in fold +locals: f@0//0|xs@1//0 +as enclosing upvalue 0 +***after 3 args stack depth: 6 +***function clause matching: : (f as :fn, [], root) +binding `f` in fold +stack depth: 3; match depth: 2 +at stack index: 0 +new locals: f@0//0 +binding `root` in fold +stack depth: 3; match depth: 0 +at stack index: 2 +new locals: f@0//0|root@2//0 +***function clause matching: : (f as :fn, xs as :list, root) +binding `f` in fold +stack depth: 3; match depth: 2 +at stack index: 0 +new locals: f@0//0 +binding `xs` in fold +stack depth: 3; match depth: 1 +at stack index: 1 +new locals: f@0//0|xs@1//0 +binding `root` in fold +stack depth: 3; match depth: 0 +at stack index: 2 +new locals: f@0//0|xs@1//0|root@2//0 +***entering loop stack depth: 3 +resolving binding `root` in fold +locals: f@0//0|xs@1//0|root@2//0 +at locals position 2 +***calling function first stack depth: 4 +resolving binding `xs` in fold +locals: f@0//0|xs@1//0|root@2//0 +at locals position 1 +resolving binding `first` in fold +locals: f@0//0|xs@1//0|root@2//0 +as enclosing upvalue 1 +***after 1 args stack depth: 6 +***calling function rest stack depth: 5 +resolving binding `xs` in fold +locals: f@0//0|xs@1//0|root@2//0 +at locals position 1 +resolving binding `rest` in fold +locals: f@0//0|xs@1//0|root@2//0 +as enclosing upvalue 2 +***after 1 args stack depth: 7 +***after loop args stack depth: 6 +***loop: after store stack depth: 3 +***loop: after load stack depth: 6 +***loop clause matching: : (prev, curr, []) +binding `prev` in fold +stack depth: 6; match depth: 2 +at stack index: 3 +new locals: f@0//0|xs@1//0|root@2//0|prev@3//1 +binding `curr` in fold +stack depth: 6; match depth: 1 +at stack index: 4 +new locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1 +***loop: before body stack depth: 6 +***calling function f stack depth: 6 +resolving binding `prev` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1 +at locals position 3 +resolving binding `curr` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1 +at locals position 4 +resolving binding `f` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1 +at locals position 0 +***after 2 args stack depth: 9 +***loop: after body, before store stack depth: 7 +***loop: after body, after store stack depth: 6 +leaving scope 1 +releasing binding Some(Binding { name: "curr", depth: 1, stack_pos: 4 }) +releasing binding Some(Binding { name: "prev", depth: 1, stack_pos: 3 }) +***resetting the stack after loop from 6 to 3 stack depth: 6 +***loop: after load stack depth: 6 +***loop clause matching: : (prev, curr, remaining) +binding `prev` in fold +stack depth: 6; match depth: 2 +at stack index: 3 +new locals: f@0//0|xs@1//0|root@2//0|prev@3//1 +binding `curr` in fold +stack depth: 6; match depth: 1 +at stack index: 4 +new locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1 +binding `remaining` in fold +stack depth: 6; match depth: 0 +at stack index: 5 +new locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +***loop: before body stack depth: 6 +***recur: before args stack depth: 6 +recur arg: 0 +***calling function f stack depth: 6 +resolving binding `prev` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +at locals position 3 +resolving binding `curr` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +at locals position 4 +resolving binding `f` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +at locals position 0 +***after 2 args stack depth: 9 +recur arg: 1 +***calling function first stack depth: 7 +resolving binding `remaining` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +at locals position 5 +resolving binding `first` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +as upvalue 1 +***after 1 args stack depth: 9 +recur arg: 2 +***calling function rest stack depth: 8 +resolving binding `remaining` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +at locals position 5 +resolving binding `rest` in fold +locals: f@0//0|xs@1//0|root@2//0|prev@3//1|curr@4//1|remaining@5//1 +as upvalue 2 +***after 1 args stack depth: 10 +***recur: after args stack depth: 9 +***recur: after store stack depth: 6 +loop root depth: 3 +***recur: after stack reset stack depth: 3 +***recur: after load, end of compilation stack depth: 6 +***loop: after body, before store stack depth: 6 +***loop: after body, after store stack depth: 5 +leaving scope 1 +releasing binding Some(Binding { name: "remaining", depth: 1, stack_pos: 5 }) +releasing binding Some(Binding { name: "curr", depth: 1, stack_pos: 4 }) +releasing binding Some(Binding { name: "prev", depth: 1, stack_pos: 3 }) +***resetting the stack after loop from 5 to 3 stack depth: 5 +***before loop arity adjustment stack depth: 6 +***at very end of loop after load stack depth: 4 +resolving binding `fold` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0 +at locals position 6 +resolving binding `first` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0 +at locals position 2 +resolving binding `rest` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0 +at locals position 3 +binding `contains?` in prelude +stack depth: 8; match depth: 0 +at stack index: 7 +new locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0 +***function clause matching: : (value, l as :list) +binding `value` in contains? +stack depth: 2; match depth: 1 +at stack index: 0 +new locals: value@0//0 +binding `l` in contains? +stack depth: 2; match depth: 0 +at stack index: 1 +new locals: value@0//0|l@1//0 +***entering loop stack depth: 2 +resolving binding `l` in contains? +locals: value@0//0|l@1//0 +at locals position 1 +***after loop args stack depth: 3 +***loop: after store stack depth: 2 +***loop: after load stack depth: 3 +***loop clause matching: : ([]) +***loop: before body stack depth: 3 +***loop: after body, before store stack depth: 4 +***loop: after body, after store stack depth: 3 +leaving scope 1 +***resetting the stack after loop from 3 to 2 stack depth: 3 +***loop: after load stack depth: 3 +***loop clause matching: : ([...xs]) +binding `xs` in contains? +stack depth: 4; match depth: 0 +at stack index: 3 +new locals: value@0//0|l@1//0|xs@3//1 +***loop: before body stack depth: 4 +***calling function eq? stack depth: 4 +***calling function first stack depth: 4 +resolving binding `xs` in contains? +locals: value@0//0|l@1//0|xs@3//1 +at locals position 3 +resolving binding `first` in contains? +locals: value@0//0|l@1//0|xs@3//1 +as enclosing upvalue 0 +***after 1 args stack depth: 6 +resolving binding `value` in contains? +locals: value@0//0|l@1//0|xs@3//1 +at locals position 0 +resolving binding `eq?` in contains? +locals: value@0//0|l@1//0|xs@3//1 +as enclosing upvalue 1 +***after 2 args stack depth: 7 +***after condition stack depth: 5 +***after consequent stack depth: 5 +***recur: before args stack depth: 4 +recur arg: 0 +***calling function rest stack depth: 4 +resolving binding `xs` in contains? +locals: value@0//0|l@1//0|xs@3//1 +at locals position 3 +resolving binding `rest` in contains? +locals: value@0//0|l@1//0|xs@3//1 +as enclosing upvalue 2 +***after 1 args stack depth: 6 +***recur: after args stack depth: 5 +***recur: after store stack depth: 4 +loop root depth: 2 +***recur: after stack reset stack depth: 2 +***recur: after load, end of compilation stack depth: 3 +***after alternative stack depth: 3 +***loop: after body, before store stack depth: 3 +***loop: after body, after store stack depth: 2 +leaving scope 1 +releasing binding Some(Binding { name: "xs", depth: 1, stack_pos: 3 }) +***resetting the stack after loop from 2 to 2 stack depth: 2 +***before loop arity adjustment stack depth: 3 +***at very end of loop after load stack depth: 3 +resolving binding `first` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0 +at locals position 2 +resolving binding `eq?` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0 +at locals position 1 +resolving binding `rest` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0 +at locals position 3 +binding `add` in prelude +stack depth: 9; match depth: 0 +at stack index: 8 +new locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0|add@8//0 +***function clause matching: : () +***function clause matching: : (x) +binding `x` in add +stack depth: 1; match depth: 0 +at stack index: 0 +new locals: x@0//0 +resolving binding `x` in add +locals: x@0//0 +at locals position 0 +***function clause matching: : (x, y) +binding `x` in add +stack depth: 2; match depth: 1 +at stack index: 0 +new locals: x@0//0 +binding `y` in add +stack depth: 2; match depth: 0 +at stack index: 1 +new locals: x@0//0|y@1//0 +***accessing keyword: base :add stack depth: 2 +resolving binding `base` in add +locals: x@0//0|y@1//0 +as enclosing upvalue 0 +***after keyword access stack depth: 3 +resolving binding `x` in add +locals: x@0//0|y@1//0 +at locals position 0 +resolving binding `y` in add +locals: x@0//0|y@1//0 +at locals position 1 +resolving binding `base` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0|add@8//0 +at locals position 0 +resolving binding `add` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0|add@8//0 +at locals position 8 +resolving binding `rest` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0|add@8//0 +at locals position 3 +resolving binding `first` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0|add@8//0 +at locals position 2 +resolving binding `eq?` in prelude +locals: base@0//-1|eq?@1//0|first@2//0|rest@3//0|inc@4//0|append@5//0|fold@6//0|contains?@7//0|add@8//0 +at locals position 1 +leaving scope 0 +releasing binding Some(Binding { name: "add", depth: 0, stack_pos: 8 }) +releasing binding Some(Binding { name: "contains?", depth: 0, stack_pos: 7 }) +releasing binding Some(Binding { name: "fold", depth: 0, stack_pos: 6 }) +releasing binding Some(Binding { name: "append", depth: 0, stack_pos: 5 }) +releasing binding Some(Binding { name: "inc", depth: 0, stack_pos: 4 }) +releasing binding Some(Binding { name: "rest", depth: 0, stack_pos: 3 }) +releasing binding Some(Binding { name: "first", depth: 0, stack_pos: 2 }) +releasing binding Some(Binding { name: "eq?", depth: 0, stack_pos: 1 }) +closing over in eq?: #{:trim fn trim/base... +closing over in first: #{:trim fn trim/base... +closing over in rest: #{:trim fn trim/base... +closing over in inc: #{:trim fn trim/base... +closing over in append: #{:trim fn trim/base... +closing over in fold: fn fold +closing over in fold: fn first +closing over in fold: fn rest +closing over in contains?: fn first +closing over in contains?: fn eq? +closing over in contains?: fn rest +closing over in add: #{:trim fn trim/base... +***before let binding stack depth: 0 +***after let expr stack depth: 1 +***let binding: matching: test +binding `test` in sandbox +stack depth: 1; match depth: 0 +at stack index: 0 +new locals: test@0//0 +***after let binding stack depth: 1 +***before let binding stack depth: 1 +***entering loop stack depth: 1 +***after loop args stack depth: 2 +***loop: after store stack depth: 1 +***loop: after load stack depth: 2 +***loop clause matching: : ([]) +***loop: before body stack depth: 2 +***loop: after body, before store stack depth: 3 +***loop: after body, after store stack depth: 2 +leaving scope 1 +***resetting the stack after loop from 2 to 1 stack depth: 2 +***loop: after load stack depth: 2 +***loop clause matching: : ([x]) +binding `x` in sandbox +stack depth: 3; match depth: 0 +at stack index: 2 +new locals: test@0//0|x@2//1 +***loop: before body stack depth: 3 +***calling function eq? stack depth: 3 +resolving binding `x` in sandbox +locals: test@0//0|x@2//1 +at locals position 2 +resolving binding `test` in sandbox +locals: test@0//0|x@2//1 +at locals position 0 +resolving binding `eq?` in sandbox +locals: test@0//0|x@2//1 +as global +***after 2 args stack depth: 6 +***loop: after body, before store stack depth: 4 +***loop: after body, after store stack depth: 3 +leaving scope 1 +releasing binding Some(Binding { name: "x", depth: 1, stack_pos: 2 }) +***resetting the stack after loop from 3 to 1 stack depth: 3 +***loop: after load stack depth: 2 +***loop clause matching: : ([x, ...xs]) +binding `x` in sandbox +stack depth: 4; match depth: 1 +at stack index: 2 +new locals: test@0//0|x@2//1 +binding `xs` in sandbox +stack depth: 4; match depth: 0 +at stack index: 3 +new locals: test@0//0|x@2//1|xs@3//1 +***loop: before body stack depth: 4 +***calling function eq? stack depth: 4 +resolving binding `x` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +at locals position 2 +resolving binding `test` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +at locals position 0 +resolving binding `eq?` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +as global +***after 2 args stack depth: 7 +***after condition stack depth: 5 +***after consequent stack depth: 5 +***recur: before args stack depth: 4 +recur arg: 0 +resolving binding `xs` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +at locals position 3 +***recur: after args stack depth: 5 +***recur: after store stack depth: 4 +loop root depth: 1 +***recur: after stack reset stack depth: 1 +***recur: after load, end of compilation stack depth: 2 +***after alternative stack depth: 2 +***loop: after body, before store stack depth: 2 +***loop: after body, after store stack depth: 1 +leaving scope 1 +releasing binding Some(Binding { name: "xs", depth: 1, stack_pos: 3 }) +releasing binding Some(Binding { name: "x", depth: 1, stack_pos: 2 }) +***resetting the stack after loop from 1 to 1 stack depth: 1 +***before loop arity adjustment stack depth: 2 +***at very end of loop after load stack depth: 2 +***after let expr stack depth: 2 +***let binding: matching: quux +binding `quux` in sandbox +stack depth: 2; match depth: 0 +at stack index: 1 +new locals: test@0//0|quux@1//0 +***after let binding stack depth: 2 +***before let binding stack depth: 2 +***after let expr stack depth: 3 +***let binding: matching: foo +binding `foo` in sandbox +stack depth: 3; match depth: 0 +at stack index: 2 +new locals: test@0//0|quux@1//0|foo@2//0 +***after let binding stack depth: 3 +binding `not` in sandbox +stack depth: 4; match depth: 0 +at stack index: 3 +new locals: test@0//0|quux@1//0|foo@2//0|not@3//0 +***function clause matching: : (false) +***function clause matching: : (nil) +***function clause matching: : (_) +=== function chuncktion: not/1 === +IDX | CODE | INFO +0000: reset_match +0001: ***function clause matching: : (false) +0003: match_depth 000 +0005: match_false +0006: jump_if_no_match 00003 +0009: jump 00000 +0012: jump_if_no_match 00004 +0015: true +0016: store +0017: pop +0018: return +0019: ***function clause matching: : (nil) +0021: match_depth 000 +0023: match_nil +0024: jump_if_no_match 00003 +0027: jump 00000 +0030: jump_if_no_match 00004 +0033: true +0034: store +0035: pop +0036: return +0037: ***function clause matching: : (_) +0039: match_depth 000 +0041: match +0042: jump_if_no_match 00003 +0045: jump 00000 +0048: jump_if_no_match 00004 +0051: false +0052: store +0053: pop +0054: return +0055: panic_no_match +***before let binding stack depth: 4 +***entering loop stack depth: 4 +***after loop args stack depth: 5 +***loop: after store stack depth: 4 +***loop: after load stack depth: 5 +***loop clause matching: : ([]) +***loop: before body stack depth: 5 +***loop: after body, before store stack depth: 6 +***loop: after body, after store stack depth: 5 +leaving scope 1 +***resetting the stack after loop from 5 to 4 stack depth: 5 +***loop: after load stack depth: 5 +***loop clause matching: : ([y]) +binding `y` in sandbox +stack depth: 6; match depth: 0 +at stack index: 5 +new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +***loop: before body stack depth: 6 +***calling function eq? stack depth: 6 +resolving binding `y` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +at locals position 5 +resolving binding `test` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +at locals position 0 +resolving binding `eq?` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +as global +***after 2 args stack depth: 9 +***loop: after body, before store stack depth: 7 +***loop: after body, after store stack depth: 6 +leaving scope 1 +releasing binding Some(Binding { name: "y", depth: 1, stack_pos: 5 }) +***resetting the stack after loop from 6 to 4 stack depth: 6 +***loop: after load stack depth: 5 +***loop clause matching: : ([y, ...ys]) +binding `y` in sandbox +stack depth: 7; match depth: 1 +at stack index: 5 +new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +binding `ys` in sandbox +stack depth: 7; match depth: 0 +at stack index: 6 +new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +***loop: before body stack depth: 7 +***calling function not stack depth: 7 +***calling function eq? stack depth: 7 +resolving binding `y` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +at locals position 5 +resolving binding `test` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +at locals position 0 +resolving binding `eq?` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +as global +***after 2 args stack depth: 10 +resolving binding `not` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +at locals position 3 +***after 1 args stack depth: 9 +***after condition stack depth: 8 +***recur: before args stack depth: 7 +recur arg: 0 +resolving binding `ys` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +at locals position 6 +***recur: after args stack depth: 8 +***recur: after store stack depth: 7 +loop root depth: 4 +***recur: after stack reset stack depth: 4 +***recur: after load, end of compilation stack depth: 5 +***after consequent stack depth: 5 +***after alternative stack depth: 5 +***loop: after body, before store stack depth: 5 +***loop: after body, after store stack depth: 4 +leaving scope 1 +releasing binding Some(Binding { name: "ys", depth: 1, stack_pos: 6 }) +releasing binding Some(Binding { name: "y", depth: 1, stack_pos: 5 }) +***resetting the stack after loop from 4 to 4 stack depth: 4 +***before loop arity adjustment stack depth: 5 +***at very end of loop after load stack depth: 5 +***after let expr stack depth: 5 +***let binding: matching: frob +binding `frob` in sandbox +stack depth: 5; match depth: 0 +at stack index: 4 +new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +***after let binding stack depth: 5 +resolving binding `quux` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +at locals position 1 +resolving binding `frob` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +at locals position 4 +leaving scope 0 +releasing binding Some(Binding { name: "frob", depth: 0, stack_pos: 4 }) +releasing binding Some(Binding { name: "not", depth: 0, stack_pos: 3 }) +releasing binding Some(Binding { name: "foo", depth: 0, stack_pos: 2 }) +releasing binding Some(Binding { name: "quux", depth: 0, stack_pos: 1 }) +releasing binding Some(Binding { name: "test", depth: 0, stack_pos: 0 }) +=== source code === +let test = 3 + +let quux = loop ([1, 2]) with { + ([]) -> false + ([x]) -> eq? (x, test) + ([x, ...xs]) -> if eq? (x, test) + then :yes + else recur (xs) +} + + +let foo = :bar + +fn not { + (false) -> true + (nil) -> true + (_) -> false +} + +let frob = loop ([1, 2, 3]) with { + ([]) -> false + ([y]) -> eq? (y, test) + ([y, ...ys]) -> if not (eq? (y, test)) + then recur (ys) + else true +} + +[quux, frob] + + + + +=== chunk: sandbox === +IDX | CODE | INFO +0000: ***before let binding stack depth: 0 +0002: constant 00000: 3 +0005: ***after let expr stack depth: 1 +0007: ***let binding: matching: test +0009: reset_match +0010: match +0011: binding `test` in sandbox +0013: stack depth: 1; match depth: 0 +0015: at stack index: 0 +0017: new locals: test@0//0 +0019: panic_if_no_match +0020: ***after let binding stack depth: 1 +0022: ***before let binding stack depth: 1 +0024: ***entering loop stack depth: 1 +0026: push_list +0027: constant 00001: 1 +0030: append_list +0031: constant 00002: 2 +0034: append_list +0035: ***after loop args stack depth: 2 +0037: store_n 001 +0039: ***loop: after store stack depth: 1 +0041: load_n 001 +0043: ***loop: after load stack depth: 2 +0045: reset_match +0046: ***loop clause matching: : ([]) +0048: match_depth 000 +0050: match_list 000 +0052: jump_if_no_match 00006 +0055: load_list +0056: jump 00002 +0059: pop_n 000 +0061: jump_if_no_match 00016 +0064: ***loop: before body stack depth: 2 +0066: false +0067: ***loop: after body, before store stack depth: 3 +0069: store +0070: ***loop: after body, after store stack depth: 2 +0072: leaving scope 1 +0074: ***resetting the stack after loop from 2 to 1 stack depth: 2 +0076: pop +0077: jump 00218 +0080: ***loop: after load stack depth: 2 +0082: reset_match +0083: ***loop clause matching: : ([x]) +0085: match_depth 000 +0087: match_list 001 +0089: jump_if_no_match 00020 +0092: load_list +0093: match_depth 000 +0095: match +0096: binding `x` in sandbox +0098: stack depth: 3; match depth: 0 +0100: at stack index: 2 +0102: new locals: test@0//0|x@2//1 +0104: jump_if_no_match 00004 +0107: jump 00002 +0110: pop_n 001 +0112: jump_if_no_match 00044 +0115: ***loop: before body stack depth: 3 +0117: ***calling function eq? stack depth: 3 +0119: resolving binding `x` in sandbox +locals: test@0//0|x@2//1 +0121: at locals position 2 +0123: push_binding 002 +0125: resolving binding `test` in sandbox +locals: test@0//0|x@2//1 +0127: at locals position 0 +0129: push_binding 000 +0131: resolving binding `eq?` in sandbox +locals: test@0//0|x@2//1 +0133: as global +0135: constant 00003: :eq? +0138: push_global +0139: ***after 2 args stack depth: 6 +0141: call 002 +0143: ***loop: after body, before store stack depth: 4 +0145: store +0146: ***loop: after body, after store stack depth: 3 +0148: leaving scope 1 +0150: releasing binding Some(Binding { name: "x", depth: 1, stack_pos: 2 }) +0152: ***resetting the stack after loop from 3 to 1 stack depth: 3 +0154: pop_n 002 +0156: jump 00139 +0159: ***loop: after load stack depth: 2 +0161: reset_match +0162: ***loop clause matching: : ([x, ...xs]) +0164: match_depth 000 +0166: match_splatted_list 002 +0168: jump_if_no_match 00035 +0171: load_splatted_list 002 +0173: match_depth 001 +0175: match +0176: binding `x` in sandbox +0178: stack depth: 4; match depth: 1 +0180: at stack index: 2 +0182: new locals: test@0//0|x@2//1 +0184: jump_if_no_match 00018 +0187: match_depth 000 +0189: match +0190: binding `xs` in sandbox +0192: stack depth: 4; match depth: 0 +0194: at stack index: 3 +0196: new locals: test@0//0|x@2//1|xs@3//1 +0198: jump_if_no_match 00004 +0201: jump 00002 +0204: pop_n 002 +0206: jump_if_no_match 00088 +0209: ***loop: before body stack depth: 4 +0211: ***calling function eq? stack depth: 4 +0213: resolving binding `x` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0215: at locals position 2 +0217: push_binding 002 +0219: resolving binding `test` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0221: at locals position 0 +0223: push_binding 000 +0225: resolving binding `eq?` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0227: as global +0229: constant 00003: :eq? +0232: push_global +0233: ***after 2 args stack depth: 7 +0235: call 002 +0237: ***after condition stack depth: 5 +0239: jump_if_false 00008 +0242: constant 00004: :yes +0245: ***after consequent stack depth: 5 +0247: jump 00031 +0250: ***recur: before args stack depth: 4 +0252: recur arg: 0 +0254: resolving binding `xs` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0256: at locals position 3 +0258: push_binding 003 +0260: ***recur: after args stack depth: 5 +0262: store_n 001 +0264: ***recur: after store stack depth: 4 +0266: loop root depth: 1 +0268: pop_n 003 +0270: ***recur: after stack reset stack depth: 1 +0272: load_n 001 +0274: ***recur: after load, end of compilation stack depth: 2 +0276: jump_back 00233 +0279: ***after alternative stack depth: 2 +0281: ***loop: after body, before store stack depth: 2 +0283: store +0284: ***loop: after body, after store stack depth: 1 +0286: leaving scope 1 +0288: releasing binding Some(Binding { name: "xs", depth: 1, stack_pos: 3 }) +0290: releasing binding Some(Binding { name: "x", depth: 1, stack_pos: 2 }) +0292: ***resetting the stack after loop from 1 to 1 stack depth: 1 +0294: jump 00001 +0297: panic_no_match +0298: ***before loop arity adjustment stack depth: 2 +0300: load +0301: ***at very end of loop after load stack depth: 2 +0303: ***after let expr stack depth: 2 +0305: ***let binding: matching: quux +0307: reset_match +0308: match +0309: binding `quux` in sandbox +0311: stack depth: 2; match depth: 0 +0313: at stack index: 1 +0315: new locals: test@0//0|quux@1//0 +0317: panic_if_no_match +0318: ***after let binding stack depth: 2 +0320: ***before let binding stack depth: 2 +0322: constant 00005: :bar +0325: ***after let expr stack depth: 3 +0327: ***let binding: matching: foo +0329: reset_match +0330: match +0331: binding `foo` in sandbox +0333: stack depth: 3; match depth: 0 +0335: at stack index: 2 +0337: new locals: test@0//0|quux@1//0|foo@2//0 +0339: panic_if_no_match +0340: ***after let binding stack depth: 3 +0342: constant 00006: fn not +0345: binding `not` in sandbox +0347: stack depth: 4; match depth: 0 +0349: at stack index: 3 +0351: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0 +0353: ***before let binding stack depth: 4 +0355: ***entering loop stack depth: 4 +0357: push_list +0358: constant 00001: 1 +0361: append_list +0362: constant 00002: 2 +0365: append_list +0366: constant 00000: 3 +0369: append_list +0370: ***after loop args stack depth: 5 +0372: store_n 001 +0374: ***loop: after store stack depth: 4 +0376: load_n 001 +0378: ***loop: after load stack depth: 5 +0380: reset_match +0381: ***loop clause matching: : ([]) +0383: match_depth 000 +0385: match_list 000 +0387: jump_if_no_match 00006 +0390: load_list +0391: jump 00002 +0394: pop_n 000 +0396: jump_if_no_match 00016 +0399: ***loop: before body stack depth: 5 +0401: false +0402: ***loop: after body, before store stack depth: 6 +0404: store +0405: ***loop: after body, after store stack depth: 5 +0407: leaving scope 1 +0409: ***resetting the stack after loop from 5 to 4 stack depth: 5 +0411: pop +0412: jump 00228 +0415: ***loop: after load stack depth: 5 +0417: reset_match +0418: ***loop clause matching: : ([y]) +0420: match_depth 000 +0422: match_list 001 +0424: jump_if_no_match 00020 +0427: load_list +0428: match_depth 000 +0430: match +0431: binding `y` in sandbox +0433: stack depth: 6; match depth: 0 +0435: at stack index: 5 +0437: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0439: jump_if_no_match 00004 +0442: jump 00002 +0445: pop_n 001 +0447: jump_if_no_match 00044 +0450: ***loop: before body stack depth: 6 +0452: ***calling function eq? stack depth: 6 +0454: resolving binding `y` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0456: at locals position 5 +0458: push_binding 005 +0460: resolving binding `test` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0462: at locals position 0 +0464: push_binding 000 +0466: resolving binding `eq?` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0468: as global +0470: constant 00003: :eq? +0473: push_global +0474: ***after 2 args stack depth: 9 +0476: call 002 +0478: ***loop: after body, before store stack depth: 7 +0480: store +0481: ***loop: after body, after store stack depth: 6 +0483: leaving scope 1 +0485: releasing binding Some(Binding { name: "y", depth: 1, stack_pos: 5 }) +0487: ***resetting the stack after loop from 6 to 4 stack depth: 6 +0489: pop_n 002 +0491: jump 00149 +0494: ***loop: after load stack depth: 5 +0496: reset_match +0497: ***loop clause matching: : ([y, ...ys]) +0499: match_depth 000 +0501: match_splatted_list 002 +0503: jump_if_no_match 00035 +0506: load_splatted_list 002 +0508: match_depth 001 +0510: match +0511: binding `y` in sandbox +0513: stack depth: 7; match depth: 1 +0515: at stack index: 5 +0517: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0519: jump_if_no_match 00018 +0522: match_depth 000 +0524: match +0525: binding `ys` in sandbox +0527: stack depth: 7; match depth: 0 +0529: at stack index: 6 +0531: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0533: jump_if_no_match 00004 +0536: jump 00002 +0539: pop_n 002 +0541: jump_if_no_match 00098 +0544: ***loop: before body stack depth: 7 +0546: ***calling function not stack depth: 7 +0548: ***calling function eq? stack depth: 7 +0550: resolving binding `y` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0552: at locals position 5 +0554: push_binding 005 +0556: resolving binding `test` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0558: at locals position 0 +0560: push_binding 000 +0562: resolving binding `eq?` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0564: as global +0566: constant 00003: :eq? +0569: push_global +0570: ***after 2 args stack depth: 10 +0572: call 002 +0574: resolving binding `not` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0576: at locals position 3 +0578: push_binding 003 +0580: ***after 1 args stack depth: 9 +0582: call 001 +0584: ***after condition stack depth: 8 +0586: jump_if_false 00034 +0589: ***recur: before args stack depth: 7 +0591: recur arg: 0 +0593: resolving binding `ys` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0595: at locals position 6 +0597: push_binding 006 +0599: ***recur: after args stack depth: 8 +0601: store_n 001 +0603: ***recur: after store stack depth: 7 +0605: loop root depth: 4 +0607: pop_n 003 +0609: ***recur: after stack reset stack depth: 4 +0611: load_n 001 +0613: ***recur: after load, end of compilation stack depth: 5 +0615: jump_back 00237 +0618: ***after consequent stack depth: 5 +0620: jump 00003 +0623: true +0624: ***after alternative stack depth: 5 +0626: ***loop: after body, before store stack depth: 5 +0628: store +0629: ***loop: after body, after store stack depth: 4 +0631: leaving scope 1 +0633: releasing binding Some(Binding { name: "ys", depth: 1, stack_pos: 6 }) +0635: releasing binding Some(Binding { name: "y", depth: 1, stack_pos: 5 }) +0637: ***resetting the stack after loop from 4 to 4 stack depth: 4 +0639: jump 00001 +0642: panic_no_match +0643: ***before loop arity adjustment stack depth: 5 +0645: load +0646: ***at very end of loop after load stack depth: 5 +0648: ***after let expr stack depth: 5 +0650: ***let binding: matching: frob +0652: reset_match +0653: match +0654: binding `frob` in sandbox +0656: stack depth: 5; match depth: 0 +0658: at stack index: 4 +0660: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +0662: panic_if_no_match +0663: ***after let binding stack depth: 5 +0665: push_list +0666: resolving binding `quux` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +0668: at locals position 1 +0670: push_binding 001 +0672: append_list +0673: resolving binding `frob` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +0675: at locals position 4 +0677: push_binding 004 +0679: append_list +0680: store +0681: leaving scope 0 +0683: releasing binding Some(Binding { name: "frob", depth: 0, stack_pos: 4 }) +0685: releasing binding Some(Binding { name: "not", depth: 0, stack_pos: 3 }) +0687: releasing binding Some(Binding { name: "foo", depth: 0, stack_pos: 2 }) +0689: releasing binding Some(Binding { name: "quux", depth: 0, stack_pos: 1 }) +0691: releasing binding Some(Binding { name: "test", depth: 0, stack_pos: 0 }) +0693: pop_n 005 +0695: load + + + +=== vm run === +0000: [] (_,_,_,_,_,_,_,_) +0000: ***before let binding stack depth: 0 +0002: [] (_,_,_,_,_,_,_,_) +0002: constant 00000: 3 +0005: [->3<-] (_,_,_,_,_,_,_,_) +0005: ***after let expr stack depth: 1 +0007: [->3<-] (_,_,_,_,_,_,_,_) +0007: ***let binding: matching: test +0009: [->3<-] (_,_,_,_,_,_,_,_) +0009: reset_match +0010: [->3<-] (_,_,_,_,_,_,_,_) +0010: match +0011: [->3<-] (_,_,_,_,_,_,_,_) +0011: binding `test` in sandbox +0013: [->3<-] (_,_,_,_,_,_,_,_) +0013: stack depth: 1; match depth: 0 +0015: [->3<-] (_,_,_,_,_,_,_,_) +0015: at stack index: 0 +0017: [->3<-] (_,_,_,_,_,_,_,_) +0017: new locals: test@0//0 +0019: [->3<-] (_,_,_,_,_,_,_,_) +0019: panic_if_no_match +0020: [->3<-] (_,_,_,_,_,_,_,_) +0020: ***after let binding stack depth: 1 +0022: [->3<-] (_,_,_,_,_,_,_,_) +0022: ***before let binding stack depth: 1 +0024: [->3<-] (_,_,_,_,_,_,_,_) +0024: ***entering loop stack depth: 1 +0026: [->3<-] (_,_,_,_,_,_,_,_) +0026: push_list +0027: [->3<-|[]] (_,_,_,_,_,_,_,_) +0027: constant 00001: 1 +0030: [->3<-|[]|1] (_,_,_,_,_,_,_,_) +0030: append_list +0031: [->3<-|[1]] (_,_,_,_,_,_,_,_) +0031: constant 00002: 2 +0034: [->3<-|[1]|2] (_,_,_,_,_,_,_,_) +0034: append_list +0035: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0035: ***after loop args stack depth: 2 +0037: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0037: store_n 001 +0039: [->3<-] ([1, 2],_,_,_,_,_,_,_) +0039: ***loop: after store stack depth: 1 +0041: [->3<-] ([1, 2],_,_,_,_,_,_,_) +0041: load_n 001 +0043: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0043: ***loop: after load stack depth: 2 +0045: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0045: reset_match +0046: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0046: ***loop clause matching: : ([]) +0048: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0048: match_depth 000 +0050: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0050: match_list 000 +0052: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0052: jump_if_no_match 00006 +0061: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0061: jump_if_no_match 00016 +0080: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0080: ***loop: after load stack depth: 2 +0082: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0082: reset_match +0083: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0083: ***loop clause matching: : ([x]) +0085: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0085: match_depth 000 +0087: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0087: match_list 001 +0089: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0089: jump_if_no_match 00020 +0112: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0112: jump_if_no_match 00044 +0159: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0159: ***loop: after load stack depth: 2 +0161: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0161: reset_match +0162: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0162: ***loop clause matching: : ([x, ...xs]) +0164: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0164: match_depth 000 +0166: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0166: match_splatted_list 002 +0168: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0168: jump_if_no_match 00035 +0171: [->3<-|[1, 2]] (_,_,_,_,_,_,_,_) +0171: load_splatted_list 002 +0173: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0173: match_depth 001 +0175: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0175: match +0176: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0176: binding `x` in sandbox +0178: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0178: stack depth: 4; match depth: 1 +0180: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0180: at stack index: 2 +0182: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0182: new locals: test@0//0|x@2//1 +0184: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0184: jump_if_no_match 00018 +0187: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0187: match_depth 000 +0189: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0189: match +0190: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0190: binding `xs` in sandbox +0192: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0192: stack depth: 4; match depth: 0 +0194: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0194: at stack index: 3 +0196: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0196: new locals: test@0//0|x@2//1|xs@3//1 +0198: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0198: jump_if_no_match 00004 +0201: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0201: jump 00002 +0206: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0206: jump_if_no_match 00088 +0209: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0209: ***loop: before body stack depth: 4 +0211: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0211: ***calling function eq? stack depth: 4 +0213: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0213: resolving binding `x` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0215: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0215: at locals position 2 +0217: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0217: push_binding 002 +0219: [->3<-|[1, 2]|1|[2]|1] (_,_,_,_,_,_,_,_) +0219: resolving binding `test` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0221: [->3<-|[1, 2]|1|[2]|1] (_,_,_,_,_,_,_,_) +0221: at locals position 0 +0223: [->3<-|[1, 2]|1|[2]|1] (_,_,_,_,_,_,_,_) +0223: push_binding 000 +0225: [->3<-|[1, 2]|1|[2]|1|3] (_,_,_,_,_,_,_,_) +0225: resolving binding `eq?` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0227: [->3<-|[1, 2]|1|[2]|1|3] (_,_,_,_,_,_,_,_) +0227: as global +0229: [->3<-|[1, 2]|1|[2]|1|3] (_,_,_,_,_,_,_,_) +0229: constant 00003: :eq? +0232: [->3<-|[1, 2]|1|[2]|1|3|:eq?] (_,_,_,_,_,_,_,_) +0232: push_global +0233: [->3<-|[1, 2]|1|[2]|1|3|fn eq?] (_,_,_,_,_,_,_,_) +0233: ***after 2 args stack depth: 7 +0235: [->3<-|[1, 2]|1|[2]|1|3|fn eq?] (_,_,_,_,_,_,_,_) +0235: call 002 +=== calling into fn eq?/2 === +0000: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0000: reset_match +0001: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0001: ***function clause matching: : (x, y) +0003: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0003: match_depth 001 +0005: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0005: match +0006: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0006: binding `x` in eq? +0008: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0008: stack depth: 2; match depth: 1 +0010: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0010: at stack index: 0 +0012: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0012: new locals: x@0//0 +0014: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0014: jump_if_no_match 00017 +0017: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0017: match_depth 000 +0019: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0019: match +0020: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0020: binding `y` in eq? +0022: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0022: stack depth: 2; match depth: 0 +0024: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0024: at stack index: 1 +0026: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0026: new locals: x@0//0|y@1//0 +0028: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0028: jump_if_no_match 00003 +0031: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0031: jump 00000 +0034: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0034: jump_if_no_match 00034 +0037: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0037: ***accessing keyword: base :eq? stack depth: 2 +0039: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0039: resolving binding `base` in eq? +locals: x@0//0|y@1//0 +0041: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0041: as enclosing upvalue 0 +0043: [3|[1, 2]|1|[2]|->1<-|3] (_,_,_,_,_,_,_,_) +0043: get_upvalue 000 +0045: [3|[1, 2]|1|[2]|->1<-|3|#{:trim fn trim/base...] (_,_,_,_,_,_,_,_) +0045: constant 00000: :eq? +0048: [3|[1, 2]|1|[2]|->1<-|3|#{:trim fn trim/base...|:eq?] (_,_,_,_,_,_,_,_) +0048: get_key +0049: [3|[1, 2]|1|[2]|->1<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0049: ***after keyword access stack depth: 3 +0051: [3|[1, 2]|1|[2]|->1<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0051: stash +0052: [3|[1, 2]|1|[2]|->1<-|3|fn eq?/base] (fn eq?/base,_,_,_,_,_,_,_) +0052: pop +0053: [3|[1, 2]|1|[2]|->1<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0053: resolving binding `x` in eq? +locals: x@0//0|y@1//0 +0055: [3|[1, 2]|1|[2]|->1<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0055: at locals position 0 +0057: [3|[1, 2]|1|[2]|->1<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0057: push_binding 000 +0059: [3|[1, 2]|1|[2]|->1<-|3|1] (fn eq?/base,_,_,_,_,_,_,_) +0059: resolving binding `y` in eq? +locals: x@0//0|y@1//0 +0061: [3|[1, 2]|1|[2]|->1<-|3|1] (fn eq?/base,_,_,_,_,_,_,_) +0061: at locals position 1 +0063: [3|[1, 2]|1|[2]|->1<-|3|1] (fn eq?/base,_,_,_,_,_,_,_) +0063: push_binding 001 +0065: [3|[1, 2]|1|[2]|->1<-|3|1|3] (fn eq?/base,_,_,_,_,_,_,_) +0065: load +0066: [3|[1, 2]|1|[2]|->1<-|3|1|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0066: tail_call 002 +=== tail call into fn eq?/base/2 from eq? === +0237: [->3<-|[1, 2]|1|[2]|false] (_,_,_,_,_,_,_,_) +0237: ***after condition stack depth: 5 +0239: [->3<-|[1, 2]|1|[2]|false] (_,_,_,_,_,_,_,_) +0239: jump_if_false 00008 +0250: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0250: ***recur: before args stack depth: 4 +0252: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0252: recur arg: 0 +0254: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0254: resolving binding `xs` in sandbox +locals: test@0//0|x@2//1|xs@3//1 +0256: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0256: at locals position 3 +0258: [->3<-|[1, 2]|1|[2]] (_,_,_,_,_,_,_,_) +0258: push_binding 003 +0260: [->3<-|[1, 2]|1|[2]|[2]] (_,_,_,_,_,_,_,_) +0260: ***recur: after args stack depth: 5 +0262: [->3<-|[1, 2]|1|[2]|[2]] (_,_,_,_,_,_,_,_) +0262: store_n 001 +0264: [->3<-|[1, 2]|1|[2]] ([2],_,_,_,_,_,_,_) +0264: ***recur: after store stack depth: 4 +0266: [->3<-|[1, 2]|1|[2]] ([2],_,_,_,_,_,_,_) +0266: loop root depth: 1 +0268: [->3<-|[1, 2]|1|[2]] ([2],_,_,_,_,_,_,_) +0268: pop_n 003 +0270: [->3<-] ([2],_,_,_,_,_,_,_) +0270: ***recur: after stack reset stack depth: 1 +0272: [->3<-] ([2],_,_,_,_,_,_,_) +0272: load_n 001 +0274: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0274: ***recur: after load, end of compilation stack depth: 2 +0276: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0276: jump_back 00233 +0043: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0043: ***loop: after load stack depth: 2 +0045: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0045: reset_match +0046: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0046: ***loop clause matching: : ([]) +0048: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0048: match_depth 000 +0050: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0050: match_list 000 +0052: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0052: jump_if_no_match 00006 +0061: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0061: jump_if_no_match 00016 +0080: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0080: ***loop: after load stack depth: 2 +0082: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0082: reset_match +0083: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0083: ***loop clause matching: : ([x]) +0085: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0085: match_depth 000 +0087: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0087: match_list 001 +0089: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0089: jump_if_no_match 00020 +0092: [->3<-|[2]] (_,_,_,_,_,_,_,_) +0092: load_list +0093: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0093: match_depth 000 +0095: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0095: match +0096: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0096: binding `x` in sandbox +0098: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0098: stack depth: 3; match depth: 0 +0100: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0100: at stack index: 2 +0102: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0102: new locals: test@0//0|x@2//1 +0104: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0104: jump_if_no_match 00004 +0107: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0107: jump 00002 +0112: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0112: jump_if_no_match 00044 +0115: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0115: ***loop: before body stack depth: 3 +0117: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0117: ***calling function eq? stack depth: 3 +0119: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0119: resolving binding `x` in sandbox +locals: test@0//0|x@2//1 +0121: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0121: at locals position 2 +0123: [->3<-|[2]|2] (_,_,_,_,_,_,_,_) +0123: push_binding 002 +0125: [->3<-|[2]|2|2] (_,_,_,_,_,_,_,_) +0125: resolving binding `test` in sandbox +locals: test@0//0|x@2//1 +0127: [->3<-|[2]|2|2] (_,_,_,_,_,_,_,_) +0127: at locals position 0 +0129: [->3<-|[2]|2|2] (_,_,_,_,_,_,_,_) +0129: push_binding 000 +0131: [->3<-|[2]|2|2|3] (_,_,_,_,_,_,_,_) +0131: resolving binding `eq?` in sandbox +locals: test@0//0|x@2//1 +0133: [->3<-|[2]|2|2|3] (_,_,_,_,_,_,_,_) +0133: as global +0135: [->3<-|[2]|2|2|3] (_,_,_,_,_,_,_,_) +0135: constant 00003: :eq? +0138: [->3<-|[2]|2|2|3|:eq?] (_,_,_,_,_,_,_,_) +0138: push_global +0139: [->3<-|[2]|2|2|3|fn eq?] (_,_,_,_,_,_,_,_) +0139: ***after 2 args stack depth: 6 +0141: [->3<-|[2]|2|2|3|fn eq?] (_,_,_,_,_,_,_,_) +0141: call 002 +=== calling into fn eq?/2 === +0000: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0000: reset_match +0001: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0001: ***function clause matching: : (x, y) +0003: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0003: match_depth 001 +0005: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0005: match +0006: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0006: binding `x` in eq? +0008: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0008: stack depth: 2; match depth: 1 +0010: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0010: at stack index: 0 +0012: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0012: new locals: x@0//0 +0014: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0014: jump_if_no_match 00017 +0017: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0017: match_depth 000 +0019: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0019: match +0020: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0020: binding `y` in eq? +0022: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0022: stack depth: 2; match depth: 0 +0024: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0024: at stack index: 1 +0026: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0026: new locals: x@0//0|y@1//0 +0028: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0028: jump_if_no_match 00003 +0031: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0031: jump 00000 +0034: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0034: jump_if_no_match 00034 +0037: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0037: ***accessing keyword: base :eq? stack depth: 2 +0039: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0039: resolving binding `base` in eq? +locals: x@0//0|y@1//0 +0041: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0041: as enclosing upvalue 0 +0043: [3|[2]|2|->2<-|3] (_,_,_,_,_,_,_,_) +0043: get_upvalue 000 +0045: [3|[2]|2|->2<-|3|#{:trim fn trim/base...] (_,_,_,_,_,_,_,_) +0045: constant 00000: :eq? +0048: [3|[2]|2|->2<-|3|#{:trim fn trim/base...|:eq?] (_,_,_,_,_,_,_,_) +0048: get_key +0049: [3|[2]|2|->2<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0049: ***after keyword access stack depth: 3 +0051: [3|[2]|2|->2<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0051: stash +0052: [3|[2]|2|->2<-|3|fn eq?/base] (fn eq?/base,_,_,_,_,_,_,_) +0052: pop +0053: [3|[2]|2|->2<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0053: resolving binding `x` in eq? +locals: x@0//0|y@1//0 +0055: [3|[2]|2|->2<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0055: at locals position 0 +0057: [3|[2]|2|->2<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0057: push_binding 000 +0059: [3|[2]|2|->2<-|3|2] (fn eq?/base,_,_,_,_,_,_,_) +0059: resolving binding `y` in eq? +locals: x@0//0|y@1//0 +0061: [3|[2]|2|->2<-|3|2] (fn eq?/base,_,_,_,_,_,_,_) +0061: at locals position 1 +0063: [3|[2]|2|->2<-|3|2] (fn eq?/base,_,_,_,_,_,_,_) +0063: push_binding 001 +0065: [3|[2]|2|->2<-|3|2|3] (fn eq?/base,_,_,_,_,_,_,_) +0065: load +0066: [3|[2]|2|->2<-|3|2|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0066: tail_call 002 +=== tail call into fn eq?/base/2 from eq? === +0143: [->3<-|[2]|2|false] (_,_,_,_,_,_,_,_) +0143: ***loop: after body, before store stack depth: 4 +0145: [->3<-|[2]|2|false] (_,_,_,_,_,_,_,_) +0145: store +0146: [->3<-|[2]|2] (false,_,_,_,_,_,_,_) +0146: ***loop: after body, after store stack depth: 3 +0148: [->3<-|[2]|2] (false,_,_,_,_,_,_,_) +0148: leaving scope 1 +0150: [->3<-|[2]|2] (false,_,_,_,_,_,_,_) +0150: releasing binding Some(Binding { name: "x", depth: 1, stack_pos: 2 }) +0152: [->3<-|[2]|2] (false,_,_,_,_,_,_,_) +0152: ***resetting the stack after loop from 3 to 1 stack depth: 3 +0154: [->3<-|[2]|2] (false,_,_,_,_,_,_,_) +0154: pop_n 002 +0156: [->3<-] (false,_,_,_,_,_,_,_) +0156: jump 00139 +0298: [->3<-] (false,_,_,_,_,_,_,_) +0298: ***before loop arity adjustment stack depth: 2 +0300: [->3<-] (false,_,_,_,_,_,_,_) +0300: load +0301: [->3<-|false] (_,_,_,_,_,_,_,_) +0301: ***at very end of loop after load stack depth: 2 +0303: [->3<-|false] (_,_,_,_,_,_,_,_) +0303: ***after let expr stack depth: 2 +0305: [->3<-|false] (_,_,_,_,_,_,_,_) +0305: ***let binding: matching: quux +0307: [->3<-|false] (_,_,_,_,_,_,_,_) +0307: reset_match +0308: [->3<-|false] (_,_,_,_,_,_,_,_) +0308: match +0309: [->3<-|false] (_,_,_,_,_,_,_,_) +0309: binding `quux` in sandbox +0311: [->3<-|false] (_,_,_,_,_,_,_,_) +0311: stack depth: 2; match depth: 0 +0313: [->3<-|false] (_,_,_,_,_,_,_,_) +0313: at stack index: 1 +0315: [->3<-|false] (_,_,_,_,_,_,_,_) +0315: new locals: test@0//0|quux@1//0 +0317: [->3<-|false] (_,_,_,_,_,_,_,_) +0317: panic_if_no_match +0318: [->3<-|false] (_,_,_,_,_,_,_,_) +0318: ***after let binding stack depth: 2 +0320: [->3<-|false] (_,_,_,_,_,_,_,_) +0320: ***before let binding stack depth: 2 +0322: [->3<-|false] (_,_,_,_,_,_,_,_) +0322: constant 00005: :bar +0325: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0325: ***after let expr stack depth: 3 +0327: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0327: ***let binding: matching: foo +0329: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0329: reset_match +0330: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0330: match +0331: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0331: binding `foo` in sandbox +0333: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0333: stack depth: 3; match depth: 0 +0335: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0335: at stack index: 2 +0337: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0337: new locals: test@0//0|quux@1//0|foo@2//0 +0339: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0339: panic_if_no_match +0340: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0340: ***after let binding stack depth: 3 +0342: [->3<-|false|:bar] (_,_,_,_,_,_,_,_) +0342: constant 00006: fn not +0345: [->3<-|false|:bar|fn not] (_,_,_,_,_,_,_,_) +0345: binding `not` in sandbox +0347: [->3<-|false|:bar|fn not] (_,_,_,_,_,_,_,_) +0347: stack depth: 4; match depth: 0 +0349: [->3<-|false|:bar|fn not] (_,_,_,_,_,_,_,_) +0349: at stack index: 3 +0351: [->3<-|false|:bar|fn not] (_,_,_,_,_,_,_,_) +0351: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0 +0353: [->3<-|false|:bar|fn not] (_,_,_,_,_,_,_,_) +0353: ***before let binding stack depth: 4 +0355: [->3<-|false|:bar|fn not] (_,_,_,_,_,_,_,_) +0355: ***entering loop stack depth: 4 +0357: [->3<-|false|:bar|fn not] (_,_,_,_,_,_,_,_) +0357: push_list +0358: [->3<-|false|:bar|fn not|[]] (_,_,_,_,_,_,_,_) +0358: constant 00001: 1 +0361: [->3<-|false|:bar|fn not|[]|1] (_,_,_,_,_,_,_,_) +0361: append_list +0362: [->3<-|false|:bar|fn not|[1]] (_,_,_,_,_,_,_,_) +0362: constant 00002: 2 +0365: [->3<-|false|:bar|fn not|[1]|2] (_,_,_,_,_,_,_,_) +0365: append_list +0366: [->3<-|false|:bar|fn not|[1, 2]] (_,_,_,_,_,_,_,_) +0366: constant 00000: 3 +0369: [->3<-|false|:bar|fn not|[1, 2]|3] (_,_,_,_,_,_,_,_) +0369: append_list +0370: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0370: ***after loop args stack depth: 5 +0372: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0372: store_n 001 +0374: [->3<-|false|:bar|fn not] ([1, 2, 3],_,_,_,_,_,_,_) +0374: ***loop: after store stack depth: 4 +0376: [->3<-|false|:bar|fn not] ([1, 2, 3],_,_,_,_,_,_,_) +0376: load_n 001 +0378: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0378: ***loop: after load stack depth: 5 +0380: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0380: reset_match +0381: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0381: ***loop clause matching: : ([]) +0383: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0383: match_depth 000 +0385: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0385: match_list 000 +0387: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0387: jump_if_no_match 00006 +0396: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0396: jump_if_no_match 00016 +0415: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0415: ***loop: after load stack depth: 5 +0417: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0417: reset_match +0418: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0418: ***loop clause matching: : ([y]) +0420: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0420: match_depth 000 +0422: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0422: match_list 001 +0424: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0424: jump_if_no_match 00020 +0447: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0447: jump_if_no_match 00044 +0494: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0494: ***loop: after load stack depth: 5 +0496: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0496: reset_match +0497: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0497: ***loop clause matching: : ([y, ...ys]) +0499: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0499: match_depth 000 +0501: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0501: match_splatted_list 002 +0503: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0503: jump_if_no_match 00035 +0506: [->3<-|false|:bar|fn not|[1, 2, 3]] (_,_,_,_,_,_,_,_) +0506: load_splatted_list 002 +0508: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0508: match_depth 001 +0510: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0510: match +0511: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0511: binding `y` in sandbox +0513: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0513: stack depth: 7; match depth: 1 +0515: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0515: at stack index: 5 +0517: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0517: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0519: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0519: jump_if_no_match 00018 +0522: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0522: match_depth 000 +0524: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0524: match +0525: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0525: binding `ys` in sandbox +0527: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0527: stack depth: 7; match depth: 0 +0529: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0529: at stack index: 6 +0531: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0531: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0533: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0533: jump_if_no_match 00004 +0536: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0536: jump 00002 +0541: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0541: jump_if_no_match 00098 +0544: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0544: ***loop: before body stack depth: 7 +0546: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0546: ***calling function not stack depth: 7 +0548: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0548: ***calling function eq? stack depth: 7 +0550: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0550: resolving binding `y` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0552: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0552: at locals position 5 +0554: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0554: push_binding 005 +0556: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1] (_,_,_,_,_,_,_,_) +0556: resolving binding `test` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0558: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1] (_,_,_,_,_,_,_,_) +0558: at locals position 0 +0560: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1] (_,_,_,_,_,_,_,_) +0560: push_binding 000 +0562: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1|3] (_,_,_,_,_,_,_,_) +0562: resolving binding `eq?` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0564: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1|3] (_,_,_,_,_,_,_,_) +0564: as global +0566: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1|3] (_,_,_,_,_,_,_,_) +0566: constant 00003: :eq? +0569: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1|3|:eq?] (_,_,_,_,_,_,_,_) +0569: push_global +0570: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1|3|fn eq?] (_,_,_,_,_,_,_,_) +0570: ***after 2 args stack depth: 10 +0572: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|1|3|fn eq?] (_,_,_,_,_,_,_,_) +0572: call 002 +=== calling into fn eq?/2 === +0000: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0000: reset_match +0001: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0001: ***function clause matching: : (x, y) +0003: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0003: match_depth 001 +0005: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0005: match +0006: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0006: binding `x` in eq? +0008: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0008: stack depth: 2; match depth: 1 +0010: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0010: at stack index: 0 +0012: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0012: new locals: x@0//0 +0014: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0014: jump_if_no_match 00017 +0017: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0017: match_depth 000 +0019: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0019: match +0020: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0020: binding `y` in eq? +0022: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0022: stack depth: 2; match depth: 0 +0024: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0024: at stack index: 1 +0026: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0026: new locals: x@0//0|y@1//0 +0028: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0028: jump_if_no_match 00003 +0031: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0031: jump 00000 +0034: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0034: jump_if_no_match 00034 +0037: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0037: ***accessing keyword: base :eq? stack depth: 2 +0039: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0039: resolving binding `base` in eq? +locals: x@0//0|y@1//0 +0041: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0041: as enclosing upvalue 0 +0043: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (_,_,_,_,_,_,_,_) +0043: get_upvalue 000 +0045: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|#{:trim fn trim/base...] (_,_,_,_,_,_,_,_) +0045: constant 00000: :eq? +0048: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|#{:trim fn trim/base...|:eq?] (_,_,_,_,_,_,_,_) +0048: get_key +0049: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0049: ***after keyword access stack depth: 3 +0051: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0051: stash +0052: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|fn eq?/base] (fn eq?/base,_,_,_,_,_,_,_) +0052: pop +0053: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0053: resolving binding `x` in eq? +locals: x@0//0|y@1//0 +0055: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0055: at locals position 0 +0057: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0057: push_binding 000 +0059: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|1] (fn eq?/base,_,_,_,_,_,_,_) +0059: resolving binding `y` in eq? +locals: x@0//0|y@1//0 +0061: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|1] (fn eq?/base,_,_,_,_,_,_,_) +0061: at locals position 1 +0063: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|1] (fn eq?/base,_,_,_,_,_,_,_) +0063: push_binding 001 +0065: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|1|3] (fn eq?/base,_,_,_,_,_,_,_) +0065: load +0066: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->1<-|3|1|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0066: tail_call 002 +=== tail call into fn eq?/base/2 from eq? === +0574: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|false] (_,_,_,_,_,_,_,_) +0574: resolving binding `not` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0576: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|false] (_,_,_,_,_,_,_,_) +0576: at locals position 3 +0578: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|false] (_,_,_,_,_,_,_,_) +0578: push_binding 003 +0580: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|false|fn not] (_,_,_,_,_,_,_,_) +0580: ***after 1 args stack depth: 9 +0582: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|false|fn not] (_,_,_,_,_,_,_,_) +0582: call 001 +=== calling into fn not/1 === +0000: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0000: reset_match +0001: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0001: ***function clause matching: : (false) +0003: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0003: match_depth 000 +0005: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0005: match_false +0006: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0006: jump_if_no_match 00003 +0009: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0009: jump 00000 +0012: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0012: jump_if_no_match 00004 +0015: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (_,_,_,_,_,_,_,_) +0015: true +0016: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-|true] (_,_,_,_,_,_,_,_) +0016: store +0017: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|->false<-] (true,_,_,_,_,_,_,_) +0017: pop +0018: [3|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (true,_,_,_,_,_,_,_) +0018: return +== returning from fn not == +0584: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|true] (_,_,_,_,_,_,_,_) +0584: ***after condition stack depth: 8 +0586: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|true] (_,_,_,_,_,_,_,_) +0586: jump_if_false 00034 +0589: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0589: ***recur: before args stack depth: 7 +0591: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0591: recur arg: 0 +0593: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0593: resolving binding `ys` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0595: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0595: at locals position 6 +0597: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] (_,_,_,_,_,_,_,_) +0597: push_binding 006 +0599: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|[2, 3]] (_,_,_,_,_,_,_,_) +0599: ***recur: after args stack depth: 8 +0601: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]|[2, 3]] (_,_,_,_,_,_,_,_) +0601: store_n 001 +0603: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] ([2, 3],_,_,_,_,_,_,_) +0603: ***recur: after store stack depth: 7 +0605: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] ([2, 3],_,_,_,_,_,_,_) +0605: loop root depth: 4 +0607: [->3<-|false|:bar|fn not|[1, 2, 3]|1|[2, 3]] ([2, 3],_,_,_,_,_,_,_) +0607: pop_n 003 +0609: [->3<-|false|:bar|fn not] ([2, 3],_,_,_,_,_,_,_) +0609: ***recur: after stack reset stack depth: 4 +0611: [->3<-|false|:bar|fn not] ([2, 3],_,_,_,_,_,_,_) +0611: load_n 001 +0613: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0613: ***recur: after load, end of compilation stack depth: 5 +0615: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0615: jump_back 00237 +0378: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0378: ***loop: after load stack depth: 5 +0380: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0380: reset_match +0381: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0381: ***loop clause matching: : ([]) +0383: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0383: match_depth 000 +0385: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0385: match_list 000 +0387: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0387: jump_if_no_match 00006 +0396: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0396: jump_if_no_match 00016 +0415: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0415: ***loop: after load stack depth: 5 +0417: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0417: reset_match +0418: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0418: ***loop clause matching: : ([y]) +0420: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0420: match_depth 000 +0422: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0422: match_list 001 +0424: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0424: jump_if_no_match 00020 +0447: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0447: jump_if_no_match 00044 +0494: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0494: ***loop: after load stack depth: 5 +0496: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0496: reset_match +0497: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0497: ***loop clause matching: : ([y, ...ys]) +0499: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0499: match_depth 000 +0501: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0501: match_splatted_list 002 +0503: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0503: jump_if_no_match 00035 +0506: [->3<-|false|:bar|fn not|[2, 3]] (_,_,_,_,_,_,_,_) +0506: load_splatted_list 002 +0508: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0508: match_depth 001 +0510: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0510: match +0511: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0511: binding `y` in sandbox +0513: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0513: stack depth: 7; match depth: 1 +0515: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0515: at stack index: 5 +0517: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0517: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0519: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0519: jump_if_no_match 00018 +0522: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0522: match_depth 000 +0524: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0524: match +0525: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0525: binding `ys` in sandbox +0527: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0527: stack depth: 7; match depth: 0 +0529: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0529: at stack index: 6 +0531: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0531: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0533: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0533: jump_if_no_match 00004 +0536: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0536: jump 00002 +0541: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0541: jump_if_no_match 00098 +0544: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0544: ***loop: before body stack depth: 7 +0546: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0546: ***calling function not stack depth: 7 +0548: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0548: ***calling function eq? stack depth: 7 +0550: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0550: resolving binding `y` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0552: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0552: at locals position 5 +0554: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0554: push_binding 005 +0556: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2] (_,_,_,_,_,_,_,_) +0556: resolving binding `test` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0558: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2] (_,_,_,_,_,_,_,_) +0558: at locals position 0 +0560: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2] (_,_,_,_,_,_,_,_) +0560: push_binding 000 +0562: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2|3] (_,_,_,_,_,_,_,_) +0562: resolving binding `eq?` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0564: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2|3] (_,_,_,_,_,_,_,_) +0564: as global +0566: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2|3] (_,_,_,_,_,_,_,_) +0566: constant 00003: :eq? +0569: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2|3|:eq?] (_,_,_,_,_,_,_,_) +0569: push_global +0570: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2|3|fn eq?] (_,_,_,_,_,_,_,_) +0570: ***after 2 args stack depth: 10 +0572: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|2|3|fn eq?] (_,_,_,_,_,_,_,_) +0572: call 002 +=== calling into fn eq?/2 === +0000: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0000: reset_match +0001: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0001: ***function clause matching: : (x, y) +0003: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0003: match_depth 001 +0005: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0005: match +0006: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0006: binding `x` in eq? +0008: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0008: stack depth: 2; match depth: 1 +0010: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0010: at stack index: 0 +0012: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0012: new locals: x@0//0 +0014: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0014: jump_if_no_match 00017 +0017: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0017: match_depth 000 +0019: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0019: match +0020: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0020: binding `y` in eq? +0022: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0022: stack depth: 2; match depth: 0 +0024: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0024: at stack index: 1 +0026: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0026: new locals: x@0//0|y@1//0 +0028: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0028: jump_if_no_match 00003 +0031: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0031: jump 00000 +0034: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0034: jump_if_no_match 00034 +0037: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0037: ***accessing keyword: base :eq? stack depth: 2 +0039: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0039: resolving binding `base` in eq? +locals: x@0//0|y@1//0 +0041: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0041: as enclosing upvalue 0 +0043: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (_,_,_,_,_,_,_,_) +0043: get_upvalue 000 +0045: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|#{:trim fn trim/base...] (_,_,_,_,_,_,_,_) +0045: constant 00000: :eq? +0048: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|#{:trim fn trim/base...|:eq?] (_,_,_,_,_,_,_,_) +0048: get_key +0049: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0049: ***after keyword access stack depth: 3 +0051: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0051: stash +0052: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|fn eq?/base] (fn eq?/base,_,_,_,_,_,_,_) +0052: pop +0053: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0053: resolving binding `x` in eq? +locals: x@0//0|y@1//0 +0055: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0055: at locals position 0 +0057: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0057: push_binding 000 +0059: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|2] (fn eq?/base,_,_,_,_,_,_,_) +0059: resolving binding `y` in eq? +locals: x@0//0|y@1//0 +0061: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|2] (fn eq?/base,_,_,_,_,_,_,_) +0061: at locals position 1 +0063: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|2] (fn eq?/base,_,_,_,_,_,_,_) +0063: push_binding 001 +0065: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|2|3] (fn eq?/base,_,_,_,_,_,_,_) +0065: load +0066: [3|false|:bar|fn not|[2, 3]|2|[3]|->2<-|3|2|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0066: tail_call 002 +=== tail call into fn eq?/base/2 from eq? === +0574: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|false] (_,_,_,_,_,_,_,_) +0574: resolving binding `not` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0576: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|false] (_,_,_,_,_,_,_,_) +0576: at locals position 3 +0578: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|false] (_,_,_,_,_,_,_,_) +0578: push_binding 003 +0580: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|false|fn not] (_,_,_,_,_,_,_,_) +0580: ***after 1 args stack depth: 9 +0582: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|false|fn not] (_,_,_,_,_,_,_,_) +0582: call 001 +=== calling into fn not/1 === +0000: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0000: reset_match +0001: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0001: ***function clause matching: : (false) +0003: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0003: match_depth 000 +0005: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0005: match_false +0006: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0006: jump_if_no_match 00003 +0009: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0009: jump 00000 +0012: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0012: jump_if_no_match 00004 +0015: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (_,_,_,_,_,_,_,_) +0015: true +0016: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-|true] (_,_,_,_,_,_,_,_) +0016: store +0017: [3|false|:bar|fn not|[2, 3]|2|[3]|->false<-] (true,_,_,_,_,_,_,_) +0017: pop +0018: [3|false|:bar|fn not|[2, 3]|2|[3]] (true,_,_,_,_,_,_,_) +0018: return +== returning from fn not == +0584: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|true] (_,_,_,_,_,_,_,_) +0584: ***after condition stack depth: 8 +0586: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|true] (_,_,_,_,_,_,_,_) +0586: jump_if_false 00034 +0589: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0589: ***recur: before args stack depth: 7 +0591: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0591: recur arg: 0 +0593: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0593: resolving binding `ys` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1|ys@6//1 +0595: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0595: at locals position 6 +0597: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] (_,_,_,_,_,_,_,_) +0597: push_binding 006 +0599: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|[3]] (_,_,_,_,_,_,_,_) +0599: ***recur: after args stack depth: 8 +0601: [->3<-|false|:bar|fn not|[2, 3]|2|[3]|[3]] (_,_,_,_,_,_,_,_) +0601: store_n 001 +0603: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] ([3],_,_,_,_,_,_,_) +0603: ***recur: after store stack depth: 7 +0605: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] ([3],_,_,_,_,_,_,_) +0605: loop root depth: 4 +0607: [->3<-|false|:bar|fn not|[2, 3]|2|[3]] ([3],_,_,_,_,_,_,_) +0607: pop_n 003 +0609: [->3<-|false|:bar|fn not] ([3],_,_,_,_,_,_,_) +0609: ***recur: after stack reset stack depth: 4 +0611: [->3<-|false|:bar|fn not] ([3],_,_,_,_,_,_,_) +0611: load_n 001 +0613: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0613: ***recur: after load, end of compilation stack depth: 5 +0615: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0615: jump_back 00237 +0378: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0378: ***loop: after load stack depth: 5 +0380: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0380: reset_match +0381: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0381: ***loop clause matching: : ([]) +0383: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0383: match_depth 000 +0385: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0385: match_list 000 +0387: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0387: jump_if_no_match 00006 +0396: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0396: jump_if_no_match 00016 +0415: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0415: ***loop: after load stack depth: 5 +0417: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0417: reset_match +0418: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0418: ***loop clause matching: : ([y]) +0420: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0420: match_depth 000 +0422: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0422: match_list 001 +0424: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0424: jump_if_no_match 00020 +0427: [->3<-|false|:bar|fn not|[3]] (_,_,_,_,_,_,_,_) +0427: load_list +0428: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0428: match_depth 000 +0430: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0430: match +0431: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0431: binding `y` in sandbox +0433: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0433: stack depth: 6; match depth: 0 +0435: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0435: at stack index: 5 +0437: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0437: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0439: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0439: jump_if_no_match 00004 +0442: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0442: jump 00002 +0447: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0447: jump_if_no_match 00044 +0450: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0450: ***loop: before body stack depth: 6 +0452: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0452: ***calling function eq? stack depth: 6 +0454: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0454: resolving binding `y` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0456: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0456: at locals position 5 +0458: [->3<-|false|:bar|fn not|[3]|3] (_,_,_,_,_,_,_,_) +0458: push_binding 005 +0460: [->3<-|false|:bar|fn not|[3]|3|3] (_,_,_,_,_,_,_,_) +0460: resolving binding `test` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0462: [->3<-|false|:bar|fn not|[3]|3|3] (_,_,_,_,_,_,_,_) +0462: at locals position 0 +0464: [->3<-|false|:bar|fn not|[3]|3|3] (_,_,_,_,_,_,_,_) +0464: push_binding 000 +0466: [->3<-|false|:bar|fn not|[3]|3|3|3] (_,_,_,_,_,_,_,_) +0466: resolving binding `eq?` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|y@5//1 +0468: [->3<-|false|:bar|fn not|[3]|3|3|3] (_,_,_,_,_,_,_,_) +0468: as global +0470: [->3<-|false|:bar|fn not|[3]|3|3|3] (_,_,_,_,_,_,_,_) +0470: constant 00003: :eq? +0473: [->3<-|false|:bar|fn not|[3]|3|3|3|:eq?] (_,_,_,_,_,_,_,_) +0473: push_global +0474: [->3<-|false|:bar|fn not|[3]|3|3|3|fn eq?] (_,_,_,_,_,_,_,_) +0474: ***after 2 args stack depth: 9 +0476: [->3<-|false|:bar|fn not|[3]|3|3|3|fn eq?] (_,_,_,_,_,_,_,_) +0476: call 002 +=== calling into fn eq?/2 === +0000: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0000: reset_match +0001: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0001: ***function clause matching: : (x, y) +0003: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0003: match_depth 001 +0005: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0005: match +0006: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0006: binding `x` in eq? +0008: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0008: stack depth: 2; match depth: 1 +0010: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0010: at stack index: 0 +0012: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0012: new locals: x@0//0 +0014: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0014: jump_if_no_match 00017 +0017: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0017: match_depth 000 +0019: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0019: match +0020: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0020: binding `y` in eq? +0022: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0022: stack depth: 2; match depth: 0 +0024: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0024: at stack index: 1 +0026: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0026: new locals: x@0//0|y@1//0 +0028: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0028: jump_if_no_match 00003 +0031: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0031: jump 00000 +0034: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0034: jump_if_no_match 00034 +0037: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0037: ***accessing keyword: base :eq? stack depth: 2 +0039: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0039: resolving binding `base` in eq? +locals: x@0//0|y@1//0 +0041: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0041: as enclosing upvalue 0 +0043: [3|false|:bar|fn not|[3]|3|->3<-|3] (_,_,_,_,_,_,_,_) +0043: get_upvalue 000 +0045: [3|false|:bar|fn not|[3]|3|->3<-|3|#{:trim fn trim/base...] (_,_,_,_,_,_,_,_) +0045: constant 00000: :eq? +0048: [3|false|:bar|fn not|[3]|3|->3<-|3|#{:trim fn trim/base...|:eq?] (_,_,_,_,_,_,_,_) +0048: get_key +0049: [3|false|:bar|fn not|[3]|3|->3<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0049: ***after keyword access stack depth: 3 +0051: [3|false|:bar|fn not|[3]|3|->3<-|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0051: stash +0052: [3|false|:bar|fn not|[3]|3|->3<-|3|fn eq?/base] (fn eq?/base,_,_,_,_,_,_,_) +0052: pop +0053: [3|false|:bar|fn not|[3]|3|->3<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0053: resolving binding `x` in eq? +locals: x@0//0|y@1//0 +0055: [3|false|:bar|fn not|[3]|3|->3<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0055: at locals position 0 +0057: [3|false|:bar|fn not|[3]|3|->3<-|3] (fn eq?/base,_,_,_,_,_,_,_) +0057: push_binding 000 +0059: [3|false|:bar|fn not|[3]|3|->3<-|3|3] (fn eq?/base,_,_,_,_,_,_,_) +0059: resolving binding `y` in eq? +locals: x@0//0|y@1//0 +0061: [3|false|:bar|fn not|[3]|3|->3<-|3|3] (fn eq?/base,_,_,_,_,_,_,_) +0061: at locals position 1 +0063: [3|false|:bar|fn not|[3]|3|->3<-|3|3] (fn eq?/base,_,_,_,_,_,_,_) +0063: push_binding 001 +0065: [3|false|:bar|fn not|[3]|3|->3<-|3|3|3] (fn eq?/base,_,_,_,_,_,_,_) +0065: load +0066: [3|false|:bar|fn not|[3]|3|->3<-|3|3|3|fn eq?/base] (_,_,_,_,_,_,_,_) +0066: tail_call 002 +=== tail call into fn eq?/base/2 from eq? === +0478: [->3<-|false|:bar|fn not|[3]|3|true] (_,_,_,_,_,_,_,_) +0478: ***loop: after body, before store stack depth: 7 +0480: [->3<-|false|:bar|fn not|[3]|3|true] (_,_,_,_,_,_,_,_) +0480: store +0481: [->3<-|false|:bar|fn not|[3]|3] (true,_,_,_,_,_,_,_) +0481: ***loop: after body, after store stack depth: 6 +0483: [->3<-|false|:bar|fn not|[3]|3] (true,_,_,_,_,_,_,_) +0483: leaving scope 1 +0485: [->3<-|false|:bar|fn not|[3]|3] (true,_,_,_,_,_,_,_) +0485: releasing binding Some(Binding { name: "y", depth: 1, stack_pos: 5 }) +0487: [->3<-|false|:bar|fn not|[3]|3] (true,_,_,_,_,_,_,_) +0487: ***resetting the stack after loop from 6 to 4 stack depth: 6 +0489: [->3<-|false|:bar|fn not|[3]|3] (true,_,_,_,_,_,_,_) +0489: pop_n 002 +0491: [->3<-|false|:bar|fn not] (true,_,_,_,_,_,_,_) +0491: jump 00149 +0643: [->3<-|false|:bar|fn not] (true,_,_,_,_,_,_,_) +0643: ***before loop arity adjustment stack depth: 5 +0645: [->3<-|false|:bar|fn not] (true,_,_,_,_,_,_,_) +0645: load +0646: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0646: ***at very end of loop after load stack depth: 5 +0648: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0648: ***after let expr stack depth: 5 +0650: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0650: ***let binding: matching: frob +0652: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0652: reset_match +0653: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0653: match +0654: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0654: binding `frob` in sandbox +0656: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0656: stack depth: 5; match depth: 0 +0658: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0658: at stack index: 4 +0660: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0660: new locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +0662: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0662: panic_if_no_match +0663: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0663: ***after let binding stack depth: 5 +0665: [->3<-|false|:bar|fn not|true] (_,_,_,_,_,_,_,_) +0665: push_list +0666: [->3<-|false|:bar|fn not|true|[]] (_,_,_,_,_,_,_,_) +0666: resolving binding `quux` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +0668: [->3<-|false|:bar|fn not|true|[]] (_,_,_,_,_,_,_,_) +0668: at locals position 1 +0670: [->3<-|false|:bar|fn not|true|[]] (_,_,_,_,_,_,_,_) +0670: push_binding 001 +0672: [->3<-|false|:bar|fn not|true|[]|false] (_,_,_,_,_,_,_,_) +0672: append_list +0673: [->3<-|false|:bar|fn not|true|[false]] (_,_,_,_,_,_,_,_) +0673: resolving binding `frob` in sandbox +locals: test@0//0|quux@1//0|foo@2//0|not@3//0|frob@4//0 +0675: [->3<-|false|:bar|fn not|true|[false]] (_,_,_,_,_,_,_,_) +0675: at locals position 4 +0677: [->3<-|false|:bar|fn not|true|[false]] (_,_,_,_,_,_,_,_) +0677: push_binding 004 +0679: [->3<-|false|:bar|fn not|true|[false]|true] (_,_,_,_,_,_,_,_) +0679: append_list +0680: [->3<-|false|:bar|fn not|true|[false, true]] (_,_,_,_,_,_,_,_) +0680: store +0681: [->3<-|false|:bar|fn not|true] ([false, true],_,_,_,_,_,_,_) +0681: leaving scope 0 +0683: [->3<-|false|:bar|fn not|true] ([false, true],_,_,_,_,_,_,_) +0683: releasing binding Some(Binding { name: "frob", depth: 0, stack_pos: 4 }) +0685: [->3<-|false|:bar|fn not|true] ([false, true],_,_,_,_,_,_,_) +0685: releasing binding Some(Binding { name: "not", depth: 0, stack_pos: 3 }) +0687: [->3<-|false|:bar|fn not|true] ([false, true],_,_,_,_,_,_,_) +0687: releasing binding Some(Binding { name: "foo", depth: 0, stack_pos: 2 }) +0689: [->3<-|false|:bar|fn not|true] ([false, true],_,_,_,_,_,_,_) +0689: releasing binding Some(Binding { name: "quux", depth: 0, stack_pos: 1 }) +0691: [->3<-|false|:bar|fn not|true] ([false, true],_,_,_,_,_,_,_) +0691: releasing binding Some(Binding { name: "test", depth: 0, stack_pos: 0 }) +0693: [->3<-|false|:bar|fn not|true] ([false, true],_,_,_,_,_,_,_) +0693: pop_n 005 +0695: [] ([false, true],_,_,_,_,_,_,_) +0695: load +0696: [] (_,_,_,_,_,_,_,_) +[false, true] diff --git a/src/chunk.rs b/src/chunk.rs new file mode 100644 index 0000000..98409a3 --- /dev/null +++ b/src/chunk.rs @@ -0,0 +1,86 @@ +use crate::op::Op; +use crate::value::Value; +use imbl::HashMap; +use num_traits::FromPrimitive; +use regex::Regex; + +#[derive(Clone, Debug)] +pub struct StrPattern { + pub words: Vec, + pub re: Regex, +} + +#[derive(Clone, Debug)] +pub struct Chunk { + pub constants: Vec, + pub bytecode: Vec, + pub keywords: Vec<&'static str>, + pub string_patterns: Vec, + pub env: HashMap<&'static str, Value>, + pub msgs: Vec, +} + +impl Chunk { + pub fn dissasemble_instr(&self, i: &mut usize) { + let op = Op::from_u8(self.bytecode[*i]).unwrap(); + use Op::*; + match op { + Pop | Store | Stash | Load | Nil | True | False | MatchNil | MatchTrue | MatchFalse + | PanicIfNoMatch | ResetMatch | GetKey | PanicNoWhen | PanicNoMatch | TypeOf + | Duplicate | Decrement | Truncate | Noop | LoadTuple | LoadList | Eq | Add | Sub + | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | EmptyString + | ConcatStrings | Stringify | MatchType | Return | Match | Print | AppendList + | ConcatList | PushList | PushDict | AppendDict | ConcatDict | Nothing | PushGlobal + | SetUpvalue => { + println!("{i:04}: {op}") + } + Constant | MatchConstant => { + let high = self.bytecode[*i + 1]; + let low = self.bytecode[*i + 2]; + let idx = ((high as usize) << 8) + low as usize; + let value = &self.constants[idx].show(); + println!("{i:04}: {:16} {idx:05}: {value}", op.to_string()); + *i += 2; + } + Msg => { + let msg_idx = self.bytecode[*i + 1]; + let msg = &self.msgs[msg_idx as usize]; + println!("{i:04}: {msg}"); + *i += 1; + } + PushBinding | MatchTuple | MatchSplattedTuple | LoadSplattedTuple | MatchList + | MatchSplattedList | LoadSplattedList | MatchDict | MatchSplattedDict + | DropDictEntry | LoadDictValue | PushTuple | PushBox | MatchDepth | PopN | StoreN + | Call | GetUpvalue | Partial | MatchString | PushStringMatches | TailCall | LoadN => { + let next = self.bytecode[*i + 1]; + println!("{i:04}: {:16} {next:03}", op.to_string()); + *i += 1; + } + Jump | JumpIfFalse | JumpIfTrue | JumpIfNoMatch | JumpIfMatch | JumpBack + | JumpIfZero => { + let high = self.bytecode[*i + 1]; + let low = self.bytecode[*i + 2]; + let len = ((high as u16) << 8) + low as u16; + println!("{i:04}: {:16} {len:05}", op.to_string()); + *i += 2; + } + } + } + + pub fn dissasemble(&self) { + println!("IDX | CODE | INFO"); + let mut i = 0; + while i < self.bytecode.len() { + self.dissasemble_instr(&mut i); + i += 1; + } + } + + // pub fn kw_from(&self, kw: &str) -> Option { + // self.kw_index_from(kw).map(Value::Keyword) + // } + + // pub fn kw_index_from(&self, kw: &str) -> Option { + // self.keywords.iter().position(|s| *s == kw) + // } +} diff --git a/src/compiler.rs b/src/compiler.rs index 39c09b7..12e1db6 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -17,6 +17,12 @@ pub struct Binding { stack_pos: usize, } +impl std::fmt::Display for Binding { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}@{}//{}", self.name, self.stack_pos, self.depth) + } +} + #[derive(Clone, Debug, PartialEq)] pub struct Upvalue { name: &'static str, @@ -147,6 +153,11 @@ impl<'a> Compiler<'a> { } fn stub_jump(&mut self, op: Op) -> usize { + use Op::*; + match op { + JumpIfFalse | JumpIfTrue | JumpIfZero => self.stack_depth -= 1, + _ => (), + } let out = self.chunk.bytecode.len(); self.emit_op(op); self.emit_byte(0xff); @@ -183,6 +194,11 @@ impl<'a> Compiler<'a> { self.stack_depth += 1; } + fn reset_match(&mut self) { + self.emit_op(Op::ResetMatch); + self.match_depth = 0; + } + fn match_constant(&mut self, val: Value) { let const_idx = match self.chunk.constants.iter().position(|v| *v == val) { Some(idx) => idx, @@ -234,7 +250,14 @@ impl<'a> Compiler<'a> { stack_pos: self.stack_depth - self.match_depth - 1, }; self.bindings.push(binding); - self.msg(format!("locals are now: {:?}", self.bindings)); + self.msg(format!( + "new locals: {}", + self.bindings + .iter() + .map(|binding| format!("{binding}")) + .collect::>() + .join("|") + )); } fn resolve_local(&self, name: &'static str) -> Option { @@ -252,8 +275,13 @@ impl<'a> Compiler<'a> { fn resolve_binding(&mut self, name: &'static str) { self.msg(format!( - "resolving binding `{name}` in {}\nlocals: {:?}", - self.name, self.bindings + "resolving binding `{name}` in {}\nlocals: {}", + self.name, + self.bindings + .iter() + .map(|binding| format!("{binding}")) + .collect::>() + .join("|") )); if let Some(pos) = self.resolve_local(name) { self.msg(format!("at locals position {pos}")); @@ -299,6 +327,28 @@ impl<'a> Compiler<'a> { } } + fn store(&mut self) { + self.emit_op(Op::Store); + self.stack_depth -= 1; + } + + fn store_n(&mut self, n: usize) { + self.emit_op(Op::StoreN); + self.emit_byte(n); + self.stack_depth -= n; + } + + fn load(&mut self) { + self.emit_op(Op::Load); + self.stack_depth += 1; + } + + fn load_n(&mut self, n: usize) { + self.emit_op(Op::LoadN); + self.emit_byte(n); + self.stack_depth += n; + } + fn enter_scope(&mut self) { self.scope_depth += 1; } @@ -308,7 +358,7 @@ impl<'a> Compiler<'a> { while let Some(binding) = self.bindings.last() { if binding.depth == self.scope_depth { let unbound = self.bindings.pop(); - self.msg(format!("releasing binding {:?}", unbound)); + self.msg(format!("releasing binding {}", unbound.unwrap())); } else { break; } @@ -316,9 +366,9 @@ impl<'a> Compiler<'a> { self.scope_depth -= 1; } - fn enter_loop(&mut self) { + fn enter_loop(&mut self, arity: usize) { self.loop_info - .push(LoopInfo::new(self.len(), self.stack_depth)); + .push(LoopInfo::new(self.len(), self.stack_depth - arity)); } fn leave_loop(&mut self) { @@ -340,6 +390,7 @@ impl<'a> Compiler<'a> { fn msg(&mut self, str: String) { self.emit_op(Op::Msg); self.emit_byte(self.chunk.msgs.len()); + println!("{str}"); self.chunk.msgs.push(str); } @@ -397,11 +448,12 @@ impl<'a> Compiler<'a> { // return the evaluated rhs instead of whatever is last on the stack // we do this by pretending it's a binding (Let(patt, expr), _) => { - self.match_depth = 0; - self.emit_op(Op::ResetMatch); + // self.match_depth = 0; + // self.emit_op(Op::ResetMatch); self.visit(expr); let expr_pos = self.stack_depth - 1; self.report_ast("let binding: matching".to_string(), patt); + self.reset_match(); self.visit(patt); self.emit_op(Op::PanicIfNoMatch); self.emit_op(Op::PushBinding); @@ -419,7 +471,8 @@ impl<'a> Compiler<'a> { self.stack_depth += 1; // store the value in the return register - self.emit_op(Op::Store); + // self.emit_op(Op::Store); + self.store(); // reset the scope self.leave_scope(); @@ -434,7 +487,8 @@ impl<'a> Compiler<'a> { // reset the stack self.pop_n(self.stack_depth - stack_depth - 1); // load the value from the return register - self.emit_op(Op::Load); + self.load(); + // self.emit_op(Op::Load); } If(cond, then, r#else) => { let tail_pos = self.tail_pos; @@ -442,7 +496,7 @@ impl<'a> Compiler<'a> { self.visit(cond); self.report_depth("after condition"); let jif_idx = self.stub_jump(Op::JumpIfFalse); - self.stack_depth -= 1; + // self.stack_depth -= 1; self.tail_pos = tail_pos; self.visit(then); self.report_depth("after consequent"); @@ -459,11 +513,12 @@ impl<'a> Compiler<'a> { } Let(patt, expr) => { self.report_depth("before let binding"); - self.match_depth = 0; - self.emit_op(Op::ResetMatch); + // self.match_depth = 0; + // self.emit_op(Op::ResetMatch); self.visit(expr); self.report_depth("after let expr"); self.report_ast("let binding: matching".to_string(), patt); + self.reset_match(); self.visit(patt); self.emit_op(Op::PanicIfNoMatch); self.report_depth("after let binding"); @@ -819,7 +874,8 @@ impl<'a> Compiler<'a> { for idx in jump_idxes { self.patch_jump(idx, self.len() - idx); } - self.emit_op(Op::Load); + // self.emit_op(Op::Load); + self.load(); } else { self.emit_op(Op::False); } @@ -837,7 +893,8 @@ impl<'a> Compiler<'a> { for idx in jump_idxes { self.patch_jump(idx, self.len() - idx); } - self.emit_op(Op::Load); + // self.emit_op(Op::Load); + self.load(); } else { self.emit_op(Op::True); } @@ -961,7 +1018,8 @@ impl<'a> Compiler<'a> { } self.tail_pos = tail_pos; self.visit(body); - self.emit_op(Op::Store); + // self.emit_op(Op::Store); + self.store(); self.leave_scope(); // self.scope_depth -= 1; // while let Some(binding) = self.bindings.last() { @@ -1047,7 +1105,8 @@ impl<'a> Compiler<'a> { self.chunk.env.clone(), self.debug, ); - compiler.emit_op(Op::ResetMatch); + compiler.reset_match(); + // compiler.emit_op(Op::ResetMatch); compilers.insert(arity, compiler); compilers.get_mut(&arity).unwrap() } @@ -1090,7 +1149,8 @@ impl<'a> Compiler<'a> { } compiler.tail_pos = true; compiler.visit(clause_body); - compiler.emit_op(Op::Store); + // compiler.emit_op(Op::Store); + compiler.store(); compiler.scope_depth -= 1; while let Some(binding) = compiler.bindings.last() { if binding.depth > compiler.scope_depth { @@ -1217,28 +1277,25 @@ impl<'a> Compiler<'a> { self.visit(member); } self.report_depth("after loop args"); - self.emit_op(Op::StoreN); - self.emit_byte(members.len()); let arity = members.len(); + // self.emit_op(Op::StoreN); + // self.emit_byte(members.len()); + self.store_n(arity); let stack_depth = self.stack_depth; - self.msg(format!( - "***after store, stack depth is now {}", - self.stack_depth - )); + self.report_depth("loop: after store"); //then, save the beginning of the loop - self.emit_op(Op::Load); - self.enter_loop(); + // self.emit_op(Op::Load); + self.load_n(arity); + self.enter_loop(arity); // self.stack_depth += arity; //next, compile each clause: - self.msg(format!( - "***after load, stack depth is now {}", - self.stack_depth - )); let mut clauses = clauses.iter(); let mut jump_idxes = vec![]; while let Some((Ast::MatchClause(pattern, guard, body), _)) = clauses.next() { self.tail_pos = false; - self.emit_op(Op::ResetMatch); + self.report_depth("loop: after load"); + self.reset_match(); + // self.emit_op(Op::ResetMatch); self.enter_scope(); // self.scope_depth += 1; let (Ast::TuplePattern(members), _) = pattern.as_ref() else { @@ -1259,19 +1316,17 @@ impl<'a> Compiler<'a> { Box::leak(Box::new(guard.clone().unwrap())); self.visit(guard_expr); jnm_idxes.push(self.stub_jump(Op::JumpIfFalse)); - self.stack_depth -= 1; } self.tail_pos = tail_pos; - self.msg(format!( - "***before visiting body, the stack depth is {}", - self.stack_depth - )); + self.report_depth("loop: before body"); self.visit(body); - self.report_depth("after loop body, before store"); - self.emit_op(Op::Store); + self.report_depth("loop: after body, before store"); + // self.emit_op(Op::Store); + self.store(); + self.report_depth("loop: after body, after store"); self.leave_scope(); self.report_depth_str(format!( - "resetting the stack after loop from {stack_depth} to {}", + "resetting the stack after loop from {} to {stack_depth}", self.stack_depth, )); self.pop_n(self.stack_depth - stack_depth); @@ -1282,26 +1337,26 @@ impl<'a> Compiler<'a> { for idx in jnm_idxes { self.patch_jump(idx, self.len() - idx - 3); } - // self.scope_depth -= 1; + self.stack_depth += arity; } self.emit_op(Op::PanicNoMatch); for idx in jump_idxes { self.patch_jump(idx, self.len() - idx - 3); } + self.report_depth("before loop arity adjustment"); self.stack_depth -= arity; // pop back to the original depth before load // i.e. clear loop args - self.pop(); - self.emit_op(Op::Load); - self.stack_depth += 1; + // self.pop(); + // self.emit_op(Op::Load); + self.load(); + // self.stack_depth += 1; self.leave_loop(); + self.report_depth("at very end of loop after load"); } Recur(args) => { // self.emit_op(Op::Nothing); - self.msg(format!( - "before visiting recur args the compiler thinks the stack depth is {}", - self.stack_depth - )); + self.report_depth("recur: before args"); let tail_pos = self.tail_pos; self.tail_pos = false; let mut argnum = 0; @@ -1310,15 +1365,14 @@ impl<'a> Compiler<'a> { argnum += 1; self.visit(arg); } - self.msg(format!( - "after visiting recur args the compiler thinks the stack depth is {}", - self.stack_depth, - )); - self.emit_op(Op::StoreN); - self.emit_byte(args.len()); - self.emit_op(Op::PopN); - self.emit_byte(self.stack_depth - self.loop_root()); - self.emit_op(Op::Load); + self.report_depth("recur: after args"); + self.store_n(args.len()); + self.report_depth("recur: after store"); + self.msg(format!("loop root depth: {}", self.loop_root())); + self.pop_n(self.stack_depth - self.loop_root()); + self.report_depth("recur: after stack reset"); + self.load_n(args.len()); + self.report_depth("recur: after load, end of compilation"); self.jump(Op::JumpBack, self.len() - self.loop_idx()); self.tail_pos = tail_pos; } diff --git a/src/op.rs b/src/op.rs new file mode 100644 index 0000000..b911e6b --- /dev/null +++ b/src/op.rs @@ -0,0 +1,226 @@ +use num_derive::{FromPrimitive, ToPrimitive}; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, FromPrimitive, ToPrimitive)] +pub enum Op { + Noop, + Nothing, + Nil, + True, + False, + Constant, + Jump, + JumpIfFalse, + JumpIfTrue, + Pop, + PopN, + PushBinding, + PushGlobal, + Store, + StoreN, + Stash, + Load, + LoadN, + ResetMatch, + Match, + MatchNil, + MatchTrue, + MatchFalse, + PanicIfNoMatch, + MatchConstant, + MatchString, + PushStringMatches, + MatchType, + MatchTuple, + MatchSplattedTuple, + PushTuple, + LoadTuple, + LoadSplattedTuple, + MatchList, + MatchSplattedList, + LoadList, + LoadSplattedList, + PushList, + AppendList, + ConcatList, + PushDict, + AppendDict, + ConcatDict, + LoadDictValue, + MatchDict, + MatchSplattedDict, + DropDictEntry, + PushBox, + GetKey, + PanicNoWhen, + JumpIfNoMatch, + JumpIfMatch, + PanicNoMatch, + TypeOf, + JumpBack, + JumpIfZero, + Duplicate, + Decrement, + Truncate, + MatchDepth, + Panic, + EmptyString, + ConcatStrings, + Stringify, + + Call, + TailCall, + Return, + Partial, + + Eq, + Add, + Sub, + Mult, + Div, + Unbox, + BoxStore, + Assert, + Get, + At, + + Not, + Print, + SetUpvalue, + GetUpvalue, + + Msg, + // Inc, + // Dec, + // Gt, + // Gte, + // Lt, + // Lte, + // Mod, + // Round, + // Ceil, + // Floor, + // Random, + // Sqrt, + + // Assoc, + // Concat, + // Conj, + // Count, + // Disj, + // Dissoc, + // Range, + // Rest, + // Slice, + + // "atan_2" math/atan2 + // "chars" chars + // "cos" math/cos + // "doc" doc + // "downcase" string/ascii-lower + // "pi" math/pi + // "show" show + // "sin" math/sin + // "split" string/split + // "str_slice" string/slice + // "tan" math/tan + // "trim" string/trim + // "triml" string/triml + // "trimr" string/trimr + // "upcase" string/ascii-upper +} + +impl std::fmt::Display for Op { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + use Op::*; + let rep = match self { + Msg => "msg", + Noop => "noop", + Nothing => "nothing", + Nil => "nil", + True => "true", + False => "false", + Constant => "constant", + Jump => "jump", + JumpIfFalse => "jump_if_false", + JumpIfTrue => "jump_if_true", + Pop => "pop", + PopN => "pop_n", + PushBinding => "push_binding", + PushGlobal => "push_global", + Store => "store", + StoreN => "store_n", + Stash => "stash", + Load => "load", + LoadN => "load_n", + Match => "match", + MatchNil => "match_nil", + MatchTrue => "match_true", + MatchFalse => "match_false", + ResetMatch => "reset_match", + PanicIfNoMatch => "panic_if_no_match", + MatchConstant => "match_constant", + MatchString => "match_string", + PushStringMatches => "push_string_matches", + MatchType => "match_type", + MatchTuple => "match_tuple", + MatchSplattedTuple => "match_splatted_tuple", + PushTuple => "push_tuple", + LoadTuple => "load_tuple", + LoadSplattedTuple => "load_splatted_tuple", + MatchList => "match_list", + MatchSplattedList => "match_splatted_list", + LoadList => "load_list", + LoadSplattedList => "load_splatted_list", + PushList => "push_list", + AppendList => "append_list", + ConcatList => "concat_list", + PushDict => "push_dict", + AppendDict => "append_dict", + ConcatDict => "concat_dict", + LoadDictValue => "load_dict_value", + MatchDict => "match_dict", + MatchSplattedDict => "match_splatted_dict", + DropDictEntry => "drop_dict_entry", + PushBox => "push_box", + GetKey => "get_key", + PanicNoWhen => "panic_no_when", + JumpIfNoMatch => "jump_if_no_match", + JumpIfMatch => "jump_if_match", + PanicNoMatch => "panic_no_match", + TypeOf => "type_of", + JumpBack => "jump_back", + JumpIfZero => "jump_if_zero", + Decrement => "decrement", + Truncate => "truncate", + Duplicate => "duplicate", + MatchDepth => "match_depth", + Panic => "panic", + EmptyString => "empty_string", + ConcatStrings => "concat_strings", + Stringify => "stringify", + Print => "print", + + Eq => "eq", + Add => "add", + Sub => "sub", + Mult => "mult", + Div => "div", + Unbox => "unbox", + BoxStore => "box_store", + Assert => "assert", + Get => "get", + At => "at", + + Not => "not", + + Call => "call", + Return => "return", + Partial => "partial", + TailCall => "tail_call", + + SetUpvalue => "set_upvalue", + GetUpvalue => "get_upvalue", + }; + write!(f, "{rep}") + } +} diff --git a/src/vm.rs b/src/vm.rs index 843b489..77d1ac4 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -326,7 +326,6 @@ impl Vm { } Store => { self.return_register[0] = self.pop(); - self.push(Value::Nothing); self.ip += 1; } StoreN => { @@ -341,14 +340,19 @@ impl Vm { self.ip += 1; } Load => { - let mut i = 0; - while i < 8 && self.return_register[i] != Value::Nothing { + let mut value = Value::Nothing; + swap(&mut self.return_register[0], &mut value); + self.push(value); + self.ip += 1; + } + LoadN => { + let n = self.chunk().bytecode[self.ip + 1] as usize; + for i in 0..n { let mut value = Value::Nothing; swap(&mut self.return_register[i], &mut value); self.push(value); - i += 1; } - self.ip += 1; + self.ip += 2; } ResetMatch => { self.matches = false;