Skip to main content

microcad_lang/syntax/
assignment.rs

1// Copyright © 2024-2026 The µcad authors <info@microcad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! µcad assignment syntax element
5
6use microcad_lang_base::{SrcRef, SrcReferrer, TreeDisplay, TreeState};
7
8use crate::{syntax::*, ty::*};
9
10/// Assignment specifying an identifier, type and value
11#[derive(Clone)]
12pub struct Assignment {
13    /// Documentation.
14    pub doc: Option<DocBlock>,
15    /// Value's visibility
16    pub visibility: Visibility,
17    /// Assignee qualifier
18    pub qualifier: Qualifier,
19    /// Assignee
20    pub(crate) id: Identifier,
21    /// Type of the assignee
22    pub specified_type: Option<TypeAnnotation>,
23    /// Value to assign
24    pub expression: Expression,
25    /// Source code reference
26    pub src_ref: SrcRef,
27}
28
29impl Assignment {
30    /// Create new assignment.
31    pub fn new(
32        doc: Option<DocBlock>,
33        visibility: Visibility,
34        qualifier: Qualifier,
35        id: Identifier,
36        specified_type: Option<TypeAnnotation>,
37        expression: Expression,
38        src_ref: SrcRef,
39    ) -> Self {
40        Self {
41            doc,
42            visibility,
43            qualifier,
44            id,
45            specified_type,
46            expression,
47            src_ref,
48        }
49    }
50
51    /// Get qualifier (makes `pub` => `pub const`)
52    pub fn qualifier(&self) -> Qualifier {
53        match self.visibility {
54            Visibility::Private | Visibility::PrivateUse(_) => self.qualifier,
55            Visibility::Public => Qualifier::Const,
56            Visibility::Deleted => unreachable!(),
57        }
58    }
59}
60
61impl Identifiable for Assignment {
62    fn id_ref(&self) -> &Identifier {
63        &self.id
64    }
65}
66
67impl SrcReferrer for Assignment {
68    fn src_ref(&self) -> SrcRef {
69        self.src_ref.clone()
70    }
71}
72
73impl std::fmt::Display for Assignment {
74    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
75        match &self.specified_type {
76            Some(t) => write!(
77                f,
78                "{vis}{qual}{id}: {ty} = {expr}",
79                vis = self.visibility,
80                qual = self.qualifier,
81                id = self.id,
82                ty = t.ty(),
83                expr = self.expression
84            ),
85            None => write!(
86                f,
87                "{vis}{qual}{id} = {expr}",
88                vis = self.visibility,
89                qual = self.qualifier,
90                id = self.id,
91                expr = self.expression
92            ),
93        }
94    }
95}
96
97impl std::fmt::Debug for Assignment {
98    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
99        match &self.specified_type {
100            Some(t) => write!(
101                f,
102                "{vis}{qual}{id:?}: {ty:?} = {expr:?}",
103                vis = self.visibility,
104                qual = self.qualifier,
105                id = self.id,
106                ty = t.ty(),
107                expr = self.expression
108            ),
109            None => write!(f, "{} = {}", self.id, self.expression),
110        }
111    }
112}
113
114impl TreeDisplay for Assignment {
115    fn tree_print(&self, f: &mut std::fmt::Formatter, mut depth: TreeState) -> std::fmt::Result {
116        writeln!(
117            f,
118            "{:depth$}Assignment {vis}{qual}'{id}':",
119            "",
120            vis = self.visibility,
121            qual = self.qualifier,
122            id = self.id
123        )?;
124        depth.indent();
125        if let Some(specified_type) = &self.specified_type {
126            specified_type.tree_print(f, depth)?;
127        }
128        self.expression.tree_print(f, depth)
129    }
130}