amarok_parser/builders/
mod.rs1use amarok_syntax::{Diagnostic, Program, Spanned, Statement};
2use pest::iterators::Pair;
3
4use crate::grammar::Rule;
5
6pub(crate) mod expressions;
7pub(crate) mod helpers;
8pub(crate) mod statements;
9
10pub(crate) use expressions::build_expression;
11
12use helpers::span_of;
13use statements::{
14 build_assignment_statement, build_block_statement, build_expression_statement,
15 build_function_definition, build_if_statement, build_return_statement, build_use_statement,
16 build_while_statement,
17};
18
19pub(crate) fn build_program(pair: Pair<Rule>) -> Result<Program, Diagnostic> {
20 if pair.as_rule() != Rule::program {
21 return Err(
22 Diagnostic::new(format!("Expected program rule, got {:?}", pair.as_rule()))
23 .with_span(span_of(&pair)),
24 );
25 }
26
27 let mut statements: Vec<Spanned<Statement>> = Vec::new();
28
29 for item in pair.into_inner() {
30 match item.as_rule() {
33 Rule::assignment_statement
34 | Rule::return_statement
35 | Rule::if_statement
36 | Rule::while_statement
37 | Rule::function_definition
38 | Rule::block_statement
39 | Rule::use_statement
40 | Rule::expression_statement => statements.push(build_statement(item)?),
41
42 _ => {}
44 }
45 }
46
47 Ok(Program { statements })
48}
49
50pub(crate) fn build_statement(pair: Pair<Rule>) -> Result<Spanned<Statement>, Diagnostic> {
51 let statement_span = span_of(&pair);
52
53 let statement_value = match pair.as_rule() {
54 Rule::assignment_statement => build_assignment_statement(pair)?,
55 Rule::expression_statement => build_expression_statement(pair)?,
56 Rule::block_statement => build_block_statement(pair)?,
57 Rule::if_statement => build_if_statement(pair)?,
58 Rule::while_statement => build_while_statement(pair)?,
59 Rule::function_definition => build_function_definition(pair)?,
60 Rule::return_statement => build_return_statement(pair)?,
61 Rule::use_statement => build_use_statement(pair)?,
62 other => {
63 return Err(
64 Diagnostic::new(format!("Unhandled statement rule: {other:?}"))
65 .with_span(statement_span),
66 );
67 }
68 };
69
70 Ok(Spanned::new(statement_span, statement_value))
71}