1use crate::ast::{ExpressionKind, Program, StatementKind};
2use crate::error::{ParseError, SemanticError};
3use crate::parser::Parser;
4
5pub struct SemanticAnalyzer {
6 ast: Program,
7}
8
9impl SemanticAnalyzer {
10 pub fn new(source: &str) -> Result<Self, ParseError> {
11 let mut parser = Parser::new(source)?;
12 let ast = parser.parse()?;
13 Ok(Self { ast })
14 }
15
16 pub fn analyze(&mut self) -> Result<Program, SemanticError> {
17 let statement = self
18 .ast
19 .statement
20 .as_ref()
21 .ok_or(SemanticError::EmptyProgram)?;
22 let expression = match &statement.kind {
23 StatementKind::Expression { expr } => expr,
24 };
25 match &expression.kind {
26 ExpressionKind::Dice { count, faces } => {
27 if *count == 0 {
28 return Err(SemanticError::DiceCountZero);
29 }
30 if *faces == 0 {
31 return Err(SemanticError::DiceFacesZero);
32 }
33 }
34 };
35 Ok(self.ast.clone())
36 }
37}