microcad_lang/syntax/
assignment.rs

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