fix interpolated string stack discipline

This commit is contained in:
Scott Richmond 2025-06-22 21:15:17 -04:00
parent f0cf43b486
commit 9d798e5e58
3 changed files with 53 additions and 32 deletions

View File

@ -275,22 +275,45 @@ fn print! {
}
}
& fn show {
& "Returns a text representation of a Ludus value as a string."
& (x) -> base :show (x)
& }
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
& }
& }
fn report! {
"Prints a value, then returns it."
(x) -> {
print! (x)
x
}
(msg as :string, x) -> {
print! (concat ("{msg} ", show (x)))
x
}
}
fn doc! {
"Prints the documentation of a function to the console."
(f as :fn) -> do f > base :doc! > print!
(_) -> :none
}
&&& strings: harder than they look!
fn string? {
"Returns true if a value is a string."
(x as :string) -> true
(_) -> false
}
fn string {
"Converts a value to a string by using `show`. If it is a string, returns it unharmed. Use this to build up strings of different kinds of values."
(x as :string) -> x
(x) -> show (x)
(x, ...xs) -> loop (string (x), xs) with {
(out, [y]) -> concat (out, show (y))
(out, [y, ...ys]) -> recur (concat (out, show (y)), ys)
}
}
#{
type
@ -327,6 +350,9 @@ fn print! {
concat
contains?
print!
& show
& report!
show
report!
doc!
string
string?
}

View File

@ -1,13 +1,4 @@
fn arity {
() -> 0
(_) -> 1
(_, _) -> 2
(_, _, ...) -> {
and (1, 2, 3)
:many
}
}
arity(:foo, :bar, :baz)

View File

@ -476,6 +476,11 @@ impl<'a> Compiler<'a> {
// reset the scope
self.leave_scope();
// reset the stack
self.report_depth("leaving block before pop");
self.msg(format!(
"popping back from {} to {}",
self.stack_depth, stack_depth,
));
self.pop_n(self.stack_depth - stack_depth);
// load the value from the return register
self.load();
@ -943,13 +948,12 @@ impl<'a> Compiler<'a> {
self.stack_depth -= 1;
}
Arguments(args) => {
self.emit_op(Op::Stash);
self.pop();
self.store();
let arity = args.len();
for arg in args {
self.visit(arg);
}
self.emit_op(Op::Load);
self.load();
if tail_pos && i == num_rest_terms - 1 {
self.emit_op(Op::TailCall)
} else {
@ -1382,7 +1386,6 @@ impl<'a> Compiler<'a> {
let allocated = Value::String(Rc::new(str.clone()));
self.emit_constant(allocated);
self.emit_op(Op::ConcatStrings);
self.stack_depth -= 1;
}
StringPart::Word(word) => {
self.resolve_binding(word);
@ -1390,6 +1393,7 @@ impl<'a> Compiler<'a> {
self.emit_op(Op::ConcatStrings);
}
}
self.stack_depth -= 1;
}
}
Do(terms) => {