diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 0000000..ee9da97 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly-2021-12-16 \ No newline at end of file diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index b44909a..a764377 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -1,12 +1,19 @@ -use crate::Tree; +use crate::{Tree, Literal}; grammar<'s>(); -pub Tree: Tree = { - "(" "+" ")" => Tree::Add(<>), - "(" "-" ")" => Tree::Sub(<>), - "(" "*" ")" => Tree::Mul(<>), - "(" "/" ")" => Tree::Div(<>), - r"[0-9]+(\.[0-9]+)?" => Tree::Val(<>.parse().unwrap()), +pub(crate) Tree: Tree = { + "(" ")" => Tree::Branch(<>), + Literal => Tree::Leaf(<>), } + + +Literal: Literal = { + Sym => Literal::Sym(<>), + Num => Literal::Num(<>), +} + + +Sym: String = { r"[A-Za-z!$%&*+\-./:<=>?@^_~][A-Za-z!$%&*+\-./:<=>?@^_~0-9]*" => <>.to_owned() } +Num: f64 = { r"[0-9]+(\.[0-9]+)?" => <>.parse().unwrap() } \ No newline at end of file diff --git a/src/grammar.rs b/src/grammar.rs index 0675b2f..00706c6 100644 --- a/src/grammar.rs +++ b/src/grammar.rs @@ -1,18 +1,18 @@ // auto-generated: "lalrpop 0.19.6" -// sha3: df1d4c73d92562a3473f57d776bdf582379e4cd2914b23c96b97e851e4c77 -use crate::Tree; +// sha3: 7ba7fe6c5aa9717ac4d235512a3b2cf277d6214df69326d5888744c6ef49d74 +use crate::{Literal, Tree}; #[allow(unused_extern_crates)] extern crate lalrpop_util as __lalrpop_util; #[allow(unused_imports)] use self::__lalrpop_util::state_machine as __state_machine; -extern crate core; extern crate alloc; +extern crate core; #[cfg_attr(rustfmt, rustfmt_skip)] mod __parse__Tree { #![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)] - use crate::Tree; + use crate::{Tree, Literal}; #[allow(unused_extern_crates)] extern crate lalrpop_util as __lalrpop_util; #[allow(unused_imports)] @@ -24,53 +24,40 @@ mod __parse__Tree { pub(crate) enum __Symbol<'input> { Variant0(&'input str), - Variant1(Tree), - Variant2(alloc::vec::Vec), + Variant1(Literal), + Variant2(f64), + Variant3(String), + Variant4(Tree), + Variant5(alloc::vec::Vec), } const __ACTION: &[i8] = &[ // State 0 - 11, 0, 0, 0, 0, 0, 12, + 2, 0, 8, 9, // State 1 - 11, 14, 0, 0, 0, 0, 12, + 2, 0, 8, 9, // State 2 - 11, 15, 0, 0, 0, 0, 12, + 2, 12, 8, 9, // State 3 - 11, 0, 0, 0, 0, 0, 12, + -6, -6, -6, -6, // State 4 - 11, 0, 0, 0, 0, 0, 12, + -2, -2, -2, -2, // State 5 - 11, 17, 0, 0, 0, 0, 12, + -1, -1, -1, -1, // State 6 - 11, 18, 0, 0, 0, 0, 12, + 0, 0, 0, 0, // State 7 - 11, 19, 0, 0, 0, 0, 12, + -3, -3, -3, -3, // State 8 - 11, 20, 0, 0, 0, 0, 12, + -4, -4, -4, -4, // State 9 - 0, 0, 0, 0, 0, 0, 0, + -7, -7, -7, -7, // State 10 - 0, 0, 2, 3, 4, 5, 0, + -8, -8, -8, -8, // State 11 - -7, -7, 0, 0, 0, 0, -7, - // State 12 - -10, -10, 0, 0, 0, 0, -10, - // State 13 - -4, -4, 0, 0, 0, 0, -4, - // State 14 - -1, -1, 0, 0, 0, 0, -1, - // State 15 - -11, -11, 0, 0, 0, 0, -11, - // State 16 - -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, + -5, -5, -5, -5, ]; fn __action(state: i8, integer: usize) -> i8 { - __ACTION[(state as usize) * 7 + integer] + __ACTION[(state as usize) * 4 + integer] } const __EOF_ACTION: &[i8] = &[ // State 0 @@ -80,53 +67,35 @@ mod __parse__Tree { // State 2 0, // State 3 - 0, + -6, // State 4 - 0, + -2, // State 5 - 0, + -1, // State 6 - 0, + -9, // State 7 - 0, + -3, // State 8 - 0, + -4, // State 9 - -12, + 0, // State 10 0, // State 11 - -7, - // State 12 - 0, - // State 13 - -4, - // State 14 - -1, - // State 15 - 0, - // State 16 -5, - // State 17 - -2, - // State 18 - -3, - // State 19 - -6, ]; fn __goto(state: i8, nt: usize) -> i8 { match nt { - 0 => match state { - 1..=4 => 12, - 5..=8 => 15, - _ => 9, - }, - 2 => match state { - 2 => 6, - 3 => 7, - 4 => 8, - _ => 5, + 0 => 3, + 1 => 4, + 2 => 5, + 3 => match state { + 1 => 9, + 2 => 10, + _ => 6, }, + 4 => 2, _ => 0, } } @@ -134,11 +103,8 @@ mod __parse__Tree { const __TERMINAL: &[&str] = &[ r###""(""###, r###"")""###, - r###""*""###, - r###""+""###, - r###""-""###, - r###""/""###, r###"r#"[0-9]+(\\.[0-9]+)?"#"###, + r###"r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"#"###, ]; __TERMINAL.iter().enumerate().filter_map(|(index, terminal)| { let next_state = __action(__state, index); @@ -191,7 +157,7 @@ mod __parse__Tree { #[inline] fn error_action(&self, state: i8) -> i8 { - __action(state, 7 - 1) + __action(state, 4 - 1) } #[inline] @@ -255,13 +221,10 @@ mod __parse__Tree { ) -> Option { match *__token { - Token(1, _) if true => Some(0), - Token(2, _) if true => Some(1), - Token(3, _) if true => Some(2), - Token(4, _) if true => Some(3), - Token(5, _) if true => Some(4), - Token(6, _) if true => Some(5), - Token(0, _) if true => Some(6), + Token(2, _) if true => Some(0), + Token(3, _) if true => Some(1), + Token(0, _) if true => Some(2), + Token(1, _) if true => Some(3), _ => None, } } @@ -275,20 +238,20 @@ mod __parse__Tree { ) -> __Symbol<'input> { match __token_index { - 0 | 1 | 2 | 3 | 4 | 5 | 6 => match __token { - 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), + 0 | 1 | 2 | 3 => match __token { + Token(2, __tok0) | Token(3, __tok0) | Token(0, __tok0) | Token(1, __tok0) if true => __Symbol::Variant0(__tok0), _ => unreachable!(), }, _ => unreachable!(), } } - pub struct TreeParser { + pub(crate) struct TreeParser { builder: __lalrpop_util::lexer::MatcherBuilder, _priv: (), } impl TreeParser { - pub fn new() -> TreeParser { + pub(crate) fn new() -> TreeParser { let __builder = super::__intern_token::new_builder(); TreeParser { builder: __builder, @@ -297,7 +260,7 @@ mod __parse__Tree { } #[allow(dead_code)] - pub fn parse< + pub(crate) fn parse< 'input, 's, >( @@ -353,17 +316,8 @@ mod __parse__Tree { __reduce7(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>) } 8 => { - __reduce8(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>) - } - 9 => { - __reduce9(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>) - } - 10 => { - __reduce10(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&(), &())>) - } - 11 => { // __Tree = Tree => ActionFn(0); - let __sym0 = __pop_Variant1(__symbols); + let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); let __nt = super::__action0::<>(input, __sym0); @@ -386,18 +340,51 @@ mod __parse__Tree { 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, Tree, usize) + ) -> (usize, Literal, usize) { match __symbols.pop() { Some((__l, __Symbol::Variant1(__v), __r)) => (__l, __v, __r), _ => __symbol_type_mismatch() } } + fn __pop_Variant3< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, String, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } + fn __pop_Variant4< + 'input, + >( + __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> + ) -> (usize, Tree, 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, alloc::vec::Vec, usize) + { + match __symbols.pop() { + Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r), + _ => __symbol_type_mismatch() + } + } fn __pop_Variant2< 'input, >( __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, alloc::vec::Vec, usize) + ) -> (usize, f64, usize) { match __symbols.pop() { Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r), @@ -425,16 +412,13 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree = "(", "+", ")" => ActionFn(10); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // Literal = Sym => ActionFn(3); + let __sym0 = __pop_Variant3(__symbols); let __start = __sym0.0.clone(); - let __end = __sym2.2.clone(); - let __nt = super::__action10::<>(input, __sym0, __sym1, __sym2); + let __end = __sym0.2.clone(); + let __nt = super::__action3::<>(input, __sym0); __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (3, 0) + (1, 0) } pub(crate) fn __reduce1< 'input, @@ -446,17 +430,13 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree = "(", "+", Tree+, ")" => ActionFn(11); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant2(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // Literal = Num => ActionFn(4); + let __sym0 = __pop_Variant2(__symbols); let __start = __sym0.0.clone(); - let __end = __sym3.2.clone(); - let __nt = super::__action11::<>(input, __sym0, __sym1, __sym2, __sym3); + let __end = __sym0.2.clone(); + let __nt = super::__action4::<>(input, __sym0); __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (4, 0) + (1, 0) } pub(crate) fn __reduce2< 'input, @@ -468,17 +448,13 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree = "(", "-", Tree+, ")" => ActionFn(2); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant2(__symbols); - let __sym1 = __pop_Variant0(__symbols); + // Num = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(6); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym3.2.clone(); - let __nt = super::__action2::<>(input, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (4, 0) + let __end = __sym0.2.clone(); + let __nt = super::__action6::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant2(__nt), __end)); + (1, 1) } pub(crate) fn __reduce3< 'input, @@ -490,16 +466,13 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree = "(", "*", ")" => ActionFn(12); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant0(__symbols); + // Sym = r#"[A-Za-z!$%&*+\\-./:<=>?@^_~][A-Za-z!$%&*+\\-./:<=>?@^_~0-9]*"# => ActionFn(5); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym2.2.clone(); - let __nt = super::__action12::<>(input, __sym0, __sym1, __sym2); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (3, 0) + let __end = __sym0.2.clone(); + let __nt = super::__action5::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant3(__nt), __end)); + (1, 2) } pub(crate) fn __reduce4< 'input, @@ -511,17 +484,16 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree = "(", "*", Tree+, ")" => ActionFn(13); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant2(__symbols); - let __sym1 = __pop_Variant0(__symbols); + // Tree = "(", Tree+, ")" => ActionFn(1); + assert!(__symbols.len() >= 3); + let __sym2 = __pop_Variant0(__symbols); + let __sym1 = __pop_Variant5(__symbols); let __sym0 = __pop_Variant0(__symbols); let __start = __sym0.0.clone(); - let __end = __sym3.2.clone(); - let __nt = super::__action13::<>(input, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (4, 0) + let __end = __sym2.2.clone(); + let __nt = super::__action1::<>(input, __sym0, __sym1, __sym2); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (3, 3) } pub(crate) fn __reduce5< 'input, @@ -533,17 +505,13 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree = "(", "/", Tree+, ")" => ActionFn(4); - assert!(__symbols.len() >= 4); - let __sym3 = __pop_Variant0(__symbols); - let __sym2 = __pop_Variant2(__symbols); - let __sym1 = __pop_Variant0(__symbols); - let __sym0 = __pop_Variant0(__symbols); + // Tree = Literal => ActionFn(2); + let __sym0 = __pop_Variant1(__symbols); let __start = __sym0.0.clone(); - let __end = __sym3.2.clone(); - let __nt = super::__action4::<>(input, __sym0, __sym1, __sym2, __sym3); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (4, 0) + let __end = __sym0.2.clone(); + let __nt = super::__action2::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant4(__nt), __end)); + (1, 3) } pub(crate) fn __reduce6< 'input, @@ -555,13 +523,13 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree = r#"[0-9]+(\\.[0-9]+)?"# => ActionFn(5); - let __sym0 = __pop_Variant0(__symbols); + // Tree+ = Tree => ActionFn(7); + let __sym0 = __pop_Variant4(__symbols); let __start = __sym0.0.clone(); let __end = __sym0.2.clone(); - let __nt = super::__action5::<>(input, __sym0); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (1, 0) + let __nt = super::__action7::<>(input, __sym0); + __symbols.push((__start, __Symbol::Variant5(__nt), __end)); + (1, 4) } pub(crate) fn __reduce7< 'input, @@ -573,75 +541,22 @@ mod __parse__Tree { _: core::marker::PhantomData<(&'input (), &'s ())>, ) -> (usize, usize) { - // Tree* = => ActionFn(8); - let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default(); - let __end = __start.clone(); - let __nt = super::__action8::<>(input, &__start, &__end); - __symbols.push((__start, __Symbol::Variant2(__nt), __end)); - (0, 1) - } - pub(crate) fn __reduce8< - '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(9); - let __sym0 = __pop_Variant2(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action9::<>(input, __sym0); - __symbols.push((__start, __Symbol::Variant2(__nt), __end)); - (1, 1) - } - pub(crate) fn __reduce9< - '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(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); + // Tree+ = Tree+, Tree => ActionFn(8); assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant1(__symbols); - let __sym0 = __pop_Variant2(__symbols); + let __sym1 = __pop_Variant4(__symbols); + let __sym0 = __pop_Variant5(__symbols); let __start = __sym0.0.clone(); let __end = __sym1.2.clone(); - let __nt = super::__action7::<>(input, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant2(__nt), __end)); - (2, 2) + let __nt = super::__action8::<>(input, __sym0, __sym1); + __symbols.push((__start, __Symbol::Variant5(__nt), __end)); + (2, 4) } } -pub use self::__parse__Tree::TreeParser; +pub(crate) use self::__parse__Tree::TreeParser; #[cfg_attr(rustfmt, rustfmt_skip)] mod __intern_token { #![allow(unused_imports)] - use crate::Tree; + use crate::{Tree, Literal}; #[allow(unused_extern_crates)] extern crate lalrpop_util as __lalrpop_util; #[allow(unused_imports)] @@ -651,12 +566,9 @@ mod __intern_token { pub fn new_builder() -> __lalrpop_util::lexer::MatcherBuilder { let __strs: &[(&str, bool)] = &[ ("^([0-9]+(\\.[0-9]+)?)", false), + ("^([!\\$-\\&\\*-\\+\\--/:<-Z\\^-_a-z\\~][!\\$-\\&\\*-\\+\\--:<-Z\\^-_a-z\\~]*)", false), ("^(\\()", false), ("^(\\))", false), - ("^(\\*)", false), - ("^(\\+)", false), - ("^(\\-)", false), - ("^(/)", false), (r"^(\s*)", true), ]; __lalrpop_util::lexer::MatcherBuilder::new(__strs.iter().copied()).unwrap() @@ -665,262 +577,92 @@ mod __intern_token { pub(crate) use self::__lalrpop_util::lexer::Token; #[allow(unused_variables)] -fn __action0< - 'input, - 's, ->( - input: &'input str, - (_, __0, _): (usize, Tree, usize), -) -> Tree -{ +fn __action0<'input, 's>(input: &'input str, (_, __0, _): (usize, Tree, usize)) -> Tree { __0 } #[allow(unused_variables)] -fn __action1< - 'input, - 's, ->( +fn __action1<'input, 's>( input: &'input str, (_, _, _): (usize, &'input str, usize), - (_, _, _): (usize, &'input str, usize), (_, __0, _): (usize, alloc::vec::Vec, usize), (_, _, _): (usize, &'input str, usize), -) -> Tree -{ - Tree::Add(__0) +) -> Tree { + Tree::Branch(__0) } #[allow(unused_variables)] -fn __action2< - 'input, - 's, ->( - input: &'input str, - (_, _, _): (usize, &'input str, usize), - (_, _, _): (usize, &'input str, usize), - (_, __0, _): (usize, alloc::vec::Vec, usize), - (_, _, _): (usize, &'input str, usize), -) -> Tree -{ - Tree::Sub(__0) +fn __action2<'input, 's>(input: &'input str, (_, __0, _): (usize, Literal, usize)) -> Tree { + Tree::Leaf(__0) } #[allow(unused_variables)] -fn __action3< - 'input, - 's, ->( - input: &'input str, - (_, _, _): (usize, &'input str, usize), - (_, _, _): (usize, &'input str, usize), - (_, __0, _): (usize, alloc::vec::Vec, usize), - (_, _, _): (usize, &'input str, usize), -) -> Tree -{ - Tree::Mul(__0) +fn __action3<'input, 's>(input: &'input str, (_, __0, _): (usize, String, usize)) -> Literal { + Literal::Sym(__0) } #[allow(unused_variables)] -fn __action4< - 'input, - 's, ->( - input: &'input str, - (_, _, _): (usize, &'input str, usize), - (_, _, _): (usize, &'input str, usize), - (_, __0, _): (usize, alloc::vec::Vec, usize), - (_, _, _): (usize, &'input str, usize), -) -> Tree -{ - Tree::Div(__0) +fn __action4<'input, 's>(input: &'input str, (_, __0, _): (usize, f64, usize)) -> Literal { + Literal::Num(__0) } #[allow(unused_variables)] -fn __action5< - 'input, - 's, ->( - input: &'input str, - (_, __0, _): (usize, &'input str, usize), -) -> Tree -{ - Tree::Val(__0.parse().unwrap()) +fn __action5<'input, 's>(input: &'input str, (_, __0, _): (usize, &'input str, usize)) -> String { + __0.to_owned() } #[allow(unused_variables)] -fn __action6< - 'input, - 's, ->( +fn __action6<'input, 's>(input: &'input str, (_, __0, _): (usize, &'input str, usize)) -> f64 { + __0.parse().unwrap() +} + +#[allow(unused_variables)] +fn __action7<'input, 's>( input: &'input str, (_, __0, _): (usize, Tree, usize), -) -> alloc::vec::Vec -{ +) -> alloc::vec::Vec { alloc::vec![__0] } #[allow(unused_variables)] -fn __action7< - 'input, - 's, ->( +fn __action8<'input, 's>( input: &'input str, (_, v, _): (usize, alloc::vec::Vec, usize), (_, e, _): (usize, Tree, usize), -) -> alloc::vec::Vec -{ - { let mut v = v; v.push(e); v } +) -> alloc::vec::Vec { + { + 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 -{ - alloc::vec![] +pub trait __ToTriple<'input, 's> { + fn to_triple( + value: Self, + ) -> Result< + (usize, Token<'input>, usize), + __lalrpop_util::ParseError, &'static str>, + >; } -#[allow(unused_variables)] -fn __action9< - 'input, - 's, ->( - input: &'input str, - (_, v, _): (usize, alloc::vec::Vec, usize), -) -> alloc::vec::Vec -{ - 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, 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, 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, > { - fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>>; -} - -impl<'input, 's, > __ToTriple<'input, 's, > for (usize, Token<'input>, usize) { - fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>> { +impl<'input, 's> __ToTriple<'input, 's> for (usize, Token<'input>, usize) { + fn to_triple( + value: Self, + ) -> Result< + (usize, Token<'input>, usize), + __lalrpop_util::ParseError, &'static str>, + > { Ok(value) } } -impl<'input, 's, > __ToTriple<'input, 's, > for Result<(usize, Token<'input>, usize), &'static str> { - fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>> { +impl<'input, 's> __ToTriple<'input, 's> for Result<(usize, Token<'input>, usize), &'static str> { + fn to_triple( + value: Self, + ) -> Result< + (usize, Token<'input>, usize), + __lalrpop_util::ParseError, &'static str>, + > { match value { Ok(v) => Ok(v), Err(error) => Err(__lalrpop_util::ParseError::User { error }), diff --git a/src/main.rs b/src/main.rs index 97db77e..91c7ec4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,13 @@ +#![feature(let_else)] + mod grammar; -use debug2::dbg; - -#[derive(Debug, debug2::Debug, PartialEq)] -pub enum Tree { - Val(f64), - Add(Vec), - Sub(Vec), - Mul(Vec), - Div(Vec), -} - use rustyline::validate::{ MatchingBracketValidator, ValidationContext, ValidationResult, Validator, }; -use rustyline::{Editor, Result}; +use rustyline::Editor; use rustyline_derive::{Completer, Helper, Highlighter, Hinter}; +use std::collections::HashMap; #[derive(Completer, Helper, Highlighter, Hinter)] struct InputValidator { @@ -23,84 +15,215 @@ struct InputValidator { } impl Validator for InputValidator { - fn validate(&self, ctx: &mut ValidationContext) -> Result { + fn validate(&self, ctx: &mut ValidationContext) -> rustyline::Result { self.brackets.validate(ctx) } } +use debug2::dbg; + +#[derive(Debug, debug2::Debug, PartialEq)] +enum Tree { + Leaf(Literal), + Branch(Vec), +} + +#[derive(Debug, debug2::Debug, PartialEq)] +enum Literal { + Sym(String), + Num(f64), +} + +#[derive(Debug)] +struct RTError(String); + +fn err(s: String) -> Result { + Err(RTError(s)) +} + +type Func = fn(&[Value]) -> Result; + +#[derive(Clone, Copy)] +enum Value { + Num(f64), + Func(Func), +} + +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("#"), + } + } +} + +impl Value { + fn as_num(&self) -> Result { + if let Self::Num(n) = self { + Ok(*n) + } else { + Err(RTError("Expected a number".to_owned())) + } + } + + fn as_func(&self) -> Result { + if let Self::Func(f) = self { + Ok(*f) + } else { + Err(RTError("Expected a function".to_owned())) + } + } +} + +struct Env { + vars: HashMap, +} 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(); rl.set_helper(Some(InputValidator { brackets: MatchingBracketValidator::new(), })); + + let mut env = default_env(); + while let Ok(line) = rl.readline("> ") { rl.add_history_entry(&line); let tree = grammar::TreeParser::new().parse(&line).unwrap(); dbg!(&tree); - println!("< {}", eval(&tree)) + println!("< {:?}", eval(&tree, &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::(), - Tree::Div(vs) => eval(&vs[0]) / vs[1..].iter().map(eval).product::(), +fn eval(t: &Tree, env: &Env) -> Result { + Ok(match t { + Tree::Leaf(l) => match l { + Literal::Sym(s) => match env.vars.get(s) { + Some(&v) => v, + None => return err(format!("Undefined variable `{}`", s)), + }, + 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::, _>>()?; + return fun(&args); + } + }) +} + +// 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::(), +// Tree::Div(vs) => eval(&vs[0]) / vs[1..].iter().map(eval).product::(), +// } +// } + +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 { + 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 { + 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 { + 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 { + 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)] -mod tests { - use super::*; +// #[cfg(test)] +// mod tests { +// use super::*; - #[test] - fn simple_math_space() { - let t = grammar::TreeParser::new() - .parse("( + 1 2 ( / 2 3 4 5) )") - .unwrap(); - assert_eq!( - t, - Tree::Add(vec![ - Tree::Val(1.0), - Tree::Val(2.0), - Tree::Div(vec![ - Tree::Val(2.0), - Tree::Val(3.0), - Tree::Val(4.0), - Tree::Val(5.0), - ]) - ]) - ); - } +// #[test] +// fn simple_math_space() { +// let t = grammar::TreeParser::new() +// .parse("( + 1 2 ( / 2 3 4 5) )") +// .unwrap(); +// assert_eq!( +// t, +// Tree::Add(vec![ +// Tree::Val(1.0), +// Tree::Val(2.0), +// Tree::Div(vec![ +// Tree::Val(2.0), +// Tree::Val(3.0), +// Tree::Val(4.0), +// Tree::Val(5.0), +// ]) +// ]) +// ); +// } - #[test] - fn simple_math_dence() { - let t = grammar::TreeParser::new() - .parse("(+ 1 2 (/ 2 3 4 5))") - .unwrap(); - assert_eq!( - t, - Tree::Add(vec![ - Tree::Val(1.0), - Tree::Val(2.0), - Tree::Div(vec![ - Tree::Val(2.0), - Tree::Val(3.0), - Tree::Val(4.0), - Tree::Val(5.0), - ]) - ]) - ); - } -} +// #[test] +// fn simple_math_dence() { +// let t = grammar::TreeParser::new() +// .parse("(+ 1 2 (/ 2 3 4 5))") +// .unwrap(); +// assert_eq!( +// t, +// Tree::Add(vec![ +// Tree::Val(1.0), +// Tree::Val(2.0), +// Tree::Div(vec![ +// Tree::Val(2.0), +// Tree::Val(3.0), +// Tree::Val(4.0), +// Tree::Val(5.0), +// ]) +// ]) +// ); +// } +// }