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, Debug, 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 Context) -> 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 TreeDisplay for Parameter {
105 fn tree_print(&self, f: &mut std::fmt::Formatter, depth: TreeState) -> std::fmt::Result {
106 match (&self.specified_type, &self.default_value) {
107 (Some(specified_type), Some(default_value)) => writeln!(
108 f,
109 "{:depth$}Parameter: {}: {} = {}",
110 "", self.id, specified_type, default_value
111 ),
112 (Some(specified_type), None) => {
113 writeln!(f, "{:depth$}Parameter: {}: {}", "", self.id, specified_type)
114 }
115 (None, Some(default_value)) => {
116 writeln!(f, "{:depth$}Parameter: {} = {}", "", self.id, default_value)
117 }
118 _ => unreachable!("impossible parameter declaration"),
119 }
120 }
121}