diff --git a/src/calc.rs b/src/calc.rs deleted file mode 100644 index 19225cc..0000000 --- a/src/calc.rs +++ /dev/null @@ -1,703 +0,0 @@ -// auto-generated: "lalrpop 0.19.5" -// sha3: 7f1eed9c7f5eae965f19f037e3f83cc3f8b8ac855ed1b7d5e579d3c668c23b2 -use std::str::FromStr; -use crate::Expr; -#[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; - -#[cfg_attr(rustfmt, rustfmt_skip)] -mod __parse__Expr { - #![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)] - - use std::str::FromStr; - use crate::Expr; - #[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; - use self::__lalrpop_util::lexer::Token; - #[allow(dead_code)] - pub(crate) enum __Symbol<'input> - { - Variant0(&'input str), - Variant1(Expr), - Variant2(alloc::vec::Vec), - Variant3(i32), - } - const __ACTION: &[i8] = &[ - // State 0 - 2, 0, 7, 8, - // State 1 - 2, 0, 7, 8, - // State 2 - 2, 11, 7, 8, - // State 3 - 0, 0, 0, 0, - // State 4 - -5, -5, -5, -5, - // State 5 - -6, -6, -6, -6, - // State 6 - -7, -7, -7, -7, - // State 7 - -8, -8, -8, -8, - // State 8 - -2, -2, -2, -2, - // State 9 - -3, -3, -3, -3, - // State 10 - -4, -4, -4, -4, - ]; - fn __action(state: i8, integer: usize) -> i8 { - __ACTION[(state as usize) * 4 + integer] - } - const __EOF_ACTION: &[i8] = &[ - // State 0 - 0, - // State 1 - 0, - // State 2 - 0, - // State 3 - -9, - // State 4 - -5, - // State 5 - -6, - // State 6 - -7, - // State 7 - -8, - // State 8 - 0, - // State 9 - 0, - // State 10 - -4, - ]; - fn __goto(state: i8, nt: usize) -> i8 { - match nt { - 1 => 2, - 2 => match state { - 1 => 8, - 2 => 9, - _ => 3, - }, - 3 => 4, - 4 => 5, - _ => 0, - } - } - fn __expected_tokens(__state: i8) -> alloc::vec::Vec { - const __TERMINAL: &[&str] = &[ - r###""(""###, - r###"")""###, - r###"r#":[^\\s]+"#"###, - r###"r#"[0-9]+"#"###, - ]; - __TERMINAL.iter().enumerate().filter_map(|(index, terminal)| { - let next_state = __action(__state, index); - if next_state == 0 { - None - } else { - Some(alloc::string::ToString::to_string(terminal)) - } - }).collect() - } - pub(crate) struct __StateMachine<'input> - where - { - input: &'input str, - __phantom: core::marker::PhantomData<(&'input ())>, - } - impl<'input> __state_machine::ParserDefinition for __StateMachine<'input> - where - { - type Location = usize; - type Error = &'static str; - type Token = Token<'input>; - type TokenIndex = usize; - type Symbol = __Symbol<'input>; - type Success = Expr; - type StateIndex = i8; - type Action = i8; - type ReduceIndex = i8; - type NonterminalIndex = usize; - - #[inline] - fn start_location(&self) -> Self::Location { - Default::default() - } - - #[inline] - fn start_state(&self) -> Self::StateIndex { - 0 - } - - #[inline] - fn token_to_index(&self, token: &Self::Token) -> Option { - __token_to_integer(token, core::marker::PhantomData::<(&())>) - } - - #[inline] - fn action(&self, state: i8, integer: usize) -> i8 { - __action(state, integer) - } - - #[inline] - fn error_action(&self, state: i8) -> i8 { - __action(state, 4 - 1) - } - - #[inline] - fn eof_action(&self, state: i8) -> i8 { - __EOF_ACTION[state as usize] - } - - #[inline] - fn goto(&self, state: i8, nt: usize) -> i8 { - __goto(state, nt) - } - - fn token_to_symbol(&self, token_index: usize, token: Self::Token) -> Self::Symbol { - __token_to_symbol(token_index, token, core::marker::PhantomData::<(&())>) - } - - fn expected_tokens(&self, state: i8) -> alloc::vec::Vec { - __expected_tokens(state) - } - - #[inline] - fn uses_error_recovery(&self) -> bool { - false - } - - #[inline] - fn error_recovery_symbol( - &self, - recovery: __state_machine::ErrorRecovery, - ) -> Self::Symbol { - panic!("error recovery not enabled for this grammar") - } - - fn reduce( - &mut self, - action: i8, - start_location: Option<&Self::Location>, - states: &mut alloc::vec::Vec, - symbols: &mut alloc::vec::Vec<__state_machine::SymbolTriple>, - ) -> Option<__state_machine::ParseResult> { - __reduce( - self.input, - action, - start_location, - states, - symbols, - core::marker::PhantomData::<(&())>, - ) - } - - fn simulate_reduce(&self, action: i8) -> __state_machine::SimulatedReduce { - panic!("error recovery not enabled for this grammar") - } - } - fn __token_to_integer< - 'input, - >( - __token: &Token<'input>, - _: core::marker::PhantomData<(&'input ())>, - ) -> Option - { - match *__token { - 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, - } - } - fn __token_to_symbol< - 'input, - >( - __token_index: usize, - __token: Token<'input>, - _: core::marker::PhantomData<(&'input ())>, - ) -> __Symbol<'input> - { - match __token_index { - 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 ExprParser { - builder: __lalrpop_util::lexer::MatcherBuilder, - _priv: (), - } - - impl ExprParser { - pub fn new() -> ExprParser { - let __builder = super::__intern_token::new_builder(); - ExprParser { - builder: __builder, - _priv: (), - } - } - - #[allow(dead_code)] - pub fn parse< - 'input, - >( - &self, - input: &'input str, - ) -> Result, &'static str>> - { - let mut __tokens = self.builder.matcher(input); - __state_machine::Parser::drive( - __StateMachine { - input, - __phantom: core::marker::PhantomData::<(&())>, - }, - __tokens, - ) - } - } - pub(crate) fn __reduce< - 'input, - >( - input: &'input str, - __action: i8, - __lookahead_start: Option<&usize>, - __states: &mut alloc::vec::Vec, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> Option, &'static str>>> - { - let (__pop_states, __nonterminal) = match __action { - 0 => { - __reduce0(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 1 => { - __reduce1(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 2 => { - __reduce2(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 3 => { - __reduce3(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 4 => { - __reduce4(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 5 => { - __reduce5(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 6 => { - __reduce6(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 7 => { - __reduce7(input, __lookahead_start, __symbols, core::marker::PhantomData::<(&())>) - } - 8 => { - // __Expr = Expr => ActionFn(0); - let __sym0 = __pop_Variant1(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action0::<>(input, __sym0); - return Some(Ok(__nt)); - } - _ => panic!("invalid action code {}", __action) - }; - let __states_len = __states.len(); - __states.truncate(__states_len - __pop_states); - let __state = *__states.last().unwrap(); - let __next_state = __goto(__state, __nonterminal); - __states.push(__next_state); - None - } - #[inline(never)] - fn __symbol_type_mismatch() -> ! { - panic!("symbol type mismatch") - } - fn __pop_Variant1< - 'input, - >( - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, Expr, usize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant1(__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) - { - match __symbols.pop() { - 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, i32, usize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } - fn __pop_Variant0< - 'input, - >( - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)> - ) -> (usize, &'input str, usize) - { - match __symbols.pop() { - Some((__l, __Symbol::Variant0(__v), __r)) => (__l, __v, __r), - _ => __symbol_type_mismatch() - } - } - pub(crate) fn __reduce0< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // () = Expr => ActionFn(8); - let __sym0 = __pop_Variant1(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action8::<>(input, __sym0); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (1, 0) - } - pub(crate) fn __reduce1< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // ()+ = Expr => ActionFn(9); - let __sym0 = __pop_Variant1(__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 __reduce2< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // ()+ = ()+, Expr => ActionFn(10); - assert!(__symbols.len() >= 2); - let __sym1 = __pop_Variant1(__symbols); - let __sym0 = __pop_Variant2(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym1.2.clone(); - let __nt = super::__action10::<>(input, __sym0, __sym1); - __symbols.push((__start, __Symbol::Variant2(__nt), __end)); - (2, 1) - } - pub(crate) fn __reduce3< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // Expr = "(", ()+, ")" => ActionFn(1); - assert!(__symbols.len() >= 3); - let __sym2 = __pop_Variant0(__symbols); - let __sym1 = __pop_Variant2(__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::Variant1(__nt), __end)); - (3, 2) - } - pub(crate) fn __reduce4< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // Expr = Keyword => ActionFn(2); - let __sym0 = __pop_Variant1(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action2::<>(input, __sym0); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (1, 2) - } - pub(crate) fn __reduce5< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // Expr = Num => ActionFn(3); - let __sym0 = __pop_Variant3(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action3::<>(input, __sym0); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (1, 2) - } - pub(crate) fn __reduce6< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // Keyword = r#":[^\\s]+"# => ActionFn(4); - let __sym0 = __pop_Variant0(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action4::<>(input, __sym0); - __symbols.push((__start, __Symbol::Variant1(__nt), __end)); - (1, 3) - } - pub(crate) fn __reduce7< - 'input, - >( - input: &'input str, - __lookahead_start: Option<&usize>, - __symbols: &mut alloc::vec::Vec<(usize,__Symbol<'input>,usize)>, - _: core::marker::PhantomData<(&'input ())>, - ) -> (usize, usize) - { - // Num = r#"[0-9]+"# => ActionFn(5); - let __sym0 = __pop_Variant0(__symbols); - let __start = __sym0.0.clone(); - let __end = __sym0.2.clone(); - let __nt = super::__action5::<>(input, __sym0); - __symbols.push((__start, __Symbol::Variant3(__nt), __end)); - (1, 4) - } -} -pub use self::__parse__Expr::ExprParser; -#[cfg_attr(rustfmt, rustfmt_skip)] -mod __intern_token { - #![allow(unused_imports)] - use std::str::FromStr; - use crate::Expr; - #[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; - pub fn new_builder() -> __lalrpop_util::lexer::MatcherBuilder { - let __strs: &[(&str, bool)] = &[ - ("^(:[\u{0}-\u{8}\u{e}-\u{1f}!-\u{84}\u{86}-\u{9f}¡-ᙿᚁ-\u{1fff}\u{200b}-‧\u{202a}-\u{202e}‰-⁞\u{2060}-\u{2fff}、-\u{10ffff}]+)", false), - ("^([0-9]+)", false), - ("^(\\()", false), - ("^(\\))", false), - (r"^(\s*)", true), - ]; - __lalrpop_util::lexer::MatcherBuilder::new(__strs.iter().copied()).unwrap() - } -} -pub(crate) use self::__lalrpop_util::lexer::Token; - -#[allow(unused_variables)] -fn __action0< - 'input, ->( - input: &'input str, - (_, __0, _): (usize, Expr, usize), -) -> Expr -{ - __0 -} - -#[allow(unused_variables)] -fn __action1< - 'input, ->( - input: &'input str, - (_, _, _): (usize, &'input str, usize), - (_, elems, _): (usize, alloc::vec::Vec, usize), - (_, _, _): (usize, &'input str, usize), -) -> Expr -{ - Expr::List(elems) -} - -#[allow(unused_variables)] -fn __action2< - 'input, ->( - input: &'input str, - (_, x, _): (usize, Expr, usize), -) -> Expr -{ - x -} - -#[allow(unused_variables)] -fn __action3< - 'input, ->( - input: &'input str, - (_, x, _): (usize, i32, usize), -) -> Expr -{ - Expr::Number(x) -} - -#[allow(unused_variables)] -fn __action4< - 'input, ->( - input: &'input str, - (_, __0, _): (usize, &'input str, usize), -) -> Expr -{ - Expr::Keyword(__0.to_string()) -} - -#[allow(unused_variables)] -fn __action5< - 'input, ->( - input: &'input str, - (_, __0, _): (usize, &'input str, usize), -) -> i32 -{ - i32::from_str(__0).unwrap() -} - -#[allow(unused_variables)] -fn __action6< - 'input, ->( - input: &'input str, - (_, __0, _): (usize, Expr, usize), -) -> alloc::vec::Vec -{ - alloc::vec![__0] -} - -#[allow(unused_variables)] -fn __action7< - 'input, ->( - input: &'input str, - (_, v, _): (usize, alloc::vec::Vec, usize), - (_, e, _): (usize, Expr, usize), -) -> alloc::vec::Vec -{ - { let mut v = v; v.push(e); v } -} - -#[allow(unused_variables)] -fn __action8< - 'input, ->( - input: &'input str, - (_, __0, _): (usize, Expr, usize), -) -> Expr -{ - __0 -} - -#[allow(unused_variables)] -fn __action9< - 'input, ->( - input: &'input str, - __0: (usize, Expr, usize), -) -> alloc::vec::Vec -{ - let __start0 = __0.0.clone(); - let __end0 = __0.2.clone(); - let __temp0 = __action8( - input, - __0, - ); - let __temp0 = (__start0, __temp0, __end0); - __action6( - input, - __temp0, - ) -} - -#[allow(unused_variables)] -fn __action10< - 'input, ->( - input: &'input str, - __0: (usize, alloc::vec::Vec, usize), - __1: (usize, Expr, usize), -) -> alloc::vec::Vec -{ - let __start0 = __1.0.clone(); - let __end0 = __1.2.clone(); - let __temp0 = __action8( - input, - __1, - ); - let __temp0 = (__start0, __temp0, __end0); - __action7( - input, - __0, - __temp0, - ) -} - -pub trait __ToTriple<'input, > { - fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>>; -} - -impl<'input, > __ToTriple<'input, > for (usize, Token<'input>, usize) { - fn to_triple(value: Self) -> Result<(usize,Token<'input>,usize), __lalrpop_util::ParseError, &'static str>> { - Ok(value) - } -} -impl<'input, > __ToTriple<'input, > 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/config.rs b/src/config.rs index ed00a29..51c8a27 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,16 +2,28 @@ use std::{collections::HashMap, iter::FromIterator}; use super::*; use anyhow::*; +use itertools::Itertools; use std::collections::LinkedList; type VarName = String; type AttrValue = String; type AttrName = String; +#[derive(Debug, PartialEq, Eq)] pub enum AstError { UnexpectedNode, InvalidDefinition, - WrongExprType, + WrongExprType(Sp), + MissingNode, +} + +trait OptionAstErrorExt { + fn or_missing(self) -> Result; +} +impl OptionAstErrorExt for Option { + fn or_missing(self) -> Result { + self.ok_or(AstError::MissingNode) + } } impl From for AstError { @@ -27,6 +39,12 @@ pub trait FromExpr: Sized { } } +impl FromExpr for Expr { + fn from_expr(e: Expr) -> Result { + Ok(e) + } +} + pub enum DefType { Widget, } @@ -54,15 +72,13 @@ pub struct Definitional { impl FromExpr for Definitional { fn from_expr(e: Expr) -> Result { if let Expr::List(list) = e { - let mut iter = SExpIterator::new(list); + let mut iter = itertools::put_back(list.into_iter()); - let def_type = DefType::from_sp(iter.next().unwrap().as_single().unwrap())?; - let name = iter.next().unwrap().as_single().unwrap().1.str()?; - let attrs = iter.next().unwrap().as_key_value().unwrap(); + let def_type = DefType::from_sp(iter.next().or_missing()?)?; + let name = iter.next().or_missing()?.1.str()?; + let attrs = parse_key_values(&mut iter); - let children = iter - .map(|elem| T::from_sp(elem.as_single()?)) - .collect::, AstError>>()?; + let children = iter.map(T::from_sp).collect::, AstError>>()?; Ok(Definitional { def_type, name, @@ -74,72 +90,88 @@ impl FromExpr for Definitional { } } } - -pub struct WidgetDefinition { +#[derive(Debug, Eq, PartialEq)] +pub struct Element { name: String, - argnames: Vec, + attrs: HashMap>, + children: Vec, } -struct SExpIterator { - elements: LinkedList>, -} +impl FromExpr for Element> { + fn from_expr(e: Expr) -> Result { + if let Expr::List(list) = e { + let mut iter = itertools::put_back(list.into_iter()); -impl SExpIterator { - fn new(elements: Vec>) -> Self { - SExpIterator { - elements: LinkedList::from_iter(elements.into_iter()), + let name = iter.next().or_missing()?.1.str()?; + let attrs = parse_key_values(&mut iter); + + Ok(Element { + name, + attrs, + children: iter.collect_vec(), + }) + } else { + Err(AstError::UnexpectedNode) } } } -enum ExpressionElement { - Single(Sp), - KeyValue(HashMap>), -} - -impl ExpressionElement { - fn as_single(self) -> Option> { - match self { - ExpressionElement::Single(x) => Some(x), - ExpressionElement::KeyValue(_) => None, - } - } - fn as_key_value(self) -> Option>> { - match self { - ExpressionElement::Single(_) => None, - ExpressionElement::KeyValue(x) => Some(x), - } - } -} - -impl Iterator for SExpIterator { - type Item = ExpressionElement; - - fn next(&mut self) -> Option { - let mut data = HashMap::new(); - loop { - let first_is_kw = self.elements.front().map_or(false, |x| x.1.is_keyword()); - if first_is_kw { - let (l, kw, r) = match self.elements.pop_front() { - Some(Sp(l, Expr::Keyword(kw), r)) => (l, kw, r), - _ => unreachable!(), - }; - if let Some(value) = self.elements.pop_front() { +fn parse_key_values>>( + iter: &mut itertools::PutBack, +) -> HashMap> { + let mut data = HashMap::new(); + loop { + match iter.next() { + Some(Sp(l, Expr::Keyword(kw), r)) => match iter.next() { + Some(value) => { data.insert(kw, value); - } else { - return if data.is_empty() { - Some(ExpressionElement::Single(Sp(l, Expr::Keyword(kw), r))) - } else { - Some(ExpressionElement::KeyValue(data)) - }; } - } else { - return if data.is_empty() { - Some(ExpressionElement::Single(self.elements.pop_front()?)) - } else { - Some(ExpressionElement::KeyValue(data)) - }; + None => { + iter.put_back(Sp(l, Expr::Keyword(kw), r)); + return data; + } + }, + Some(expr) => { + iter.put_back(expr); + return data; } + None => return data, } } } + +#[cfg(test)] +mod test { + + use super::*; + + #[test] + fn test() { + let parser = parser::ExprParser::new(); + assert_eq!( + Element::>::from_expr( + parser + .parse("(box foo :bar 12 :baz \"hi\" foo (bar))") + .unwrap() + ) + .unwrap(), + Element { + name: "box".to_string(), + children: vec![ + Sp(1, Expr::Symbol("foo".to_string()), 2), + Sp( + 2, + Expr::List(vec![Sp(2, Expr::Symbol("bar".to_string()), 3)]), + 3 + ) + ], + attrs: { + let mut data = HashMap::new(); + data.insert("foo".to_string(), Sp(2, Expr::Number(12), 3)); + data.insert("bar".to_string(), Sp(2, Expr::Str("hi".to_string()), 3)); + data + }, + } + ); + } +} diff --git a/src/main.rs b/src/main.rs index aa5b2b3..400c56f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use lalrpop_util::lalrpop_mod; //mod lexer; -lalrpop_mod!(pub calc); +lalrpop_mod!(pub parser); #[derive(Debug, Eq, PartialEq, Clone, Copy)] pub struct Sp(pub usize, pub T, pub usize); @@ -22,10 +22,10 @@ impl std::fmt::Display for Sp { } } -#[derive(Debug, Clone, Copy)] -pub struct WrongExprType; +#[derive(Debug, Clone)] +pub struct WrongExprType(Sp); -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum Expr { List(Vec>), Table(Vec<(Sp, Sp)>), @@ -41,7 +41,7 @@ impl Expr { use Expr::*; match self { Str(x) => Ok(x), - _ => Err(WrongExprType), + x => Err(WrongExprType(x)), } } fn is_keyword(&self) -> bool { @@ -77,7 +77,7 @@ fn main() {} macro_rules! test_p { ($e:expr) => { let e = $e; - let p = calc::ExprParser::new(); + let p = parser::ExprParser::new(); match p.parse(e) { Ok(res) => println!("{}\n=> {}\n", e, res), Err(e) => eprintln!("{}", e), @@ -86,31 +86,29 @@ macro_rules! test_p { } #[test] -fn calc() { - test_p!("1"); - test_p!("(12)"); - test_p!("(1 2)"); - test_p!("(1 :foo 1)"); - test_p!("(:foo 1)"); - test_p!("(:foo->: 1)"); - test_p!("(foo 1)"); - test_p!("(lol😄 1)"); +fn test() { + //test_p!("1"); + //test_p!("(12)"); + //test_p!("(1 2)"); + //test_p!("(1 :foo 1)"); + //test_p!("(:foo 1)"); + //test_p!("(:foo->: 1)"); + //test_p!("(foo 1)"); + //test_p!("(lol😄 1)"); - test_p!(r#"(test "hi")"#); - test_p!(r#"(test "h\"i")"#); - test_p!(r#"(test " hi ")"#); + //test_p!(r#"(test "hi")"#); + //test_p!(r#"(test "h\"i")"#); + //test_p!(r#"(test " hi ")"#); - test_p!("(+ (1 2 (* 2 5)))"); + //test_p!("(+ (1 2 (* 2 5)))"); - test_p!(r#"{:key value 12 "hi" (test) (1 2 3)}"#); + //test_p!(r#"{:key value 12 "hi" (test) (1 2 3)}"#); - test_p!(r#"; test"#); - test_p!( - r#"(f arg ; test - arg2)"# - ); + //test_p!(r#"; test"#); + //test_p!( + //r#"(f arg ; test + //arg2)"# + //); - println!("\n\n\n\n\n\n"); - - panic!() + //println!("\n\n\n\n\n\n"); } diff --git a/src/calc.lalrpop b/src/parser.lalrpop similarity index 100% rename from src/calc.lalrpop rename to src/parser.lalrpop