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