py_ast/parse/
item.rs

1use super::*;
2use py_lex::syntax::Symbol;
3
4#[derive(Debug, Clone)]
5pub struct Comment;
6
7impl ParseUnit<Token> for Comment {
8    type Target = Comment;
9
10    fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
11        p.r#match(Symbol::Comment)?;
12
13        loop {
14            let str = p
15                .parse::<Token>()
16                .map_err(|e| e.append("comment without ending"))?;
17
18            if &*str == "jie2" {
19                return Ok(Comment {});
20            }
21        }
22    }
23}
24
25#[derive(Debug, Clone)]
26pub struct FnDefine {
27    pub export: Option<Span>,
28    pub ty: types::TypeDefine,
29    pub name: Ident,
30    pub params: Parameters,
31    pub codes: CodeBlock,
32    pub retty_span: Span,
33    pub sign_span: Span,
34}
35
36impl ParseUnit<Token> for FnDefine {
37    type Target = FnDefine;
38
39    fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
40        let export = p
41            .r#match(RPU(Symbol::Export))
42            .apply(mapper::Try)?
43            .map(|pu| pu.get_span());
44        let ty = p.parse::<PU<types::TypeDefine>>()?;
45        let name = p.parse::<Ident>()?;
46        let params = p.parse::<PU<Parameters>>()?;
47        let codes = p.parse::<CodeBlock>().apply(mapper::MustMatch)?;
48
49        Ok(Self {
50            export,
51            retty_span: ty.get_span(),
52            sign_span: ty.get_span().merge(params.get_span()),
53            ty: ty.take(),
54            name,
55            params: params.take(),
56            codes,
57        })
58    }
59}
60
61#[derive(Debug, Clone)]
62pub struct CodeBlock {
63    pub stmts: Vec<Statement>,
64}
65
66impl ParseUnit<Token> for CodeBlock {
67    type Target = CodeBlock;
68
69    fn parse(p: &mut Parser<Token>) -> ParseResult<Self, Token> {
70        p.r#match(Symbol::Block)?;
71        let mut stmts = vec![];
72        while let Some(stmt) = p.parse::<Statement>().apply(mapper::Try)? {
73            stmts.push(stmt)
74        }
75        p.r#match(Symbol::EndOfBlock)?;
76        Ok(Self { stmts })
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use crate::parse_test;
83
84    use super::*;
85
86    #[test]
87    fn code_block() {
88        parse_test("han2 jie2", |p| {
89            p.parse::<CodeBlock>()?;
90            Ok(())
91        });
92    }
93
94    #[test]
95    fn function_define() {
96        parse_test(
97            "zheng3 zhu3 can1 zheng3 argc fen1 zhi3 zhi3 zi4 argv jie2
98                    han2
99                    jie2",
100            |p| {
101                p.parse::<FnDefine>()?;
102                Ok(())
103            },
104        );
105    }
106
107    #[test]
108    fn complex_funcion_define() {
109        parse_test(
110            "zheng3 zhu3 can1 zheng3 argc fen1 zhi3 zu3 zi4 argv jie2 
111                    han2
112                        ruo4 can1 jie2 1 da4 0 he2 huo4 jie2 2 xiao3 3 he2 yu3 fei1 fou3 jie2
113                        han2 
114                            shi4 if ((1>0)||(2<3)&&!false){} else{} jie2
115                        jie2 ze2 han2 
116
117                        jie2
118                    jie2",
119            |p| {
120                p.parse::<FnDefine>()?;
121                Ok(())
122            },
123        )
124    }
125
126    #[test]
127    fn comment() {
128        parse_test("shi4 ehhhaaaaaaaaaaaaaaaaaaaaaaaa jie2", |p| {
129            p.parse::<Comment>()?;
130            Ok(())
131        });
132    }
133
134    #[test]
135    #[should_panic]
136    fn comment_without_ending() {
137        parse_test("shi4 ehhhaaaaaaaaaaaaaaaaaaaaaaaa ajie2", |p| {
138            p.parse::<CodeBlock>()?;
139            Ok(())
140        });
141    }
142}