leap_lang/parser/
valuetypeparser.rs

1use super::itemposition::ItemPosition;
2use super::parsetree::ParseTree;
3use super::proptypesimple::PropTypeSimple;
4use super::token::Token;
5use super::tokenstream::TokenStream;
6use super::treevariant::TreeVariant;
7use crate::leaptypes::{Name, SimpleType};
8
9/*
10
11    Full BNF
12
13
14    PTYPE               := NAME | NAME PT_ARGS_BLOCK
15    PT_ARGS_BLOCK       := [ PT_ARGS ]
16    PT_ARGS             := PTYPE | PTYPE PT_ARGS
17
18    NAME                := word
19
20*/
21
22#[derive(Debug, Clone)]
23pub enum ValueType {
24    Simple(SimpleType),
25    List(Box<ValueType>),
26    LeapType { name: Name, args: Vec<ValueType> },
27}
28
29impl From<PropTypeSimple> for ValueType {
30    fn from(item: PropTypeSimple) -> Self {
31        let mut item = item;
32        match item.name.as_str() {
33            "str" => Self::Simple(SimpleType::String),
34            "int" => Self::Simple(SimpleType::Integer),
35            "float" => Self::Simple(SimpleType::Float),
36            "bool" => Self::Simple(SimpleType::Boolean),
37            "list" => Self::List(Box::new(Self::from(item.args.remove(0)))),
38            name => {
39                let name = Name::new(name.to_owned(), item.position).unwrap();
40                let args = item.args.into_iter().map(Self::from).collect();
41                Self::LeapType { name, args }
42            }
43        }
44    }
45}
46
47impl ValueType {
48    pub fn args(&self) -> Vec<&ValueType> {
49        match self {
50            ValueType::Simple(_) => vec![],
51            ValueType::List(t) => vec![&t],
52            ValueType::LeapType { args, .. } => args.iter().collect(),
53        }
54    }
55}
56
57pub struct ValueTypeParser {
58    stream: TokenStream,
59}
60
61impl ValueTypeParser {
62    pub fn parse(data: &str) -> Result<ValueType, ItemPosition<String>> {
63        let stream = TokenStream::new(&data);
64        let mut parser = ValueTypeParser { stream };
65        let tree = parser.parse_ptype()?;
66        let value_type = Self::tree_to_prop_type_simple(&tree);
67        Ok(ValueType::from(value_type))
68    }
69
70    fn parse_ptype(&mut self) -> Result<ParseTree, ItemPosition<String>> {
71        let mut tree = ParseTree::new(TreeVariant::PType, self.stream.get().0);
72        tree.nodes.push(self.parse_name()?);
73        if self.stream.get().1 == Token::BracketLeft {
74            tree.nodes.push(self.parse_pt_args_block()?);
75        }
76        Ok(tree)
77    }
78
79    fn parse_pt_args_block(&mut self) -> Result<ParseTree, ItemPosition<String>> {
80        let mut tree = ParseTree::new(TreeVariant::PTArgsBlock, self.stream.get().0);
81        if self.stream.get().1 == Token::BracketLeft {
82            self.stream.next();
83            tree.nodes.push(self.parse_pt_args()?);
84            if self.stream.get().1 == Token::BracketRight {
85                self.stream.next();
86            } else {
87                return Err(self.stream.get().replace("Expecting `]`".to_owned()));
88            }
89        } else {
90            return Err(self.stream.get().replace("Expecting `[`".to_owned()));
91        }
92        Ok(tree)
93    }
94
95    fn parse_pt_args(&mut self) -> Result<ParseTree, ItemPosition<String>> {
96        let mut tree = ParseTree::new(TreeVariant::PTArgs, self.stream.get().0);
97        tree.nodes.push(self.parse_ptype()?);
98        if let Token::Word(_) = self.stream.get().1 {
99            tree.nodes.push(self.parse_pt_args()?);
100        }
101        Ok(tree)
102    }
103
104    fn parse_name(&mut self) -> Result<ParseTree, ItemPosition<String>> {
105        match self.stream.consume() {
106            ItemPosition(p, Token::Word(w)) => Ok(ParseTree {
107                variant: TreeVariant::Name(w.clone()),
108                position: *p,
109                nodes: vec![],
110            }),
111            p => Err(p.replace("Expecting name".to_owned())),
112        }
113    }
114
115    fn tree_to_prop_type_simple(tree: &ParseTree) -> PropTypeSimple {
116        // tree -> PType
117        let name_node = &tree.nodes[0];
118        let name = if let TreeVariant::Name(w) = &name_node.variant {
119            w.clone()
120        } else {
121            panic!("Incorrect parse tree");
122        };
123        let args = if let Some(t) = tree.nodes.get(1) {
124            // t -> PTArgsBlock
125            let t = &t.nodes[0];
126            // t -> PTArgs
127            Self::tree_to_ptargs(t)
128        } else {
129            vec![]
130        };
131        PropTypeSimple {
132            name,
133            args,
134            position: tree.position,
135        }
136    }
137
138    fn tree_to_ptargs(tree: &ParseTree) -> Vec<PropTypeSimple> {
139        // tree -> PTArgs
140        let mut args = vec![Self::tree_to_prop_type_simple(&tree.nodes[0])];
141        if let Some(t) = tree.nodes.get(1) {
142            // t -> PTArgs
143            args.append(&mut Self::tree_to_ptargs(t));
144        }
145        args
146    }
147}
148
149#[cfg(test)]
150mod tests {
151
152    use super::*;
153
154    #[test]
155    fn test_simple_type() {
156        let vt = ValueTypeParser::parse("int").unwrap();
157        assert!(matches!(vt, ValueType::Simple(SimpleType::Integer)));
158    }
159
160    #[test]
161    fn test_complex_type() {
162        let vt = ValueTypeParser::parse("some-class[int aaa[str]]").unwrap();
163        assert!(matches!(vt, ValueType::LeapType { .. }));
164        if let ValueType::LeapType { name, args } = vt {
165            assert_eq!(name.get(), "some-class");
166            assert_eq!(args.len(), 2);
167        }
168    }
169}