From d437e1297c9dc7d8577c8f600706106e49a6709d Mon Sep 17 00:00:00 2001 From: Nixon Enraght-Moony Date: Fri, 17 Dec 2021 02:57:20 +0000 Subject: [PATCH] Bools and ifs --- src/grammar.lalrpop | 11 +- src/grammar.rs | 506 ++++++++++++++++++++++++++++++++------------ src/main.rs | 78 ++++--- 3 files changed, 433 insertions(+), 162 deletions(-) diff --git a/src/grammar.lalrpop b/src/grammar.lalrpop index c9cf1f5..8c57a09 100644 --- a/src/grammar.lalrpop +++ b/src/grammar.lalrpop @@ -5,17 +5,24 @@ grammar<'s>(); pub(crate) Tree: Tree = { "(" ")" => Tree::Branch(<>), - "(" "define" > ")" => Tree::Define(<>), + "(" "define" ")" => Tree::Define(<>), + "(" "if" ")" => Tree::If(Box::new([<>])), Literal => Tree::Leaf(<>), } +BTree = { Box } Literal: Literal = { Sym => Literal::Sym(<>), Num => Literal::Num(<>), + Bool => Literal::Bool(<>), } Box: Box = { 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() } \ No newline at end of file +Num: f64 = { r"[0-9]+(\.[0-9]+)?" => <>.parse().unwrap() } +Bool: bool = { + "#t" => true, + "#f" => false, +} \ No newline at end of file diff --git a/src/grammar.rs b/src/grammar.rs index 97c554b..8557a8a 100644 --- a/src/grammar.rs +++ b/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), - Variant2(Literal), - Variant3(f64), - Variant4(String), - Variant5(Tree), - Variant6(alloc::vec::Vec), + Variant2(bool), + Variant3(Literal), + Variant4(f64), + Variant5(String), + Variant6(Tree), + Variant7(alloc::vec::Vec), } 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 { 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, 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, 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 => ActionFn(8); - let __sym0 = __pop_Variant5(__symbols); + // BTree = Box => 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 => 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, ")" => 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, usize), +) -> Box +{ + __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, >( diff --git a/src/main.rs b/src/main.rs index c9fa974..96766af 100644 --- a/src/main.rs +++ b/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 { - self.brackets.validate(ctx) - } -} -use debug2::dbg; - #[derive(Debug, debug2::Debug, PartialEq)] enum Tree { Leaf(Literal), Define(String, Box), + If(Box<[Tree; 3]>), Branch(Vec), } @@ -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; 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("#"), + 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 { + 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 { 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 { 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::(), -// 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), + ("=", 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 { + 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 { + self.brackets.validate(ctx) + } +}