update block stack work

This commit is contained in:
Scott Richmond 2025-06-22 20:43:51 -04:00
parent f35cdd0e8d
commit e2c9619fa6
3 changed files with 65 additions and 40 deletions

View File

@ -51,11 +51,11 @@ fn some {
& ...and if two things are the same & ...and if two things are the same
fn eq? { fn eq? {
"Returns true if all arguments have the same value." "Returns true if all arguments have the same value."
& (x) -> true (x) -> true
(x, y) -> base :eq? (x, y) (x, y) -> base :eq? (x, y)
(x, y, ...zs) -> if eq? (x, y) (x, y, ...zs) -> if eq? (x, y)
then loop (y, zs) with { then loop (y, zs) with {
(a, []) -> eq? (a, x) (a, [b]) -> and (eq? (a, x), eq? (b, x))
(a, [b, ...cs]) -> if eq? (a, x) (a, [b, ...cs]) -> if eq? (a, x)
then recur (b, cs) then recur (b, cs)
else false else false
@ -115,19 +115,19 @@ fn fn? {
fn first { fn first {
"Retrieves the first element of an ordered collection--a tuple or a list. If the collection is empty, returns nil." "Retrieves the first element of an ordered collection--a tuple or a list. If the collection is empty, returns nil."
([]) -> nil ([]) -> nil
& (()) -> nil (()) -> nil
& ("") -> nil & ("") -> nil
(xs as :list) -> base :first (xs) (xs as :list) -> base :first (xs)
& (xs as :tuple) -> base :first (xs) (xs as :tuple) -> base :first (xs)
& (str as :string) -> base :slice (str, 0, 1) & (str as :string) -> base :slice (str, 0, 1)
} }
fn rest { fn rest {
"Returns all but the first element of a list or tuple, as a list." "Returns all but the first element of a list or tuple, as a list."
([]) -> [] ([]) -> []
& (()) -> () (()) -> ()
(xs as :list) -> base :rest (xs) (xs as :list) -> base :rest (xs)
& (xs as :tuple) -> base :rest (xs) (xs as :tuple) -> base :rest (xs)
& (str as :string) -> base :rest (str) & (str as :string) -> base :rest (str)
} }
@ -203,18 +203,33 @@ fn fold {
} }
} }
fn foldr {
"Folds a list, right-associatively."
(f as :fn, []) -> []
(f as :fn, xs as :list) -> foldr(f, xs, f ())
(f as :fn, [], root) -> []
(f as :fn, xs as :list, root) -> loop (root, first (xs), rest (xs)) with {
(prev, curr, []) -> f (curr, prev)
(prev, curr, remaining) -> recur (
f (curr, prev)
first (remaining)
rest (remaining)
)
}
}
fn map { fn map {
"Maps a function over a list: returns a new list with elements that are the result of applying the function to each element in the original list. E.g., `map ([1, 2, 3], inc) &=> [2, 3, 4]`. With one argument, returns a function that is a mapper over lists; with two, it executes the mapping function right away." "Maps a function over a list: returns a new list with elements that are the result of applying the function to each element in the original list. E.g., `map ([1, 2, 3], inc) &=> [2, 3, 4]`. With one argument, returns a function that is a mapper over lists; with two, it executes the mapping function right away."
& (f as :fn) -> map (f, _) (f as :fn) -> map (f, _)
& (kw as :keyword) -> map (kw, _) (kw as :keyword) -> map (kw, _)
(f as :fn, xs) -> { (f as :fn, xs) -> {
fn mapper (prev, curr) -> append (prev, f (curr)) fn mapper (prev, curr) -> append (prev, f (curr))
fold (mapper, xs, []) fold (mapper, xs, [])
} }
& (kw as :keyword, xs) -> { (kw as :keyword, xs) -> {
& fn mapper (prev, curr) -> append (prev, kw (curr)) fn mapper (prev, curr) -> append (prev, kw (curr))
& fold (mapper, xs, []) fold (mapper, xs, [])
& } }
} }
fn filter { fn filter {
@ -252,6 +267,30 @@ fn contains? {
} }
} }
& fn print! {
& "Sends a text representation of Ludus values to the console."
& (...args) -> {
& base :print! (args)
& :ok
& }
& }
& fn show {
& "Returns a text representation of a Ludus value as a string."
& (x) -> base :show (x)
& }
& fn report! {
& "Prints a value, then returns it."
& (x) -> {
& print! (x)
& x
& }
& (msg as :string, x) -> {
& print! (concat ("{msg} ", show (x)))
& x
& }
& }
#{ #{
type type
@ -280,10 +319,14 @@ fn contains? {
list list
first first
fold fold
foldr
append append
map map
filter filter
keep keep
concat concat
contains? contains?
& print!
& show
& report!
} }

View File

@ -1,15 +1,13 @@
fn my_eq? { fn arity {
(x, y, ...zs) -> if eq? (x, y) () -> 0
then loop (y, zs) with { (_) -> 1
(a, [b]) -> and (eq? (a, x), eq? (b, x)) (_, _) -> 2
(a, [b, ...cs]) -> if eq? (a, x) (_, _, ...) -> {
then recur (b, cs) and (1, 2, 3)
else false :many
} }
else false
} }
my_eq? (1, 1, 3) arity(:foo, :bar, :baz)

View File

@ -433,7 +433,6 @@ impl<'a> Compiler<'a> {
self.tail_pos = false; self.tail_pos = false;
// increase the scope // increase the scope
self.enter_scope(); self.enter_scope();
// self.scope_depth += 1;
// stash the stack depth // stash the stack depth
let stack_depth = self.stack_depth; let stack_depth = self.stack_depth;
// evaluate all the lines but the last // evaluate all the lines but the last
@ -454,7 +453,6 @@ impl<'a> Compiler<'a> {
// we do this by pretending it's a binding // we do this by pretending it's a binding
(Let(patt, expr), _) => { (Let(patt, expr), _) => {
// self.match_depth = 0; // self.match_depth = 0;
// self.emit_op(Op::ResetMatch);
self.visit(expr); self.visit(expr);
let expr_pos = self.stack_depth - 1; let expr_pos = self.stack_depth - 1;
self.report_ast("let binding: matching".to_string(), patt); self.report_ast("let binding: matching".to_string(), patt);
@ -472,28 +470,15 @@ impl<'a> Compiler<'a> {
} }
} }
// we've made a new value, so increase the stack level in the compiler
self.stack_depth += 1;
// store the value in the return register // store the value in the return register
// self.emit_op(Op::Store);
self.store(); self.store();
// reset the scope // reset the scope
self.leave_scope(); self.leave_scope();
// self.scope_depth -= 1;
// while let Some(binding) = self.bindings.last() {
// if binding.depth > self.scope_depth {
// self.bindings.pop();
// } else {
// break;
// }
// }
// reset the stack // reset the stack
self.pop_n(self.stack_depth - stack_depth - 1); self.pop_n(self.stack_depth - stack_depth);
// load the value from the return register // load the value from the return register
self.load(); self.load();
// self.emit_op(Op::Load);
} }
If(cond, then, r#else) => { If(cond, then, r#else) => {
let tail_pos = self.tail_pos; let tail_pos = self.tail_pos;
@ -1156,7 +1141,6 @@ impl<'a> Compiler<'a> {
} }
compiler.tail_pos = true; compiler.tail_pos = true;
compiler.visit(clause_body); compiler.visit(clause_body);
// compiler.emit_op(Op::Store);
compiler.store(); compiler.store();
compiler.scope_depth -= 1; compiler.scope_depth -= 1;
while let Some(binding) = compiler.bindings.last() { while let Some(binding) = compiler.bindings.last() {