meet with mnl
This commit is contained in:
parent
4f80c500a2
commit
87e58364e0
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user