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
fn eq? {
"Returns true if all arguments have the same value."
& (x) -> true
(x) -> true
(x, y) -> base :eq? (x, y)
(x, y, ...zs) -> if eq? (x, y)
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)
then recur (b, cs)
else false
@ -115,19 +115,19 @@ fn fn? {
fn first {
"Retrieves the first element of an ordered collection--a tuple or a list. If the collection is empty, returns nil."
([]) -> nil
& (()) -> nil
(()) -> nil
& ("") -> nil
(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)
}
fn rest {
"Returns all but the first element of a list or tuple, as a list."
([]) -> []
& (()) -> ()
(()) -> ()
(xs as :list) -> base :rest (xs)
& (xs as :tuple) -> base :rest (xs)
(xs as :tuple) -> base :rest (xs)
& (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 {
"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, _)
& (kw as :keyword) -> map (kw, _)
(f as :fn) -> map (f, _)
(kw as :keyword) -> map (kw, _)
(f as :fn, xs) -> {
fn mapper (prev, curr) -> append (prev, f (curr))
fold (mapper, xs, [])
}
& (kw as :keyword, xs) -> {
& fn mapper (prev, curr) -> append (prev, kw (curr))
& fold (mapper, xs, [])
& }
(kw as :keyword, xs) -> {
fn mapper (prev, curr) -> append (prev, kw (curr))
fold (mapper, xs, [])
}
}
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
@ -280,10 +319,14 @@ fn contains? {
list
first
fold
foldr
append
map
filter
keep
concat
contains?
& print!
& show
& report!
}

View File

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

View File

@ -433,7 +433,6 @@ impl<'a> Compiler<'a> {
self.tail_pos = false;
// increase the scope
self.enter_scope();
// self.scope_depth += 1;
// stash the stack depth
let stack_depth = self.stack_depth;
// evaluate all the lines but the last
@ -454,7 +453,6 @@ impl<'a> Compiler<'a> {
// we do this by pretending it's a binding
(Let(patt, expr), _) => {
// 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);
@ -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
// self.emit_op(Op::Store);
self.store();
// reset the 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
self.pop_n(self.stack_depth - stack_depth - 1);
self.pop_n(self.stack_depth - stack_depth);
// load the value from the return register
self.load();
// self.emit_op(Op::Load);
}
If(cond, then, r#else) => {
let tail_pos = self.tail_pos;
@ -1156,7 +1141,6 @@ impl<'a> Compiler<'a> {
}
compiler.tail_pos = true;
compiler.visit(clause_body);
// compiler.emit_op(Op::Store);
compiler.store();
compiler.scope_depth -= 1;
while let Some(binding) = compiler.bindings.last() {