dice_rust/
analyzer.rs

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}