Bools and ifs
parent
969c526d89
commit
d437e1297c
|
@ -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,
|
||||
}
|
506
src/grammar.rs
506
src/grammar.rs
|
@ -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,
|
||||
>(
|
||||
|
|
78
src/main.rs
78
src/main.rs
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue