Compare commits

..

No commits in common. "969c526d89bb0c8b058e1aa17ed4fa03fcc1fccd" and "eb7a23672074476d17bfe0332442eff98de6a901" have entirely different histories.

4 changed files with 415 additions and 448 deletions

View File

@ -1 +0,0 @@
nightly-2021-12-16

View File

@ -1,21 +1,12 @@
use crate::{Tree, Literal}; use crate::Tree;
grammar<'s>(); grammar<'s>();
pub(crate) Tree: Tree = { pub Tree: Tree = {
"(" <Tree+> ")" => Tree::Branch(<>), "(" "+" <Tree*> ")" => Tree::Add(<>),
"(" "define" <Sym> <Box<Tree>> ")" => Tree::Define(<>), "(" "-" <Tree+> ")" => Tree::Sub(<>),
Literal => Tree::Leaf(<>), "(" "*" <Tree*> ")" => Tree::Mul(<>),
"(" "/" <Tree+> ")" => Tree::Div(<>),
r"[0-9]+(\.[0-9]+)?" => Tree::Val(<>.parse().unwrap()),
} }
Literal: Literal = {
Sym => Literal::Sym(<>),
Num => Literal::Num(<>),
}
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() }

View File

@ -1,6 +1,6 @@
// auto-generated: "lalrpop 0.19.6" // auto-generated: "lalrpop 0.19.6"
// sha3: 5c17121d6330bf8eebfa9cdfd4782fcc522dc2e0de3d264435b7dabb6e5fde // sha3: df1d4c73d92562a3473f57d776bdf582379e4cd2914b23c96b97e851e4c77
use crate::{Tree, Literal}; use crate::Tree;
#[allow(unused_extern_crates)] #[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util; extern crate lalrpop_util as __lalrpop_util;
#[allow(unused_imports)] #[allow(unused_imports)]
@ -12,7 +12,7 @@ extern crate alloc;
mod __parse__Tree { mod __parse__Tree {
#![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)] #![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)]
use crate::{Tree, Literal}; use crate::Tree;
#[allow(unused_extern_crates)] #[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util; extern crate lalrpop_util as __lalrpop_util;
#[allow(unused_imports)] #[allow(unused_imports)]
@ -24,51 +24,53 @@ mod __parse__Tree {
pub(crate) enum __Symbol<'input> pub(crate) enum __Symbol<'input>
{ {
Variant0(&'input str), Variant0(&'input str),
Variant1(Box<Tree>), Variant1(Tree),
Variant2(Literal), Variant2(alloc::vec::Vec<Tree>),
Variant3(f64),
Variant4(String),
Variant5(Tree),
Variant6(alloc::vec::Vec<Tree>),
} }
const __ACTION: &[i8] = &[ const __ACTION: &[i8] = &[
// State 0 // State 0
2, 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 12,
// State 1 // State 1
2, 0, 4, 10, 11, 11, 14, 0, 0, 0, 0, 12,
// State 2 // State 2
2, 14, 0, 10, 11, 11, 15, 0, 0, 0, 0, 12,
// State 3 // State 3
0, 0, 0, 0, 11, 11, 0, 0, 0, 0, 0, 12,
// State 4 // State 4
2, 0, 0, 10, 11, 11, 0, 0, 0, 0, 0, 12,
// State 5 // State 5
-8, -8, 0, -8, -8, 11, 17, 0, 0, 0, 0, 12,
// State 6 // State 6
-3, -3, 0, -3, -3, 11, 18, 0, 0, 0, 0, 12,
// State 7 // State 7
-2, -2, 0, -2, -2, 11, 19, 0, 0, 0, 0, 12,
// State 8 // State 8
0, 0, 0, 0, 0, 11, 20, 0, 0, 0, 0, 12,
// State 9 // State 9
-4, -4, 0, -4, -4, 0, 0, 0, 0, 0, 0, 0,
// State 10 // State 10
-5, -5, 0, -5, -5, 0, 0, 2, 3, 4, 5, 0,
// State 11 // State 11
-9, -9, 0, -9, -9, -7, -7, 0, 0, 0, 0, -7,
// State 12 // State 12
-10, -10, 0, -10, -10, -10, -10, 0, 0, 0, 0, -10,
// State 13 // State 13
-6, -6, 0, -6, -6, -4, -4, 0, 0, 0, 0, -4,
// State 14 // State 14
0, 17, 0, 0, 0, -1, -1, 0, 0, 0, 0, -1,
// State 15 // State 15
0, -1, 0, 0, 0, -11, -11, 0, 0, 0, 0, -11,
// State 16 // State 16
-7, -7, 0, -7, -7, -5, -5, 0, 0, 0, 0, -5,
// State 17
-2, -2, 0, 0, 0, 0, -2,
// State 18
-3, -3, 0, 0, 0, 0, -3,
// State 19
-6, -6, 0, 0, 0, 0, -6,
]; ];
fn __action(state: i8, integer: usize) -> i8 { fn __action(state: i8, integer: usize) -> i8 {
__ACTION[(state as usize) * 5 + integer] __ACTION[(state as usize) * 7 + integer]
} }
const __EOF_ACTION: &[i8] = &[ const __EOF_ACTION: &[i8] = &[
// State 0 // State 0
@ -82,46 +84,49 @@ mod __parse__Tree {
// State 4 // State 4
0, 0,
// State 5 // State 5
-8,
// State 6
-3,
// State 7
-2,
// State 8
-11,
// State 9
-4,
// State 10
-5,
// State 11
0, 0,
// State 6
0,
// State 7
0,
// State 8
0,
// State 9
-12,
// State 10
0,
// State 11
-7,
// State 12 // State 12
0, 0,
// State 13 // State 13
-6, -4,
// State 14 // State 14
0, -1,
// State 15 // State 15
0, 0,
// State 16 // State 16
-7, -5,
// State 17
-2,
// State 18
-3,
// State 19
-6,
]; ];
fn __goto(state: i8, nt: usize) -> i8 { fn __goto(state: i8, nt: usize) -> i8 {
match nt { match nt {
0 => 14, 0 => match state {
1 => 5, 1..=4 => 12,
2 => 6, 5..=8 => 15,
3 => match state { _ => 9,
3 => 4,
_ => 7,
}, },
4 => match state { 2 => match state {
1 => 11, 2 => 6,
2 => 12, 3 => 7,
4 => 15, 4 => 8,
_ => 8, _ => 5,
}, },
5 => 2,
_ => 0, _ => 0,
} }
} }
@ -129,9 +134,11 @@ mod __parse__Tree {
const __TERMINAL: &[&str] = &[ const __TERMINAL: &[&str] = &[
r###""(""###, r###""(""###,
r###"")""###, r###"")""###,
r###""define""###, r###""*""###,
r###""+""###,
r###""-""###,
r###""/""###,
r###"r#"[0-9]+(\\.[0-9]+)?"#"###, r###"r#"[0-9]+(\\.[0-9]+)?"#"###,
r###"r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"#"###,
]; ];
__TERMINAL.iter().enumerate().filter_map(|(index, terminal)| { __TERMINAL.iter().enumerate().filter_map(|(index, terminal)| {
let next_state = __action(__state, index); let next_state = __action(__state, index);
@ -184,7 +191,7 @@ mod __parse__Tree {
#[inline] #[inline]
fn error_action(&self, state: i8) -> i8 { fn error_action(&self, state: i8) -> i8 {
__action(state, 5 - 1) __action(state, 7 - 1)
} }
#[inline] #[inline]
@ -248,11 +255,13 @@ mod __parse__Tree {
) -> Option<usize> ) -> Option<usize>
{ {
match *__token { match *__token {
Token(2, _) if true => Some(0), Token(1, _) if true => Some(0),
Token(3, _) if true => Some(1), Token(2, _) if true => Some(1),
Token(4, _) if true => Some(2), Token(3, _) if true => Some(2),
Token(0, _) if true => Some(3), Token(4, _) if true => Some(3),
Token(1, _) if true => Some(4), Token(5, _) if true => Some(4),
Token(6, _) if true => Some(5),
Token(0, _) if true => Some(6),
_ => None, _ => None,
} }
} }
@ -266,20 +275,20 @@ mod __parse__Tree {
) -> __Symbol<'input> ) -> __Symbol<'input>
{ {
match __token_index { match __token_index {
0 | 1 | 2 | 3 | 4 => match __token { 0 | 1 | 2 | 3 | 4 | 5 | 6 => match __token {
Token(2, __tok0) | Token(3, __tok0) | Token(4, __tok0) | Token(0, __tok0) | Token(1, __tok0) if true => __Symbol::Variant0(__tok0), Token(1, __tok0) | Token(2, __tok0) | Token(3, __tok0) | Token(4, __tok0) | Token(5, __tok0) | Token(6, __tok0) | Token(0, __tok0) if true => __Symbol::Variant0(__tok0),
_ => unreachable!(), _ => unreachable!(),
}, },
_ => unreachable!(), _ => unreachable!(),
} }
} }
pub(crate) struct TreeParser { pub struct TreeParser {
builder: __lalrpop_util::lexer::MatcherBuilder, builder: __lalrpop_util::lexer::MatcherBuilder,
_priv: (), _priv: (),
} }
impl TreeParser { impl TreeParser {
pub(crate) fn new() -> TreeParser { pub fn new() -> TreeParser {
let __builder = super::__intern_token::new_builder(); let __builder = super::__intern_token::new_builder();
TreeParser { TreeParser {
builder: __builder, builder: __builder,
@ -288,7 +297,7 @@ mod __parse__Tree {
} }
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) fn parse< pub fn parse<
'input, 'input,
's, 's,
>( >(
@ -350,8 +359,11 @@ mod __parse__Tree {
__reduce9(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>) __reduce9(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
} }
10 => { 10 => {
__reduce10(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>)
}
11 => {
// __Tree = Tree => ActionFn(0); // __Tree = Tree => ActionFn(0);
let __sym0 = __pop_Variant5(__symbols); let __sym0 = __pop_Variant1(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym0.2.clone();
let __nt = super::__action0::<>(input, __sym0); let __nt = super::__action0::<>(input, __sym0);
@ -374,7 +386,7 @@ mod __parse__Tree {
'input, 'input,
>( >(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, Box<Tree>, usize) ) -> (usize, Tree, usize)
{ {
match __symbols.pop() { match __symbols.pop() {
Some((__l, __Symbol::Variant1(__v), __r)) => (__l, __v, __r), Some((__l, __Symbol::Variant1(__v), __r)) => (__l, __v, __r),
@ -385,54 +397,10 @@ mod __parse__Tree {
'input, 'input,
>( >(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> __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),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant5<
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, Tree, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant6<
'input,
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>
) -> (usize, alloc::vec::Vec<Tree>, usize) ) -> (usize, alloc::vec::Vec<Tree>, usize)
{ {
match __symbols.pop() { match __symbols.pop() {
Some((__l, __Symbol::Variant6(__v), __r)) => (__l, __v, __r), Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant3<
'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),
_ => __symbol_type_mismatch() _ => __symbol_type_mismatch()
} }
} }
@ -457,13 +425,16 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Box<Tree> = Tree => ActionFn(8); // Tree = "(", "+", ")" => ActionFn(10);
let __sym0 = __pop_Variant5(__symbols); assert!(__symbols.len() >= 3);
let __sym2 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym2.2.clone();
let __nt = super::__action8::<>(input, __sym0); let __nt = super::__action10::<>(input, __sym0, __sym1, __sym2);
__symbols.push((__start, __Symbol::Variant1(__nt), __end)); __symbols.push((__start, __Symbol::Variant1(__nt), __end));
(1, 0) (3, 0)
} }
pub(crate) fn __reduce1< pub(crate) fn __reduce1<
'input, 'input,
@ -475,13 +446,17 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Literal = Sym => ActionFn(4); // Tree = "(", "+", Tree+, ")" => ActionFn(11);
let __sym0 = __pop_Variant4(__symbols); assert!(__symbols.len() >= 4);
let __sym3 = __pop_Variant0(__symbols);
let __sym2 = __pop_Variant2(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym3.2.clone();
let __nt = super::__action4::<>(input, __sym0); let __nt = super::__action11::<>(input, __sym0, __sym1, __sym2, __sym3);
__symbols.push((__start, __Symbol::Variant2(__nt), __end)); __symbols.push((__start, __Symbol::Variant1(__nt), __end));
(1, 1) (4, 0)
} }
pub(crate) fn __reduce2< pub(crate) fn __reduce2<
'input, 'input,
@ -493,13 +468,17 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Literal = Num => ActionFn(5); // Tree = "(", "-", Tree+, ")" => ActionFn(2);
let __sym0 = __pop_Variant3(__symbols); assert!(__symbols.len() >= 4);
let __sym3 = __pop_Variant0(__symbols);
let __sym2 = __pop_Variant2(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym3.2.clone();
let __nt = super::__action5::<>(input, __sym0); let __nt = super::__action2::<>(input, __sym0, __sym1, __sym2, __sym3);
__symbols.push((__start, __Symbol::Variant2(__nt), __end)); __symbols.push((__start, __Symbol::Variant1(__nt), __end));
(1, 1) (4, 0)
} }
pub(crate) fn __reduce3< pub(crate) fn __reduce3<
'input, 'input,
@ -511,13 +490,16 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Num = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(7); // Tree = "(", "*", ")" => ActionFn(12);
assert!(__symbols.len() >= 3);
let __sym2 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym2.2.clone();
let __nt = super::__action7::<>(input, __sym0); let __nt = super::__action12::<>(input, __sym0, __sym1, __sym2);
__symbols.push((__start, __Symbol::Variant3(__nt), __end)); __symbols.push((__start, __Symbol::Variant1(__nt), __end));
(1, 2) (3, 0)
} }
pub(crate) fn __reduce4< pub(crate) fn __reduce4<
'input, 'input,
@ -529,13 +511,17 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Sym = r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"# => ActionFn(6); // Tree = "(", "*", Tree+, ")" => ActionFn(13);
assert!(__symbols.len() >= 4);
let __sym3 = __pop_Variant0(__symbols);
let __sym2 = __pop_Variant2(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym3.2.clone();
let __nt = super::__action6::<>(input, __sym0); let __nt = super::__action13::<>(input, __sym0, __sym1, __sym2, __sym3);
__symbols.push((__start, __Symbol::Variant4(__nt), __end)); __symbols.push((__start, __Symbol::Variant1(__nt), __end));
(1, 3) (4, 0)
} }
pub(crate) fn __reduce5< pub(crate) fn __reduce5<
'input, 'input,
@ -547,16 +533,17 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Tree = "(", Tree+, ")" => ActionFn(1); // Tree = "(", "/", Tree+, ")" => ActionFn(4);
assert!(__symbols.len() >= 3); assert!(__symbols.len() >= 4);
let __sym2 = __pop_Variant0(__symbols); let __sym3 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant6(__symbols); let __sym2 = __pop_Variant2(__symbols);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant0(__symbols); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym2.2.clone(); let __end = __sym3.2.clone();
let __nt = super::__action1::<>(input, __sym0, __sym1, __sym2); let __nt = super::__action4::<>(input, __sym0, __sym1, __sym2, __sym3);
__symbols.push((__start, __Symbol::Variant5(__nt), __end)); __symbols.push((__start, __Symbol::Variant1(__nt), __end));
(3, 4) (4, 0)
} }
pub(crate) fn __reduce6< pub(crate) fn __reduce6<
'input, 'input,
@ -568,18 +555,13 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Tree = "(", "define", Sym, Box<Tree>, ")" => ActionFn(2); // Tree = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(5);
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); let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym4.2.clone(); let __end = __sym0.2.clone();
let __nt = super::__action2::<>(input, __sym0, __sym1, __sym2, __sym3, __sym4); let __nt = super::__action5::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant5(__nt), __end)); __symbols.push((__start, __Symbol::Variant1(__nt), __end));
(5, 4) (1, 0)
} }
pub(crate) fn __reduce7< pub(crate) fn __reduce7<
'input, 'input,
@ -591,13 +573,12 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Tree = Literal => ActionFn(3); // Tree* = => ActionFn(8);
let __sym0 = __pop_Variant2(__symbols); let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default();
let __start = __sym0.0.clone(); let __end = __start.clone();
let __end = __sym0.2.clone(); let __nt = super::__action8::<>(input, &__start, &__end);
let __nt = super::__action3::<>(input, __sym0); __symbols.push((__start, __Symbol::Variant2(__nt), __end));
__symbols.push((__start, __Symbol::Variant5(__nt), __end)); (0, 1)
(1, 4)
} }
pub(crate) fn __reduce8< pub(crate) fn __reduce8<
'input, 'input,
@ -609,13 +590,13 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Tree+ = Tree => ActionFn(9); // Tree* = Tree+ => ActionFn(9);
let __sym0 = __pop_Variant5(__symbols); let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym0.2.clone(); let __end = __sym0.2.clone();
let __nt = super::__action9::<>(input, __sym0); let __nt = super::__action9::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant6(__nt), __end)); __symbols.push((__start, __Symbol::Variant2(__nt), __end));
(1, 5) (1, 1)
} }
pub(crate) fn __reduce9< pub(crate) fn __reduce9<
'input, 'input,
@ -627,22 +608,40 @@ mod __parse__Tree {
_: core::marker::PhantomData<(&'input (), &'s ())>, _: core::marker::PhantomData<(&'input (), &'s ())>,
) -> (usize, usize) ) -> (usize, usize)
{ {
// Tree+ = Tree+, Tree => ActionFn(10); // Tree+ = Tree => ActionFn(6);
let __sym0 = __pop_Variant1(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action6::<>(input, __sym0);
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
(1, 2)
}
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+ = Tree+, Tree => ActionFn(7);
assert!(__symbols.len() >= 2); assert!(__symbols.len() >= 2);
let __sym1 = __pop_Variant5(__symbols); let __sym1 = __pop_Variant1(__symbols);
let __sym0 = __pop_Variant6(__symbols); let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone(); let __start = __sym0.0.clone();
let __end = __sym1.2.clone(); let __end = __sym1.2.clone();
let __nt = super::__action10::<>(input, __sym0, __sym1); let __nt = super::__action7::<>(input, __sym0, __sym1);
__symbols.push((__start, __Symbol::Variant6(__nt), __end)); __symbols.push((__start, __Symbol::Variant2(__nt), __end));
(2, 5) (2, 2)
} }
} }
pub(crate) use self::__parse__Tree::TreeParser; pub use self::__parse__Tree::TreeParser;
#[cfg_attr(rustfmt, rustfmt_skip)] #[cfg_attr(rustfmt, rustfmt_skip)]
mod __intern_token { mod __intern_token {
#![allow(unused_imports)] #![allow(unused_imports)]
use crate::{Tree, Literal}; use crate::Tree;
#[allow(unused_extern_crates)] #[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util; extern crate lalrpop_util as __lalrpop_util;
#[allow(unused_imports)] #[allow(unused_imports)]
@ -652,10 +651,12 @@ mod __intern_token {
pub fn new_builder() -> __lalrpop_util::lexer::MatcherBuilder { pub fn new_builder() -> __lalrpop_util::lexer::MatcherBuilder {
let __strs: &[(&str, bool)] = &[ let __strs: &[(&str, bool)] = &[
("^([0-9]+(\\.[0-9]+)?)", false), ("^([0-9]+(\\.[0-9]+)?)", false),
("^([!\\$-\\&\\*-\\+\\--/:<-Z\\^-_a-z\\~][!\\$-\\&\\*-\\+\\--:<-Z\\^-_a-z\\~]*)", false),
("^(\\()", false), ("^(\\()", false),
("^(\\))", false), ("^(\\))", false),
("^(define)", false), ("^(\\*)", false),
("^(\\+)", false),
("^(\\-)", false),
("^(/)", false),
(r"^(\s*)", true), (r"^(\s*)", true),
]; ];
__lalrpop_util::lexer::MatcherBuilder::new(__strs.iter().copied()).unwrap() __lalrpop_util::lexer::MatcherBuilder::new(__strs.iter().copied()).unwrap()
@ -682,11 +683,12 @@ fn __action1<
>( >(
input: &'input str, input: &'input str,
(_, _, _): (usize, &'input str, usize), (_, _, _): (usize, &'input str, usize),
(_, _, _): (usize, &'input str, usize),
(_, __0, _): (usize, alloc::vec::Vec<Tree>, usize), (_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
(_, _, _): (usize, &'input str, usize), (_, _, _): (usize, &'input str, usize),
) -> Tree ) -> Tree
{ {
Tree::Branch(__0) Tree::Add(__0)
} }
#[allow(unused_variables)] #[allow(unused_variables)]
@ -697,12 +699,11 @@ fn __action2<
input: &'input str, input: &'input str,
(_, _, _): (usize, &'input str, usize), (_, _, _): (usize, &'input str, usize),
(_, _, _): (usize, &'input str, usize), (_, _, _): (usize, &'input str, usize),
(_, __0, _): (usize, String, usize), (_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
(_, __1, _): (usize, Box<Tree>, usize),
(_, _, _): (usize, &'input str, usize), (_, _, _): (usize, &'input str, usize),
) -> Tree ) -> Tree
{ {
Tree::Define(__0, __1) Tree::Sub(__0)
} }
#[allow(unused_variables)] #[allow(unused_variables)]
@ -711,10 +712,13 @@ fn __action3<
's, 's,
>( >(
input: &'input str, input: &'input str,
(_, __0, _): (usize, Literal, usize), (_, _, _): (usize, &'input str, usize),
(_, _, _): (usize, &'input str, usize),
(_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
(_, _, _): (usize, &'input str, usize),
) -> Tree ) -> Tree
{ {
Tree::Leaf(__0) Tree::Mul(__0)
} }
#[allow(unused_variables)] #[allow(unused_variables)]
@ -723,10 +727,13 @@ fn __action4<
's, 's,
>( >(
input: &'input str, input: &'input str,
(_, __0, _): (usize, String, usize), (_, _, _): (usize, &'input str, usize),
) -> Literal (_, _, _): (usize, &'input str, usize),
(_, __0, _): (usize, alloc::vec::Vec<Tree>, usize),
(_, _, _): (usize, &'input str, usize),
) -> Tree
{ {
Literal::Sym(__0) Tree::Div(__0)
} }
#[allow(unused_variables)] #[allow(unused_variables)]
@ -735,52 +742,16 @@ fn __action5<
's, 's,
>( >(
input: &'input str, input: &'input str,
(_, __0, _): (usize, f64, usize), (_, __0, _): (usize, &'input str, usize),
) -> Literal ) -> Tree
{ {
Literal::Num(__0) Tree::Val(__0.parse().unwrap())
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn __action6< fn __action6<
'input, 'input,
's, 's,
>(
input: &'input str,
(_, __0, _): (usize, &'input str, usize),
) -> String
{
__0.to_owned()
}
#[allow(unused_variables)]
fn __action7<
'input,
's,
>(
input: &'input str,
(_, __0, _): (usize, &'input str, usize),
) -> f64
{
__0.parse().unwrap()
}
#[allow(unused_variables)]
fn __action8<
'input,
's,
>(
input: &'input str,
(_, __0, _): (usize, Tree, usize),
) -> Box<Tree>
{
Box::new(__0)
}
#[allow(unused_variables)]
fn __action9<
'input,
's,
>( >(
input: &'input str, input: &'input str,
(_, __0, _): (usize, Tree, usize), (_, __0, _): (usize, Tree, usize),
@ -790,7 +761,7 @@ fn __action9<
} }
#[allow(unused_variables)] #[allow(unused_variables)]
fn __action10< fn __action7<
'input, 'input,
's, 's,
>( >(
@ -802,6 +773,143 @@ fn __action10<
{ let mut v = v; v.push(e); v } { let mut v = v; v.push(e); v }
} }
#[allow(unused_variables)]
fn __action8<
'input,
's,
>(
input: &'input str,
__lookbehind: &usize,
__lookahead: &usize,
) -> alloc::vec::Vec<Tree>
{
alloc::vec![]
}
#[allow(unused_variables)]
fn __action9<
'input,
's,
>(
input: &'input str,
(_, v, _): (usize, alloc::vec::Vec<Tree>, usize),
) -> alloc::vec::Vec<Tree>
{
v
}
#[allow(unused_variables)]
fn __action10<
'input,
's,
>(
input: &'input str,
__0: (usize, &'input str, usize),
__1: (usize, &'input str, usize),
__2: (usize, &'input str, usize),
) -> Tree
{
let __start0 = __1.2.clone();
let __end0 = __2.0.clone();
let __temp0 = __action8(
input,
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action1(
input,
__0,
__1,
__temp0,
__2,
)
}
#[allow(unused_variables)]
fn __action11<
'input,
's,
>(
input: &'input str,
__0: (usize, &'input str, usize),
__1: (usize, &'input str, usize),
__2: (usize, alloc::vec::Vec<Tree>, usize),
__3: (usize, &'input str, usize),
) -> Tree
{
let __start0 = __2.0.clone();
let __end0 = __2.2.clone();
let __temp0 = __action9(
input,
__2,
);
let __temp0 = (__start0, __temp0, __end0);
__action1(
input,
__0,
__1,
__temp0,
__3,
)
}
#[allow(unused_variables)]
fn __action12<
'input,
's,
>(
input: &'input str,
__0: (usize, &'input str, usize),
__1: (usize, &'input str, usize),
__2: (usize, &'input str, usize),
) -> Tree
{
let __start0 = __1.2.clone();
let __end0 = __2.0.clone();
let __temp0 = __action8(
input,
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action3(
input,
__0,
__1,
__temp0,
__2,
)
}
#[allow(unused_variables)]
fn __action13<
'input,
's,
>(
input: &'input str,
__0: (usize, &'input str, usize),
__1: (usize, &'input str, usize),
__2: (usize, alloc::vec::Vec<Tree>, usize),
__3: (usize, &'input str, usize),
) -> Tree
{
let __start0 = __2.0.clone();
let __end0 = __2.2.clone();
let __temp0 = __action9(
input,
__2,
);
let __temp0 = (__start0, __temp0, __end0);
__action3(
input,
__0,
__1,
__temp0,
__3,
)
}
pub trait __ToTriple<'input, 's, > { pub trait __ToTriple<'input, 's, > {
fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError<usize, Token<'input>, &'static str>>; fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError<usize, Token<'input>, &'static str>>;
} }

View File

@ -1,13 +1,21 @@
#![feature(let_else)]
mod grammar; mod grammar;
use debug2::dbg;
#[derive(Debug, debug2::Debug, PartialEq)]
pub enum Tree {
Val(f64),
Add(Vec<Tree>),
Sub(Vec<Tree>),
Mul(Vec<Tree>),
Div(Vec<Tree>),
}
use rustyline::validate::{ use rustyline::validate::{
MatchingBracketValidator, ValidationContext, ValidationResult, Validator, MatchingBracketValidator, ValidationContext, ValidationResult, Validator,
}; };
use rustyline::Editor; use rustyline::{Editor, Result};
use rustyline_derive::{Completer, Helper, Highlighter, Hinter}; use rustyline_derive::{Completer, Helper, Highlighter, Hinter};
use std::collections::HashMap;
#[derive(Completer, Helper, Highlighter, Hinter)] #[derive(Completer, Helper, Highlighter, Hinter)]
struct InputValidator { struct InputValidator {
@ -15,223 +23,84 @@ struct InputValidator {
} }
impl Validator for InputValidator { impl Validator for InputValidator {
fn validate(&self, ctx: &mut ValidationContext) -> rustyline::Result<ValidationResult> { fn validate(&self, ctx: &mut ValidationContext) -> Result<ValidationResult> {
self.brackets.validate(ctx) self.brackets.validate(ctx)
} }
} }
use debug2::dbg;
#[derive(Debug, debug2::Debug, PartialEq)]
enum Tree {
Leaf(Literal),
Define(String, Box<Tree>),
Branch(Vec<Tree>),
}
#[derive(Debug, debug2::Debug, PartialEq)]
enum Literal {
Sym(String),
Num(f64),
}
#[derive(Debug)]
struct RTError(String);
fn err<T>(s: String) -> Result<T, RTError> {
Err(RTError(s))
}
type Func = fn(&[Value]) -> Result<Value, RTError>;
#[derive(Clone, Copy)]
enum Value {
Num(f64),
Func(Func),
NotAValue,
}
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::NotAValue => Ok(()),
}
}
}
impl Value {
fn as_num(&self) -> Result<f64, RTError> {
if let Self::Num(n) = self {
Ok(*n)
} else {
Err(RTError("Expected a number".to_owned()))
}
}
fn as_func(&self) -> Result<Func, RTError> {
if let Self::Func(f) = self {
Ok(*f)
} else {
Err(RTError("Expected a function".to_owned()))
}
}
}
struct Env {
vars: HashMap<String, Value>,
}
fn main() { fn main() {
// let src = std::fs::read_to_string(std::env::args().nth(1).unwrap()).unwrap();
// let tree = grammar::TreeParser::new().parse(&src);
// let t = dbg!(tree.unwrap());
// println!("{}", eval(&t));
let mut rl = Editor::new(); let mut rl = Editor::new();
rl.set_helper(Some(InputValidator { rl.set_helper(Some(InputValidator {
brackets: MatchingBracketValidator::new(), brackets: MatchingBracketValidator::new(),
})); }));
let mut env = default_env();
while let Ok(line) = rl.readline("> ") { while let Ok(line) = rl.readline("> ") {
rl.add_history_entry(&line); rl.add_history_entry(&line);
let tree = grammar::TreeParser::new().parse(&line).unwrap(); let tree = grammar::TreeParser::new().parse(&line).unwrap();
dbg!(&tree); dbg!(&tree);
println!("< {:?}", eval(&tree, &mut env)) println!("< {}", eval(&tree))
} }
} }
fn eval(t: &Tree, env: &mut Env) -> Result<Value, RTError> { fn eval(t: &Tree) -> f64 {
Ok(match t { match t {
Tree::Leaf(l) => match l { Tree::Val(v) => *v,
Literal::Sym(s) => match env.vars.get(s) { Tree::Add(vs) => vs.iter().map(eval).sum(),
Some(&v) => v, Tree::Mul(vs) => vs.iter().map(eval).product(),
None => return err(format!("Undefined variable `{}`", s)), 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>(),
Literal::Num(v) => Value::Num(*v),
},
Tree::Branch(args) => {
let Some(fun) = args.get(0) else { return err("No argument given".to_owned()) };
let fun = eval(fun, env)?.as_func()?;
let args = args
.iter()
.skip(1)
.map(|a| eval(a, env))
.collect::<Result<Vec<_>, _>>()?;
return fun(&args);
}
Tree::Define(name, to) => {
let val = eval(to, env)?;
env.vars.insert(name.to_owned(), val);
Value::NotAValue
}
})
}
// 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),
] {
vars.insert(name.to_owned(), Value::Func(fun));
}
Env { vars }
}
mod prims {
use crate::{RTError, Value};
pub(crate) fn add(args: &[Value]) -> Result<Value, RTError> {
args.iter()
.map(Value::as_num)
.try_fold(0.0, |a, b| Ok(a + b?))
.map(Value::Num)
}
pub(crate) fn mul(args: &[Value]) -> Result<Value, RTError> {
args.iter()
.map(Value::as_num)
.try_fold(1.0, |a, b| Ok(a * b?))
.map(Value::Num)
}
pub(crate) fn div(args: &[Value]) -> Result<Value, RTError> {
let init = args
.get(0)
.ok_or_else(|| RTError("`div` needs at least one argument".to_owned()))?
.as_num()?;
let rest = mul(&args[1..])?.as_num().unwrap();
Ok(Value::Num(init / rest))
}
pub(crate) fn sub(args: &[Value]) -> Result<Value, RTError> {
let init = args
.get(0)
.ok_or_else(|| RTError("`sub` needs at least one argument".to_owned()))?
.as_num()?;
let rest = add(&args[1..])?.as_num().unwrap();
Ok(Value::Num(init - rest))
} }
} }
// #[cfg(test)] #[cfg(test)]
// mod tests { mod tests {
// use super::*; use super::*;
// #[test] #[test]
// fn simple_math_space() { fn simple_math_space() {
// let t = grammar::TreeParser::new() let t = grammar::TreeParser::new()
// .parse("( + 1 2 ( / 2 3 4 5) )") .parse("( + 1 2 ( / 2 3 4 5) )")
// .unwrap(); .unwrap();
// assert_eq!( assert_eq!(
// t, t,
// Tree::Add(vec![ Tree::Add(vec![
// Tree::Val(1.0), Tree::Val(1.0),
// Tree::Val(2.0), Tree::Val(2.0),
// Tree::Div(vec![ Tree::Div(vec![
// Tree::Val(2.0), Tree::Val(2.0),
// Tree::Val(3.0), Tree::Val(3.0),
// Tree::Val(4.0), Tree::Val(4.0),
// Tree::Val(5.0), Tree::Val(5.0),
// ]) ])
// ]) ])
// ); );
// } }
// #[test] #[test]
// fn simple_math_dence() { fn simple_math_dence() {
// let t = grammar::TreeParser::new() let t = grammar::TreeParser::new()
// .parse("(+ 1 2 (/ 2 3 4 5))") .parse("(+ 1 2 (/ 2 3 4 5))")
// .unwrap(); .unwrap();
// assert_eq!( assert_eq!(
// t, t,
// Tree::Add(vec![ Tree::Add(vec![
// Tree::Val(1.0), Tree::Val(1.0),
// Tree::Val(2.0), Tree::Val(2.0),
// Tree::Div(vec![ Tree::Div(vec![
// Tree::Val(2.0), Tree::Val(2.0),
// Tree::Val(3.0), Tree::Val(3.0),
// Tree::Val(4.0), Tree::Val(4.0),
// Tree::Val(5.0), Tree::Val(5.0),
// ]) ])
// ]) ])
// ); );
// } }
// } }