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' { Some('⏎') } else { Some(ch) }
71 } else {
72 None
73 }
74 })
75 .collect();
76
77 if cfg!(feature = "ansi-color") && short.contains('\x1b') {
78 short + "\x1b[0m"
79 } else {
80 short
81 }
82}
83
84#[macro_export]
86macro_rules! shorten {
87 ($what:expr) => {
88 $crate::shorten(&format!("{}", $what), 140)
89 };
90 ($what:expr,$shorten:expr) => {
91 if $shorten {
92 $crate::shorten!($what)
93 } else {
94 $what
95 }
96 };
97 ($what:expr, $max_chars:literal) => {
98 shorten(format!("{}", $what).lines(), max_chars)
99 };
100}
101
102#[cfg(feature = "ansi-color")]
104#[macro_export]
105macro_rules! mark {
106 (FOUND) => {
107 color_print::cformat!("<G!,k,s> FOUND </>")
108 };
109 (FOUND_INTERIM) => {
110 color_print::cformat!("<W!,k,s> FOUND </>")
111 };
112 (MATCH) => {
113 color_print::cformat!("<Y!,k,s> MATCH </>")
114 };
115 (CALL) => {
116 color_print::cformat!("<B,k,s> CALL </>")
117 };
118 (LOOKUP) => {
119 color_print::cformat!("<c,s>LOOKUP</>")
120 };
121 (LOAD) => {
122 color_print::cformat!("<Y,k,s> LOADING </>")
123 };
124 (RESOLVE) => {
125 color_print::cformat!("<M,k,s> RESOLVE </>")
126 };
127 (AMBIGUOUS) => {
128 color_print::cformat!("<R,k,s> AMBIGUOUS </>")
129 };
130 (NOT_FOUND) => {
131 color_print::cformat!("<R,k,s> NOT FOUND </>")
132 };
133 (NOT_FOUND_INTERIM) => {
134 color_print::cformat!("<Y,k,s> NOT FOUND </>")
135 };
136}
137
138#[cfg(not(feature = "ansi-color"))]
139#[macro_export]
140macro_rules! found {
141 (FOUND) => {
142 "Found"
143 };
144 (FINAL) => {
145 "Found"
146 };
147 (INTERMEDIATE) => {
148 "Found"
149 };
150 (MATCH) => {
151 "Match"
152 };
153 (CALL) => {
154 "Call"
155 };
156 (LOOKUP) => {
157 "Lookup"
158 };
159 (LOAD) => {
160 "Loading"
161 };
162 (RESOLVE) => {
163 "Resolve"
164 };
165 (AMBIGUOUS) => {
166 "Ambiguous"
167 };
168 (NOT_FOUND) => {
169 "Not found"
170 };
171 (NOT_FOUND_INTERIM) => {
172 "Not found"
173 };
174}
175
176#[cfg(feature = "ansi-color")]
178#[macro_export]
179macro_rules! invalid {
180 (VALUE) => {
181 color_print::cstr!("<R!,k,s> NO VALUE </>")
182 };
183 (TYPE) => {
184 color_print::cstr!("<R!,k,s> NO TYPE </>")
185 };
186 (OUTPUT) => {
187 color_print::cstr!("<R!,k,s> NO OUTPUT </>")
188 };
189 (STACK) => {
190 color_print::cstr!("<W,k,s> EMPTY STACK </>")
191 };
192 (REF) => {
193 color_print::cstr!("<Y!,k,s> NO REF </>")
194 };
195 (FILE) => {
196 color_print::cstr!("<Y!,k,s> NO FILE </>")
197 };
198 (RESULT) => {
199 color_print::cstr!("<Y!,k,s> NO RESULT </>")
200 };
201 (LINE) => {
202 color_print::cstr!("<Y!,k,s> NO LINE </>")
203 };
204 (SOURCE) => {
205 color_print::cstr!("<C!,k,s> FROM STR </>")
206 };
207 (UNKNOWN) => {
208 color_print::cstr!("<M!,k,s> UNKNOWN </>")
209 };
210 (ID) => {
211 color_print::cstr!("<M!,k,s> NO ID </>")
212 };
213 (NAME) => {
214 color_print::cstr!("<M!,k,s> NO NAME </>")
215 };
216 (EXPRESSION) => {
217 color_print::cstr!("<R!,k,s> INVALID EXPRESSION </>")
218 };
219}
220
221#[macro_export]
223macro_rules! invalid_no_ansi {
224 (VALUE) => {
225 "<NO VALUE>"
226 };
227 (TYPE) => {
228 "<NO TYPE>"
229 };
230 (OUTPUT) => {
231 "<NO OUTPUT>"
232 };
233 (STACK) => {
234 "<EMPTY STACK>"
235 };
236 (REF) => {
237 "<NO REF>"
238 };
239 (FILE) => {
240 "<NO FILE>"
241 };
242 (RESULT) => {
243 "<NO RESULT>"
244 };
245 (LINE) => {
246 "<NO LINE>"
247 };
248 (SOURCE) => {
249 "<FROM STR>"
250 };
251 (UNKNOWN) => {
252 "<UNKNOWN>"
253 };
254 (ID) => {
255 "<NO ID>"
256 };
257 (NAME) => {
258 "<INVALID NAME>"
259 };
260 (EXPRESSION) => {
261 "<INVALID EXPRESSION>"
262 };
263}
264
265#[cfg(not(feature = "ansi-color"))]
266macro_rules! invalid {
267 ($x:literal) => {
268 invalid_no_ansi!($x)
269 };
270}