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