cas_compiler/expr/
stmt.rs

1use cas_compute::numerical::value::Value;
2use cas_error::Error;
3use cas_parser::parser::ast::stmt::Stmt;
4use crate::{Compile, Compiler, InstructionKind};
5
6/// Helper function to compile multiple statements.
7pub fn compile_stmts(stmts: &[Stmt], compiler: &mut Compiler) -> Result<(), Error> {
8    let Some((last, stmts)) = stmts.split_last() else {
9        // nothing to compile
10        compiler.add_instr(InstructionKind::LoadConst(Value::Unit));
11        return Ok(());
12    };
13
14    compiler.with_state(|state| {
15        state.last_stmt = false;
16    }, |compiler| {
17        stmts.iter()
18            .try_for_each(|stmt| stmt.compile(compiler))
19    })?;
20
21    compiler.with_state(|state| {
22        state.last_stmt = true;
23    }, |compiler| {
24        last.compile(compiler)
25    })
26}
27
28impl Compile for Stmt {
29    fn compile(&self, compiler: &mut Compiler) -> Result<(), Error> {
30        self.expr.compile(compiler)?;
31        if self.semicolon.is_some() {
32            compiler.add_instr(InstructionKind::Drop);
33            compiler.add_instr(InstructionKind::LoadConst(Value::Unit));
34        }
35        if !compiler.state.last_stmt {
36            compiler.add_instr(InstructionKind::Drop);
37        }
38        Ok(())
39    }
40}