1pub mod builtin;
18pub mod diag;
19pub mod eval;
20pub mod model;
21pub mod ord_map;
22pub mod parse;
23pub mod parser;
24pub mod rc;
25pub mod render;
26pub mod resolve;
27pub mod src_ref;
28pub mod syntax;
29pub mod tree_display;
30pub mod ty;
31pub mod value;
32
33pub type Id = compact_str::CompactString;
35
36pub const MICROCAD_EXTENSIONS: &[&str] = &["µcad", "mcad", "ucad"];
38
39#[macro_export]
44macro_rules! parse {
45 ($ty:path, $rule:path, $code:expr) => {
46 $crate::parser::Parser::parse_rule::<$ty>($rule, $code, 0).expect("bad inline code")
47 };
48}
49
50#[test]
51fn parse_macro() {
52 let y3 = 3;
53 let p = parse!(
54 syntax::ParameterList,
55 parser::Rule::parameter_list,
56 &format!("(x=0,y=[1,2,{y3},4],z=2)")
57 );
58 assert_eq!(p.to_string(), "x = 0, y = [1, 2, 3, 4], z = 2");
59}
60
61pub fn shorten(what: &str, max_chars: usize) -> String {
63 let short: String = what
64 .chars()
65 .enumerate()
66 .filter_map(|(p, ch)| {
67 if p == max_chars {
68 Some('…')
69 } else if p < max_chars {
70 if ch == '\n' {
71 Some('⏎')
72 } else {
73 Some(ch)
74 }
75 } else {
76 None
77 }
78 })
79 .collect();
80
81 if cfg!(feature = "ansi-color") && short.contains('\x1b') {
82 short + "\x1b[0m"
83 } else {
84 short
85 }
86}
87
88#[macro_export]
90macro_rules! shorten {
91 ($what:expr) => {
92 $crate::shorten(&format!("{}", $what), 140)
93 };
94 ($what:expr,$shorten:expr) => {
95 if $shorten {
96 $crate::shorten!($what)
97 } else {
98 $what
99 }
100 };
101 ($what:expr, $max_chars:literal) => {
102 shorten(format!("{}", $what).lines(), max_chars)
103 };
104}
105
106#[cfg(feature = "ansi-color")]
108#[macro_export]
109macro_rules! mark {
110 (FOUND) => {
111 color_print::cformat!("<G!,k,s> FOUND </>")
112 };
113 (FOUND_INTERIM) => {
114 color_print::cformat!("<W!,k,s> FOUND </>")
115 };
116 (MATCH) => {
117 color_print::cformat!("<Y!,k,s> MATCH </>")
118 };
119 (CALL) => {
120 color_print::cformat!("<B,k,s> CALL </>")
121 };
122 (LOOKUP) => {
123 color_print::cformat!("<c,s>LOOKUP</>")
124 };
125 (LOAD) => {
126 color_print::cformat!("<Y,k,s> LOADING </>")
127 };
128 (RESOLVE) => {
129 color_print::cformat!("<M,k,s> RESOLVE </>")
130 };
131 (AMBIGUOUS) => {
132 color_print::cformat!("<R,k,s> AMBIGUOUS </>")
133 };
134 (NOT_FOUND) => {
135 color_print::cformat!("<R,k,s> NOT FOUND </>")
136 };
137 (NOT_FOUND_INTERIM) => {
138 color_print::cformat!("<Y,k,s> NOT FOUND </>")
139 };
140}
141
142#[cfg(not(feature = "ansi-color"))]
143#[macro_export]
144macro_rules! found {
145 (FOUND) => {
146 "Found"
147 };
148 (FINAL) => {
149 "Found"
150 };
151 (INTERMEDIATE) => {
152 "Found"
153 };
154 (MATCH) => {
155 "Match"
156 };
157 (CALL) => {
158 "Call"
159 };
160 (LOOKUP) => {
161 "Lookup"
162 };
163 (LOAD) => {
164 "Loading"
165 };
166 (RESOLVE) => {
167 "Resolve"
168 };
169 (AMBIGUOUS) => {
170 "Ambiguous"
171 };
172 (NOT_FOUND) => {
173 "Not found"
174 };
175 (NOT_FOUND_INTERIM) => {
176 "Not found"
177 };
178}
179
180#[cfg(feature = "ansi-color")]
182#[macro_export]
183macro_rules! invalid {
184 (VALUE) => {
185 color_print::cstr!("<R!,k,s> NO VALUE </>")
186 };
187 (TYPE) => {
188 color_print::cstr!("<R!,k,s> NO TYPE </>")
189 };
190 (OUTPUT) => {
191 color_print::cstr!("<R!,k,s> NO OUTPUT </>")
192 };
193 (STACK) => {
194 color_print::cstr!("<W,k,s> EMPTY STACK </>")
195 };
196 (REF) => {
197 color_print::cstr!("<Y!,k,s> NO REF </>")
198 };
199 (FILE) => {
200 color_print::cstr!("<Y!,k,s> NO FILE </>")
201 };
202 (RESULT) => {
203 color_print::cstr!("<Y!,k,s> NO RESULT </>")
204 };
205 (LINE) => {
206 color_print::cstr!("<Y!,k,s> NO LINE </>")
207 };
208 (SOURCE) => {
209 color_print::cstr!("<C!,k,s> FROM STR </>")
210 };
211 (UNKNOWN) => {
212 color_print::cstr!("<M!,k,s> UNKNOWN </>")
213 };
214 (ID) => {
215 color_print::cstr!("<M!,k,s> NO ID </>")
216 };
217 (NAME) => {
218 color_print::cstr!("<M!,k,s> NO NAME </>")
219 };
220 (EXPRESSION) => {
221 color_print::cstr!("<R!,k,s> INVALID EXPRESSION </>")
222 };
223}
224
225#[macro_export]
227macro_rules! invalid_no_ansi {
228 (VALUE) => {
229 "<NO VALUE>"
230 };
231 (TYPE) => {
232 "<NO TYPE>"
233 };
234 (OUTPUT) => {
235 "<NO OUTPUT>"
236 };
237 (STACK) => {
238 "<EMPTY STACK>"
239 };
240 (REF) => {
241 "<NO REF>"
242 };
243 (FILE) => {
244 "<NO FILE>"
245 };
246 (RESULT) => {
247 "<NO RESULT>"
248 };
249 (LINE) => {
250 "<NO LINE>"
251 };
252 (SOURCE) => {
253 "<FROM STR>"
254 };
255 (UNKNOWN) => {
256 "<UNKNOWN>"
257 };
258 (ID) => {
259 "<NO ID>"
260 };
261 (NAME) => {
262 "<INVALID NAME>"
263 };
264 (EXPRESSION) => {
265 "<INVALID EXPRESSION>"
266 };
267}
268
269#[cfg(not(feature = "ansi-color"))]
270macro_rules! invalid {
271 ($x:literal) => {
272 invalid_no_ansi!($x)
273 };
274}