microcad_lang/builtin/
mod.rs

1// Copyright © 2025 The µcad authors <info@ucad.xyz>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4//! Builtin module
5
6pub mod export;
7pub mod file_io;
8pub mod import;
9pub mod module_builder;
10pub mod operation;
11pub mod workpiece;
12
13pub use export::*;
14pub use file_io::*;
15pub use import::*;
16pub use module_builder::*;
17pub use workpiece::*;
18
19use microcad_core::*;
20
21use crate::{ty::*, value::*};
22
23/// This enum is used to declare parameter list for builtin symbols conveniently.
24///
25/// It is used in the `parameter!` and `argument!` macros to be able
26/// to declare parameters and arguments in µcad like way, for example: `a: Scalar = 4.0`.
27pub enum BuiltinTypeHelper {
28    /// Integer type.
29    Integer,
30    /// A unitless scalar value.
31    Scalar,
32    /// Length in mm.
33    Length,
34    /// Area in mm².
35    Area,
36    /// Volume in mm³.
37    Volume,
38    /// Density in g/mm³
39    Density,
40    /// An angle in radians.
41    Angle,
42    /// Weight of a specific volume of material.
43    Weight,
44    /// String type.
45    String,
46    /// Bool type.
47    Bool,
48    /// Color type.
49    Color,
50    /// used for assert_valid() and assert_invalid()
51    Target,
52}
53
54impl From<BuiltinTypeHelper> for Type {
55    fn from(value: BuiltinTypeHelper) -> Self {
56        match value {
57            BuiltinTypeHelper::Integer => Type::Integer,
58            BuiltinTypeHelper::Scalar => Type::Quantity(QuantityType::Scalar),
59            BuiltinTypeHelper::Length => Type::Quantity(QuantityType::Length),
60            BuiltinTypeHelper::Area => Type::Quantity(QuantityType::Area),
61            BuiltinTypeHelper::Volume => Type::Quantity(QuantityType::Volume),
62            BuiltinTypeHelper::Density => Type::Quantity(QuantityType::Density),
63            BuiltinTypeHelper::Angle => Type::Quantity(QuantityType::Angle),
64            BuiltinTypeHelper::Weight => Type::Quantity(QuantityType::Weight),
65            BuiltinTypeHelper::String => Type::String,
66            BuiltinTypeHelper::Bool => Type::Bool,
67            BuiltinTypeHelper::Color => Type::Tuple(TupleType::new_color().into()),
68            BuiltinTypeHelper::Target => Type::Target,
69        }
70    }
71}
72
73/// This enum is used to declare parameter list for builtin symbols conveniently.
74///
75/// It is used in the `parameter!` and `argument!` macros to be able
76/// to declare parameters and arguments in µcad like way, for example: `a: Scalar = 4.0`.
77pub enum BuiltinValueHelper {
78    /// Integer type.
79    Integer(Integer),
80    /// Scalar type.
81    Scalar(Scalar),
82    /// Length type.
83    Length(Scalar),
84    /// Area type
85    Area(Scalar),
86    /// Volume type
87    Volume(Scalar),
88    /// Density type
89    Density(Scalar),
90    /// Angle type
91    Angle(Scalar),
92    /// Weight type
93    Weight(Scalar),
94    /// String type.
95    String(String),
96    /// Bool type
97    Bool(bool),
98    /// Color type
99    Color(Color),
100    /// Name (for assert_valid() and assert_invalid()
101    Name(Target),
102}
103
104impl From<BuiltinValueHelper> for Value {
105    fn from(value: BuiltinValueHelper) -> Self {
106        match value {
107            BuiltinValueHelper::Scalar(v) => {
108                Value::Quantity(Quantity::new(v, QuantityType::Scalar))
109            }
110            BuiltinValueHelper::Integer(i) => Value::Integer(i),
111            BuiltinValueHelper::Length(v) => {
112                Value::Quantity(Quantity::new(v, QuantityType::Length))
113            }
114            BuiltinValueHelper::Area(v) => Value::Quantity(Quantity::new(v, QuantityType::Area)),
115            BuiltinValueHelper::Volume(v) => {
116                Value::Quantity(Quantity::new(v, QuantityType::Volume))
117            }
118            BuiltinValueHelper::Density(v) => {
119                Value::Quantity(Quantity::new(v, QuantityType::Density))
120            }
121            BuiltinValueHelper::Angle(v) => Value::Quantity(Quantity::new(v, QuantityType::Angle)),
122            BuiltinValueHelper::Weight(v) => {
123                Value::Quantity(Quantity::new(v, QuantityType::Weight))
124            }
125            BuiltinValueHelper::String(s) => Value::String(s),
126            BuiltinValueHelper::Bool(b) => Value::Bool(b),
127            BuiltinValueHelper::Color(c) => c.try_into().expect("Valid value"),
128            BuiltinValueHelper::Name(t) => t.try_into().expect("Valid value"),
129        }
130    }
131}
132
133// Re-export symbols
134pub use crate::model::Operation;
135pub use crate::parameter;
136pub use crate::resolve::Symbol;
137pub use crate::syntax::Identifier;
138pub use crate::value::ParameterValue;
139pub use crate::value::ParameterValueList;
140pub use crate::value::ValueAccess;
141
142/// Shortcut to create a `ParameterValue`
143#[macro_export]
144macro_rules! parameter {
145    ($id:ident) => {
146        (
147            $crate::builtin::Identifier::no_ref(stringify!($id)),
148            $crate::value::ParameterValue {
149                src_ref: $crate::src_ref::SrcRef(None),
150                ..Default::default()
151            },
152        )
153    };
154    ($id:ident: $ty:ident) => {
155        (
156            $crate::syntax::Identifier::no_ref(stringify!($id)),
157            $crate::value::ParameterValue {
158                specified_type: Some($crate::builtin::BuiltinTypeHelper::$ty.into()),
159                src_ref: $crate::src_ref::SrcRef(None),
160                ..Default::default()
161            },
162        )
163    };
164    ($id:ident: $ty:ident = $value:expr) => {
165        (
166            $crate::syntax::Identifier::no_ref(stringify!($id)),
167            $crate::value::ParameterValue {
168                specified_type: Some($crate::builtin::BuiltinTypeHelper::$ty.into()),
169                default_value: Some($crate::builtin::BuiltinValueHelper::$ty($value).into()),
170                src_ref: $crate::src_ref::SrcRef(None),
171            },
172        )
173    };
174    ($id:ident = $value:expr) => {
175        (
176            $crate::syntax::Identifier::no_ref(stringify!($id)),
177            $crate::value::ParameterValue {
178                default_value: Some($value),
179                ..Default::default()
180            },
181        )
182    };
183    () => {};
184}
185
186/// Shortcut to create a argument value
187#[macro_export]
188macro_rules! argument {
189    ($id:ident: $ty:ident = $value:expr) => {
190        (
191            $crate::syntax::Identifier::no_ref(stringify!($id)),
192            ArgumentValue::new(
193                $crate::builtin::BuiltinValueHelper::$ty($value).into(),
194                None,
195                $crate::src_ref::SrcRef(None),
196            ),
197        )
198    };
199    ($ty:ident = $value:expr) => {
200        (
201            Identifier::none(),
202            ArgumentValue::new(
203                $crate::builtin::BuiltinValueHelper::$ty($value).into(),
204                None,
205                $crate::src_ref::SrcRef(None),
206            ),
207        )
208    };
209    () => {};
210}
211
212/// Create tuple of stringified `Identifier` and a `Value`
213#[macro_export]
214macro_rules! property {
215    ($id:ident : $ty:ident = $value:expr) => {
216        (
217            Identifier::no_ref(stringify!($id)),
218            $crate::builtin::BuiltinValueHelper::$ty($value).into(),
219        )
220    };
221    () => {};
222}