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 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.
|
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
|
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