microcad_lang/syntax/parameter/
mod.rs1mod parameter_list;
7
8use crate::{diag::*, eval::*, ord_map::*, src_ref::*, syntax::*, ty::*, value::*};
9
10pub use parameter_list::*;
11
12#[derive(Clone, Default)]
14pub struct Parameter {
15 pub id: Identifier,
17 pub specified_type: Option<TypeAnnotation>,
19 pub default_value: Option<Expression>,
21 pub src_ref: SrcRef,
23}
24
25impl Parameter {
26 pub fn new(
28 id: Identifier,
29 specified_type: Option<TypeAnnotation>,
30 default_value: Option<Expression>,
31 src_ref: SrcRef,
32 ) -> Self {
33 assert!(!id.is_empty());
34 Self {
35 id,
36 specified_type,
37 default_value,
38 src_ref,
39 }
40 }
41
42 pub fn no_ref(id: &str, ty: Type) -> Self {
44 Self {
45 id: Identifier::no_ref(id),
46 specified_type: Some(TypeAnnotation(Refer::none(ty))),
47 default_value: None,
48 src_ref: SrcRef(None),
49 }
50 }
51
52 pub fn eval_default_value(&self, context: &mut EvalContext) -> crate::eval::EvalResult<Value> {
56 use crate::eval::Eval;
57
58 match (&self.specified_type, &self.default_value) {
59 (Some(specified_type), Some(default_value)) => {
60 let value: Value = default_value.eval(context)?;
61 if specified_type.ty() != value.ty() {
62 context.error(
63 &self.src_ref,
64 EvalError::TypeMismatch {
65 id: self.id.clone(),
66 expected: specified_type.ty(),
67 found: value.ty(),
68 },
69 )?;
70 Ok(Value::None)
71 } else {
72 Ok(value)
73 }
74 }
75 (None, Some(default_value)) => Ok(default_value.eval(context)?),
76 _ => Ok(Value::None),
77 }
78 }
79}
80
81impl SrcReferrer for Parameter {
82 fn src_ref(&self) -> SrcRef {
83 self.src_ref.clone()
84 }
85}
86
87impl OrdMapValue<Identifier> for Parameter {
88 fn key(&self) -> Option<Identifier> {
89 Some(self.id.clone())
90 }
91}
92
93impl std::fmt::Display for Parameter {
94 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
95 match (&self.specified_type, &self.default_value) {
96 (Some(t), Some(v)) => write!(f, "{}: {t} = {v}", self.id),
97 (Some(t), None) => write!(f, "{}: {t}", self.id),
98 (None, Some(v)) => write!(f, "{} = {v}", self.id),
99 _ => Ok(()),
100 }
101 }
102}
103
104impl std::fmt::Debug for Parameter {
105 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
106 match (&self.specified_type, &self.default_value) {
107 (Some(t), Some(v)) => write!(f, "{:?}: {t:?} = {v:?}", self.id),
108 (Some(t), None) => write!(f, "{:?}: {t:?}", self.id),
109 (None, Some(v)) => write!(f, "{:?} = {v:?}", self.id),
110 _ => Ok(()),
111 }
112 }
113}
114
115impl TreeDisplay for Parameter {
116 fn tree_print(&self, f: &mut std::fmt::Formatter, depth: TreeState) -> std::fmt::Result {
117 match (&self.specified_type, &self.default_value) {
118 (Some(specified_type), Some(default_value)) => writeln!(
119 f,
120 "{:depth$}Parameter: {}: {} = {}",
121 "", self.id, specified_type, default_value
122 ),
123 (Some(specified_type), None) => {
124 writeln!(f, "{:depth$}Parameter: {}: {}", "", self.id, specified_type)
125 }
126 (None, Some(default_value)) => {
127 writeln!(f, "{:depth$}Parameter: {} = {}", "", self.id, default_value)
128 }
129 _ => unreachable!("impossible parameter declaration"),
130 }
131 }
132}