nessa/
lib.rs

1use mimalloc::MiMalloc;
2
3#[global_allocator]
4static GLOBAL: MiMalloc = MiMalloc;
5
6extern crate nom;
7
8#[macro_use]
9extern crate lazy_static;
10
11pub mod cache;
12pub mod patterns;
13pub mod object;
14pub mod operations;
15pub mod functions;
16pub mod types;
17pub mod interfaces;
18pub mod annotations;
19pub mod context;
20pub mod docs;
21
22pub mod debug;
23pub mod parser;
24pub mod macros;
25pub mod inference;
26pub mod checks;
27pub mod compilation;
28pub mod optimization;
29pub mod execution;
30pub mod translation;
31pub mod serialization;
32
33pub mod config;
34
35#[path = "algorithms/regex_ext.rs"]
36pub mod regex_ext;
37
38#[path = "algorithms/html_ext.rs"]
39pub mod html_ext;
40
41#[path = "algorithms/integer_ext.rs"]
42pub mod integer_ext;
43
44#[path = "algorithms/git.rs"]
45pub mod git;
46
47#[path = "algorithms/profiling.rs"]
48pub mod profiling;
49
50#[path = "algorithms/formats.rs"]
51pub mod formats;
52
53#[path = "structures/graph.rs"]
54pub mod graph;
55
56#[path = "structures/variable_map.rs"]
57pub mod variable_map;
58
59#[path = "structures/id_mapper.rs"]
60pub mod id_mapper;
61
62#[path = "structures/precedence_cache.rs"]
63pub mod precedence_cache;
64
65#[path = "structures/mut_cell.rs"]
66pub mod mut_cell;
67
68#[cfg(test)]
69mod integration {
70    use std::fs::read_to_string;
71    use crate::compilation::NessaError;
72    use crate::context::standard_ctx;
73    use crate::config::{precompile_nessa_module_with_config, compute_project_hash};
74    use glob::glob;
75
76    fn integration_test(file_path: &str) {
77        let file = read_to_string(file_path).expect("Unable to locate file");
78        let mut ctx = standard_ctx();
79        ctx.optimize = true;
80
81        if let Err(err) = ctx.parse_and_execute_nessa_module(&file) {
82            err.emit();
83        }
84    }
85
86    fn integration_test_batch(glob_path: &str) {
87        for file_path in glob(glob_path).expect("Invalid glob") {
88            let file = read_to_string(file_path.unwrap()).expect("Unable to locate file");
89
90            if file.starts_with("// ") {
91                // Negative test
92                let expected_msg = &file.lines().next().unwrap()[3..];
93
94                let result = std::panic::catch_unwind(|| {
95                    let mut ctx = standard_ctx();
96                    ctx.optimize = true;
97
98                    ctx.parse_and_execute_nessa_module(&file)
99        
100                }).unwrap_or_else(|err| {
101                    Err(NessaError::execution_error(panic_message::panic_message(&err).to_owned()))
102                });
103        
104                if let Err(err) = result {
105                    let exp_chars = expected_msg.chars().collect::<Vec<_>>();
106                    let err_chars = err.message.chars().collect::<Vec<_>>();
107                    let mut exp_idx = 0;
108                    let mut err_idx = 0;
109        
110                    while exp_idx < exp_chars.len() && err_idx < err_chars.len() {
111                        exp_idx += (err_chars[err_idx] == exp_chars[exp_idx]) as usize;
112                        err_idx += 1;
113                    }
114        
115                    if exp_idx != exp_chars.len() {
116                        panic!("Error message was different from expected:\n - Expected: {}\n - Got: {}", expected_msg, err.message);
117                    }
118        
119                } else {
120                    panic!("Test did not fail!");
121                }
122        
123            } else {
124                // Positive test
125                let mut ctx = standard_ctx();
126
127                if let Err(err) = ctx.parse_and_execute_nessa_module(&file) {
128                    err.emit();
129                }        
130            }
131        }
132    }
133
134    fn module_test(module_path: &str) {
135        let path_str = &module_path.to_string();
136        let (_, all_mods, files) = compute_project_hash(path_str, None, true, false).unwrap();
137        let err = precompile_nessa_module_with_config(path_str, all_mods, files, true, false, true);
138
139        if let Err(err) = &err {
140            err.emit();
141        }        
142
143        let (mut ctx, lines) = err.unwrap();
144
145        match ctx.compiled_form(&lines) {
146            Ok(mut code) => {
147                ctx.optimize_instructions(&mut code);
148
149                for (idx, i) in code.iter().enumerate() {
150                    println!("{:<3} {}", idx, i.to_string(&ctx));
151                }
152
153                if let Err(err) = ctx.execute_compiled_code::<false>(&code.into_iter().map(|i| i.instruction).collect::<Vec<_>>(), &[]) {
154                    err.emit();
155                }
156            },
157
158            Err(err) => err.emit()
159        };
160    }
161
162    #[test]
163    fn naive_primality() {
164        integration_test("test/primality.nessa");
165    }
166
167    #[test]
168    fn mapped_iterator() {
169        integration_test("test/mapped_iterator.nessa");
170    }
171
172    #[test]
173    fn dice() {
174        integration_test("test/dice.nessa");
175    }
176
177    #[test]
178    fn ints_custom_syntax() {
179        integration_test("test/ints.nessa");
180    }
181
182    #[test]
183    fn random() {
184        integration_test("test/random.nessa");
185    }
186
187    #[test]
188    fn tuples() {
189        integration_test("test/tuples.nessa");
190    }
191
192    #[test]
193    fn array_access() {
194        integration_test("test/array_access.nessa");
195    }
196
197    #[test]
198    fn array_init() {
199        integration_test("test/array_init.nessa");
200    }
201
202    #[test]
203    fn list_comprehension() {
204        integration_test("test/list_comprehension.nessa");
205    }
206
207    #[test]
208    fn map_array() {
209        integration_test("test/map_array.nessa");
210    }
211
212    #[test]
213    fn array_transform() {
214        integration_test("test/array_transform.nessa");
215    }
216
217    #[test]
218    fn e_approximation() {
219        integration_test("test/e_approximation.nessa");
220    }
221
222    #[test]
223    fn basic_alias() {
224        integration_test("test/basic_alias.nessa");
225    }
226
227    #[test]
228    fn adt_list() {
229        integration_test("test/adt_list.nessa");
230    }
231
232    #[test]
233    fn adt_generic_list() {
234        integration_test("test/adt_generic_list.nessa");
235    }
236
237    #[test]
238    fn adt_bin_tree() {
239        integration_test("test/adt_bin_tree.nessa");
240    }
241
242    #[test]
243    fn numeric_interface() {
244        integration_test("test/numeric_interface.nessa");
245    }
246
247    #[test]
248    fn parametric_interface() {
249        integration_test("test/parametric_interface.nessa");
250    }
251
252    #[test]
253    fn peano_arithmetic() {
254        integration_test("test/peano_arithmetic.nessa");
255    }
256
257    #[test]
258    fn short_circuit() {
259        integration_test("test/short_circuit.nessa");
260    }
261
262    #[test]
263    fn file_manip() {
264        integration_test("test/file_manip.nessa");
265    }
266
267    #[test]
268    fn string_manip() {
269        integration_test("test/string_manip.nessa");
270    }
271
272    #[test]
273    fn ambiguous_impl() {
274        integration_test("test/ambiguous_impl.nessa");
275    }
276
277    #[test]
278    fn ternary() {
279        integration_test("test/ternary.nessa");
280    }
281
282    #[test]
283    fn adt_assignment() {
284        integration_test("test/adt_assignment.nessa");
285    }
286
287    #[test]
288    fn bitwise() {
289        integration_test("test/bitwise.nessa");
290    }
291
292    #[test]
293    fn ndl_macros() {
294        integration_test("test/ndl_macros.nessa");
295    }
296
297    #[test]
298    fn do_blocks() {
299        integration_test("test/do_blocks.nessa");
300    }
301
302    #[test]
303    fn break_loops() {
304        integration_test("test/break_loops.nessa");
305    }
306
307    #[test]
308    fn continue_loops() {
309        integration_test("test/continue_loops.nessa");
310    }
311
312    #[test]
313    fn lambda_capture() {
314        integration_test("test/lambda_capture.nessa");
315    }
316
317    #[test]
318    fn unicode() {
319        integration_test("test/unicode.nessa");
320    }
321
322    #[test]
323    fn implicit_lambda() {
324        integration_test("test/implicit_lambda.nessa");
325    }
326
327    #[test]
328    fn exp_floats() {
329        integration_test("test/exp_floats.nessa");
330    }
331
332    #[test]
333    fn moving() {
334        integration_test_batch("test/batches/moving/*.nessa");
335    }
336
337    #[test]
338    fn interfaces() {
339        integration_test_batch("test/batches/interfaces/*.nessa");
340    }
341
342    #[test]
343    fn macros() {
344        integration_test_batch("test/batches/macros/*.nessa");
345    }
346
347    #[test]
348    fn stack() {
349        integration_test_batch("test/batches/stack/*.nessa");
350    }
351
352    #[test]
353    fn sum() {
354        module_test("test/modules/sum");
355    }
356
357    #[test]
358    fn prime_check() {
359        module_test("test/modules/prime_check");
360    }
361
362    #[test]
363    fn prime_streaming() {
364        module_test("test/modules/prime_streaming");
365    }
366
367    #[test]
368    fn props_test() {
369        module_test("test/modules/props_test");
370    }
371
372    #[test]
373    fn math_ops() {
374        module_test("test/modules/math_ops");
375    }
376
377    #[test]
378    fn syntax_test() {
379        module_test("test/modules/syntax_test");
380    }
381
382    #[test]
383    fn hash_extensions() {
384        module_test("test/modules/hash_extensions");
385    }
386
387    #[test]
388    fn hash_structs_test() {
389        module_test("test/modules/hash_structs_test");
390    }
391
392    #[test]
393    fn json_test() {
394        module_test("test/modules/json_test");
395    }
396
397    #[test]
398    fn set_syntax_test() {
399        module_test("test/modules/set_syntax_test");
400    }
401
402    #[test]
403    fn array_algorithms() {
404        module_test("test/modules/array_algorithms");
405    }
406
407    #[test]
408    fn iterators_test() {
409        module_test("test/modules/iterators_test");
410    }
411
412    #[test]
413    fn macro_code_ex() {
414        module_test("test/modules/macro_code_ex");
415    }
416
417    #[test]
418    fn bf_embed() {
419        module_test("test/modules/bf_embed");
420    }
421
422    #[test]
423    fn match_test() {
424        module_test("test/modules/match_test");
425    }
426}