cpclib_asm/assembler/
string.rs

1use std::fmt::{Display, Write};
2
3use cpclib_common::smol_str::SmolStr;
4use cpclib_tokens::{Expr, ExprFormat, ExprResult, FormattedExpr};
5
6use super::Env;
7use crate::error::AssemblerError;
8
9#[derive(Clone, Debug)]
10pub enum PreprocessedFormattedExpr {
11    String(SmolStr),
12    Char(char),
13    ExprResult(ExprResult),
14    Formatted(ExprFormat, i32)
15}
16
17#[derive(Default, Clone, Debug)]
18pub struct PreprocessedFormattedString {
19    components: Vec<PreprocessedFormattedExpr>
20}
21
22impl Display for PreprocessedFormattedExpr {
23    #[inline]
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        match self {
26            PreprocessedFormattedExpr::String(s) => f.write_str(s),
27            PreprocessedFormattedExpr::Char(c) => f.write_char(*c),
28            PreprocessedFormattedExpr::ExprResult(e) => f.write_str(&e.to_string()),
29            PreprocessedFormattedExpr::Formatted(f2, v) => {
30                f.write_str(&f2.string_representation(*v))
31            },
32        }
33    }
34}
35
36impl Display for PreprocessedFormattedString {
37    #[inline]
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        self.components.iter().for_each(|c| {
40            c.fmt(f);
41        });
42        Ok(())
43    }
44}
45
46impl PreprocessedFormattedExpr {
47    pub fn try_new(
48        fe: &FormattedExpr,
49        env: &mut Env
50    ) -> Result<PreprocessedFormattedExpr, AssemblerError> {
51        match fe {
52            FormattedExpr::Raw(Expr::String(string)) => {
53                Ok(PreprocessedFormattedExpr::String(string.clone()))
54            },
55            FormattedExpr::Raw(Expr::Char(char)) => Ok(PreprocessedFormattedExpr::Char(*char)),
56            FormattedExpr::Raw(expr) => {
57                let value = env.resolve_expr_may_fail_in_first_pass(expr)?;
58                Ok(PreprocessedFormattedExpr::ExprResult(value))
59            },
60            FormattedExpr::Formatted(format, expr) => {
61                let value = env.resolve_expr_may_fail_in_first_pass(expr)?.int()?;
62                Ok(PreprocessedFormattedExpr::Formatted(*format, value))
63            }
64        }
65    }
66}
67
68impl PreprocessedFormattedString {
69    pub fn try_new(info: &[FormattedExpr], env: &mut Env) -> Result<Self, AssemblerError> {
70        let mut components = Vec::with_capacity(info.len());
71        for component in info.iter() {
72            components.push(PreprocessedFormattedExpr::try_new(component, env)?);
73        }
74
75        Ok(Self { components })
76    }
77}