aplang_lib/standard_library/
std_macros.rs1#[macro_export]
2macro_rules! std_function {
3 ($location:expr => fn $name:ident ($($arg:ident: Value $(:: $arg_type:ident)? $(<$ot:ty>)?),*) {$($body:tt)*}) => {
4 $location.insert(
5 String::from(stringify!($name)),
6 (std::rc::Rc::new($crate::interpreter::NativeProcedure {
7 name: String::from(stringify!($name)),
8 arity: $crate::arity!($($arg)*),
9 callable: |_interpreter: &mut $crate::interpreter::Interpreter, args: &[$crate::interpreter::Value], args_toks: &[miette::SourceSpan], _source: std::sync::Arc<str>| {
10 #[allow(unused_mut, unused_variables)]
11 let mut iter = args.into_iter();
12 #[allow(unused_mut)]
13 let mut __iter_toks = iter.zip(args_toks.into_iter());
14
15 $(
16 let $arg = __iter_toks.next().unwrap();
17 $crate::unwrap_arg_type!($arg => Value $(::$arg_type)? $(<$ot>)?, _interpreter, _source);
18 )*
19
20 $($body)*
21 }
22 }), None)
23 )
24 };
25}
26
27#[macro_export]
28macro_rules! arity {
29 ($arg:ident $($tail:tt)*) => {
30 1u8 + $crate::arity!($($tail)*)
31 };
32 () => {
33 0u8
34 };
35}
36
37#[macro_export]
38macro_rules! unwrap_arg_type {
39 ($value:ident => Value::Null, $interpreter:ident, $source:ident) => {
40 #[allow(unused_mut)]
41 let mut $value = match $value.0 {
42 $crate::interpreter::value::Value::Null => $crate::interpreter::Value::Null,
43 _ => return Err(
44 $crate::interpreter::errors::RuntimeError {
45 named_source: miette::NamedSource::new($interpreter.get_file_path(), $source),
46 span: *$value.1,
47 message: "Invalid Argument Cast".to_string(),
48 help: format!("Argument Value ({}) is not of type NULL", stringify!($value)),
49 label: "This argument cannot be cast into null".to_string(),
50 }
51 )
52 }
53 };
54 ($value:ident => Value::Number, $interpreter:ident, $source:ident) => {
55 #[allow(unused_mut)]
56 let $crate::interpreter::Value::Number(mut $value) = $value.0.clone() else {
57 return Err(
58 $crate::interpreter::errors::RuntimeError {
59 named_source: miette::NamedSource::new($interpreter.get_file_path(), $source),
60 span: *$value.1,
61 message: "Invalid Argument Cast".to_string(),
62 help: format!("Argument Value ({}) is not of type NUMBER", stringify!($value)),
63 label: "This argument cannot be cast into NUMBER".to_string(),
64 }
65 );
66 };
67 };
68 ($value:ident => Value::String, $interpreter:ident, $source:ident) => {
69 #[allow(unused_mut)]
70 let $crate::interpreter::Value::String(mut $value) = $value.0.clone() else {
71 return Err(
72 $crate::interpreter::errors::RuntimeError {
73 named_source: miette::NamedSource::new($interpreter.get_file_path(), $source),
74 span: *$value.1,
75 message: "Invalid Argument Cast".to_string(),
76 help: format!("Argument Value ({}) is not of type STRING", stringify!($value)),
77 label: "This argument cannot be cast into STRING".to_string(),
78 }
79 );
80 };
81 };
82 ($value:ident => Value::Bool, $interpreter:ident, $source:ident) => {
83 #[allow(unused_mut)]
84 let $crate::interpreter::value::Value::Bool(mut $value) = $value.0.clone() else {
85 return Err(
86 $crate::interpreter::errors::RuntimeError {
87 named_source: miette::NamedSource::new($interpreter.get_file_path(), $source),
88 span: *$value.1,
89 message: "Invalid Argument Cast".to_string(),
90 help: format!("Argument Value ({}) is not of type BOOL", stringify!($value)),
91 label: "This argument cannot be cast into BOOL".to_string(),
92 }
93 );
94 };
95 };
96 ($value:ident => Value::List, $interpreter:ident, $source:ident) => {
97 #[allow(unused_mut)]
98 let $crate::interpreter::Value::List(mut $value) = $value.0.clone() else {
99 return Err(
100 $crate::interpreter::errors::RuntimeError {
101 named_source: miette::NamedSource::new($interpreter.get_file_path(), $source),
102 span: *$value.1,
103 message: "Invalid Argument Cast".to_string(),
104 help: format!("Argument Value ({}) is not of type LIST<Value>", stringify!($value)),
105 label: "This argument cannot be cast into LIST".to_string(),
106 }
107 );
108 };
109 };
110 ($value:ident => Value::NativeObject<$ot:ty>, $interpreter:ident, $source:ident) => {
111
112 let __span = *$value.1;
113 #[allow(unused_mut)]
114 let $crate::interpreter::Value::NativeObject(mut $value) = $value.0.clone() else {
115 return Err(
116 $crate::interpreter::errors::RuntimeError {
117 named_source: miette::NamedSource::new($interpreter.get_file_path(), $source),
118 span: __span,
119 message: "Invalid Argument Cast".to_string(),
120 help: format!("Argument Value ({}) is not of type NATIVE_OBJECT<A>", stringify!($value)),
121 label: "This argument cannot be cast into NATIVE_OBJECT".to_string(),
122 }
123 );
124 };
125
126 if $value.as_ref().borrow().downcast_ref::<$ot>().is_none() {
128 return Err(
129 $crate::interpreter::errors::RuntimeError {
130 named_source: miette::NamedSource::new($interpreter.get_file_path(), $source),
131 span: __span,
132 message: "Invalid NATIVE_OBJECT variety for function".to_string(),
133 help: format!("THe function cannot accept this type"),
134 label: "This argument is a NATIVE_OBJECT but not the correct variety".to_string(),
135 }
136 )
137 }
138 };
139 ($value:ident => Value, $interpreter:ident, $source:ident) => {
140 #[allow(unused_mut)]
141 let mut $value = $value.0;
142 };
143}
144
145#[macro_export]
146macro_rules! downcast {
147 ($any:ident => $ty:ty) => {
148 #[allow(clippy::mutable_key_type)]
149 let mut __any_ref = $any.as_ref().borrow_mut();
150 let $any = __any_ref.downcast_mut::<$ty>().unwrap();
151 };
152}