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