add more parser tests
This commit is contained in:
parent
6f71d9f5b3
commit
79c3113689
5 changed files with 145 additions and 27 deletions
17
Cargo.lock
generated
17
Cargo.lock
generated
|
|
@ -99,6 +99,12 @@ dependencies = [
|
||||||
"windows-sys 0.45.0",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "diff"
|
||||||
|
version = "0.1.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
|
|
@ -206,6 +212,16 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pretty_assertions"
|
||||||
|
version = "1.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
|
||||||
|
dependencies = [
|
||||||
|
"diff",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.104"
|
version = "1.0.104"
|
||||||
|
|
@ -232,6 +248,7 @@ dependencies = [
|
||||||
"ariadne",
|
"ariadne",
|
||||||
"chumsky",
|
"chumsky",
|
||||||
"logos",
|
"logos",
|
||||||
|
"pretty_assertions",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,6 @@ edition = "2024"
|
||||||
ariadne = { version = "0.6.0", features = ["auto-color"]}
|
ariadne = { version = "0.6.0", features = ["auto-color"]}
|
||||||
chumsky = { version = "0.12.0", features = ["pratt"] }
|
chumsky = { version = "0.12.0", features = ["pratt"] }
|
||||||
logos = "0.16.0"
|
logos = "0.16.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
pretty_assertions = "1.4.1"
|
||||||
|
|
|
||||||
24
README.md
24
README.md
|
|
@ -14,7 +14,7 @@ Values:
|
||||||
`double x = x * 2`
|
`double x = x * 2`
|
||||||
```rust
|
```rust
|
||||||
double = fn([x] [x]) (
|
double = fn([x] [x]) (
|
||||||
^x = x * 2;
|
^x := x * 2;
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ double = fn([x] [x]) (
|
||||||
```rust
|
```rust
|
||||||
;; same as apply = fn([f x] [x]) ( ... )
|
;; same as apply = fn([f x] [x]) ( ... )
|
||||||
fn apply([f x] [x]) (
|
fn apply([f x] [x]) (
|
||||||
^x = f x;
|
^x := f x;
|
||||||
);
|
);
|
||||||
|
|
||||||
;; f would have to be like fn([a] [a]) ( ... )
|
;; f would have to be like fn([a] [a]) ( ... )
|
||||||
|
|
@ -37,10 +37,10 @@ fn apply([f x] [x]) (
|
||||||
```
|
```
|
||||||
```rust
|
```rust
|
||||||
fn make_counter([] [inc]) (
|
fn make_counter([] [inc]) (
|
||||||
i = 0;
|
i := 0;
|
||||||
^inc = fn([] [i]) (
|
^inc := fn([] [i]) (
|
||||||
i = i + 1;
|
i := i + 1;
|
||||||
^i = i;
|
^i := i;
|
||||||
);
|
);
|
||||||
|
|
||||||
;; or fn ^inc(...)
|
;; or fn ^inc(...)
|
||||||
|
|
@ -51,20 +51,20 @@ fn make_counter([] [inc]) (
|
||||||
```rust
|
```rust
|
||||||
;; omitting the return means it's the same
|
;; omitting the return means it's the same
|
||||||
fn desat([h s l a]) (
|
fn desat([h s l a]) (
|
||||||
^s = ^s / 2;
|
^s := ^s / 2;
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
`compose f g x = f (g x)`
|
`compose f g x = f (g x)`
|
||||||
```rust
|
```rust
|
||||||
fn compose([f g x] [x]) (
|
fn compose([f g x] [x]) (
|
||||||
^x = g x;
|
^x := g x;
|
||||||
^x = f x;
|
^x := f x;
|
||||||
)
|
)
|
||||||
|
|
||||||
f = fn([x]) (^x = x + 2;);
|
f := fn([x]) (^x := x + 2;);
|
||||||
g = fn([x]) (^x = x * 3;);
|
g := fn([x]) (^x := x * 3;);
|
||||||
f2 = f;
|
f2 := f;
|
||||||
|
|
||||||
compose f g x == (((compose f) g) x) == compose {f: f2, g} x == compose {x} f g
|
compose f g x == (((compose f) g) x) == compose {f: f2, g} x == compose {x} f g
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,9 @@ impl fmt::Display for Ast {
|
||||||
body,
|
body,
|
||||||
} => {
|
} => {
|
||||||
let body: Vec<_> = body.iter().map(|stmt| format!("{stmt}")).collect();
|
let body: Vec<_> = body.iter().map(|stmt| format!("{stmt}")).collect();
|
||||||
|
if body.is_empty() {
|
||||||
|
write!(f, "(fn ([{}] [{}]))", inputs.join(" "), outputs.join(" "),)
|
||||||
|
} else {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"(fn ([{}] [{}]) {})",
|
"(fn ([{}] [{}]) {})",
|
||||||
|
|
@ -93,6 +96,7 @@ impl fmt::Display for Ast {
|
||||||
body.join(" ")
|
body.join(" ")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ast::Map(body) => {
|
Ast::Map(body) => {
|
||||||
let body: Vec<_> = body.iter().map(|stmt| format!("{stmt}")).collect();
|
let body: Vec<_> = body.iter().map(|stmt| format!("{stmt}")).collect();
|
||||||
write!(f, "{{{}}}", body.join(" "))
|
write!(f, "{{{}}}", body.join(" "))
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::parser::*;
|
use crate::parser::*;
|
||||||
|
|
||||||
fn test(src: &str, expected: &str) {
|
fn test(src: &str, expected: &str) {
|
||||||
assert_eq!(
|
pretty_assertions::assert_eq!(
|
||||||
parse(src)
|
parse(src)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|stmt| format!("{stmt}"))
|
.map(|stmt| format!("{stmt}"))
|
||||||
|
|
@ -16,10 +16,27 @@ fn double() {
|
||||||
test(
|
test(
|
||||||
"
|
"
|
||||||
fn double([x]) (
|
fn double([x]) (
|
||||||
^x = x * 2;
|
^x := x * 2;
|
||||||
)
|
)
|
||||||
",
|
",
|
||||||
"(set! double (fn ([x] [x]) (^x = (x * 2))))",
|
"
|
||||||
|
(set! double (fn ([x] [x]) (set! ^x (x * 2))))
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn apply() {
|
||||||
|
test(
|
||||||
|
"
|
||||||
|
# same as apply = fn([f x] [x]) ( ... )
|
||||||
|
fn apply([f x] [x]) (
|
||||||
|
^x := f x;
|
||||||
|
)
|
||||||
|
|
||||||
|
# f would have to be like fn([a] [a]) ( ... )
|
||||||
|
",
|
||||||
|
"(set! apply (fn ([f x] [x]) (set! ^x (f x))))",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,15 +45,92 @@ fn make_counter() {
|
||||||
test(
|
test(
|
||||||
"
|
"
|
||||||
fn make_counter([] [inc]) (
|
fn make_counter([] [inc]) (
|
||||||
i = 0;
|
i := 0;
|
||||||
^inc = fn([] [i]) (
|
^inc := fn([] [i]) (
|
||||||
i = i + 1;
|
i := i + 1;
|
||||||
^i = i;
|
^i := i;
|
||||||
);
|
);
|
||||||
|
|
||||||
# or fn ^inc(...)
|
# or fn ^inc(...)
|
||||||
)
|
)
|
||||||
",
|
",
|
||||||
"(set! make_counter (fn ([] [inc]) (i = 0) (^inc = (fn ([] [i]) (i = (i + 1)) (^i = i)))))",
|
"
|
||||||
|
(set! make_counter \
|
||||||
|
(fn ([] [inc]) \
|
||||||
|
(set! i 0) \
|
||||||
|
(set! ^inc (fn ([] [i]) \
|
||||||
|
(set! i (i + 1)) \
|
||||||
|
(set! ^i i)))))
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn desat() {
|
||||||
|
test(
|
||||||
|
"
|
||||||
|
fn desat([h s l a]) (
|
||||||
|
^s := ^s / 2;
|
||||||
|
)
|
||||||
|
",
|
||||||
|
"(set! desat (fn ([h s l a] [h s l a]) (set! ^s (^s / 2))))",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compose() {
|
||||||
|
test(
|
||||||
|
"
|
||||||
|
fn compose([f g x] [x]) (
|
||||||
|
^x := g x;
|
||||||
|
^x := f x;
|
||||||
|
);
|
||||||
|
|
||||||
|
f := fn([x]) (^x := x + 2;);
|
||||||
|
g := fn([x]) (^x := x * 3;);
|
||||||
|
f2 := f;
|
||||||
|
|
||||||
|
compose f g x = (((compose f) g) x);
|
||||||
|
compose f g x = compose {^f := f2; ^g} x;
|
||||||
|
compose f g x = compose {^x} f g;
|
||||||
|
",
|
||||||
|
"
|
||||||
|
(set! compose (fn ([f g x] [x]) (set! ^x (g x)) (set! ^x (f x))));
|
||||||
|
(set! f (fn ([x] [x]) (set! ^x (x + 2))));
|
||||||
|
(set! g (fn ([x] [x]) (set! ^x (x * 3))));
|
||||||
|
(set! f2 f);
|
||||||
|
((((compose f) g) x) = ((((((compose f)) g)) x)));
|
||||||
|
((((compose f) g) x) = ((compose {(set! ^f f2) ^g}) x));
|
||||||
|
((((compose f) g) x) = (((compose {^x}) f) g))
|
||||||
|
",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn id() {
|
||||||
|
test("fn id([x]) ()", "(set! id (fn ([x] [x])))");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn map() {
|
||||||
|
test(
|
||||||
|
"
|
||||||
|
foo := 3;
|
||||||
|
{
|
||||||
|
x := 42;
|
||||||
|
^twice_x := x * 2;
|
||||||
|
^thrice_x := x * 3;
|
||||||
|
^foo;
|
||||||
|
}
|
||||||
|
",
|
||||||
|
"
|
||||||
|
(set! foo 3);
|
||||||
|
{\
|
||||||
|
(set! x 42) \
|
||||||
|
(set! ^twice_x (x * 2)) \
|
||||||
|
(set! ^thrice_x (x * 3)) \
|
||||||
|
^foo\
|
||||||
|
}
|
||||||
|
",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue