meet with mnl

This commit is contained in:
Scott Richmond 2025-06-25 13:34:59 -04:00
parent 4f80c500a2
commit 87e58364e0

View File

@ -522,4 +522,238 @@ SOLUTION: test to see if the function has been forward-declared, and if it has,
NEW PROBLEM: a lot of instructions in the VM don't properly offset from the call frame's stack base, which leads to weirdness when doing things inside function calls.
NEW SOLUTION: create a function that does the offset properly, and replace everywhere we directly access the stack.
<<<<<<< Updated upstream
This is the thing I am about to do
||||||| Stash base
This is the thing I am about to do.
### I think the interpreter, uh, works?
#### 2025-06-24
I'm sure I'll find some small problems.
But right now the thing works.
At the moment, I'm thinking about how to get good error messages.
Panics are difficult.
And I'm worried about ariadne as the error reporting crate.
Since it writes to stdout, it has all kinds of escape codes.
I need a plain ass string, at least for the web frontend.
So.
Current task, however, is how to get reasonable panic error messages.
Let's simplify the problem.
First, let's get tracebacks and line numbers.
We use Chumsky spanned ASTs.
The span is just a range into an str.
What I can do is pretty stupidly just generate line numbers from the spans in the compiler, and from there, get a reasonable traceback.
So instead of using Ariadne's fancy report builder, let's just do something more what we already have here:
```
Ludus panicked! no match
on line 1 in input,
calling: add
with arguments: ("foo")
expected match with one of:
()
(x as :number)
(x as :number, y as :number)
(x, y, ...zs)
((x1, y1), (x2, y2))
>>> add ("foo")
......^
```
We need:
* the location of the function call in terms of the line number
* the arguments used
* the patterns expected to match (special cases: `let` vs `match` vs `fn`)
That means, for bookkeeping, we need:
* In the compiler, line number
* In the VM, the arguments
* In the VM, the pattern AST node.
In Janet-Ludus, there are only a few types of panic:
* `fn-no-match`: no match against a function call
* `let-no-match`: no match against a `let` binding
* `match-no-match`: no match against a `match` form
* `generic-panic`: everything else
* `runtime-error`: an internal Ludus error
The first three are simply formatting differences.
There are no tracebacks.
Tracebacks should be easy enough, although there's some fiddly bits.
While it's nice to have the carret, the brutalist attempt here should be just to give us the line--since the carret isn't exactly precise in the Janet interpereter.
And the traceback should look something like:
```
calling foo with (:bar, :baz)
at line 12 in input
calling bar with ()
at line 34 in prelude
calling baz with (1, 2, 3)
at line 12 in input
```
Which means, again: function names, ip->line conversion, and arguments.
The runtime needs a representation of the patterns in _any_ matching form.
The speed is so much greater now that I'm not so concerned about little optimizations.
So: a chunk needs a vec of patterns-representations. (I'm thinking simply a `Vec<String>`.)
So does a function, for `doc!`.
Same same re: `Vec<String>`.
A VM needs a register for the scrutinee (which with function calls is just the arguments, already captured).
A VM also needs a register for the pattern.
So when there's a no match, we just yank the pattern and the scrutinee out of these registers.
This all seems very straightforward compared to the compiling & VM stuff.
Here's some stub code I wrote for dealing with ranges, source, line numbers:
```rust
let str = "foo bar baz\nquux frob\nthing thing thing";
let range = 0..4;
println!("{}", str.get(range).unwrap());
let lines: Vec<&str> = str.split_terminator("\n").collect();
println!("{:?}", lines);
let idx = 20;
let mut line_no = 1;
for i in 0..idx {
if str.chars().nth(i).unwrap() == '\n' {
line_no += 1;
}
}
println!("line {line_no}: {}", lines[line_no - 1]);
```
=======
This is the thing I am about to do.
### I think the interpreter, uh, works?
#### 2025-06-24
I'm sure I'll find some small problems.
But right now the thing works.
At the moment, I'm thinking about how to get good error messages.
Panics are difficult.
And I'm worried about ariadne as the error reporting crate.
Since it writes to stdout, it has all kinds of escape codes.
I need a plain ass string, at least for the web frontend.
So.
Current task, however, is how to get reasonable panic error messages.
Let's simplify the problem.
First, let's get tracebacks and line numbers.
We use Chumsky spanned ASTs.
The span is just a range into an str.
What I can do is pretty stupidly just generate line numbers from the spans in the compiler, and from there, get a reasonable traceback.
So instead of using Ariadne's fancy report builder, let's just do something more what we already have here:
```
Ludus panicked! no match
on line 1 in input,
calling: add
with arguments: ("foo")
expected match with one of:
()
(x as :number)
(x as :number, y as :number)
(x, y, ...zs)
((x1, y1), (x2, y2))
>>> add ("foo")
......^
```
We need:
* the location of the function call in terms of the line number
* the arguments used
* the patterns expected to match (special cases: `let` vs `match` vs `fn`)
That means, for bookkeeping, we need:
* In the compiler, line number
* In the VM, the arguments
* In the VM, the pattern AST node.
In Janet-Ludus, there are only a few types of panic:
* `fn-no-match`: no match against a function call
* `let-no-match`: no match against a `let` binding
* `match-no-match`: no match against a `match` form
* `generic-panic`: everything else
* `runtime-error`: an internal Ludus error
The first three are simply formatting differences.
There are no tracebacks.
Tracebacks should be easy enough, although there's some fiddly bits.
While it's nice to have the carret, the brutalist attempt here should be just to give us the line--since the carret isn't exactly precise in the Janet interpereter.
And the traceback should look something like:
```
calling foo with (:bar, :baz)
at line 12 in input
calling bar with ()
at line 34 in prelude
calling baz with (1, 2, 3)
at line 12 in input
```
Which means, again: function names, ip->line conversion, and arguments.
The runtime needs a representation of the patterns in _any_ matching form.
The speed is so much greater now that I'm not so concerned about little optimizations.
So: a chunk needs a vec of patterns-representations. (I'm thinking simply a `Vec<String>`.)
So does a function, for `doc!`.
Same same re: `Vec<String>`.
A VM needs a register for the scrutinee (which with function calls is just the arguments, already captured).
A VM also needs a register for the pattern.
So when there's a no match, we just yank the pattern and the scrutinee out of these registers.
This all seems very straightforward compared to the compiling & VM stuff.
Here's some stub code I wrote for dealing with ranges, source, line numbers:
```rust
let str = "foo bar baz\nquux frob\nthing thing thing";
let range = 0..4;
println!("{}", str.get(range).unwrap());
let lines: Vec<&str> = str.split_terminator("\n").collect();
println!("{:?}", lines);
let idx = 20;
let mut line_no = 1;
for i in 0..idx {
if str.chars().nth(i).unwrap() == '\n' {
line_no += 1;
}
}
println!("line {line_no}: {}", lines[line_no - 1]);
```
### Integration meeting with mnl
#### 2025-06-25
* Web workers
* My javascript wrapper needs to execute WASM in its own thread (ugh)
- [ ] is this a thing that can be done easily in a platform-independent way (node vs. bun vs. browser)?
* Top priorities:
- [ ] Get a node package out
- [ ] Stand up actors + threads, etc.
- [ ] How to model keyboard input from p5?
* [ ] Model after the p5 keyboard input API
* [ ] ludus keyboard API: `key_is_down(), key_pressed(), key_released()`, key code values (use a dict)
- Assets:
* We don't (for now) need to worry about serialization formats, since we're not doing perceptrons
* We do need to read from URLs, which need in a *.ludus.dev.
* Users can create their own (public) repos and put stuff in there.
* We still want saving text output from web Ludus
* Later, with perceptrons & the book, we'll need additional solutions.
>>>>>>> Stashed changes