1use std::str::FromStr;
2
3use crate::{
4 ast::*,
5 errors::{Error as OYError, Result as OYResult},
6 utils,
7};
8
9use super::ast::{Block, ExpressionStatement, Program, Statement};
10use bigdecimal::BigDecimal;
11use pest::{iterators::Pair, Parser};
12use pest_derive::Parser;
13
14#[derive(Parser, Debug)]
16#[grammar = "grammar.pest"]
17pub struct OYParser;
18
19impl<'a> OYParser {
20 pub fn parse_program(input: &'a str) -> OYResult<Program> {
22 let program_pair = OYParser::parse(Rule::program, input)
23 .map_err(OYError::from)?
24 .next()
25 .unwrap();
26 let span = program_pair.as_span();
27 Ok((
28 program_pair
29 .into_inner()
30 .filter(|pair| pair.as_rule() != Rule::EOI)
31 .map(Self::parse_statement)
32 .collect::<OYResult<Vec<_>>>()?
33 .into_iter()
34 .flatten()
35 .collect(),
36 span,
37 ))
38 }
39
40 pub fn parse_statement(statement: Pair<'a, Rule>) -> OYResult<Option<Statement>> {
42 match statement.as_rule() {
43 Rule::func_def => Ok(Some(Self::parse_function(statement)?)),
44 Rule::assignment => Ok(Some(Self::parse_assignment(statement)?)),
45 Rule::return_stmt => Ok(Some(Self::parse_return(statement)?)),
46 Rule::expression => Ok(Some(Statement::Expression(Self::parse_expression(
47 statement,
48 )?))),
49 Rule::statement => Self::parse_statement(statement.into_inner().next().unwrap()),
50 Rule::semicolon => Ok(None),
51 _ => {
52 dbg!(statement.as_rule());
53 unreachable!("This function only parse the statements")
54 }
55 }
56 }
57
58 pub fn parse_block(block: Pair<'a, Rule>) -> OYResult<Block> {
60 let span = block.as_span();
61 Ok(Block {
62 statements: block
63 .into_inner()
64 .map(Self::parse_statement)
65 .collect::<OYResult<Vec<Option<_>>>>()?
66 .into_iter()
67 .flatten()
68 .collect(),
69 span: span.into(),
70 })
71 }
72
73 pub fn parse_ident(ident: Pair<'a, Rule>) -> Ident {
76 let span = ident.as_span();
77 let ident = ident.as_str().to_owned();
78 Ident {
79 ident: ident.as_str().to_owned(),
80 span: span.into(),
81 }
82 }
83
84 pub fn parse_visibility(visibility: Pair<'a, Rule>) -> Visibility {
87 match visibility.as_rule() {
88 Rule::PUBLIC => Visibility::Public,
89 Rule::PRIVATE => Visibility::Private,
90 Rule::visibility => Self::parse_visibility(visibility.into_inner().next().unwrap()),
91 _ => {
92 dbg!(visibility.as_rule());
93 unreachable!("This function only parse the visibility")
94 }
95 }
96 }
97
98 pub fn parse_expression(expr: Pair<'a, Rule>) -> OYResult<ExpressionStatement> {
100 match expr.as_rule() {
101 Rule::func_call => Ok(ExpressionStatement::FunctionCall(
102 Self::parse_function_call(expr)?,
103 )),
104 Rule::value => Ok(ExpressionStatement::Value(Self::parse_value(expr)?)),
105 Rule::expression => Self::parse_expression(expr.into_inner().next().unwrap()),
106 Rule::anonymous_function => {
107 let anonymous_function = Self::parse_anonymous_function(expr)?;
108 Ok(ExpressionStatement::Value(ValueExpression::Object(
109 ObjectExpression::Function(anonymous_function),
110 )))
111 }
112 _ => {
113 dbg!(expr.as_rule());
114 unreachable!("This function only parse the expressions")
115 }
116 }
117 }
118
119 pub fn parse_function_call(func: Pair<'a, Rule>) -> OYResult<FunctionCallExpression> {
122 let span = func.as_span();
123 let mut inner = func.into_inner();
124 let callable = inner.next().unwrap();
125 let args = inner
126 .next()
127 .unwrap()
128 .into_inner()
129 .map(Self::parse_arg)
130 .collect::<OYResult<Vec<_>>>()?;
131 match callable.as_rule() {
132 Rule::IDENT => Ok(FunctionCallExpression {
133 callable: ValueExpression::Ident(Self::parse_ident(callable)),
134 args,
135 span: span.into(),
136 }),
137 Rule::anonymous_function => {
138 let anonymous_function = Self::parse_anonymous_function(callable)?;
139
140 Ok(FunctionCallExpression {
141 callable: ValueExpression::Object(ObjectExpression::Function(
142 anonymous_function,
143 )),
144 args,
145 span: span.into(),
146 })
147 }
148 _ => {
149 dbg!(callable.as_rule());
150 unreachable!("This function only parse the function call expressions")
151 }
152 }
153 }
154
155 pub fn parse_return(return_stmt: Pair<'a, Rule>) -> OYResult<Statement> {
158 let span = return_stmt.as_span();
159 let mut inner = return_stmt.into_inner();
160 Ok(Statement::Return(ReturnStatement {
161 value: Self::parse_expression(inner.next().unwrap())?,
162 span: span.into(),
163 }))
164 }
165
166 pub fn parse_value(value: Pair<'a, Rule>) -> OYResult<ValueExpression> {
169 let span = value.as_span();
170 Ok(match value.as_rule() {
171 Rule::IDENT => ValueExpression::Ident(Self::parse_ident(value)),
172 Rule::string => ValueExpression::Object(ObjectExpression::String(
173 value.as_str()[1..value.as_str().len() - 1]
174 .replace(r#"\\"#, r#"\"#)
175 .replace(r#"\""#, r#"""#)
176 .replace(r#"\n"#, "\n")
177 .replace(r#"\t"#, "\t")
178 .replace(r#"\r"#, "\r"),
179 span.into(),
180 )),
181 Rule::float => ValueExpression::Object(ObjectExpression::Float(
182 BigDecimal::from_str(value.as_str()).unwrap(),
183 span.into(),
184 )),
185 Rule::integer => ValueExpression::Object(ObjectExpression::Int(
186 BigDecimal::from_str(value.as_str()).unwrap(),
187 span.into(),
188 )),
189 Rule::boolean => ValueExpression::Object(ObjectExpression::Bool(
190 value.as_str().parse().unwrap(),
191 span.into(),
192 )),
193 Rule::array => ValueExpression::Object(ObjectExpression::Array(
194 value
195 .into_inner()
196 .map(Self::parse_expression)
197 .collect::<OYResult<_>>()?,
198 span.into(),
199 )),
200 Rule::nil => ValueExpression::Object(ObjectExpression::Nil(span.into())),
201 Rule::value => Self::parse_value(value.into_inner().next().unwrap())?,
202 _ => {
203 dbg!(value.as_rule());
204 unreachable!("This function only parse the values")
205 }
206 })
207 }
208
209 pub fn parse_anonymous_function(anonymous_func: Pair<'a, Rule>) -> OYResult<FunctionStatement> {
212 let span = anonymous_func.as_span();
213 let mut anonymous_inner = anonymous_func.into_inner();
214 let params = anonymous_inner
215 .next()
216 .unwrap()
217 .into_inner()
218 .map(Self::parse_param)
219 .collect::<OYResult<_>>()?;
220 let block = Self::parse_block(anonymous_inner.next().unwrap())?;
221 Ok(FunctionStatement {
222 ident: None,
223 params,
224 block: Some(block),
225 span: span.into(),
226 visibility: Visibility::Private,
227 })
228 }
229
230 pub fn parse_function(func: Pair<'a, Rule>) -> OYResult<Statement> {
233 let span = func.as_span();
234 let mut inner = func.into_inner();
235 let visibility = Self::parse_visibility(inner.next().unwrap());
236 let ident = utils::check_ident_case(
237 Self::parse_ident(inner.next().unwrap()),
238 "function",
239 "the function name must be snake_case",
240 utils::Case::Snake,
241 )?;
242 let params = inner
243 .next()
244 .unwrap()
245 .into_inner()
246 .map(Self::parse_param)
247 .collect::<OYResult<Vec<_>>>()?;
248 let params = utils::cheeck_params(params, &ident)?;
249 let block = Some(Self::parse_block(inner.next().unwrap())?);
250 utils::check_main_function(&ident, ¶ms, &visibility)?;
251 Ok(Statement::Function(FunctionStatement {
252 ident: Some(ident),
253 params,
254 block,
255 visibility,
256 span: span.into(),
257 }))
258 }
259
260 pub fn parse_arg(arg: Pair<'a, Rule>) -> OYResult<Arg> {
263 let mut inner = arg.into_inner();
264 let is_unpack = inner.next().unwrap().as_str() == "...";
265 let expr = Self::parse_expression(inner.next().unwrap())?;
266 let span = expr.span();
267 Ok(Arg {
268 expr,
269 is_unpack,
270 span,
271 })
272 }
273
274 pub fn parse_param(param: Pair<'a, Rule>) -> OYResult<Param> {
277 let mut inner = param.into_inner();
278 let is_pack = inner.next().unwrap().as_str() == "*";
279 let ident = utils::check_ident_case(
280 Self::parse_ident(inner.next().unwrap()),
281 "parameter",
282 "the parameter name must be snake_case",
283 utils::Case::Snake,
284 )?;
285 Ok(Param { ident, is_pack })
286 }
287
288 pub fn parse_assignment(assignment: Pair<'a, Rule>) -> OYResult<Statement> {
291 let span = assignment.as_span();
292 let mut inner = assignment.into_inner();
293 let ident = utils::check_ident_case(
294 Self::parse_ident(inner.next().unwrap()),
295 "variable",
296 "the variable name must be snake_case",
297 utils::Case::Snake,
298 )?;
299 let expression = Self::parse_expression(inner.next().unwrap())?;
300 Ok(Statement::Assignment(AssignmentStatement {
301 ident,
302 expression,
303 span: span.into(),
304 }))
305 }
306}