Compare commits

...

2 Commits

Author SHA1 Message Date
Scott Richmond
c62b5c903d update chumsky, lose ariadne, update parser to conform to new chumsky 2025-06-29 18:08:44 -04:00
Scott Richmond
de6cb5380d add a justfile, some project management 2025-06-29 17:47:08 -04:00
5 changed files with 47 additions and 17 deletions

View File

@ -9,8 +9,7 @@ edition = "2021"
crate-type = ["cdylib", "rlib"]
[dependencies]
ariadne = { git = "https://github.com/zesterer/ariadne" }
chumsky = { git = "https://github.com/zesterer/chumsky", features = ["label"] }
chumsky = "0.10.1"
imbl = "3.0.0"
ran = "2.0.1"
num-derive = "0.4.2"

10
justfile Normal file
View File

@ -0,0 +1,10 @@
wasm:
wasm-pack build --target web
rm pkg/.gitignore
cp pkg/rudus.js pkg/rudus.js.backup
echo 'import {io} from "../worker.js"' > rudus.js
cat rudus.js.backup | tail -n+2>> rudus.js
rm rudus.js.backup
default:
@just --list

View File

@ -1113,23 +1113,26 @@ That leaves the following list:
- Original version of `update` also had this same problem with `assoc`; fixed it by calling the Ludus, rather than Rust, function.
* [a] `loop`/`recur` is still giving me a very headache. It breaks stack discipline to avoid packing tuples into a heap-allocated vec. There may be a way to fix this in the current compiler scheme around how I do and don't handle arguments--make recur stupider and don't bother loading anything. A different solution would be to desugar loop into an anonymous function call. A final solution would be just to use a heap-allocated tuple.
* 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)?
- [x] is this a thing that can be done easily in a platform-independent way (node vs. bun vs. browser)?
- No, no it is not. I will need to build a separate node version for using at the command line (and, like, for testing with our test harness.)
* Top priorities:
- [-] Get a node package out
- [x] 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)
* [ ] ludus keyboard API: `key_down?(), key_pressed?(), key_released?()`, key code values (use a dict)
* [a] Escape characters in strings: \n, \t, and \{, \}.
* [ ] `doc!` needs to print the patterns of a function.
* [ ] I need to return to the question of whether/how strings are ordered; do we use `at`, or do we want `char_at`? etc.
- MNL and I decided: yes, stings are indexable
- [ ] implement `slice` and `at` and others for strings
* [ ] Automate this build process
* [ ] Start testing against the cases in `ludus-test`
* [ ] Systematically debug prelude
- [ ] Bring it in function by function, testing each in turn
* [ ] Bring it in function by function, testing each in turn
* [ ] Animation hooked into the web frontend (Spacewar!)
* [ ] Text input (Spacewar!)
- [ ] Makey makey for alternate input?
* [ ] Makey makey for alternate input?
* [ ] Saving and loading data into Ludus (perceptrons, dissociated press)
* [ ] Finding corpuses for Dissociated Press
* [ ] improve validator
@ -1145,3 +1148,21 @@ That leaves the following list:
* [ ] that suggests that we need a mapping from bytecodes to AST nodes
* The way I had been planning on doing this is having a vec that moves in lockstep with bytecode that's just references to ast nodes, which are `'static`, so that shouldn't be too bad. But this is per-chunk, which means we need a reference to that vec in the VM. My sense is that what we want is actually a separate data structure that holds the AST nodes--we'll only need them in the sad path, which can be slow.
### Next steps in integration hell
#### 2025-06-29
* [ ] improve build process for rudus+wasm_pack
- [ ] delete generated .gitignore
- [ ] edit first line of rudus.js to import the local `ludus.js`
* [ ] design & implement asynchronous i/o+runtime
- [ ] use `box`es for i/o: they can be reified in rust: making actors available is rather more complex (i.e. require message passing between the ludus and rust)
* We also then don't have to have prelude run in the vm; that's good
- [ ] start with ludus->rust->js pipeline
* [ ] console
* [ ] turtle graphics
* [ ] completion
- [ ] then js->rust->ludus
* [ ] kill
* [ ] text input
* [ ] keypresses
- [ ] then ludus->rust->js->rust->ludus
* [ ] slurp

View File

@ -1,6 +1,5 @@
// use crate::process::{LErr, Trace};
use crate::validator::VErr;
use ariadne::{sources, Color, Label, Report, ReportKind};
// pub fn report_panic(err: LErr) {
// let mut srcs = HashSet::new();
@ -42,11 +41,12 @@ use ariadne::{sources, Color, Label, Report, ReportKind};
pub fn report_invalidation(errs: Vec<VErr>) {
for err in errs {
Report::build(ReportKind::Error, (err.input, err.span.into_range()))
.with_message(err.msg.to_string())
.with_label(Label::new((err.input, err.span.into_range())).with_color(Color::Cyan))
.finish()
.print(sources(vec![(err.input, err.src)]))
.unwrap();
// Report::build(ReportKind::Error, (err.input, err.span.into_range()))
// .with_message(err.msg.to_string())
// .with_label(Label::new((err.input, err.span.into_range())).with_color(Color::Cyan))
// .finish()
// .print(sources(vec![(err.input, err.src)]))
// .unwrap();
println!("{}", err.msg);
}
}

View File

@ -62,7 +62,7 @@ fn parse_string(s: &'static str, span: SimpleSpan) -> Result<Vec<Spanned<StringP
if !current_part.is_empty() {
parts.push((
StringPart::Data(current_part),
SimpleSpan::new(start, start + i),
SimpleSpan::new(span.context(), start..start + i),
));
};
current_part = String::new();
@ -80,7 +80,7 @@ fn parse_string(s: &'static str, span: SimpleSpan) -> Result<Vec<Spanned<StringP
if is_word {
parts.push((
StringPart::Word(current_part.clone()),
SimpleSpan::new(start, start + i),
SimpleSpan::new(span.context(), start..start + i),
));
current_part = String::new();
start = i;
@ -109,13 +109,13 @@ fn parse_string(s: &'static str, span: SimpleSpan) -> Result<Vec<Spanned<StringP
if current_part == s {
parts.push((
StringPart::Inline(current_part),
SimpleSpan::new(start, span.end),
SimpleSpan::new(span.context(), start..span.end),
))
} else if !current_part.is_empty() {
let part_len = current_part.len();
parts.push((
StringPart::Data(current_part),
SimpleSpan::new(start, part_len),
SimpleSpan::new(span.context(), start..part_len),
))
}