cpclib_asm/assembler/
string.rs1use 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}