Bools and ifs

trunk
Alona EM 2021-12-17 02:57:20 +00:00
parent 969c526d89
commit d437e1297c
3 changed files with 433 additions and 162 deletions

View File

@ -5,17 +5,24 @@ grammar<'s>();
pub(crate) Tree: Tree = {
"(" <Tree+> ")" => Tree::Branch(<>),
"(" "define" <Sym> <Box<Tree>> ")" => Tree::Define(<>),
"(" "define" <Sym> <BTree> ")" => Tree::Define(<>),
"(" "if" <Tree> <Tree> <Tree> ")" => Tree::If(Box::new([<>])),
Literal => Tree::Leaf(<>),
}
BTree = { Box<Tree> }
Literal: Literal = {
Sym => Literal::Sym(<>),
Num => Literal::Num(<>),
Bool => Literal::Bool(<>),
}
Box<T>: Box<T> = { T => Box::new(<>) }
Sym: String = { r"[A-Za-z!$%&*+\-./:<=>?@^_~][A-Za-z!$%&*+\-./:<=>?@^_~0-9]*" => <>.to_owned() }
Num: f64 = { r"[0-9]+(\.[0-9]+)?" => <>.parse().unwrap() }
Num: f64 = { r"[0-9]+(\.[0-9]+)?" => <>.parse().unwrap() }
Bool: bool = {
"#t" => true,
"#f" => false,
}

View File

@ -1,5 +1,5 @@
// auto-generated: "lalrpop 0.19.6"
// sha3: 5c17121d6330bf8eebfa9cdfd4782fcc522dc2e0de3d264435b7dabb6e5fde
// sha3: 571c188ccc79ac263d1d3e5f9c8ba79f8d57f5a72af80ada9090216ab299e
use crate::{Tree, Literal};
#[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util;
@ -25,50 +25,69 @@ mod __parse__Tree {
{
Variant0(&'input str),
Variant1(Box<Tree>),
Variant2(Literal),
Variant3(f64),
Variant4(String),
Variant5(Tree),
Variant6(alloc::vec::Vec<Tree>),
Variant2(bool),
Variant3(Literal),
Variant4(f64),
Variant5(String),
Variant6(Tree),
Variant7(alloc::vec::Vec<Tree>),
}
const __ACTION: &[i8] = &[
// State 0
2, 0, 0, 10, 11,
14, 15, 2, 0, 0, 0, 16, 17,
// State 1
2, 0, 4, 10, 11,
14, 15, 2, 0, 4, 5, 16, 17,
// State 2
2, 14, 0, 10, 11,
14, 15, 2, 20, 0, 0, 16, 17,
// State 3
0, 0, 0, 0, 11,
0, 0, 0, 0, 0, 0, 0, 17,
// State 4
2, 0, 0, 10, 11,
14, 15, 2, 0, 0, 0, 16, 17,
// State 5
-8, -8, 0, -8, -8,
14, 15, 2, 0, 0, 0, 16, 17,
// State 6
-3, -3, 0, -3, -3,
14, 15, 2, 0, 0, 0, 16, 17,
// State 7
-2, -2, 0, -2, -2,
14, 15, 2, 0, 0, 0, 16, 17,
// State 8
0, 0, 0, 0, 0,
-7, -7, -7, -7, 0, 0, -7, -7,
// State 9
-4, -4, 0, -4, -4,
-13, -13, -13, -13, 0, 0, -13, -13,
// State 10
-5, -5, 0, -5, -5,
-6, -6, -6, -6, 0, 0, -6, -6,
// State 11
-9, -9, 0, -9, -9,
-5, -5, -5, -5, 0, 0, -5, -5,
// State 12
-10, -10, 0, -10, -10,
0, 0, 0, 0, 0, 0, 0, 0,
// State 13
-6, -6, 0, -6, -6,
-3, -3, -3, -3, 0, 0, -3, -3,
// State 14
0, 17, 0, 0, 0,
-2, -2, -2, -2, 0, 0, -2, -2,
// State 15
0, -1, 0, 0, 0,
-8, -8, -8, -8, 0, 0, -8, -8,
// State 16
-7, -7, 0, -7, -7,
-9, -9, -9, -9, 0, 0, -9, -9,
// State 17
-14, -14, -14, -14, 0, 0, -14, -14,
// State 18
-15, -15, -15, -15, 0, 0, -15, -15,
// State 19
-10, -10, -10, -10, 0, 0, -10, -10,
// State 20
0, 0, 0, 24, 0, 0, 0, 0,
// State 21
0, 0, 0, -1, 0, 0, 0, 0,
// State 22
0, 0, 0, -4, 0, 0, 0, 0,
// State 23
-11, -11, -11, -11, 0, 0, -11, -11,
// State 24
0, 0, 0, 26, 0, 0, 0, 0,
// State 25
-12, -12, -12, -12, 0, 0, -12, -12,
];
fn __action(state: i8, integer: usize) -> i8 {
__ACTION[(state as usize) * 5 + integer]
__ACTION[(state as usize) * 8 + integer]
}
const __EOF_ACTION: &[i8] = &[
// State 0
@ -82,54 +101,80 @@ mod __parse__Tree {
// State 4
0,
// State 5
-8,
0,
// State 6
-3,
0,
// State 7
-2,
0,
// State 8
-11,
// State 9
-4,
// State 10
-5,
// State 11
0,
// State 12
0,
// State 13
-6,
// State 14
0,
// State 15
0,
// State 16
-7,
// State 9
-13,
// State 10
-6,
// State 11
-5,
// State 12
-16,
// State 13
-3,
// State 14
-2,
// State 15
-8,
// State 16
-9,
// State 17
0,
// State 18
0,
// State 19
-10,
// State 20
0,
// State 21
0,
// State 22
0,
// State 23
-11,
// State 24
0,
// State 25
-12,
];
fn __goto(state: i8, nt: usize) -> i8 {
match nt {
0 => 14,
1 => 5,
2 => 6,
3 => match state {
3 => 4,
_ => 7,
0 => 20,
1 => 8,
2 => 21,
3 => 9,
4 => 10,
5 => match state {
3 => 5,
_ => 11,
},
4 => match state {
1 => 11,
2 => 12,
4 => 15,
_ => 8,
6 => match state {
6 => 7,
0 => 12,
1 => 17,
2 => 18,
5 => 22,
7 => 24,
_ => 6,
},
5 => 2,
7 => 2,
_ => 0,
}
}
fn __expected_tokens(__state: i8) -> alloc::vec::Vec<alloc::string::String> {
const __TERMINAL: &[&str] = &[
r###""#f""###,
r###""#t""###,
r###""(""###,
r###"")""###,
r###""define""###,
r###""if""###,
r###"r#"[0-9]+(\\.[0-9]+)?"#"###,
r###"r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"#"###,
];
@ -184,7 +229,7 @@ mod __parse__Tree {
#[inline]
fn error_action(&self, state: i8) -> i8 {
__action(state, 5 - 1)
__action(state, 8 - 1)
}
#[inline]
@ -251,8 +296,11 @@ mod __parse__Tree {
Token(2, _) if true => Some(0),
Token(3, _) if true => Some(1),
Token(4, _) if true => Some(2),
Token(0, _) if true => Some(3),
Token(1, _) if true => Some(4),
Token(5, _) if true => Some(3),
Token(6, _) if true => Some(4),
Token(7, _) if true => Some(5),
Token(0, _) if true => Some(6),
Token(1, _) if true => Some(7),
_ => None,
}
}
@ -266,8 +314,8 @@ mod __parse__Tree {
) -> __Symbol<'input>
{
match __token_index {
0 | 1 | 2 | 3 | 4 => match __token {
Token(2, __tok0) | Token(3, __tok0) | Token(4, __tok0) | Token(0, __tok0) | Token(1, __tok0) if true => __Symbol::Variant0(__tok0),
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 => match __token {
Token(2, __tok0) | Token(3, __tok0) | Token(4, __tok0) | Token(5, __tok0) | Token(6, __tok0) | Token(7, __tok0) | Token(0, __tok0) | Token(1, __tok0) if true => __Symbol::Variant0(__tok0),
_ => unreachable!(),
},
_ => unreachable!(),
@ -350,8 +398,23 @@ mod __parse__Tree {
__reduce9(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
}
10 => {
__reduce10(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
}
11 => {
__reduce11(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
}
12 => {
__reduce12(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
}
13 => {
__reduce13(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
}
14 => {
__reduce14(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
}
15 => {
// __Tree = Tree => ActionFn(0);
let __sym0 = __pop_Variant5(__symbols);
let __sym0 = __pop_Variant6(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action0::<>(input, __sym0);
@ -381,25 +444,14 @@ mod __parse__Tree {
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant2<
fn __pop_Variant3<
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, Literal, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant4<
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, String, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r),
Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
@ -407,7 +459,7 @@ mod __parse__Tree {
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, Tree, usize)
) -> (usize, String, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r),
@ -418,21 +470,43 @@ mod __parse__Tree {
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, alloc::vec::Vec<Tree>, usize)
) -> (usize, Tree, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant3<
fn __pop_Variant7<
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, alloc::vec::Vec<Tree>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant7(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant2<
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, bool, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant4<
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, f64, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r),
Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
@ -457,11 +531,11 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Box<Tree> = Tree => ActionFn(8);
let __sym0 = __pop_Variant5(__symbols);
// BTree = Box<Tree> => ActionFn(5);
let __sym0 = __pop_Variant1(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action8::<>(input, __sym0);
let __nt = super::__action5::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
(1, 0)
}
@ -475,11 +549,11 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Literal = Sym => ActionFn(4);
let __sym0 = __pop_Variant4(__symbols);
// Bool = "#t" => ActionFn(11);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action4::<>(input, __sym0);
let __nt = super::__action11::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
(1, 1)
}
@ -493,11 +567,11 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Literal = Num => ActionFn(5);
let __sym0 = __pop_Variant3(__symbols);
// Bool = "#f" => ActionFn(12);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action5::<>(input, __sym0);
let __nt = super::__action12::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
(1, 1)
}
@ -511,12 +585,12 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Num = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(7);
let __sym0 = __pop_Variant0(__symbols);
// Box<Tree> = Tree => ActionFn(13);
let __sym0 = __pop_Variant6(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action7::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
let __nt = super::__action13::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant1(__nt), __end));
(1, 2)
}
pub(crate) fn __reduce4<
@ -529,12 +603,12 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Sym = r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"# => ActionFn(6);
let __sym0 = __pop_Variant0(__symbols);
// Literal = Sym => ActionFn(6);
let __sym0 = __pop_Variant5(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action6::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
(1, 3)
}
pub(crate) fn __reduce5<
@ -547,16 +621,13 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree = "(", Tree+, ")" => ActionFn(1);
assert!(__symbols.len() >= 3);
let __sym2 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant6(__symbols);
let __sym0 = __pop_Variant0(__symbols);
// Literal = Num => ActionFn(7);
let __sym0 = __pop_Variant4(__symbols);
let __start = __sym0.0.clone();
let __end = __sym2.2.clone();
let __nt = super::__action1::<>(input, __sym0, __sym1, __sym2);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(3, 4)
let __end = __sym0.2.clone();
let __nt = super::__action7::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
(1, 3)
}
pub(crate) fn __reduce6<
'input,
@ -568,18 +639,13 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree = "(", "define", Sym, Box<Tree>, ")" => ActionFn(2);
assert!(__symbols.len() >= 5);
let __sym4 = __pop_Variant0(__symbols);
let __sym3 = __pop_Variant1(__symbols);
let __sym2 = __pop_Variant4(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols);
// Literal = Bool => ActionFn(8);
let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone();
let __end = __sym4.2.clone();
let __nt = super::__action2::<>(input, __sym0, __sym1, __sym2, __sym3, __sym4);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(5, 4)
let __end = __sym0.2.clone();
let __nt = super::__action8::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
(1, 3)
}
pub(crate) fn __reduce7<
'input,
@ -591,12 +657,12 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree = Literal => ActionFn(3);
let __sym0 = __pop_Variant2(__symbols);
// Num = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(10);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action3::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
let __nt = super::__action10::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
(1, 4)
}
pub(crate) fn __reduce8<
@ -609,12 +675,12 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree+ = Tree => ActionFn(9);
let __sym0 = __pop_Variant5(__symbols);
// Sym = r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"# => ActionFn(9);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action9::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(1, 5)
}
pub(crate) fn __reduce9<
@ -627,15 +693,119 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree+ = Tree+, Tree => ActionFn(10);
assert!(__symbols.len() >= 2);
let __sym1 = __pop_Variant5(__symbols);
// Tree = "(", Tree+, ")" => ActionFn(1);
assert!(__symbols.len() >= 3);
let __sym2 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant7(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym2.2.clone();
let __nt = super::__action1::<>(input, __sym0, __sym1, __sym2);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(3, 6)
}
pub(crate) fn __reduce10<
'input,
's,
>(
input: &'input str,
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree = "(", "define", Sym, BTree, ")" => ActionFn(2);
assert!(__symbols.len() >= 5);
let __sym4 = __pop_Variant0(__symbols);
let __sym3 = __pop_Variant1(__symbols);
let __sym2 = __pop_Variant5(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym4.2.clone();
let __nt = super::__action2::<>(input, __sym0, __sym1, __sym2, __sym3, __sym4);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(5, 6)
}
pub(crate) fn __reduce11<
'input,
's,
>(
input: &'input str,
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree = "(", "if", Tree, Tree, Tree, ")" => ActionFn(3);
assert!(__symbols.len() >= 6);
let __sym5 = __pop_Variant0(__symbols);
let __sym4 = __pop_Variant6(__symbols);
let __sym3 = __pop_Variant6(__symbols);
let __sym2 = __pop_Variant6(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym5.2.clone();
let __nt = super::__action3::<>(input, __sym0, __sym1, __sym2, __sym3, __sym4, __sym5);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(6, 6)
}
pub(crate) fn __reduce12<
'input,
's,
>(
input: &'input str,
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree = Literal => ActionFn(4);
let __sym0 = __pop_Variant3(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action4::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(1, 6)
}
pub(crate) fn __reduce13<
'input,
's,
>(
input: &'input str,
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree+ = Tree => ActionFn(14);
let __sym0 = __pop_Variant6(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action14::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant7(__nt), __end));
(1, 7)
}
pub(crate) fn __reduce14<
'input,
's,
>(
input: &'input str,
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>,
_: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize)
{
// Tree+ = Tree+, Tree => ActionFn(15);
assert!(__symbols.len() >= 2);
let __sym1 = __pop_Variant6(__symbols);
let __sym0 = __pop_Variant7(__symbols);
let __start = __sym0.0.clone();
let __end = __sym1.2.clone();
let __nt = super::__action10::<>(input, __sym0, __sym1);
__symbols.push((__start, __Symbol::Variant6(__nt), __end));
(2, 5)
let __nt = super::__action15::<>(input, __sym0, __sym1);
__symbols.push((__start, __Symbol::Variant7(__nt), __end));
(2, 7)
}
}
pub(crate) use self::__parse__Tree::TreeParser;
@ -653,9 +823,12 @@ mod __intern_token {
let __strs: &[(&str, bool)] = &[
("^([0-9]+(\\.[0-9]+)?)", false),
("^([!\\$-\\&\\*-\\+\\--/:<-Z\\^-_a-z\\~][!\\$-\\&\\*-\\+\\--:<-Z\\^-_a-z\\~]*)", false),
("^(\\#f)", false),
("^(\\#t)", false),
("^(\\()", false),
("^(\\))", false),
("^(define)", false),
("^(if)", false),
(r"^(\s*)", true),
];
__lalrpop_util::lexer::MatcherBuilder::new(__strs.iter().copied()).unwrap()
@ -709,6 +882,23 @@ fn __action2<
fn __action3<
'input,
's,
>(
input: &'input str,
(_, _, _): (usize, &'input str, usize),
(_, _, _): (usize, &'input str, usize),
(_, __0, _): (usize, Tree, usize),
(_, __1, _): (usize, Tree, usize),
(_, __2, _): (usize, Tree, usize),
(_, _, _): (usize, &'input str, usize),
) -> Tree
{
Tree::If(Box::new([__0, __1, __2]))
}
#[allow(unused_variables)]
fn __action4<
'input,
's,
>(
input: &'input str,
(_, __0, _): (usize, Literal, usize),
@ -718,7 +908,19 @@ fn __action3<
}
#[allow(unused_variables)]
fn __action4<
fn __action5<
'input,
's,
>(
input: &'input str,
(_, __0, _): (usize, Box<Tree>, usize),
) -> Box<Tree>
{
__0
}
#[allow(unused_variables)]
fn __action6<
'input,
's,
>(
@ -730,7 +932,7 @@ fn __action4<
}
#[allow(unused_variables)]
fn __action5<
fn __action7<
'input,
's,
>(
@ -742,7 +944,19 @@ fn __action5<
}
#[allow(unused_variables)]
fn __action6<
fn __action8<
'input,
's,
>(
input: &'input str,
(_, __0, _): (usize, bool, usize),
) -> Literal
{
Literal::Bool(__0)
}
#[allow(unused_variables)]
fn __action9<
'input,
's,
>(
@ -754,7 +968,7 @@ fn __action6<
}
#[allow(unused_variables)]
fn __action7<
fn __action10<
'input,
's,
>(
@ -766,7 +980,31 @@ fn __action7<
}
#[allow(unused_variables)]
fn __action8<
fn __action11<
'input,
's,
>(
input: &'input str,
(_, __0, _): (usize, &'input str, usize),
) -> bool
{
true
}
#[allow(unused_variables)]
fn __action12<
'input,
's,
>(
input: &'input str,
(_, __0, _): (usize, &'input str, usize),
) -> bool
{
false
}
#[allow(unused_variables)]
fn __action13<
'input,
's,
>(
@ -778,7 +1016,7 @@ fn __action8<
}
#[allow(unused_variables)]
fn __action9<
fn __action14<
'input,
's,
>(
@ -790,7 +1028,7 @@ fn __action9<
}
#[allow(unused_variables)]
fn __action10<
fn __action15<
'input,
's,
>(

View File

@ -1,7 +1,10 @@
#![feature(let_else)]
#![feature(array_windows)]
#![feature(box_patterns)]
mod grammar;
use debug2::dbg;
use rustyline::validate::{
MatchingBracketValidator, ValidationContext, ValidationResult, Validator,
};
@ -9,22 +12,11 @@ use rustyline::Editor;
use rustyline_derive::{Completer, Helper, Highlighter, Hinter};
use std::collections::HashMap;
#[derive(Completer, Helper, Highlighter, Hinter)]
struct InputValidator {
brackets: MatchingBracketValidator,
}
impl Validator for InputValidator {
fn validate(&self, ctx: &mut ValidationContext) -> rustyline::Result<ValidationResult> {
self.brackets.validate(ctx)
}
}
use debug2::dbg;
#[derive(Debug, debug2::Debug, PartialEq)]
enum Tree {
Leaf(Literal),
Define(String, Box<Tree>),
If(Box<[Tree; 3]>),
Branch(Vec<Tree>),
}
@ -32,6 +24,7 @@ enum Tree {
enum Literal {
Sym(String),
Num(f64),
Bool(bool),
}
#[derive(Debug)]
@ -47,14 +40,31 @@ type Func = fn(&[Value]) -> Result<Value, RTError>;
enum Value {
Num(f64),
Func(Func),
Bool(bool),
NotAValue,
}
impl PartialEq for Value {
fn eq(&self, other: &Self) -> bool {
use Value::*;
match (self, other) {
(Num(l), Num(r)) => l == r,
(Num(_), _) => false,
(Func(l), Func(r)) => *l as usize == *r as usize,
(Func(_), _) => false,
(Bool(l), Bool(r)) => l == r,
(Bool(_), _) => false,
(NotAValue, _) => panic!("Trap value"),
}
}
}
impl std::fmt::Debug for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Num(n) => n.fmt(f),
Self::Func(_) => f.write_str("#<procedure>"),
Self::Bool(b) => f.write_str(if *b { "#t" } else { "#f" }),
Self::NotAValue => Ok(()),
}
}
@ -76,6 +86,14 @@ impl Value {
Err(RTError("Expected a function".to_owned()))
}
}
fn as_bool(&self) -> Result<bool, RTError> {
if let Self::Bool(b) = self {
Ok(*b)
} else {
Err(RTError("Expected a bool".to_owned()))
}
}
}
struct Env {
@ -107,6 +125,7 @@ fn eval(t: &Tree, env: &mut Env) -> Result<Value, RTError> {
None => return err(format!("Undefined variable `{}`", s)),
},
Literal::Num(v) => Value::Num(*v),
Literal::Bool(b) => Value::Bool(*b),
},
Tree::Branch(args) => {
let Some(fun) = args.get(0) else { return err("No argument given".to_owned()) };
@ -123,31 +142,23 @@ fn eval(t: &Tree, env: &mut Env) -> Result<Value, RTError> {
env.vars.insert(name.to_owned(), val);
Value::NotAValue
}
Tree::If(box [cond, tcase, fcase]) => {
let b = eval(cond, env)?.as_bool()?;
let body = if b { tcase } else { fcase };
eval(body, env)?
}
})
}
// fn eval(t: &Tree) -> f64 {
// match t {
// Tree::Val(v) => *v,
// Tree::Add(vs) => vs.iter().map(eval).sum(),
// Tree::Mul(vs) => vs.iter().map(eval).product(),
// Tree::Sub(vs) => eval(&vs[0]) - vs[1..].iter().map(eval).sum::<f64>(),
// Tree::Div(vs) => eval(&vs[0]) / vs[1..].iter().map(eval).product::<f64>(),
// }
// }
fn default_env() -> Env {
let mut vars = HashMap::new();
// vars.insert("+".to_owned(), prims::add);
// vars.insert("-".to_owned(), prims::sub);
// vars.insert("*".to_owned(), prims::mul);
// vars.insert("/".to_owned(), prims::div);
for (name, fun) in [
("*", prims::mul as Func),
("+", prims::add as Func),
("-", prims::sub as Func),
("/", prims::div as Func),
("=", prims::equals as Func),
] {
vars.insert(name.to_owned(), Value::Func(fun));
}
@ -189,6 +200,10 @@ mod prims {
let rest = add(&args[1..])?.as_num().unwrap();
Ok(Value::Num(init - rest))
}
pub(crate) fn equals(args: &[Value]) -> Result<Value, RTError> {
Ok(Value::Bool(args.array_windows().all(|[l, r]| l == r)))
}
}
// #[cfg(test)]
@ -235,3 +250,14 @@ mod prims {
// );
// }
// }
#[derive(Completer, Helper, Highlighter, Hinter)]
struct InputValidator {
brackets: MatchingBracketValidator,
}
impl Validator for InputValidator {
fn validate(&self, ctx: &mut ValidationContext) -> rustyline::Result<ValidationResult> {
self.brackets.validate(ctx)
}
}