1use std::collections::HashMap;
2
3use pest::iterators::Pair;
4use pest::Parser;
5use pest_derive::Parser;
6use thiserror::Error;
7use paste::paste;
8
9use super::ast::{expression::{Atom, BinaryOperator, ConditionBody, EqResult, Expression, ExpressionTail, IdentExpression, MulResult, OptionalIdentifier, Parameter, PathIdent, Primary, SumResult, UnaryOperator}, program::Program, statement::Statement, top_level::{BasicBody, Body, Function, Struct, TopLevel}, r#type::CortexType};
10
11macro_rules! operator_parser {
12 ($name:ident, $typ:ty, $prev_name:ident, $prev_typ:ty) => {
13 paste! {
14 fn [<parse_ $name>](pair: Pair<Rule>) -> Result<$typ, ParseError> {
15 let mut pairs = pair.into_inner();
16 let first = Self::[<parse_ $prev_name>](pairs.next().unwrap())?;
17 let mut pair_iter = pairs.into_iter().peekable();
18 let mut rest = Vec::<(BinaryOperator, $prev_typ)>::new();
19 while pair_iter.peek().is_some() {
20 let first_pair = pair_iter.next().unwrap();
21 let second_pair = pair_iter.next().unwrap();
22 let op = Self::parse_binop(first_pair)?;
23 let right = Self::[<parse_ $prev_name>](second_pair)?;
24 rest.push((op, right));
25 }
26 Ok(
27 $typ {
28 first: first,
29 rest: rest,
30 }
31 )
32 }
33 }
34 }
35}
36
37#[derive(Parser)]
38#[grammar = "grammar.pest"] struct PestCortexParser;
40
41pub struct CortexParser;
42
43#[derive(Error, Debug)]
44pub enum ParseError {
45 #[error("Failed to parse statement '{0}'")]
46 FailStatement(String),
47 #[error("Failed to parse expression '{0}'")]
48 FailExpression(String),
49 #[error("Failed to parse atom '{0}'")]
50 FailAtom(String),
51 #[error("Failed to parse expression tail '{0}'")]
52 FailTail(String),
53 #[error("Failed to parse path '{0}'")]
54 FailPath(String),
55 #[error("Failed to parse identifier '{0}'")]
56 FailOptionalIdentifier(String),
57 #[error("Failed to parse type '{0}'")]
58 FailType(String),
59 #[error("Failed to parse top level declaration '{0}'")]
60 FailTopLevel(String),
61 #[error("Operator does not exist '{0}'")]
62 OperatorDoesNotExist(String),
63 #[error("Failed to parse program")]
64 FailProgram,
65}
66
67impl CortexParser {
68 pub fn parse_statement(input: &str) -> Result<Statement, ParseError> {
69 let pair = PestCortexParser::parse(Rule::statement, input);
70 match pair {
71 Ok(mut v) => Self::parse_stmt_pair(v.next().unwrap()),
72 Err(_) => Err(ParseError::FailStatement(String::from(input))),
73 }
74 }
75 pub fn parse_expression(input: &str) -> Result<Expression, ParseError> {
76 let pair = PestCortexParser::parse(Rule::expr, input);
77 match pair {
78 Ok(mut v) => Self::parse_expr_pair(v.next().unwrap()),
79 Err(_) => Err(ParseError::FailExpression(String::from(input))),
80 }
81 }
82 pub fn parse_type(input: &str) -> Result<CortexType, ParseError> {
83 let pair = PestCortexParser::parse(Rule::typ, input);
84 match pair {
85 Ok(mut v) => Self::parse_type_pair(v.next().unwrap()),
86 Err(_) => Err(ParseError::FailType(String::from(input))),
87 }
88 }
89 pub fn parse_function(input: &str) -> Result<Function, ParseError> {
90 let pair = PestCortexParser::parse(Rule::function, input);
91 match pair {
92 Ok(mut v) => Self::parse_func_pair(v.next().unwrap()),
93 Err(_) => Err(ParseError::FailType(String::from(input))),
94 }
95 }
96 pub fn parse_struct(input: &str) -> Result<Struct, ParseError> {
97 let pair = PestCortexParser::parse(Rule::r#struct, input);
98 match pair {
99 Ok(mut v) => Self::parse_struct_pair(v.next().unwrap()),
100 Err(_) => Err(ParseError::FailType(String::from(input))),
101 }
102 }
103 pub fn parse_top_level(input: &str) -> Result<TopLevel, ParseError> {
104 let pair = PestCortexParser::parse(Rule::topLevel, input);
105 match pair {
106 Ok(mut v) => Self::parse_toplevel_pair(v.next().unwrap()),
107 Err(_) => Err(ParseError::FailType(String::from(input))),
108 }
109 }
110 pub fn parse_path(input: &str) -> Result<PathIdent, ParseError> {
111 let pair = PestCortexParser::parse(Rule::pathIdent, input);
112 match pair {
113 Ok(mut v) => Self::parse_path_ident(v.next().unwrap()),
114 Err(_) => Err(ParseError::FailType(String::from(input))),
115 }
116 }
117 pub fn parse_program(input: &str) -> Result<Program, ParseError> {
118 let pair = PestCortexParser::parse(Rule::program, input);
119 match pair {
120 Ok(mut v) => Self::parse_program_pair(v.next().unwrap()),
121 Err(_) => Err(ParseError::FailProgram),
122 }
123 }
124
125 fn parse_program_pair(pair: Pair<Rule>) -> Result<Program, ParseError> {
126 let pairs = pair.into_inner();
127 let mut content = Vec::<TopLevel>::new();
128 for p in pairs {
129 if p.as_rule() != Rule::EOI {
130 let t = Self::parse_toplevel_pair(p)?;
131 content.push(t);
132 }
133 }
134 Ok(Program { content: content })
135 }
136
137 fn parse_toplevel_pair(mut pair: Pair<Rule>) -> Result<TopLevel, ParseError> {
138 pair = pair.into_inner().next().unwrap();
139 match pair.as_rule() {
140 Rule::function => {
141 Ok(TopLevel::Function(Self::parse_func_pair(pair)?))
142 },
143 Rule::r#struct => {
144 Ok(TopLevel::Struct(Self::parse_struct_pair(pair)?))
145 },
146 Rule::import => {
147 let name: &str;
148 let mut is_string = false;
149 let p = pair.into_inner().next().unwrap();
150 if p.as_rule() == Rule::string {
151 name = p.into_inner().next().unwrap().as_str();
152 is_string = true;
153 } else {
154 name = p.as_str();
155 }
156 Ok(TopLevel::Import { name: String::from(name), is_string_import: is_string })
157 },
158 Rule::module => {
159 let mut pairs = pair.into_inner();
160 let name = pairs.next().unwrap().as_str();
161 let mut contents = Vec::<TopLevel>::new();
162 for p in pairs {
163 let toplevel = Self::parse_toplevel_pair(p)?;
164 contents.push(toplevel);
165 }
166 Ok(TopLevel::Module { name: String::from(name), contents: contents })
167 },
168 _ => Err(ParseError::FailTopLevel(String::from(pair.as_str()))),
169 }
170 }
171
172 fn parse_stmt_pair(mut pair: Pair<Rule>) -> Result<Statement, ParseError> {
173 pair = pair.into_inner().next().unwrap();
174 let orig = pair.as_str();
175 match pair.as_rule() {
176 Rule::expr => {
177 let expression = Self::parse_expr_pair(pair)?;
178 Ok(Statement::Expression(expression))
179 },
180 Rule::throw => {
181 let expression = Self::parse_expr_pair(pair.into_inner().next().unwrap())?;
182 Ok(Statement::Throw(expression))
183 },
184 Rule::varDec => {
185 let is_const = pair.as_str().starts_with("const");
186 let mut pairs = pair.into_inner();
187 let name = Self::parse_opt_ident(pairs.next().unwrap())?;
188 let third_pair = pairs.next().unwrap();
189 let mut typ: Option<CortexType> = None;
190 let init_value =
191 if third_pair.as_rule() == Rule::typ {
192 typ = Some(Self::parse_type_pair(third_pair)?);
193 Self::parse_expr_pair(pairs.next().unwrap())?
194 } else {
195 Self::parse_expr_pair(third_pair)?
196 };
197 Ok(Statement::VariableDeclaration {
198 name: name,
199 is_const: is_const,
200 typ: typ,
201 initial_value: init_value,
202 })
203 },
204 Rule::varAssign => {
205 let mut pairs = pair.into_inner();
206 let left = Self::parse_ident_expr(pairs.next().unwrap())?;
207 let value;
208 let op;
209 let next = pairs.next().unwrap();
210 match next.as_rule() {
211 Rule::arithLogicBinOp => {
212 op = Some(Self::parse_binop(next.into_inner().next().unwrap())?);
213 value = Self::parse_expr_pair(pairs.next().unwrap())?;
214 },
215 Rule::expr => {
216 op = None;
217 value = Self::parse_expr_pair(next)?;
218 },
219 _ => return Err(ParseError::FailStatement(String::from(orig)))
220 }
221
222 Ok(Statement::VariableAssignment {
223 name: left,
224 value: value,
225 op: op,
226 })
227 },
228 Rule::r#while => {
229 let mut pairs = pair.into_inner();
230 let cond = Self::parse_expr_pair(pairs.next().unwrap())?;
231 let body = Self::parse_body(pairs.next().unwrap())?;
232 Ok(Statement::WhileLoop(ConditionBody { condition: cond, body: body }))
233 },
234 _ => Err(ParseError::FailStatement(String::from(pair.as_str()))),
235 }
236 }
237
238 fn parse_primary(pair: Pair<Rule>) -> Result<Primary, ParseError> {
239 let mut pairs = pair.into_inner();
240 let atom_pair = pairs.next().unwrap();
241 let atom = Self::parse_atom_pair(atom_pair.into_inner().next().unwrap())?;
242 let mut expr_tail = ExpressionTail::None;
243 let next = pairs.next();
244 if next.is_some() {
245 let expr_tail_pair = next.unwrap();
246 expr_tail = Self::parse_expr_tail_pair(expr_tail_pair)?;
247 }
248 Ok(Primary {
249 atom: atom,
250 tail: expr_tail,
251 })
252 }
253 operator_parser!(mul_result, MulResult, primary, Primary);
254 operator_parser!(sum_result, SumResult, mul_result, MulResult);
255 operator_parser!(eq_result, EqResult, sum_result, SumResult);
256 operator_parser!(expr_pair, Expression, eq_result, EqResult);
257
258 fn parse_atom_pair(pair: Pair<Rule>) -> Result<Atom, ParseError> {
259 match pair.as_rule() {
260 Rule::number => {
261 let value: f64 = pair.as_str().parse().unwrap();
262 Ok(Atom::Number(value))
263 },
264 Rule::boolean => {
265 let value: bool = pair.as_str().parse().unwrap();
266 Ok(Atom::Boolean(value))
267 },
268 Rule::string => {
269 Ok(Atom::String(String::from(pair.into_inner().next().unwrap().as_str())))
270 },
271 Rule::null => {
272 Ok(Atom::Null)
273 },
274 Rule::void => {
275 Ok(Atom::Void)
276 },
277 Rule::pathIdent => {
278 Ok(Atom::PathIdent(Self::parse_path_ident(pair)?))
279 },
280 Rule::expr => {
281 Ok(Atom::Expression(Box::new(Self::parse_expr_pair(pair)?)))
282 },
283 Rule::call => {
284 let mut pairs = pair.into_inner();
285 let name = Self::parse_path_ident(pairs.next().unwrap())?;
286 let mut args: Vec<Expression> = Vec::new();
287 for arg in pairs {
288 let parsed_arg = Self::parse_expr_pair(arg)?;
289 args.push(parsed_arg);
290 }
291 Ok(Atom::Call(name, args))
292 },
293 Rule::structConstruction => {
294 let mut pairs = pair.into_inner();
295 let name = Self::parse_path_ident(pairs.next().unwrap())?;
296 let mut assignments = Vec::new();
297 for p in pairs {
298 let mut member_init = p.into_inner();
299 let name = member_init.next().unwrap().as_str();
300 let expr = Self::parse_expr_pair(member_init.next().unwrap())?;
301 assignments.push((String::from(name), expr));
302 }
303 Ok(Atom::StructConstruction { name: name, assignments: assignments })
304 },
305 Rule::r#if => {
306 let mut pairs = pair.into_inner();
307 let first_cond = Self::parse_expr_pair(pairs.next().unwrap())?;
308 let first_body = Self::parse_body(pairs.next().unwrap())?;
309 let elifs_pair = pairs.next().unwrap();
310 let elifs_pairs = elifs_pair.into_inner();
311 let mut elifs = Vec::<ConditionBody>::new();
312 for p in elifs_pairs {
313 elifs.push(Self::parse_condition_body(p)?);
314 }
315 let op_else_pair = pairs.next();
316 let else_body =
317 if let Some(else_pair) = op_else_pair {
318 Some(Box::new(Self::parse_body(else_pair.into_inner().next().unwrap())?))
319 } else {
320 None
321 };
322
323 Ok(Atom::IfStatement {
324 first: Box::new(ConditionBody { condition: first_cond, body: first_body }),
325 conds: elifs,
326 last: else_body,
327 })
328 },
329 Rule::unOpAtom => {
330 let mut pairs = pair.into_inner();
331 let unop = Self::parse_unop(pairs.next().unwrap())?;
332 let expr = Self::parse_expr_pair(pairs.next().unwrap())?;
333 Ok(Atom::UnaryOperation { op: unop, exp: Box::new(expr) })
334 },
335 _ => Err(ParseError::FailAtom(String::from(pair.as_str()))),
336 }
337 }
338
339 fn parse_expr_tail_pair(pair: Pair<Rule>) -> Result<ExpressionTail, ParseError> {
340 match pair.as_rule() {
341 Rule::exprTail => {
342 if let Some(tail_pair) = pair.into_inner().next() {
343 match tail_pair.as_rule() {
344 Rule::postfixBangTail => {
345 let next = Self::parse_expr_tail_pair(tail_pair.into_inner().next().unwrap())?;
346 Ok(ExpressionTail::PostfixBang { next: Box::new(next) })
347 },
348 Rule::memberAccessTail => {
349 let mut pairs = tail_pair.into_inner();
350 let member = pairs.next().unwrap().as_str();
351 let next = Self::parse_expr_tail_pair(pairs.next().unwrap())?;
352 Ok(ExpressionTail::MemberAccess { member: String::from(member), next: Box::new(next) })
353 },
354 _ => Err(ParseError::FailTail(String::from(tail_pair.as_str()))),
355 }
356 } else {
357 Ok(ExpressionTail::None)
358 }
359 }
360 _ => Err(ParseError::FailTail(String::from(pair.as_str()))),
361 }
362 }
363
364 fn parse_condition_body(pair: Pair<Rule>) -> Result<ConditionBody, ParseError> {
365 let mut pairs = pair.into_inner();
366 let cond = Self::parse_expr_pair(pairs.next().unwrap())?;
367 let body = Self::parse_body(pairs.next().unwrap())?;
368 Ok(ConditionBody {
369 condition: cond,
370 body: body,
371 })
372 }
373
374 fn parse_binop(pair: Pair<Rule>) -> Result<BinaryOperator, ParseError> {
375 match pair.as_rule() {
376 Rule::add => Ok(BinaryOperator::Add),
377 Rule::sub => Ok(BinaryOperator::Subtract),
378 Rule::mul => Ok(BinaryOperator::Multiply),
379 Rule::div => Ok(BinaryOperator::Divide),
380 Rule::rem => Ok(BinaryOperator::Remainder),
381 Rule::and => Ok(BinaryOperator::LogicAnd),
382 Rule::or => Ok(BinaryOperator::LogicOr),
383 Rule::eq => Ok(BinaryOperator::IsEqual),
384 Rule::neq => Ok(BinaryOperator::IsNotEqual),
385 Rule::lt => Ok(BinaryOperator::IsLessThan),
386 Rule::lte => Ok(BinaryOperator::IsLessThanOrEqualTo),
387 Rule::gt => Ok(BinaryOperator::IsGreaterThan),
388 Rule::gte => Ok(BinaryOperator::IsGreaterThanOrEqualTo),
389 _ => Err(ParseError::OperatorDoesNotExist(String::from(pair.as_str()))),
390 }
391 }
392 fn parse_unop(pair: Pair<Rule>) -> Result<UnaryOperator, ParseError> {
393 match pair.as_rule() {
394 Rule::negate => Ok(UnaryOperator::Negate),
395 Rule::invert => Ok(UnaryOperator::Invert),
396 _ => Err(ParseError::OperatorDoesNotExist(String::from(pair.as_str()))),
397 }
398 }
399
400 fn parse_path_ident(pair: Pair<Rule>) -> Result<PathIdent, ParseError> {
401 let mut names = Vec::<String>::new();
402 for p in pair.into_inner() {
403 let name = String::from(p.as_str());
404 names.push(name);
405 }
406 Ok(PathIdent {
407 path: names,
408 })
409 }
410
411 fn parse_ident_expr(pair: Pair<Rule>) -> Result<IdentExpression, ParseError> {
412 let mut pairs = pair.into_inner();
413 let path = Self::parse_path_ident(pairs.next().unwrap())?;
414 let mut chain = Vec::new();
415 for p in pairs {
416 chain.push(String::from(p.as_str()));
417 }
418 Ok(IdentExpression {
419 base: path,
420 chain: chain,
421 })
422 }
423
424 fn parse_type_pair(pair: Pair<Rule>) -> Result<CortexType, ParseError> {
425 let nullable = pair.as_str().contains("?");
426 let path_pair = pair.into_inner().next().unwrap();
427 let path_str = String::from(path_pair.as_str());
428 let ident = Self::parse_path_ident(path_pair)?;
429 if ident.get_back().map_err(|_e| ParseError::FailPath(path_str))? == "any" {
430 Ok(CortexType::any(nullable))
431 } else {
432 Ok(CortexType::new(ident, nullable))
433 }
434 }
435
436 fn parse_opt_ident(pair: Pair<Rule>) -> Result<OptionalIdentifier, ParseError> {
437 if pair.as_str() == "~" {
438 Ok(OptionalIdentifier::Ignore)
439 } else {
440 Ok(OptionalIdentifier::Ident(String::from(pair.as_str())))
441 }
442 }
443
444 fn parse_struct_pair(pair: Pair<Rule>) -> Result<Struct, ParseError> {
445 let mut pairs = pair.into_inner();
446 let name = Self::parse_opt_ident(pairs.next().unwrap())?;
447 let field_params = Self::parse_param_list(pairs.next().unwrap())?;
448 let mut fields = HashMap::new();
449 for p in field_params {
450 fields.insert(p.name, p.typ);
451 }
452
453 Ok(
454 Struct {
455 name: name,
456 fields: fields,
457 }
458 )
459 }
460
461 fn parse_func_pair(pair: Pair<Rule>) -> Result<Function, ParseError> {
462 let mut pairs = pair.into_inner();
463 let name = Self::parse_opt_ident(pairs.next().unwrap())?;
464 let params = Self::parse_param_list(pairs.next().unwrap())?;
465 let return_type = Self::parse_type_pair(pairs.next().unwrap())?;
466 let body = Self::parse_body(pairs.next().unwrap())?;
467 Ok(Function {
468 name: name,
469 params: params,
470 return_type: return_type,
471 body: Body::Basic(body),
472 })
473 }
474
475 fn parse_param_list(pair: Pair<Rule>) -> Result<Vec<Parameter>, ParseError> {
476 let pairs = pair.into_inner();
477 let mut params = Vec::<Parameter>::new();
478 for p in pairs {
479 params.push(Self::parse_param(p)?);
480 }
481 Ok(params)
482 }
483 fn parse_param(pair: Pair<Rule>) -> Result<Parameter, ParseError> {
484 let mut pairs = pair.into_inner();
485 let ident = pairs.next().unwrap().as_str();
486 let typ = Self::parse_type_pair(pairs.next().unwrap())?;
487 Ok(
488 Parameter {
489 name: String::from(ident),
490 typ: typ,
491 }
492 )
493 }
494
495 fn parse_body(pair: Pair<Rule>) -> Result<BasicBody, ParseError> {
496 let mut result: Option<Expression> = None;
497 let mut statements = Vec::<Statement>::new();
498
499 let mut iter = pair.into_inner().peekable();
500 while let Some(p) = iter.next() {
501 let is_last = iter.peek().is_none();
502 if is_last {
503 if p.as_rule() == Rule::expr {
504 result = Some(Self::parse_expr_pair(p)?);
505 } else {
506 statements.push(Self::parse_stmt_pair(p)?);
507 }
508 } else {
509 statements.push(Self::parse_stmt_pair(p)?);
510 }
511 }
512 Ok(
513 BasicBody {
514 statements: statements,
515 result: result,
516 }
517 )
518 }
519}