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}