1use std::cell::RefCell;
2use std::collections::HashMap;
3use std::fmt::Debug;
4use std::sync::Arc;
5
6use colored::Colorize;
7use levenshtein::levenshtein;
8use nom::error::{VerboseErrorKind, VerboseError};
9use rustc_hash::FxHashSet;
10use serde::{Serialize, Deserialize};
11use malachite::Integer;
12
13use crate::cache::needs_import;
14use crate::cache::needs_line_import;
15use crate::config::ImportMap;
16use crate::config::Imports;
17use crate::config::NessaModule;
18use crate::context::NessaContext;
19use crate::debug::DebugInfo;
20use crate::debug::DebugInfoBuilder;
21use crate::graph::DirectedGraph;
22use crate::id_mapper::IdMapper;
23use crate::interfaces::ITERABLE_ID;
24use crate::macros::NessaMacro;
25use crate::object::TypeInstance;
26use crate::parser::*;
27use crate::object::NessaArray;
28use crate::types::*;
29use crate::object::Object;
30use crate::functions::*;
31use crate::operations::*;
32use crate::variable_map::VariableMap;
33
34#[derive(Debug, Clone)]
47pub struct NessaError {
48 pub err_type: String,
49 pub message: String,
50
51 pub has_location: bool,
52 pub line: usize,
53 pub column: usize,
54 pub module: Arc<String>,
55 pub fragment: String,
56
57 pub suggestions: Vec<String>
58}
59
60impl NessaError {
61 pub fn in_module(mut self, module: Arc<String>) -> Self {
62 self.module = module;
63 self
64 }
65
66 pub fn syntax_error(message: String, line: usize, column: usize, module: Arc<String>, fragment: String, suggestions: Vec<String>) -> Self {
67 NessaError { err_type: "Syntax error".into(), has_location: true, message, line, column, module, fragment, suggestions }
68 }
69
70 #[cold]
71 pub fn compiler_error(message: String, location: &Location, suggestions: Vec<String>) -> Self {
72 NessaError {
73 err_type: "Compilation error".into(),
74 has_location: true,
75 message,
76 line: location.line,
77 column: location.column,
78 module: location.module.clone(),
79 fragment: location.span.clone(),
80 suggestions
81 }
82 }
83
84 #[cold]
85 pub fn execution_error(message: String) -> Self {
86 NessaError {
87 err_type: "Execution error".into(),
88 has_location: false,
89 message,
90 line: 0,
91 column: 0,
92 module: Arc::default(),
93 fragment: "".into(),
94 suggestions: vec!()
95 }
96 }
97
98 #[cold]
99 pub fn module_error(message: String) -> Self {
100 NessaError {
101 err_type: "Module error".into(),
102 has_location: false,
103 message,
104 line: 0,
105 column: 0,
106 module: Arc::default(),
107 fragment: "".into(),
108 suggestions: vec!()
109 }
110 }
111
112 #[cold]
113 pub fn emit(&self) -> ! {
114 if self.has_location {
115 let mut frag = self.fragment.as_str();
116
117 if let Some(pos) = frag.find('\n') {
118 frag = &frag[..pos];
119 }
120
121 if frag.len() > 50 {
122 frag = &frag[..50];
123 }
124
125 frag = frag.trim();
126
127 eprintln!(
128 "\n[{} in module {}, line {}, column {}]\n\n • {}:\n\n\t[...] {} [...]\n\t {}\n",
129 self.err_type.red().bold(),
130 self.module.green(),
131 self.line.to_string().yellow(), self.column.to_string().yellow(),
132 self.message, frag,
133 "^".repeat(frag.len()).red()
134 );
135
136 if !self.suggestions.is_empty() {
137 eprintln!("[{}]\n", "Suggestions".blue().bold());
138
139 for s in &self.suggestions {
140 eprintln!(" • {}", s);
141 }
142
143 eprintln!();
144 }
145
146 } else {
147 eprintln!(
148 "\n[{}] {}\n",
149 self.err_type.red().bold(),
150 self.message
151 );
152 }
153
154 exit_process();
155 }
156}
157
158impl<'a> From<VerboseError<Span<'a>>> for NessaError {
159 fn from(error: VerboseError<Span<'a>>) -> Self {
160 let err = error.errors.last().unwrap();
161
162 let fragment = err.0;
163 let error_msg = match &err.1 {
164 VerboseErrorKind::Context(ctx) => ctx,
165 _ => "Unable to parse"
166 };
167
168 NessaError::syntax_error(
169 error_msg.into(),
170 fragment.location_line() as usize, fragment.get_column(), Arc::default(),
171 fragment.to_string(),
172 vec!()
173 )
174 }
175}
176
177impl<'a> From<nom::Err<VerboseError<Span<'a>>>> for NessaError {
178 fn from(error: nom::Err<VerboseError<Span<'a>>>) -> Self {
179 match error {
180 nom::Err::Error(err) |
181 nom::Err::Failure(err) => NessaError::from(err),
182
183 _ => unreachable!()
184 }
185 }
186}
187
188pub fn exit_process() -> ! {
195 if cfg!(test) {
196 panic!();
197
198 } else {
199 std::process::exit(1);
200 }
201}
202
203pub fn message_and_exit(msg: String) -> ! {
204 if cfg!(test) {
205 panic!("{}", msg);
206
207 } else {
208 NessaError::execution_error(msg).emit();
209 }
210}
211
212#[macro_export]
213macro_rules! nessa_warning {
214 ($pat: expr $( , $more: expr)*) => {
215 println!(
216 "[{}] {}",
217 "Warning".yellow(),
218 format!($pat, $($more,)*)
219 );
220 };
221}
222
223#[macro_export]
224macro_rules! located_nessa_warning {
225 ($l: expr, $pat: expr $( , $more: expr)*) => {
226 use colored::Colorize;
227
228 let loc = $l;
229
230 println!(
231 "[{} in module {}, line {}, column {}] {}",
232 "Warning".yellow(),
233 loc.module.green(),
234 loc.line.to_string().yellow(), loc.column.to_string().yellow(),
235 format!($pat, $($more,)*)
236 );
237 };
238}
239
240#[macro_export]
241macro_rules! nessa_error {
242 ($pat: expr $( , $more: expr)*) => {
243 {
244 use colored::Colorize;
245 use $crate::compilation::exit_process;
246
247 eprintln!(
248 "[{}] {}",
249 "Error".red(),
250 format!($pat, $($more,)*)
251 );
252
253 exit_process();
254 }
255 };
256}
257
258impl NessaContext {
259 fn infer_lambda_return_type(&mut self, lines: &mut Vec<NessaExpr>) -> Result<Option<Type>, NessaError> {
266 let merge_types = |a: Option<Type>, b: Option<Type>, ctx: &mut NessaContext| -> Option<Type> {
267 if b.is_none() {
268 return a;
269 }
270
271 match &a {
272 Some(na) => {
273 if na.bindable_to(b.as_ref().unwrap(), ctx) {
274 b
275
276 } else if b.as_ref().unwrap().bindable_to(na, ctx) {
277 return a;
278
279 } else {
280 return Some(Type::Or(vec!(na.clone(), b.unwrap())));
281 }
282 },
283
284 None => b,
285 }
286 };
287
288 let mut res = None;
289
290 for expr in lines {
291 match expr {
292 NessaExpr::While(_, _, b) |
293 NessaExpr::CompiledFor(_, _, _, _, _, b) => res = merge_types(res, self.infer_lambda_return_type(b)?, self),
294
295 NessaExpr::If(_, _, ib, ei, eb) => {
296 res = merge_types(res, self.infer_lambda_return_type(ib)?, self);
297
298 for (_, eib) in ei {
299 res = merge_types(res, self.infer_lambda_return_type(eib)?, self);
300 }
301
302 if let Some(eb_inner) = eb {
303 res = merge_types(res, self.infer_lambda_return_type(eb_inner)?, self);
304 }
305 },
306
307 NessaExpr::Return(_, expr) => res = merge_types(res, Some(self.infer_type(expr)?), self),
308
309 _ => {}
310 }
311 }
312
313 Ok(res)
314 }
315
316 fn compile_expr_variables(&mut self, expr: &mut NessaExpr, registers: &mut Vec<usize>, var_map: &mut VariableMap) -> Result<(), NessaError> {
323 match expr {
324 NessaExpr::NameReference(l, n) if var_map.is_var_defined(n) => {
326 let (idx, t) = var_map.get_var(n).unwrap();
327 *expr = NessaExpr::Variable(l.clone(), *idx, n.clone(), t.clone());
328 },
329
330 NessaExpr::NameReference(l, n) => {
331 let func = self.get_function_id(n.clone()).ok();
332 *expr = NessaExpr::QualifiedName(l.clone(), n.clone(), func);
333 },
334
335 NessaExpr::VariableAssignment(l, n, e) if var_map.is_var_defined(n) => {
336 if var_map.is_var_defined(n) {
337 self.compile_expr_variables(e, registers, var_map)?;
338
339 let (idx, t) = var_map.get_var(n).unwrap();
340
341 *expr = NessaExpr::CompiledVariableAssignment(l.clone(), *idx, n.clone(), t.clone(), e.clone());
342
343 } else {
344 return Err(NessaError::compiler_error(format!("Variable with name {} is not defined", n.green()), l, vec!()));
345 }
346 },
347
348 NessaExpr::VariableDefinition(l, n, t, e) => {
350 if var_map.is_var_defined_in_last_ctx(n) {
351 return Err(NessaError::compiler_error(format!("Variable with name {} is already defined", n.green()), l, vec!()));
352 }
353
354 let idx = registers.pop().unwrap();
355
356 self.compile_expr_variables(e, registers, var_map)?;
357
358 if let Type::InferenceMarker = t {
359 *t = self.infer_type(e)?;
360 }
361
362 var_map.define_var(n.clone(), idx, t.clone());
363
364 *expr = NessaExpr::CompiledVariableDefinition(l.clone(), idx, n.clone(), t.clone(), e.clone());
365 },
366
367 NessaExpr::CompiledVariableAssignment(_, _, _, _, e) => {
368 self.compile_expr_variables(e, registers, var_map)?;
369 }
370
371 NessaExpr::CompiledVariableDefinition(l, id, n, t, e) => {
372 if var_map.is_var_defined_in_last_ctx(n) {
373 return Err(NessaError::compiler_error(format!("Variable with name {} is already defined", n.green()), l, vec!()));
374 }
375
376 self.compile_expr_variables(e, registers, var_map)?;
377
378 var_map.define_var(n.clone(), *id, t.clone());
379 }
380
381 NessaExpr::UnaryOperation(l, id, t, e) => {
383 self.compile_expr_variables(e, registers, var_map)?;
384
385 if t.is_empty() {
386 let arg_type = self.infer_type(e)?;
387
388 if self.is_unary_op_ambiguous(*id, arg_type.clone()).is_none() {
389 if let Ok((_, _, _, it_args)) = self.get_first_unary_op(*id, arg_type.clone(), None, true, l) {
390 if !it_args.is_empty() {
391 *t = it_args;
392 }
393 }
394 }
395 }
396 }
397
398 NessaExpr::BinaryOperation(l, id, t, a, b) => {
399 self.compile_expr_variables(a, registers, var_map)?;
400 self.compile_expr_variables(b, registers, var_map)?;
401
402 let is_func = matches!(b.as_ref(), NessaExpr::FunctionCall(..));
403 let is_name = matches!(b.as_ref(), NessaExpr::QualifiedName(..));
404 let is_attr = matches!(a.as_ref(), NessaExpr::AttributeAccess(..));
405
406 if *id == DEFINE_BINOP_ID && is_attr {
408 if let NessaExpr::AttributeAccess(_, e, att_idx) = a.as_ref() {
409 *expr = NessaExpr::AttributeAssignment(l.clone(), e.clone(), b.clone(), *att_idx);
410
411 return Ok(());
412 }
413 }
414
415 if *id == DOT_BINOP_ID && is_func {
417 if let NessaExpr::FunctionCall(_, f_id, t, args) = b.as_ref() {
418 let mut new_args = vec!(a.as_ref().clone());
420 new_args.extend(args.iter().cloned());
421
422 *expr = NessaExpr::FunctionCall(l.clone(), *f_id, t.clone(), new_args);
423
424 self.compile_expr_variables(expr, registers, var_map)?;
426 }
427
428 } else if *id == DOT_BINOP_ID && is_name {
429 if let NessaExpr::QualifiedName(_, n, _) = b.as_ref() {
430 let arg_type = self.infer_type(a)?;
431 let mut changed = false;
432 let l_cpy = l.clone();
433 let n_cpy = n.clone();
434
435 if let Type::Basic(id) | Type::Template(id, _) = arg_type.deref_type() {
436 let attrs = &self.type_templates[*id].attributes;
437
438 for (i, att) in attrs.iter().enumerate() {
439 if &att.0 == n {
440 *expr = NessaExpr::AttributeAccess(l.clone(), a.clone(), i);
441 changed = true;
442 break;
443 }
444 }
445
446 } else {
447 return Err(NessaError::compiler_error(
448 format!("Type {} has no attributes", arg_type.get_name(self)),
449 &l_cpy, vec!()
450 ));
451 }
452
453 if !changed {
454 return Err(NessaError::compiler_error(
455 format!("Attribute with name {} was not found in class {}", n_cpy.cyan(), arg_type.deref_type().get_name(self)),
456 &l_cpy, vec!()
457 ));
458 }
459 }
460
461 } else if t.is_empty() {
462 let arg_type_1 = self.infer_type(a)?;
463 let arg_type_2 = self.infer_type(b)?;
464
465 if self.is_binary_op_ambiguous(*id, arg_type_1.clone(), arg_type_2.clone()).is_none() {
466 if let Ok((_, _, _, it_args)) = self.get_first_binary_op(*id, arg_type_1.clone(), arg_type_2.clone(), None, true, l) {
467 if !it_args.is_empty() {
468 *t = it_args;
469 }
470 }
471 }
472 }
473 }
474
475 NessaExpr::NaryOperation(l, id, t, a, b) => {
476 self.compile_expr_variables(a, registers, var_map)?;
477
478 for i in b.iter_mut() {
479 self.compile_expr_variables(i, registers, var_map)?;
480 }
481
482 let is_func = matches!(a.as_ref(), NessaExpr::QualifiedName(_, _, Some(_)));
483
484 if *id == CALL_OP && is_func {
485 if let NessaExpr::QualifiedName(_, _, Some(id)) = a.as_ref() {
486 *expr = NessaExpr::FunctionCall(l.clone(), *id, t.clone(), b.clone());
487
488 self.compile_expr_variables(expr, registers, var_map)?;
490 }
491
492 } else if t.is_empty() {
493 let arg_type = self.infer_type(a)?;
494 let arg_types: Vec<_> = b.iter().map(|a| self.infer_type(a)).collect::<Result<_, _>>()?;
495
496 if self.is_nary_op_ambiguous(*id, arg_type.clone(), arg_types.clone()).is_none() {
497 if let Ok((_, _, _, it_args)) = self.get_first_nary_op(*id, arg_type.clone(), arg_types, None, true, l) {
498 if !it_args.is_empty() {
499 *t = it_args;
500 }
501 }
502 }
503 }
504 }
505
506 NessaExpr::Tuple(_, args) => {
507 if args.len() == 1 {
508 *expr = args.pop().unwrap();
509 self.compile_expr_variables(expr, registers, var_map)?;
510
511 } else {
512 for i in args {
513 self.compile_expr_variables(i, registers, var_map)?;
514 }
515 }
516 }
517
518 NessaExpr::FunctionCall(l, id, t, args) => {
519 for i in args.iter_mut() {
520 self.compile_expr_variables(i, registers, var_map)?;
521 }
522
523 if t.is_empty() {
524 let arg_types: Vec<_> = args.iter().map(|a| self.infer_type(a)).collect::<Result<_, _>>()?;
525
526 if self.is_function_overload_ambiguous(*id, arg_types.clone()).is_none() {
527 if let Ok((_, _, _, it_args)) = self.get_first_function_overload(*id, arg_types.clone(), None, true, l) {
528 if !it_args.is_empty() {
529 *t = it_args;
530 }
531 }
532 }
533 }
534
535
536 }
537
538 NessaExpr::If(_, h, ib, ei, eb) => {
540 self.compile_expr_variables(h, registers, var_map)?;
541 self.compile_vars_and_infer_ctx(ib, registers, var_map, &vec!())?;
542
543 for (ei_h, ei_b) in ei {
544 self.compile_expr_variables(ei_h, registers, var_map)?;
545 self.compile_vars_and_infer_ctx(ei_b, registers, var_map, &vec!())?;
546 }
547
548 if let Some(eb_inner) = eb {
549 self.compile_vars_and_infer_ctx(eb_inner, registers, var_map, &vec!())?;
550 }
551 }
552
553 NessaExpr::While(_, c, b) => {
554 self.compile_expr_variables(c, registers, var_map)?;
555 self.compile_vars_and_infer_ctx(b, registers, var_map, &vec!())?;
556 }
557
558 NessaExpr::For(l, i, c, b) => {
559 self.compile_expr_variables(c, registers, var_map)?;
560
561 let container_type = self.infer_type(c)?;
562
563 if !self.implements_iterable(&container_type) {
564 return Err(NessaError::compiler_error(
565 format!("type {} does not implement {} interface", container_type.get_name(self), self.interfaces[ITERABLE_ID].name.green()),
566 l, vec!()
567 ));
568 }
569
570 let (it_ov_id, iterator_type, _, it_args) = self.get_iterator_type(&container_type, l)?;
571 let (next_ov_id, element_type, _, next_args) = self.get_iterator_output_type(&iterator_type, l)?;
572
573 let iterator_idx = *registers.last().unwrap();
574 let element_idx = *registers.get(registers.len() - 2).unwrap();
575
576 let it_mut = iterator_type.clone().to_mut();
577
578 let (consumed_ov_id, _, _, consumed_args) = self.get_first_function_overload(IS_CONSUMED_FUNC_ID, vec!(it_mut.clone()), None, true, l)?;
579
580 self.cache.usages.functions.add_new(ITERATOR_FUNC_ID, vec!(container_type.clone()), it_args.clone());
581 self.cache.usages.functions.add_new(NEXT_FUNC_ID, vec!(it_mut.clone()), next_args.clone());
582 self.cache.usages.functions.add_new(IS_CONSUMED_FUNC_ID, vec!(it_mut.clone()), consumed_args.clone());
583
584 self.cache.overloads.functions.insert((ITERATOR_FUNC_ID, vec!(container_type.clone()), it_args.clone()), it_ov_id);
585 self.cache.overloads.functions.insert((NEXT_FUNC_ID, vec!(it_mut.clone()), next_args.clone()), next_ov_id);
586 self.cache.overloads.functions.insert((IS_CONSUMED_FUNC_ID, vec!(it_mut.clone()), consumed_args.clone()), consumed_ov_id);
587
588 self.compile_vars_and_infer_ctx(b, registers, var_map, &vec!(("__iterator__".into(), iterator_type.clone()), (i.clone(), element_type.clone())))?;
589
590 *expr = NessaExpr::CompiledFor(l.clone(), iterator_idx, element_idx, i.clone(), c.clone(), b.clone());
591 }
592
593 NessaExpr::Return(_, e) => {
594 self.compile_expr_variables(e, registers, var_map)?;
595 }
596
597 NessaExpr::DoBlock(_, b, r) => {
598 self.compile_vars_and_infer_ctx(b, registers, var_map, &vec!())?;
599
600 if *r == Type::InferenceMarker {
602 *r = self.infer_lambda_return_type(b)?.unwrap_or(Type::Empty);
603 }
604 }
605
606 NessaExpr::Lambda(l, c, a, r, b) => {
607 let mut captures = vec!();
608 let mut capture_args = vec!();
609
610 for n in c {
612 if var_map.is_var_defined(n) {
613 let (idx, t) = var_map.get_var(n).unwrap();
614 captures.push((n.clone(), NessaExpr::Variable(l.clone(), *idx, n.clone(), t.clone())));
615 capture_args.push((n.clone(), t.clone()));
616
617 } else {
618 return Err(NessaError::compiler_error(format!("Variable with name {} is not defined", n.green()), l, vec!()));
619 }
620 }
621
622 self.compile(b, &capture_args.iter().chain(a.iter()).cloned().collect())?;
623
624 if *r == Type::InferenceMarker {
626 *r = self.infer_lambda_return_type(b)?.unwrap_or(Type::Empty);
627 }
628
629 *expr = NessaExpr::CompiledLambda(l.clone(), self.lambdas, captures, a.clone(), r.clone(), b.clone());
630 self.lambdas += 1;
631 },
632
633 NessaExpr::FunctionDefinition(l, _, _, tm, a, r, b) => {
634 if tm.is_empty() {
635 self.compile(b, a)?;
636 }
637
638 if let Type::Empty = r {
639 if NessaContext::ensured_return_check_body(b, l, "Function").is_err() {
640 b.push(NessaExpr::Return(l.clone(), Box::new(NessaExpr::Literal(l.clone(), Object::empty()))));
641 }
642 }
643 },
644
645 NessaExpr::PrefixOperationDefinition(l, _, _, tm, n, t, r, b) => {
646 if tm.is_empty() {
647 self.compile(b, &vec!((n.clone(), t.clone())))?;
648 }
649
650 if let Type::Empty = r {
651 if NessaContext::ensured_return_check_body(b, l, "Operation").is_err() {
652 b.push(NessaExpr::Return(l.clone(), Box::new(NessaExpr::Literal(l.clone(), Object::empty()))));
653 }
654 }
655 },
656
657 NessaExpr::PostfixOperationDefinition(l, _, _, tm, n, t, r, b) => {
658 if tm.is_empty() {
659 self.compile(b, &vec!((n.clone(), t.clone())))?;
660 }
661
662 if let Type::Empty = r {
663 if NessaContext::ensured_return_check_body(b, l, "Operation").is_err() {
664 b.push(NessaExpr::Return(l.clone(), Box::new(NessaExpr::Literal(l.clone(), Object::empty()))));
665 }
666 }
667 },
668
669 NessaExpr::BinaryOperationDefinition(l, _, _, tm, a1, a2, r, b) => {
670 if tm.is_empty() {
671 self.compile(b, &vec!(a1.clone(), a2.clone()))?;
672 }
673
674 if let Type::Empty = r {
675 if NessaContext::ensured_return_check_body(b, l, "Operation").is_err() {
676 b.push(NessaExpr::Return(l.clone(), Box::new(NessaExpr::Literal(l.clone(), Object::empty()))));
677 }
678 }
679 },
680
681 NessaExpr::NaryOperationDefinition(l, _, _, tm, a, args, r, b) => {
682 let mut all_args = vec!(a.clone());
683 all_args.extend(args.iter().cloned());
684
685 if tm.is_empty() {
686 self.compile(b, &all_args)?;
687 }
688
689 if let Type::Empty = r {
690 if NessaContext::ensured_return_check_body(b, l, "Operation").is_err() {
691 b.push(NessaExpr::Return(l.clone(), Box::new(NessaExpr::Literal(l.clone(), Object::empty()))));
692 }
693 }
694 }
695
696 _ => {}
697 }
698
699 Ok(())
700 }
701
702 fn compile_vars_and_infer_ctx(&mut self, body: &mut Vec<NessaExpr>, registers: &mut Vec<usize>, var_map: &mut VariableMap, args: &Vec<(String, Type)>) -> Result<usize, NessaError> {
703 var_map.add_context();
704
705 for (n, t) in args {
706 let idx = registers.pop().unwrap();
707 var_map.define_var(n.clone(), idx, t.clone());
708 }
709
710 for e in body {
712 self.compile_expr_variables(e, registers, var_map)?;
713 }
714
715 let mut max_var = 0;
716
717 var_map.for_each_last_ctx(|i| {
719 registers.push(i);
720 max_var = max_var.max(i + 1); });
722
723 var_map.remove_context();
724
725 Ok(max_var)
726 }
727
728 pub fn transform_term(&mut self, expr: &mut NessaExpr) -> Result<(), NessaError> {
729 match expr {
730 NessaExpr::QualifiedName(l, _, Some(id)) => {
731 let func = &self.functions[*id];
732
733 if func.overloads.len() > 1 {
734 return Err(NessaError::compiler_error(
735 format!(
736 "Implicit lambda for function with name {} is ambiguous (found {} overloads)",
737 func.name.green(),
738 func.overloads.len()
739 ),
740 l, vec!()
741 ));
742 }
743
744 if func.overloads[0].templates != 0 {
745 return Err(NessaError::compiler_error(
746 format!(
747 "Implicit lambda for function with name {} cannot be formed from generic overload",
748 func.name.green()
749 ),
750 l, vec!()
751 ));
752 }
753
754 let ov = &func.overloads[0];
755 let mut args = vec!();
756
757 if let Type::And(a) = &ov.args {
758 if a.len() == 1 {
759 args.push(a[0].clone());
760
761 } else {
762 args.extend(a.iter().cloned());
763 }
764
765 } else {
766 args.push(ov.args.clone());
767 }
768
769 let move_id = self.get_function_id("move".into()).unwrap();
770
771 let fn_call = NessaExpr::FunctionCall(
773 Location::none(), *id, vec!(),
774 args.iter().enumerate()
775 .map(|(i, t)| {
776 let v = NessaExpr::Variable(Location::none(), i, format!("arg_{i}"), t.clone());
777
778 if t.is_ref() {
780 v
781
782 } else {
783 NessaExpr::FunctionCall(
784 Location::none(), move_id, vec!(t.clone()), vec!(v)
785 )
786 }
787 })
788 .collect()
789 );
790
791 *expr = NessaExpr::CompiledLambda(
793 l.clone(), self.lambdas, vec!(),
794 args.into_iter().enumerate().map(|(i, t)| (format!("arg_{i}"), t)).collect(),
795 ov.ret.clone(),
796 vec!(NessaExpr::Return(Location::none(), Box::new(fn_call)))
797 );
798
799 self.lambdas += 1;
800
801 Ok(())
802 }
803
804 NessaExpr::QualifiedName(l, n, func) => {
805 if func.is_none() {
806 let similar_func = self.functions.iter().map(|f| &f.name)
807 .filter(|name| levenshtein(n, name) < 3)
808 .map(|i| format!("{} (Function)", i.green()))
809 .collect::<Vec<_>>();
810
811 return Err(NessaError::compiler_error(
812 format!("Identifier with name {} is not defined", n), l,
813 similar_func.iter().map(|i| format!("Similar: {}", i)).collect()
814 ));
815 }
816
817 Ok(())
818 }
819
820 NessaExpr::AttributeAccess(_, e, _) |
821 NessaExpr::UnaryOperation(_, _, _, e) |
822 NessaExpr::Return(_, e) |
823 NessaExpr::CompiledVariableDefinition(_, _, _, _, e) |
824 NessaExpr::CompiledVariableAssignment(_, _, _, _, e) => self.transform_term(e),
825
826 NessaExpr::CompiledLambda(_, _, c, _, _, _) => {
827 for (_, e) in c {
828 self.transform_term(e)?;
829 }
830
831 Ok(())
832 }
833
834 NessaExpr::DoBlock(_, exprs, _) |
835 NessaExpr::FunctionCall(_, _, _, exprs) |
836 NessaExpr::Tuple(_, exprs) => {
837 for e in exprs {
838 self.transform_term(e)?;
839 }
840
841 Ok(())
842 },
843
844 NessaExpr::CompiledFor(_, _, _, _, c, exprs) |
845 NessaExpr::While(_, c, exprs) => {
846 self.transform_term(c)?;
847
848 for e in exprs {
849 self.transform_term(e)?;
850 }
851
852 Ok(())
853 },
854
855 NessaExpr::NaryOperation(_, _, _, c, exprs) => {
856 self.transform_term(c)?;
857
858 for e in exprs {
859 self.transform_term(e)?;
860 }
861
862 Ok(())
863 },
864
865 NessaExpr::AttributeAssignment(_, a, b, _) |
866 NessaExpr::BinaryOperation(_, _, _, a, b) => {
867 self.transform_term(a)?;
868 self.transform_term(b)?;
869
870 Ok(())
871 },
872
873 NessaExpr::If(_, ic, ib, ei, eb) => {
874 self.transform_term(ic)?;
875
876 for e in ib {
877 self.transform_term(e)?;
878 }
879
880 for (ei_h, ei_b) in ei {
881 self.transform_term(ei_h)?;
882
883 for e in ei_b {
884 self.transform_term(e)?;
885 }
886 }
887
888 if let Some(inner) = eb {
889 for e in inner {
890 self.transform_term(e)?;
891 }
892 }
893
894 Ok(())
895 },
896
897 NessaExpr::Variable(_, _, _, _) |
898 NessaExpr::Break(_) |
899 NessaExpr::Continue(_) |
900 NessaExpr::Literal(_, _) |
901 NessaExpr::Macro(_, _, _, _, _, _) |
902 NessaExpr::FunctionDefinition(_, _, _, _, _, _, _) |
903 NessaExpr::PrefixOperatorDefinition(_, _, _) |
904 NessaExpr::PostfixOperatorDefinition(_, _, _) |
905 NessaExpr::BinaryOperatorDefinition(_, _, _, _) |
906 NessaExpr::NaryOperatorDefinition(_, _, _, _) |
907 NessaExpr::ClassDefinition(_, _, _, _, _, _, _) |
908 NessaExpr::InterfaceDefinition(_, _, _, _, _, _, _, _) |
909 NessaExpr::InterfaceImplementation(_, _, _, _, _) |
910 NessaExpr::PrefixOperationDefinition(_, _, _, _, _, _, _, _) |
911 NessaExpr::PostfixOperationDefinition(_, _, _, _, _, _, _, _) |
912 NessaExpr::BinaryOperationDefinition(_, _, _, _, _, _, _, _) |
913 NessaExpr::NaryOperationDefinition(_, _, _, _, _, _, _, _) => { Ok(()) },
914
915 e => unreachable!("{:?}", e)
916 }
917 }
918
919 pub fn compile_vars_and_infer(&mut self, body: &mut Vec<NessaExpr>, args: &Vec<(String, Type)>) -> Result<usize, NessaError> {
920 self.compile_vars_and_infer_ctx(body, &mut (0..self.variables.len()).rev().collect(), &mut VariableMap::new(), args)
921 }
922
923 pub fn compile(&mut self, body: &mut Vec<NessaExpr>, args: &Vec<(String, Type)>) -> Result<(), NessaError> {
924 self.compile_vars_and_infer(body, args)?;
925
926 for expr in body.iter_mut() {
928 self.transform_term(expr)?;
929 }
930
931 Ok(())
932 }
933}
934
935#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
942pub enum PlaceholderType {
943 Break, Continue
944}
945
946#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
947pub enum CompiledNessaExpr {
948 Empty,
949 Bool(bool),
950 Int(Integer),
951 Float(f64),
952 Str(String),
953 Array(usize, Type),
954 Lambda(usize, usize, Type, Type),
955
956 Construct(usize, usize, Vec<Type>),
957 AttributeAssign(usize),
958 AttributeMove(usize),
959 AttributeRef(usize),
960 AttributeMut(usize),
961 AttributeCopy(usize),
962 AttributeDeref(usize),
963
964 Tuple(usize),
965 TupleElemMove(usize),
966 TupleElemRef(usize),
967 TupleElemMut(usize),
968 TupleElemCopy(usize),
969 TupleElemDeref(usize),
970
971 IdxMove, IdxRef, IdxMut, IdxMoveRef,
972
973 StoreIntVariable(usize, Integer),
974 StoreBoolVariable(usize, bool),
975 StoreFloatVariable(usize, f64),
976 StoreStringVariable(usize, String),
977
978 StoreVariable(usize),
979 GetVariable(usize),
980 CloneVariable(usize),
981 RefVariable(usize),
982 DerefVariable(usize),
983 CopyVariable(usize),
984 MoveVariable(usize),
985 Assign,
986 AssignToVar(usize), AssignToVarDirect(usize),
987 Drop,
988
989 Jump(usize),
990 RelativeJump(i32),
991 RelativeJumpIfFalse(usize, bool),
992 RelativeJumpIfTrue(usize, bool),
993 Call(usize),
994 LambdaCall, LambdaCallRef,
995 Return,
996
997 NativeFunctionCall(usize, usize, Vec<Type>),
998 UnaryOperatorCall(usize, usize, Vec<Type>),
999 BinaryOperatorCall(usize, usize, Vec<Type>),
1000 NaryOperatorCall(usize, usize, Vec<Type>),
1001
1002 NativeFunctionCallNoRet(usize, usize, Vec<Type>), UnaryOperatorCallNoRet(usize, usize, Vec<Type>),
1004 BinaryOperatorCallNoRet(usize, usize, Vec<Type>),
1005
1006 Ref, Mut, Copy, Deref, Demut, Move, ToFloat,
1008
1009 Inc, Dec,
1011 Addi, Addf,
1012 Subi, Subf,
1013 Muli, Mulf,
1014 Divi, Divf,
1015 Modi, Modf,
1016 Negi, Negf,
1017
1018 AddStr,
1019
1020 NotB, AndB, OrB, XorB, Shr, Shl,
1022
1023 Lti, Ltf,
1025 Gti, Gtf,
1026 Lteqi, Lteqf,
1027 Gteqi, Gteqf,
1028 Eqi, Eqf,
1029 Neqi, Neqf,
1030 EqBool, NeqBool,
1031 EqStr, NeqStr,
1032
1033 Not, Or, And, Xor,
1035
1036 Nand, Nor, Placeholder(PlaceholderType),
1039
1040 Halt
1041}
1042
1043impl CompiledNessaExpr {
1044 pub fn needs_float(&self) -> bool {
1045 use CompiledNessaExpr::*;
1046
1047 matches!(
1048 self,
1049 Addf | Subf | Mulf | Divf | Modf |
1050 Ltf | Gtf | Lteqf | Gteqf | Eqf | Neqf |
1051 Negf
1052 )
1053 }
1054
1055 pub fn needs_deref(&self) -> bool {
1056 use CompiledNessaExpr::*;
1057
1058 matches!(
1059 self,
1060 Addf | Subf | Mulf | Divf | Modf |
1061 Ltf | Gtf | Lteqf | Gteqf | Eqf | Neqf | Negf |
1062 Addi | Subi | Muli | Divi | Modi |
1063 Lti | Gti | Lteqi | Gteqi | Eqi | Neqi | Negi |
1064 Not | Or | And | Xor |
1065 NotB | AndB | OrB | XorB | Shr | Shl |
1066 EqStr | NeqStr | EqBool | NeqBool | AddStr
1067 )
1068 }
1069
1070 pub fn needs_no_drop(&self) -> bool {
1071 use CompiledNessaExpr::*;
1072
1073 matches!(
1074 self,
1075 Assign |
1076 Inc | Dec
1077 )
1078 }
1079
1080 pub fn to_string(&self, ctx: &NessaContext) -> String {
1081 use CompiledNessaExpr::*;
1082
1083 match self {
1084 Bool(obj) => format!("{}({})", "Bool".green(), obj.to_string().blue()),
1085 Int(obj) => format!("{}({})", "Int".green(), obj.to_string().blue()),
1086 Float(obj) => format!("{}({})", "Float".green(), obj.to_string().blue()),
1087 Str(obj) => format!("{}(\"{}\")", "Str".green(), obj.to_string().blue()),
1088
1089 Array(length, t) => format!(
1090 "{}({}, {})", "Array".green(),
1091 length.to_string().magenta(),
1092 t.get_name(ctx)
1093 ),
1094
1095 Lambda(pos, cap, args, ret) => format!(
1096 "{}({}, {}, {}, {})", "Lambda".green(),
1097 pos.to_string().magenta(),
1098 cap.to_string().magenta(),
1099 args.get_name(ctx),
1100 ret.get_name(ctx)
1101 ),
1102
1103 Tuple(to) => format!("{}({})", "Tuple".green(), to.to_string().blue()),
1104
1105 StoreVariable(to) => format!("{}({})", "StoreVariable".green(), to.to_string().blue()),
1106 GetVariable(to) => format!("{}({})", "GetVariable".green(), to.to_string().blue()),
1107 CopyVariable(to) => format!("{}({})", "CopyVariable".green(), to.to_string().blue()),
1108 DerefVariable(to) => format!("{}({})", "DerefVariable".green(), to.to_string().blue()),
1109 MoveVariable(to) => format!("{}({})", "MoveVariable".green(), to.to_string().blue()),
1110
1111 Call(to) => format!("{}({})", "Call".green(), to.to_string().blue()),
1112
1113 Jump(to) => format!("{}({})", "Jump".green(), to.to_string().blue()),
1114 RelativeJump(to) => format!("{}({})", "RelativeJump".green(), to.to_string().blue()),
1115 RelativeJumpIfTrue(to, p) => format!("{}({}, {})", "RelativeJumpIfTrue".green(), to.to_string().blue(), p.to_string().blue()),
1116 RelativeJumpIfFalse(to, p) => format!("{}({}, {})", "RelativeJumpIfFalse".green(), to.to_string().blue(), p.to_string().blue()),
1117
1118 Construct(id, length, args) => format!(
1119 "{}({}, {}, {{{}}})", "Construct".green(),
1120 ctx.type_templates[*id].name.magenta(),
1121 length.to_string().magenta(),
1122 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1123 ),
1124
1125 AttributeMove(to) => format!("{}({})", "Attribute".green(), to.to_string().blue()),
1126 AttributeRef(to) => format!("{}({})", "AttributeRef".green(), to.to_string().blue()),
1127 AttributeMut(to) => format!("{}({})", "AttributeMut".green(), to.to_string().blue()),
1128 AttributeCopy(to) => format!("{}({})", "AttributeCopy".green(), to.to_string().blue()),
1129 AttributeDeref(to) => format!("{}({})", "AttributeDeref".green(), to.to_string().blue()),
1130
1131 TupleElemMove(to) => format!("{}({})", "TupleElem".green(), to.to_string().blue()),
1132 TupleElemRef(to) => format!("{}({})", "TupleElemRef".green(), to.to_string().blue()),
1133 TupleElemMut(to) => format!("{}({})", "TupleElemMut".green(), to.to_string().blue()),
1134 TupleElemCopy(to) => format!("{}({})", "TupleElemCopy".green(), to.to_string().blue()),
1135 TupleElemDeref(to) => format!("{}({})", "TupleElemDeref".green(), to.to_string().blue()),
1136
1137 NativeFunctionCall(id, ov, args) => format!(
1138 "{}({}, {}, {{{}}})", "FunctionCall".green(),
1139 ctx.functions[*id].name.magenta(),
1140 ov.to_string().blue(),
1141 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1142 ),
1143
1144 NativeFunctionCallNoRet(id, ov, args) => format!(
1145 "{}({}, {}, {{{}}})", "FunctionCallNoRet".green(),
1146 ctx.functions[*id].name.magenta(),
1147 ov.to_string().blue(),
1148 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1149 ),
1150
1151 UnaryOperatorCall(id, ov, args) => format!(
1152 "{}({}, {}, {{{}}})", "UnOpCall".green(),
1153 ctx.unary_ops[*id].get_repr().magenta(),
1154 ov.to_string().blue(),
1155 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1156 ),
1157
1158 UnaryOperatorCallNoRet(id, ov, args) => format!(
1159 "{}({}, {}, {{{}}})", "UnOpCallNoRet".green(),
1160 ctx.unary_ops[*id].get_repr().magenta(),
1161 ov.to_string().blue(),
1162 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1163 ),
1164
1165 BinaryOperatorCall(id, ov, args) => format!(
1166 "{}({}, {}, {{{}}})", "BinOpCall".green(),
1167 ctx.binary_ops[*id].get_repr().magenta(),
1168 ov.to_string().blue(),
1169 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1170 ),
1171
1172 BinaryOperatorCallNoRet(id, ov, args) => format!(
1173 "{}({}, {}, {{{}}})", "BinOpCallNoRet".green(),
1174 ctx.binary_ops[*id].get_repr().magenta(),
1175 ov.to_string().blue(),
1176 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1177 ),
1178
1179 NaryOperatorCall(id, ov, args) => format!(
1180 "{}({}, {}, {{{}}})", "NaryOpCall".green(),
1181 ctx.nary_ops[*id].get_repr().magenta(),
1182 ov.to_string().blue(),
1183 args.iter().map(|i| i.get_name(ctx)).collect::<Vec<_>>().join(", ")
1184 ),
1185
1186 _ => format!("{:?}", self).green().to_string()
1187 }
1188 }
1189}
1190
1191#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1192pub struct NessaInstruction {
1193 pub instruction: CompiledNessaExpr,
1194 pub debug_info: DebugInfo
1195}
1196
1197impl NessaInstruction {
1198 pub fn to_string(&self, ctx: &NessaContext) -> String {
1199 format!("{:<30}{}{}", self.instruction.to_string(ctx), if self.debug_info.comment.is_empty() { "" } else { " # " }, self.debug_info.comment)
1200 }
1201}
1202
1203impl From<CompiledNessaExpr> for NessaInstruction {
1204 fn from(obj: CompiledNessaExpr) -> NessaInstruction {
1205 NessaInstruction {
1206 instruction: obj,
1207 debug_info: DebugInfo::default()
1208 }
1209 }
1210}
1211
1212impl NessaInstruction {
1213 pub fn new(instruction: CompiledNessaExpr, comment: String) -> NessaInstruction {
1214 NessaInstruction {
1215 instruction,
1216 debug_info: DebugInfoBuilder::default().comment(comment).build().unwrap()
1217 }
1218 }
1219
1220 pub fn new_with_type(instruction: CompiledNessaExpr, comment: String, var_type: Type) -> NessaInstruction {
1221 NessaInstruction {
1222 instruction,
1223 debug_info: DebugInfoBuilder::default().comment(comment).var_type(Some(var_type)).build().unwrap()
1224 }
1225 }
1226
1227 pub fn set_loc(mut self, loc: &Location) -> Self {
1228 self.debug_info.set_line(loc.module.clone(), loc.line);
1229 self
1230 }
1231}
1232
1233impl NessaContext{
1234 pub fn get_inner_dep_graph(&mut self, lines: &[NessaExpr]) -> Result<DirectedGraph<(ImportType, usize), ()>, NessaError> {
1235 let mut res = DirectedGraph::new();
1236 let mut compiled = lines.to_owned();
1237
1238 self.compile(&mut compiled, &vec!())?; for (line_idx, e) in compiled.iter().enumerate() {
1241 self.get_inner_dep_graph_expr(e, &(ImportType::Line(line_idx), 0), &mut res);
1242 }
1243
1244 Ok(res)
1245 }
1246
1247 pub fn get_inner_dep_graph_body(&self, lines: &Vec<NessaExpr>, parent: &(ImportType, usize), deps: &mut DirectedGraph<(ImportType, usize), ()>) {
1248 for line in lines {
1249 self.get_inner_dep_graph_expr(line, parent, deps);
1250 }
1251 }
1252
1253 pub fn get_inner_dep_graph_expr(&self, expr: &NessaExpr, parent: &(ImportType, usize), deps: &mut DirectedGraph<(ImportType, usize), ()>) {
1254 match expr {
1255 NessaExpr::Literal(_, obj) => {
1256 deps.connect(parent.clone(), (ImportType::Class, obj.get_type_id()), ());
1257 }
1258
1259 NessaExpr::Return(_, e) => self.get_inner_dep_graph_expr(e, parent, deps),
1260
1261 NessaExpr::CompiledVariableAssignment(_, _, _, t, e) |
1262 NessaExpr::CompiledVariableDefinition(_, _, _, t, e) => {
1263 self.get_inner_dep_graph_expr(e, parent, deps);
1264
1265 for td in t.type_dependencies() {
1266 deps.connect(parent.clone(), (ImportType::Class, td), ());
1267 }
1268
1269 for id in t.interface_dependencies() {
1270 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1271 }
1272 }
1273
1274 NessaExpr::Tuple(_, b) => {
1275 self.get_inner_dep_graph_body(b, parent, deps);
1276 }
1277
1278 NessaExpr::FunctionCall(_, id, ts, args) => {
1279 deps.connect(parent.clone(), (ImportType::Fn, *id), ());
1280
1281 self.get_inner_dep_graph_body(args, parent, deps);
1282
1283 for t in ts {
1284 for td in t.type_dependencies() {
1285 deps.connect(parent.clone(), (ImportType::Class, td), ());
1286 }
1287
1288 for id in t.interface_dependencies() {
1289 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1290 }
1291 }
1292 }
1293
1294 NessaExpr::UnaryOperation(_, id, ts, a) => {
1295 if let Operator::Unary { id, prefix, .. } = &self.unary_ops[*id] {
1296 if *prefix {
1297 deps.connect(parent.clone(), (ImportType::Prefix, *id), ());
1298
1299 } else {
1300 deps.connect(parent.clone(), (ImportType::Postfix, *id), ());
1301 }
1302
1303 self.get_inner_dep_graph_expr(a, parent, deps);
1304
1305 for t in ts {
1306 for td in t.type_dependencies() {
1307 deps.connect(parent.clone(), (ImportType::Class, td), ());
1308 }
1309
1310 for id in t.interface_dependencies() {
1311 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1312 }
1313 }
1314 }
1315 }
1316
1317 NessaExpr::BinaryOperation(_, id, ts, a, b) => {
1318 if let Operator::Binary { id, .. } = &self.binary_ops[*id] {
1319 deps.connect(parent.clone(), (ImportType::Binary, *id), ());
1320
1321 self.get_inner_dep_graph_expr(a, parent, deps);
1322 self.get_inner_dep_graph_expr(b, parent, deps);
1323
1324 for t in ts {
1325 for td in t.type_dependencies() {
1326 deps.connect(parent.clone(), (ImportType::Class, td), ());
1327 }
1328
1329 for id in t.interface_dependencies() {
1330 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1331 }
1332 }
1333 }
1334 }
1335
1336 NessaExpr::NaryOperation(_, id, ts, a, b) => {
1337 if let Operator::Nary { id, .. } = &self.nary_ops[*id] {
1338 deps.connect(parent.clone(), (ImportType::Nary, *id), ());
1339
1340 self.get_inner_dep_graph_expr(a, parent, deps);
1341 self.get_inner_dep_graph_body(b, parent, deps);
1342
1343 for t in ts {
1344 for td in t.type_dependencies() {
1345 deps.connect(parent.clone(), (ImportType::Class, td), ());
1346 }
1347
1348 for id in t.interface_dependencies() {
1349 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1350 }
1351 }
1352 }
1353 }
1354
1355 NessaExpr::While(_, c, b) => {
1356 self.get_inner_dep_graph_expr(c, parent, deps);
1357 self.get_inner_dep_graph_body(b, parent, deps);
1358 }
1359
1360 NessaExpr::CompiledFor(_, _, _, _, c, b) => {
1361 self.get_inner_dep_graph_expr(c, parent, deps);
1362 self.get_inner_dep_graph_body(b, parent, deps);
1363
1364 deps.connect(parent.clone(), (ImportType::Interface, ITERABLE_ID), ());
1366 deps.connect(parent.clone(), (ImportType::Fn, ITERATOR_FUNC_ID), ());
1367 deps.connect(parent.clone(), (ImportType::Fn, NEXT_FUNC_ID), ());
1368 deps.connect(parent.clone(), (ImportType::Fn, IS_CONSUMED_FUNC_ID), ());
1369 }
1370
1371 NessaExpr::If(_, ic, ib, ie, eb) => {
1372 self.get_inner_dep_graph_expr(ic, parent, deps);
1373 self.get_inner_dep_graph_body(ib, parent, deps);
1374
1375 for (ie_c, ie_b) in ie {
1376 self.get_inner_dep_graph_expr(ie_c, parent, deps);
1377 self.get_inner_dep_graph_body(ie_b, parent, deps);
1378 }
1379
1380 if let Some(b) = eb {
1381 self.get_inner_dep_graph_body(b, parent, deps);
1382 }
1383 }
1384
1385 NessaExpr::CompiledLambda(_, _, c, args, ret, b) => {
1386 self.get_inner_dep_graph_body(b, parent, deps);
1387
1388 for (_, a) in c {
1389 self.get_inner_dep_graph_expr(a, parent, deps);
1390 }
1391
1392 for (_, t) in args {
1393 for td in t.type_dependencies() {
1394 deps.connect(parent.clone(), (ImportType::Class, td), ());
1395 }
1396
1397 for id in t.interface_dependencies() {
1398 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1399 }
1400 }
1401
1402 for td in ret.type_dependencies() {
1403 deps.connect(parent.clone(), (ImportType::Class, td), ());
1404 }
1405
1406 for id in ret.interface_dependencies() {
1407 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1408 }
1409 }
1410
1411 NessaExpr::FunctionDefinition(_, _, id, _, args, ret, b) => {
1412 self.get_inner_dep_graph_body(b, &(ImportType::Fn, *id), deps);
1413
1414 for (_, t) in args {
1415 for td in t.type_dependencies() {
1416 deps.connect(parent.clone(), (ImportType::Class, td), ());
1417 }
1418
1419 for id in t.interface_dependencies() {
1420 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1421 }
1422 }
1423
1424 for td in ret.type_dependencies() {
1425 deps.connect(parent.clone(), (ImportType::Class, td), ());
1426 }
1427
1428 for id in ret.interface_dependencies() {
1429 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1430 }
1431 }
1432
1433 NessaExpr::PrefixOperationDefinition(_, _, id, _, _, t1, t2, b) => {
1434 self.get_inner_dep_graph_body(b, &(ImportType::Prefix, *id), deps);
1435
1436 for td in t1.type_dependencies() {
1437 deps.connect(parent.clone(), (ImportType::Class, td), ());
1438 }
1439
1440 for id in t1.interface_dependencies() {
1441 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1442 }
1443
1444 for td in t2.type_dependencies() {
1445 deps.connect(parent.clone(), (ImportType::Class, td), ());
1446 }
1447
1448 for id in t2.interface_dependencies() {
1449 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1450 }
1451 }
1452
1453 NessaExpr::PostfixOperationDefinition(_, _, id, _, _, t1, t2, b) => {
1454 self.get_inner_dep_graph_body(b, &(ImportType::Postfix, *id), deps);
1455
1456 for td in t1.type_dependencies() {
1457 deps.connect(parent.clone(), (ImportType::Class, td), ());
1458 }
1459
1460 for id in t1.interface_dependencies() {
1461 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1462 }
1463
1464 for td in t2.type_dependencies() {
1465 deps.connect(parent.clone(), (ImportType::Class, td), ());
1466 }
1467
1468 for id in t2.interface_dependencies() {
1469 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1470 }
1471 }
1472
1473 NessaExpr::BinaryOperationDefinition(_, _, id, _, (_, t1), (_, t2), ret, b) => {
1474 self.get_inner_dep_graph_body(b, &(ImportType::Binary, *id), deps);
1475
1476 for td in t1.type_dependencies() {
1477 deps.connect(parent.clone(), (ImportType::Class, td), ());
1478 }
1479
1480 for id in t1.interface_dependencies() {
1481 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1482 }
1483
1484 for td in t2.type_dependencies() {
1485 deps.connect(parent.clone(), (ImportType::Class, td), ());
1486 }
1487
1488 for id in t2.interface_dependencies() {
1489 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1490 }
1491
1492 for td in ret.type_dependencies() {
1493 deps.connect(parent.clone(), (ImportType::Class, td), ());
1494 }
1495
1496 for id in ret.interface_dependencies() {
1497 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1498 }
1499 }
1500
1501 NessaExpr::NaryOperationDefinition(_, _, id, _, (_, t1), args, ret, b) => {
1502 self.get_inner_dep_graph_body(b, &(ImportType::Nary, *id), deps);
1503
1504 for (_, t) in args {
1505 for td in t.type_dependencies() {
1506 deps.connect(parent.clone(), (ImportType::Class, td), ());
1507 }
1508
1509 for id in t.interface_dependencies() {
1510 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1511 }
1512 }
1513
1514 for td in t1.type_dependencies() {
1515 deps.connect(parent.clone(), (ImportType::Class, td), ());
1516 }
1517
1518 for id in t1.interface_dependencies() {
1519 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1520 }
1521
1522 for td in ret.type_dependencies() {
1523 deps.connect(parent.clone(), (ImportType::Class, td), ());
1524 }
1525
1526 for id in ret.interface_dependencies() {
1527 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1528 }
1529 }
1530
1531 NessaExpr::InterfaceImplementation(_, _, t_i, n, a) => {
1532 if let Some(t) = self.get_interface(n) {
1533 match t_i {
1534 Type::Basic(id) | Type::Template(id, _) => {
1535 deps.connect((ImportType::Class, *id), (ImportType::Interface, t.id), ());
1536 }
1537
1538 _ => {}
1539 }
1540
1541 for tp in a {
1542 for t_dep in tp.type_dependencies() {
1543 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1544 }
1545
1546 for id in tp.interface_dependencies() {
1547 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1548 }
1549 }
1550
1551 for t_dep in t_i.type_dependencies() {
1552 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1553 }
1554
1555 for id in t_i.interface_dependencies() {
1556 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1557 }
1558 }
1559 }
1560
1561 NessaExpr::InterfaceDefinition(_, _, n, _, fns, uns, bin, nary) => {
1562 if let Some(t) = self.get_interface(n) {
1563 for (_, f_n, _, a, r) in fns {
1564 if let Some(f) = self.get_function(f_n) {
1565 deps.connect((ImportType::Interface, t.id), (ImportType::Fn, f.id), ());
1566 }
1567
1568 for (_, tp) in a {
1569 for t_dep in tp.type_dependencies() {
1570 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1571 }
1572
1573 for id in tp.interface_dependencies() {
1574 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1575 }
1576 }
1577
1578 for t_dep in r.type_dependencies() {
1579 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1580 }
1581
1582 for id in r.interface_dependencies() {
1583 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1584 }
1585 }
1586
1587 for (_, op_id, _, _, at, r) in uns {
1588 if let Operator::Unary { prefix, .. } = &self.unary_ops[*op_id] {
1589 if *prefix {
1590 deps.connect((ImportType::Interface, t.id), (ImportType::Prefix, *op_id), ());
1591
1592 } else {
1593 deps.connect((ImportType::Interface, t.id), (ImportType::Postfix, *op_id), ());
1594 }
1595 }
1596
1597 for t_dep in at.type_dependencies() {
1598 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1599 }
1600
1601 for id in at.interface_dependencies() {
1602 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1603 }
1604
1605 for t_dep in r.type_dependencies() {
1606 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1607 }
1608
1609 for id in r.interface_dependencies() {
1610 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1611 }
1612 }
1613
1614 for (_, op_id, _, (_, a0t), (_, a1t), r) in bin {
1615 deps.connect((ImportType::Interface, t.id), (ImportType::Binary, *op_id), ());
1616
1617 for t_dep in a0t.type_dependencies() {
1618 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1619 }
1620
1621 for id in a0t.interface_dependencies() {
1622 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1623 }
1624
1625 for t_dep in a1t.type_dependencies() {
1626 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1627 }
1628
1629 for id in a1t.interface_dependencies() {
1630 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1631 }
1632
1633 for t_dep in r.type_dependencies() {
1634 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1635 }
1636
1637 for id in r.interface_dependencies() {
1638 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1639 }
1640 }
1641
1642 for (_, op_id, _, (_, a0t), a, r) in nary {
1643 deps.connect((ImportType::Interface, t.id), (ImportType::Nary, *op_id), ());
1644
1645 for t_dep in a0t.type_dependencies() {
1646 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1647 }
1648
1649 for id in a0t.interface_dependencies() {
1650 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1651 }
1652
1653 for (_, tp) in a {
1654 for t_dep in tp.type_dependencies() {
1655 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1656 }
1657
1658 for id in tp.interface_dependencies() {
1659 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1660 }
1661 }
1662
1663 for t_dep in r.type_dependencies() {
1664 deps.connect((ImportType::Interface, t.id), (ImportType::Class, t_dep), ());
1665 }
1666
1667 for id in r.interface_dependencies() {
1668 deps.connect((ImportType::Interface, t.id), (ImportType::Interface, id), ());
1669 }
1670 }
1671 }
1672 }
1673
1674 NessaExpr::ClassDefinition(_, _, n, _, _, _, _) => {
1675 if let Some(t) = self.get_type_template(n) {
1676 deps.connect(parent.clone(), (ImportType::Class, t.id), ());
1677
1678 for (_, tp) in &t.attributes {
1680 for t_dep in tp.type_dependencies() {
1681 deps.connect((ImportType::Class, t.id), (ImportType::Class, t_dep), ());
1682 }
1683
1684 for id in tp.interface_dependencies() {
1685 deps.connect(parent.clone(), (ImportType::Interface, id), ());
1686 }
1687 }
1688 }
1689 },
1690
1691 _ => {}
1692 }
1693 }
1694
1695 pub fn get_template_calls_body(
1696 &mut self,
1697 lines: &Vec<NessaExpr>
1698 ) -> Result<(), NessaError> {
1699 let mut changed = true;
1700
1701 while changed {
1702 changed = false;
1703 self.get_template_calls_body_pass(lines, &mut changed)?;
1704 }
1705
1706 Ok(())
1707 }
1708
1709 pub fn get_template_calls_pass(
1710 &mut self,
1711 expr: &NessaExpr,
1712 changed: &mut bool
1713 ) -> Result<(), NessaError> {
1714 return match expr {
1715 NessaExpr::FunctionDefinition(_, _, id, _, a, r, b) => {
1716 let arg_types = a.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
1717 let and = Type::And(arg_types.clone());
1718
1719 if let Some(usages) = self.cache.usages.functions.get_checked(id) {
1720 for (args, ov) in usages {
1721 if Type::And(args).bindable_to(&and, self) {
1722 let mut body = b.clone();
1723 let key = (*id, ov.clone(), arg_types.clone());
1724
1725 if !self.cache.templates.functions.contains(&key) {
1726 if !ov.is_empty() {
1727 let templates = ov.iter().cloned().enumerate().collect();
1728
1729 body.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, &templates));
1731 self.compile(&mut body, &a.iter().map(|(n, t)| (n.clone(), t.sub_templates(&templates))).collect())?;
1732
1733 for line in &body {
1735 self.static_check_expected(line, &Some(r.sub_templates(&templates)))?;
1736 }
1737 }
1738
1739 self.cache.templates.functions.insert(key, body.clone());
1740
1741 self.get_template_calls_body_pass(&body, changed)?;
1743
1744 *changed = true;
1745 }
1746 }
1747 }
1748 }
1749
1750 Ok(())
1751 }
1752
1753 NessaExpr::PostfixOperationDefinition(_, _, id, _, n, tp, r, b) |
1754 NessaExpr::PrefixOperationDefinition(_, _, id, _, n, tp, r, b) => {
1755 if let Some(usages) = self.cache.usages.unary.get_checked(id) {
1756 for (arg, ov) in usages {
1757 if arg[0].bindable_to(tp, self) {
1758 let mut body = b.clone();
1759 let key = (*id, ov.clone(), vec!(tp.clone()));
1760
1761 if !self.cache.templates.unary.contains(&key) {
1762 if !ov.is_empty() {
1763 let templates = ov.iter().cloned().enumerate().collect();
1764
1765 body.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, &templates));
1767 self.compile(&mut body, &vec!((n.clone(), tp.sub_templates(&templates))))?;
1768
1769 for line in &body {
1771 self.static_check_expected(line, &Some(r.sub_templates(&templates)))?;
1772 }
1773 }
1774
1775 self.cache.templates.unary.insert(key, body.clone());
1776
1777 self.get_template_calls_body_pass(&body, changed)?;
1779
1780 *changed = true;
1781 }
1782 }
1783 }
1784 }
1785
1786 Ok(())
1787 }
1788
1789 NessaExpr::BinaryOperationDefinition(_, _, id, _, (n1, t1), (n2, t2), r, b) => {
1790 if let Some(usages) = self.cache.usages.binary.get_checked(id) {
1791 for (arg, ov) in usages {
1792 if arg[0].bindable_to(t1, self) && arg[1].bindable_to(t2, self) {
1793 let mut body = b.clone();
1794 let key = (*id, ov.clone(), vec!(t1.clone(), t2.clone()));
1795
1796 if !self.cache.templates.binary.contains(&key) {
1797 if !ov.is_empty() {
1798 let templates = ov.iter().cloned().enumerate().collect();
1799
1800 body.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, &templates));
1802 self.compile(&mut body, &vec!((n1.clone(), t1.sub_templates(&templates)), (n2.clone(), t2.sub_templates(&templates))))?;
1803
1804 for line in &body {
1806 self.static_check_expected(line, &Some(r.sub_templates(&templates)))?;
1807 }
1808 }
1809
1810 self.cache.templates.binary.insert(key, body.clone());
1811
1812 self.get_template_calls_body_pass(&body, changed)?;
1814
1815 *changed = true;
1816 }
1817 }
1818 }
1819 }
1820
1821 Ok(())
1822 }
1823
1824 NessaExpr::NaryOperationDefinition(_, _, id, _, (n, t), a, r, b) => {
1825 let mut all_args = vec!(t.clone());
1826 all_args.extend(a.iter().map(|(_, t)| t).cloned());
1827 let and = Type::And(all_args.clone());
1828
1829 if let Some(usages) = self.cache.usages.nary.get_checked(id) {
1830 for (args, ov) in usages {
1831 if Type::And(args.clone()).bindable_to(&and, self) {
1832 let mut body = b.clone();
1833 let key = (*id, ov.clone(), all_args.clone());
1834
1835 if !self.cache.templates.nary.contains(&key) {
1836 if !ov.is_empty() {
1837 let templates = ov.iter().cloned().enumerate().collect();
1838
1839 body.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, &templates));
1841
1842 let named_args = [(n.clone(), t.clone())].iter().chain(a).map(|(n, t)| (n.clone(), t.sub_templates(&templates))).collect();
1843 self.compile(&mut body, &named_args)?;
1844
1845 for line in &body {
1847 self.static_check_expected(line, &Some(r.sub_templates(&templates)))?;
1848 }
1849 }
1850
1851 self.cache.templates.nary.insert(key, body.clone());
1852
1853 self.get_template_calls_body_pass(&body, changed)?;
1855
1856 *changed = true;
1857 }
1858 }
1859 }
1860 }
1861
1862 Ok(())
1863 }
1864
1865 _ => Ok(())
1866 }
1867 }
1868
1869 pub fn get_template_calls_body_pass(
1870 &mut self,
1871 lines: &Vec<NessaExpr>,
1872 changed: &mut bool
1873 ) -> Result<(), NessaError> {
1874 for line in lines {
1875 self.get_template_calls_pass(line, changed)?;
1876 }
1877
1878 Ok(())
1879 }
1880
1881 pub fn subtitute_type_params_expr(expr: &mut NessaExpr, templates: &HashMap<usize, Type>) {
1882 match expr {
1883 NessaExpr::Continue(..) |
1884 NessaExpr::Break(..) |
1885 NessaExpr::Literal(..) |
1886 NessaExpr::NameReference(..) => {},
1887
1888 NessaExpr::Tuple(_, e) => e.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates)),
1889
1890 NessaExpr::DoBlock(_, e, t) => {
1891 *t = t.sub_templates(templates);
1892
1893 e.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates))
1894 },
1895
1896 NessaExpr::Variable(_, _, _, t) => *t = t.sub_templates(templates),
1897
1898 NessaExpr::Lambda(_, _, args, r, lines) => {
1899 for (_, tp) in args {
1900 *tp = tp.sub_templates(templates);
1901 }
1902
1903 if *r != Type::InferenceMarker {
1904 *r = r.sub_templates(templates);
1905 }
1906
1907 lines.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates));
1908 },
1909
1910 NessaExpr::VariableAssignment(_, _, e) |
1911 NessaExpr::AttributeAccess(_, e, _) |
1912 NessaExpr::Return(_, e) => NessaContext::subtitute_type_params_expr(e, templates),
1913
1914 NessaExpr::VariableDefinition(_, _, t, e) |
1915 NessaExpr::CompiledVariableAssignment(_, _, _, t, e) |
1916 NessaExpr::CompiledVariableDefinition(_, _, _, t, e) => {
1917 *t = t.sub_templates(templates);
1918
1919 NessaContext::subtitute_type_params_expr(e, templates);
1920 },
1921
1922 NessaExpr::UnaryOperation(_, _, t, a) => {
1923 t.iter_mut().for_each(|i| *i = i.sub_templates(templates));
1924
1925 NessaContext::subtitute_type_params_expr(a, templates);
1926 },
1927
1928 NessaExpr::AttributeAssignment(_, a, b, _) => {
1929 NessaContext::subtitute_type_params_expr(a, templates);
1930 NessaContext::subtitute_type_params_expr(b, templates);
1931 }
1932
1933 NessaExpr::BinaryOperation(_, _, t, a, b) => {
1934 t.iter_mut().for_each(|i| *i = i.sub_templates(templates));
1935
1936 NessaContext::subtitute_type_params_expr(a, templates);
1937 NessaContext::subtitute_type_params_expr(b, templates);
1938 }
1939
1940 NessaExpr::NaryOperation(_, _, t, first, args) => {
1941 t.iter_mut().for_each(|i| *i = i.sub_templates(templates));
1942
1943 NessaContext::subtitute_type_params_expr(first, templates);
1944 args.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates));
1945 },
1946
1947 NessaExpr::FunctionCall(_, _, t, args) => {
1948 t.iter_mut().for_each(|i| *i = i.sub_templates(templates));
1949
1950 args.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates));
1951 },
1952
1953 NessaExpr::For(_, _, container, body) |
1954 NessaExpr::CompiledFor(_, _, _, _, container, body) |
1955 NessaExpr::While(_, container, body) => {
1956 NessaContext::subtitute_type_params_expr(container, templates);
1957 body.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates));
1958 },
1959
1960 NessaExpr::If(_, ih, ib, ei, eb) => {
1961 NessaContext::subtitute_type_params_expr(ih, templates);
1962 ib.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates));
1963
1964 for (ei_h, ei_b) in ei {
1965 NessaContext::subtitute_type_params_expr(ei_h, templates);
1966 ei_b.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates));
1967 }
1968
1969 if let Some(b) = eb {
1970 b.iter_mut().for_each(|i| NessaContext::subtitute_type_params_expr(i, templates));
1971 }
1972 }
1973
1974 _ => unimplemented!("{:?}", expr)
1975 };
1976 }
1977
1978 pub fn compile_lambda_expr(
1979 &mut self,
1980 line: &NessaExpr,
1981 only_length: bool
1982 ) -> Result<(), NessaError> {
1983 return match line {
1984 NessaExpr::Break(..) |
1985 NessaExpr::Continue(..) |
1986 NessaExpr::Literal(..) |
1987 NessaExpr::Variable(..) |
1988 NessaExpr::ClassDefinition(..) |
1989 NessaExpr::InterfaceDefinition(..) |
1990 NessaExpr::InterfaceImplementation(..) |
1991 NessaExpr::PrefixOperatorDefinition(..) |
1992 NessaExpr::PostfixOperatorDefinition(..) |
1993 NessaExpr::BinaryOperatorDefinition(..) |
1994 NessaExpr::NaryOperatorDefinition(..) => Ok(()),
1995
1996 NessaExpr::CompiledLambda(_, i, c, a, _, b) => {
1997 self.compile_lambdas(b, only_length)?;
1998
1999 if only_length {
2000 self.lambda_positions.entry(*i).or_insert(1 + self.lambda_code_length);
2001
2002 self.lambda_code_length += self.compiled_form_body_size(b, true)? + a.len() + c.len();
2003
2004 } else {
2005 for (i, e) in c.iter().enumerate() {
2006 if i == 0 {
2007 self.lambda_code.push(NessaInstruction::new_with_type(
2008 CompiledNessaExpr::StoreVariable(i),
2009 "Lambda expression start".into(),
2010 self.infer_type(&e.1).unwrap()
2011 ));
2012
2013 } else {
2014 self.lambda_code.push(NessaInstruction::new_with_type(
2015 CompiledNessaExpr::StoreVariable(i),
2016 String::new(),
2017 self.infer_type(&e.1).unwrap()
2018 ));
2019 }
2020 }
2021
2022 for (i, arg) in a.iter().enumerate() {
2023 self.lambda_code.push(NessaInstruction::new_with_type(
2024 CompiledNessaExpr::StoreVariable(i + c.len()),
2025 String::new(),
2026 arg.1.clone()
2027 ));
2028 }
2029
2030 self.lambda_code.extend(self.compiled_form_body(b)?);
2031 }
2032
2033 Ok(())
2034 }
2035
2036 NessaExpr::CompiledVariableDefinition(_, _, _, _, e) |
2037 NessaExpr::CompiledVariableAssignment(_, _, _, _, e) |
2038 NessaExpr::Return(_, e) |
2039 NessaExpr::AttributeAccess(_, e, _) |
2040 NessaExpr::UnaryOperation(_, _, _, e) => self.compile_lambda_expr(e, only_length),
2041
2042 NessaExpr::AttributeAssignment(_, a, b, _) |
2043 NessaExpr::BinaryOperation(_, _, _, a, b) => {
2044 self.compile_lambda_expr(a, only_length)?;
2045 self.compile_lambda_expr(b, only_length)?;
2046
2047 Ok(())
2048 }
2049
2050 NessaExpr::CompiledFor(_, _, _, _, a, b) |
2051 NessaExpr::While(_, a, b) |
2052 NessaExpr::NaryOperation(_, _, _, a, b) => {
2053 self.compile_lambda_expr(a, only_length)?;
2054 self.compile_lambdas(b, only_length)?;
2055
2056 Ok(())
2057 }
2058
2059 NessaExpr::If(_, ih, ib, ei, eb) => {
2060 self.compile_lambda_expr(ih, only_length)?;
2061 self.compile_lambdas(ib, only_length)?;
2062
2063 for (ei_h, ei_b) in ei {
2064 self.compile_lambda_expr(ei_h, only_length)?;
2065 self.compile_lambdas(ei_b, only_length)?;
2066 }
2067
2068 if let Some(eb_inner) = eb {
2069 self.compile_lambdas(eb_inner, only_length)?;
2070 }
2071
2072 Ok(())
2073 }
2074
2075 NessaExpr::DoBlock(_, args, _) |
2076 NessaExpr::Tuple(_, args) |
2077 NessaExpr::FunctionCall(_, _, _, args) => self.compile_lambdas(args, only_length),
2078
2079 NessaExpr::PrefixOperationDefinition(..) |
2080 NessaExpr::PostfixOperationDefinition(..) |
2081 NessaExpr::BinaryOperationDefinition(..) |
2082 NessaExpr::NaryOperationDefinition(..) |
2083 NessaExpr::FunctionDefinition(..) => Ok(()),
2084
2085 NessaExpr::Macro(..) => { Ok(()) },
2086
2087 _ => unimplemented!("{:?}", line)
2088 };
2089 }
2090
2091 pub fn compile_lambdas(
2092 &mut self,
2093 lines: &Vec<NessaExpr>,
2094 only_length: bool
2095 ) -> Result<(), NessaError> {
2096 for line in lines {
2097 self.compile_lambda_expr(line, only_length)?;
2098 }
2099
2100 Ok(())
2101 }
2102
2103 pub fn compile_function_lambdas(&mut self, lines: &Vec<NessaExpr>, only_length: bool) -> Result<(), NessaError> {
2104 for expr in lines {
2105 match expr {
2106 NessaExpr::FunctionDefinition(_, _, id, _, a, _, _) => {
2107 let arg_types = a.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
2108 let and = Type::And(arg_types.clone());
2109
2110 if let Some(usages) = self.cache.usages.functions.get_checked(id) {
2111 for (args, ov) in usages {
2112 if Type::And(args.clone()).bindable_to(&and, self) {
2113 let sub_b = self.cache.templates.functions.get_checked(&(*id, ov.clone(), arg_types.clone())).unwrap();
2114 self.compile_lambdas(&sub_b, only_length)?;
2115 }
2116 }
2117 }
2118 },
2119
2120 NessaExpr::PrefixOperationDefinition(_, _, id, _, _, tp, _, _) |
2121 NessaExpr::PostfixOperationDefinition(_, _, id, _, _, tp, _, _) => {
2122 if let Some(usages) = self.cache.usages.unary.get_checked(id) {
2123 for (args, ov) in usages {
2124 if Type::And(args.clone()).bindable_to(tp, self) {
2125 let sub_b = self.cache.templates.unary.get_checked(&(*id, ov.clone(), vec!(tp.clone()))).unwrap();
2126 self.compile_lambdas(&sub_b, only_length)?;
2127 }
2128 }
2129 }
2130 },
2131
2132 NessaExpr::BinaryOperationDefinition(_, _, id, _, (_, t1), (_, t2), _, _) => {
2133 let and = Type::And(vec!(t1.clone(), t2.clone()));
2134
2135 if let Some(usages) = self.cache.usages.binary.get_checked(id) {
2136 for (args, ov) in usages {
2137 if Type::And(args.clone()).bindable_to(&and, self) {
2138 let sub_b = self.cache.templates.binary.get_checked(&(*id, ov.clone(), vec!(t1.clone(), t2.clone()))).unwrap();
2139 self.compile_lambdas(&sub_b, only_length)?;
2140 }
2141 }
2142 }
2143 },
2144
2145 NessaExpr::NaryOperationDefinition(_, _, id, _, (_, a_t), a, _, _) => {
2146 let mut arg_types = vec!(a_t.clone());
2147 arg_types.extend(a.iter().map(|(_, t)| t).cloned());
2148
2149 let and = Type::And(arg_types.clone());
2150
2151 if let Some(usages) = self.cache.usages.nary.get_checked(id) {
2152 for (args, ov) in usages {
2153 if Type::And(args.clone()).bindable_to(&and, self) {
2154 let sub_b = self.cache.templates.nary.get_checked(&(*id, ov.clone(), arg_types.clone())).unwrap();
2155 self.compile_lambdas(&sub_b, only_length)?;
2156 }
2157 }
2158 }
2159 },
2160
2161 _ => {}
2162 }
2163 }
2164
2165 Ok(())
2166 }
2167
2168 pub fn compiled_form(&mut self, lines: &Vec<NessaExpr>) -> Result<Vec<NessaInstruction>, NessaError> {
2169 self.compile_function_lambdas(lines, true)?;
2170 self.compile_lambdas(lines, true)?;
2171
2172 let mut program_size = 1 + self.lambda_code_length;
2173
2174 for expr in lines {
2176 match expr {
2177 NessaExpr::FunctionDefinition(_, _, id, t, a, ret, _) => {
2178 let arg_types = a.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
2179 let and = Type::And(arg_types.clone());
2180
2181 if let Some(usages) = self.cache.usages.functions.get_checked(id) {
2182 for (args, ov) in usages {
2183 if Type::And(args.clone()).bindable_to(&and, self) {
2184 if self.cache.overloads.functions.get_checked(&(*id, args.clone(), ov.clone())).is_some() {
2186 let init_loc = program_size;
2187 self.cache.locations.functions.insert((*id, args.clone(), ov.clone()), program_size);
2188
2189 let arg_types = a.iter().map(|(_, t)| t.clone()).collect();
2190 let sub_b = self.cache.templates.functions.get_checked(&(*id, ov.clone(), arg_types)).unwrap();
2191
2192 program_size += self.compiled_form_body_size(&sub_b, true)? + a.len();
2193
2194 if t.is_empty() {
2195 let signature = format!(
2196 "fn {}({}) -> {}",
2197 self.functions[*id].name,
2198 a.iter().map(|(_, at)| {
2199 at.get_name_plain(self)
2200 }).collect::<Vec<_>>().join(", "),
2201 ret.get_name_plain(self)
2202 );
2203
2204 self.cache.ranges.insert(signature, (init_loc, program_size));
2205
2206 } else {
2207 let signature = format!(
2208 "fn<{}> {}({}) -> {}",
2209 ov.iter().map(|i| {
2210 i.get_name_plain(self)
2211 }).collect::<Vec<_>>().join(", "),
2212 self.functions[*id].name,
2213 a.iter().map(|(_, at)| {
2214 at.get_name_plain(self)
2215 }).collect::<Vec<_>>().join(", "),
2216 ret.get_name_plain(self)
2217 );
2218
2219 self.cache.ranges.insert(signature, (init_loc, program_size));
2220 }
2221 }
2222 }
2223 }
2224 }
2225 },
2226
2227 NessaExpr::PrefixOperationDefinition(_, _, id, t, _, tp, ret, _) |
2228 NessaExpr::PostfixOperationDefinition(_, _, id, t, _, tp, ret, _) => {
2229 if let Some(usages) = self.cache.usages.unary.get_checked(id) {
2230 for (args, ov) in usages {
2231 if Type::And(args.clone()).bindable_to(tp, self) {
2232 if self.cache.overloads.unary.get_checked(&(*id, args.clone(), ov.clone())).is_some() {
2234 let init_loc = program_size;
2235 self.cache.locations.unary.insert((*id, args.clone(), ov.clone()), program_size);
2236
2237 let prefix = if let Operator::Unary { prefix, .. } = self.unary_ops[*id] {
2238 prefix
2239 } else {
2240 false
2241 };
2242
2243 let sub_b = self.cache.templates.unary.get_checked(&(*id, ov.clone(), vec!(tp.clone()))).unwrap();
2244 program_size += self.compiled_form_body_size(&sub_b, true)? + 1;
2245
2246 if t.is_empty() {
2247 let signature = format!(
2248 "op {}({}){} -> {}",
2249 if prefix { self.unary_ops[*id].get_repr() } else { "".into() },
2250 tp.get_name_plain(self),
2251 if prefix { "".into() } else { self.unary_ops[*id].get_repr() },
2252 ret.get_name_plain(self)
2253 );
2254
2255 self.cache.ranges.insert(signature, (init_loc, program_size));
2256
2257 } else {
2258 let signature = format!(
2259 "op<{}> {}({}){} -> {}",
2260 ov.iter().map(|i| {
2261 i.get_name_plain(self)
2262 }).collect::<Vec<_>>().join(", "),
2263 if prefix { self.unary_ops[*id].get_repr() } else { "".into() },
2264 tp.get_name_plain(self),
2265 if prefix { "".into() } else { self.unary_ops[*id].get_repr() },
2266 ret.get_name_plain(self)
2267 );
2268
2269 self.cache.ranges.insert(signature, (init_loc, program_size));
2270 }
2271 }
2272 }
2273 }
2274 }
2275 }
2276
2277 NessaExpr::BinaryOperationDefinition(_, _, id, t, (_, t1), (_, t2), ret, _) => {
2278 let and = Type::And(vec!(t1.clone(), t2.clone()));
2279
2280 if let Some(usages) = self.cache.usages.binary.get_checked(id) {
2281 for (args, ov) in usages {
2282 if Type::And(args.clone()).bindable_to(&and, self) {
2283 if self.cache.overloads.binary.get_checked(&(*id, args.clone(), ov.clone())).is_some() {
2285 let init_loc = program_size;
2286 self.cache.locations.binary.insert((*id, args.clone(), ov.clone()), program_size);
2287
2288 let sub_b = self.cache.templates.binary.get_checked(&(*id, ov.clone(), vec!(t1.clone(), t2.clone()))).unwrap();
2289 program_size += self.compiled_form_body_size(&sub_b, true)? + 2;
2290
2291 if t.is_empty() {
2292 let signature = format!(
2293 "op ({}){}({}) -> {}",
2294 t1.get_name_plain(self),
2295 self.binary_ops[*id].get_repr(),
2296 t2.get_name_plain(self),
2297 ret.get_name_plain(self)
2298 );
2299
2300 self.cache.ranges.insert(signature, (init_loc, program_size));
2301
2302 } else {
2303 let signature = format!(
2304 "op<{}> ({}){}({}) -> {}",
2305 ov.iter().map(|i| {
2306 i.get_name_plain(self)
2307 }).collect::<Vec<_>>().join(", "),
2308 t1.get_name_plain(self),
2309 self.binary_ops[*id].get_repr(),
2310 t2.get_name_plain(self),
2311 ret.get_name_plain(self)
2312 );
2313
2314 self.cache.ranges.insert(signature, (init_loc, program_size));
2315 }
2316 }
2317 }
2318 }
2319 }
2320 }
2321
2322 NessaExpr::NaryOperationDefinition(_, _, id, t, (_, a_t), a, ret, _) => {
2323 let mut arg_types = vec!(a_t.clone());
2324 arg_types.extend(a.iter().map(|(_, t)| t).cloned());
2325
2326 let and = Type::And(arg_types.clone());
2327
2328 if let Some(usages) = self.cache.usages.nary.get_checked(id) {
2329 for (args, ov) in usages {
2330 if Type::And(args.clone()).bindable_to(&and, self) {
2331 if self.cache.overloads.nary.get_checked(&(*id, args.clone(), ov.clone())).is_some() {
2333 let init_loc = program_size;
2334 self.cache.locations.nary.insert((*id, args.clone(), ov.clone()), program_size);
2335
2336 let mut o_rep = "".to_string();
2337 let mut c_rep = "".to_string();
2338
2339 if let Operator::Nary { open_rep, close_rep, .. } = &self.nary_ops[*id] {
2340 o_rep = open_rep.clone();
2341 c_rep = close_rep.clone();
2342 }
2343
2344 let sub_b = self.cache.templates.nary.get_checked(&(*id, ov.clone(), arg_types.clone())).unwrap();
2345 program_size += self.compiled_form_body_size(&sub_b, true)? + a.len() + 1;
2346
2347 if t.is_empty() {
2348 let signature = format!(
2349 "op ({}){}({}){} -> {}",
2350 a_t.get_name_plain(self),
2351 o_rep,
2352 a.iter().map(|(_, at)| {
2353 at.get_name_plain(self)
2354 }).collect::<Vec<_>>().join(", "),
2355 c_rep,
2356 ret.get_name_plain(self)
2357 );
2358
2359 self.cache.ranges.insert(signature, (init_loc, program_size));
2360
2361 } else {
2362 let signature = format!(
2363 "op<{}> ({}){}({}){} -> {}",
2364 ov.iter().map(|i| {
2365 i.get_name_plain(self)
2366 }).collect::<Vec<_>>().join(", "),
2367 a_t.get_name_plain(self),
2368 o_rep,
2369 a.iter().map(|(_, at)| {
2370 at.get_name_plain(self)
2371 }).collect::<Vec<_>>().join(", "),
2372 c_rep,
2373 ret.get_name_plain(self)
2374 );
2375
2376 self.cache.ranges.insert(signature, (init_loc, program_size));
2377 }
2378 }
2379 }
2380 }
2381 }
2382 }
2383
2384 _ => {}
2385 }
2386 }
2387
2388 let mut res = vec!(NessaInstruction::from(CompiledNessaExpr::Jump(program_size + self.lambda_code.len())));
2389
2390 self.compile_function_lambdas(lines, false)?;
2391 self.compile_lambdas(lines, false)?;
2392
2393 res.append(&mut self.lambda_code);
2394
2395 for expr in lines {
2397 match expr {
2398 NessaExpr::FunctionDefinition(_, _, id, _, a, r, _) => {
2399 let arg_types = a.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
2400 let and = Type::And(arg_types.clone());
2401
2402 if let Some(usages) = self.cache.usages.functions.get_checked(id) {
2403 for (args, ov) in usages {
2404 if Type::And(args.clone()).bindable_to(&and, self) {
2405 for (i, arg) in args.iter().enumerate() {
2407 if i == 0 {
2408 let comment = format!(
2409 "fn {}{}({}) -> {}",
2410 self.functions[*id].name.green(),
2411 if ov.is_empty() { "".into() } else { format!("<{}>", ov.iter().map(|i| i.get_name(self)).collect::<Vec<_>>().join(", ")) },
2412 a.iter().map(|(_, t)| t.get_name(self)).collect::<Vec<_>>().join(", "),
2413 r.get_name(self)
2414 );
2415
2416 res.push(NessaInstruction::new_with_type(
2417 CompiledNessaExpr::StoreVariable(i),
2418 comment,
2419 arg.clone()
2420 ));
2421
2422 } else {
2423 res.push(NessaInstruction::new_with_type(
2424 CompiledNessaExpr::StoreVariable(i),
2425 String::new(),
2426 arg.clone()
2427 ));
2428 }
2429 }
2430
2431 let sub_b = self.cache.templates.functions.get_checked(&(*id, ov.clone(), arg_types.clone())).unwrap();
2432 res.extend(self.compiled_form_body(&sub_b)?);
2433 }
2434 }
2435 }
2436 },
2437
2438 NessaExpr::PrefixOperationDefinition(_, _, id, _, _, tp, r, _) |
2439 NessaExpr::PostfixOperationDefinition(_, _, id, _, _, tp, r, _) => {
2440 if let Some(usages) = self.cache.usages.unary.get_checked(id) {
2441 for (args, ov) in usages {
2442 if Type::And(args.clone()).bindable_to(tp, self) {
2443 let mut rep = String::new();
2444 let mut is_prefix = false;
2445
2446 if let Operator::Unary{representation, prefix, ..} = &self.unary_ops[*id] {
2447 rep = representation.clone();
2448 is_prefix = *prefix;
2449 }
2450
2451 let comment = if is_prefix {
2453 format!("op {}({}) -> {}", rep, tp.get_name(self), r.get_name(self))
2454
2455 } else {
2456 format!("op ({}){} -> {}", tp.get_name(self), rep, r.get_name(self))
2457 };
2458
2459 res.push(NessaInstruction::new_with_type(
2460 CompiledNessaExpr::StoreVariable(0),
2461 comment,
2462 args[0].clone()
2463 ));
2464
2465 let sub_b = self.cache.templates.unary.get_checked(&(*id, ov.clone(), vec!(tp.clone()))).unwrap();
2466 res.extend(self.compiled_form_body(&sub_b)?);
2467 }
2468 }
2469 }
2470 },
2471
2472 NessaExpr::BinaryOperationDefinition(_, _, id, _, (_, t1), (_, t2), r, _) => {
2473 let and = Type::And(vec!(t1.clone(), t2.clone()));
2474
2475 if let Some(usages) = self.cache.usages.binary.get_checked(id) {
2476 for (args, ov) in usages {
2477 if Type::And(args.clone()).bindable_to(&and, self) {
2478 let mut rep = String::new();
2480
2481 if let Operator::Binary{representation, ..} = &self.binary_ops[*id] {
2482 rep = representation.clone();
2483 }
2484
2485 let comment = format!("op ({}) {} ({}) -> {}", t1.get_name(self), rep, t2.get_name(self), r.get_name(self));
2486
2487 res.push(NessaInstruction::new_with_type(
2488 CompiledNessaExpr::StoreVariable(0),
2489 comment,
2490 args[0].clone()
2491 ));
2492
2493 res.push(NessaInstruction::new_with_type(
2494 CompiledNessaExpr::StoreVariable(1),
2495 String::new(),
2496 args[1].clone()
2497 ));
2498
2499 let sub_b = self.cache.templates.binary.get_checked(&(*id, ov.clone(), vec!(t1.clone(), t2.clone()))).unwrap();
2500 res.extend(self.compiled_form_body(&sub_b)?);
2501 }
2502 }
2503 }
2504 },
2505
2506 NessaExpr::NaryOperationDefinition(_, _, id, _, (_, a_t), a, r, _) => {
2507 let mut arg_types = vec!(a_t.clone());
2508 arg_types.extend(a.iter().map(|(_, t)| t).cloned());
2509
2510 let and = Type::And(arg_types.clone());
2511
2512 if let Some(usages) = self.cache.usages.nary.get_checked(id) {
2513 for (args, ov) in usages {
2514 if Type::And(args.clone()).bindable_to(&and, self) {
2515 let mut o_rep = String::new();
2517 let mut c_rep = String::new();
2518
2519 if let Operator::Nary{open_rep, close_rep, ..} = &self.nary_ops[*id] {
2520 o_rep = open_rep.clone();
2521 c_rep = close_rep.clone();
2522 }
2523
2524 for (i, arg) in args.iter().enumerate() {
2525 if i == 0 {
2526 let comment = format!(
2527 "op ({}){}{}{} -> {}",
2528 a_t.get_name(self),
2529 o_rep,
2530 a.iter().map(|(_, t)| t.get_name(self)).collect::<Vec<_>>().join(", "),
2531 c_rep,
2532 r.get_name(self)
2533 );
2534
2535 res.push(NessaInstruction::new_with_type(
2536 CompiledNessaExpr::StoreVariable(i),
2537 comment,
2538 arg.clone()
2539 ));
2540
2541 } else {
2542 res.push(NessaInstruction::new_with_type(
2543 CompiledNessaExpr::StoreVariable(i),
2544 String::new(),
2545 arg.clone()
2546 ));
2547 }
2548 }
2549
2550 let sub_b = self.cache.templates.nary.get_checked(&(*id, ov.clone(), arg_types.clone())).unwrap();
2551 res.extend(self.compiled_form_body(&sub_b)?);
2552 }
2553 }
2554 }
2555 },
2556
2557 _ => {}
2558 }
2559 }
2560
2561 res[0] = NessaInstruction::from(CompiledNessaExpr::Jump(program_size));
2563
2564 for expr in lines {
2566 match expr {
2567 NessaExpr::FunctionDefinition(..) |
2568 NessaExpr::PrefixOperationDefinition(..) |
2569 NessaExpr::PostfixOperationDefinition(..) |
2570 NessaExpr::BinaryOperationDefinition(..) |
2571 NessaExpr::NaryOperationDefinition(..) => {},
2572
2573 _ => res.extend(self.compiled_form_expr(expr, true)?)
2574 }
2575 }
2576
2577 res.push(NessaInstruction::new(CompiledNessaExpr::Halt, "End of the program".into()));
2578
2579 Ok(res)
2580 }
2581
2582 pub fn compiled_form_size(&self, expr: &NessaExpr, root: bool, root_counter: &mut usize) -> Result<usize, NessaError> {
2583 use NessaExpr::*;
2584
2585 match expr {
2586 Break(..) |
2587 Continue(..) => Ok(1),
2588
2589 Variable(..) => {
2590 *root_counter += root as usize; Ok(1)
2593 },
2594
2595 Literal(_, obj) => {
2596 *root_counter += root as usize; Ok(NessaContext::compiled_literal_size(obj))
2599 },
2600
2601 AttributeAccess(_, e, _) => {
2602 *root_counter += root as usize; Ok(self.compiled_form_size(e, false, root_counter)? + 1)
2605 }
2606
2607 AttributeAssignment(_, a, b, _) => {
2608 Ok(self.compiled_form_size(a, false, root_counter)? + self.compiled_form_size(b, false, root_counter)? + 1)
2609 }
2610
2611 CompiledLambda(_, _, c, ..) => {
2612 *root_counter += root as usize; Ok(1 + c.len())
2615 }
2616
2617 UnaryOperation(_, id, t, arg) => {
2618 *root_counter += root as usize; let a_t = self.infer_type(arg)?;
2621
2622 let ov_id = self.cache.overloads.unary.get_checked(&(*id, vec!(a_t.clone()), t.clone())).unwrap();
2623 let offset = self.cache.opcodes.unary.get_checked(&(*id, ov_id)).map(|i| i.1).unwrap_or(0);
2624
2625 Ok(self.compiled_form_size(arg, false, root_counter)? + 1 + offset)
2626 }
2627
2628 BinaryOperation(_, id, t, a, b) => {
2629 *root_counter += root as usize; let a_t = self.infer_type(a)?;
2632 let b_t = self.infer_type(b)?;
2633
2634 let ov_id = self.cache.overloads.binary.get_checked(&(*id, vec!(a_t.clone(), b_t.clone()), t.clone())).unwrap();
2635 let (opcode, mut offset) = self.cache.opcodes.binary.get_checked(&(*id, ov_id)).unwrap_or((CompiledNessaExpr::Halt, 0));
2636
2637 if (*id == AND_BINOP_ID || *id == OR_BINOP_ID) && *a_t.deref_type() == BOOL && *b_t.deref_type() == BOOL {
2638 offset += 1;
2639 }
2640
2641 if root && opcode.needs_no_drop() {
2642 *root_counter -= 1; }
2644
2645 Ok(self.compiled_form_size(a, false, root_counter)? + self.compiled_form_size(b, false, root_counter)? + 1 + offset)
2646 },
2647
2648 NaryOperation(_, _, _, a, b) => {
2649 *root_counter += root as usize; Ok(self.compiled_form_size(a, false, root_counter)? + self.compiled_form_body_size(b, false)? + 1)
2652 },
2653
2654 Return(_, e) | CompiledVariableDefinition(_, _, _, _, e) | CompiledVariableAssignment(_, _, _, _, e) => Ok(self.compiled_form_size(e, false, root_counter)? + 1),
2655
2656 If(_, ih, ib, ei, e) => {
2657 let needs_deref = self.infer_type(ih).unwrap().is_ref();
2658 let mut res = self.compiled_form_size(ih, false, root_counter)? + self.compiled_form_body_size(ib, true)? + 2 + needs_deref as usize;
2659
2660 for (h, b) in ei {
2661 let needs_deref = self.infer_type(h).unwrap().is_ref();
2662 res += self.compiled_form_size(h, false, root_counter)? + self.compiled_form_body_size(b, true)? + 2 + needs_deref as usize;
2663 }
2664
2665 if let Some(b) = e {
2666 res += self.compiled_form_body_size(b, true)?;
2667 }
2668
2669 Ok(res)
2670 },
2671
2672 CompiledFor(_, _, _, _, c, b) => Ok(self.compiled_form_size(c, false, root_counter)? + self.compiled_form_body_size(b, true)? + 9),
2673
2674 While(_, c, b) => {
2675 let needs_deref = self.infer_type(c).unwrap().is_ref();
2676
2677 Ok(self.compiled_form_size(c, false, root_counter)? + self.compiled_form_body_size(b, true)? + 2 + needs_deref as usize)
2678 },
2679
2680 DoBlock(_, b, _) => {
2681 *root_counter += root as usize; Ok(self.compiled_form_body_size(b, true)?)
2684 }
2685
2686 Tuple(_, b) => {
2687 *root_counter += root as usize; Ok(1 + self.compiled_form_body_size(b, false)?)
2690 },
2691
2692 FunctionCall(_, id, t, a) => {
2693 *root_counter += root as usize; let args_types = a.iter().map(|i| self.infer_type(i)).collect::<Result<Vec<_>, _>>()?;
2696
2697 let ov_id = self.cache.overloads.functions.get_checked(&(*id, args_types.clone(), t.clone())).unwrap();
2698 let (opcode, offset) = self.cache.opcodes.functions.get_checked(&(*id, ov_id)).unwrap_or((CompiledNessaExpr::Halt, 0));
2699
2700 if root && opcode.needs_no_drop() {
2701 *root_counter -= 1; }
2703
2704 Ok(self.compiled_form_body_size(a, false)? + 1 + offset)
2705 },
2706
2707 _ => unreachable!("{:?}", expr)
2708 }
2709 }
2710
2711 pub fn compiled_form_body_size(&self, lines: &Vec<NessaExpr>, root: bool) -> Result<usize, NessaError> {
2712 let mut counter = 0;
2713 let mut res = 0;
2714
2715 for i in lines {
2716 res += self.compiled_form_size(i, root, &mut counter)?;
2717 }
2718
2719 Ok(res + counter)
2720 }
2721
2722 pub fn compiled_literal_size(obj: &Object) -> usize {
2723 match obj.get_type() {
2724 Type::Empty |
2725 Type::Basic(INT_ID) |
2726 Type::Basic(FLOAT_ID) |
2727 Type::Basic(BOOL_ID) |
2728 Type::Basic(STR_ID) => 1,
2729
2730 Type::Basic(_) => {
2731 let obj_t = obj.get::<TypeInstance>();
2732 let mut res = 1;
2733
2734 for i in obj_t.attributes.iter().rev() {
2735 res += NessaContext::compiled_literal_size(i);
2736 }
2737
2738 res
2739 },
2740
2741 Type::Template(ARR_ID, _) => {
2742 let obj_t = obj.get::<NessaArray>();
2743 let mut res = 1;
2744
2745 for i in obj_t.elements.iter().rev() {
2746 res += NessaContext::compiled_literal_size(i);
2747 }
2748
2749 res
2750 },
2751
2752 _ => 1
2753 }
2754 }
2755
2756 pub fn compile_literal(obj: &Object) -> Vec<NessaInstruction> {
2757 match obj.get_type() {
2758 Type::Empty => vec!(NessaInstruction::from(CompiledNessaExpr::Empty)),
2759
2760 Type::Basic(INT_ID) => vec!(NessaInstruction::from(CompiledNessaExpr::Int(obj.get::<Integer>().clone()))),
2761 Type::Basic(FLOAT_ID) => vec!(NessaInstruction::from(CompiledNessaExpr::Float(*obj.get::<f64>()))),
2762 Type::Basic(BOOL_ID) => vec!(NessaInstruction::from(CompiledNessaExpr::Bool(*obj.get::<bool>()))),
2763 Type::Basic(STR_ID) => vec!(NessaInstruction::from(CompiledNessaExpr::Str(obj.get::<String>().clone()))),
2764
2765 Type::Basic(id) => {
2766 let obj_t = obj.get::<TypeInstance>();
2767 let mut res = vec!();
2768
2769 for i in obj_t.attributes.iter().rev() {
2770 res.extend(NessaContext::compile_literal(i));
2771 }
2772
2773 res.push(NessaInstruction::from(CompiledNessaExpr::Construct(id, obj_t.attributes.len(), obj_t.params.clone())));
2774
2775 res
2776 },
2777
2778 Type::Template(ARR_ID, _) => {
2779 let obj_t = obj.get::<NessaArray>();
2780 let mut res = vec!();
2781
2782 for i in obj_t.elements.iter().rev() {
2783 res.extend(NessaContext::compile_literal(i));
2784 }
2785
2786 res.push(NessaInstruction::from(CompiledNessaExpr::Array(obj_t.elements.len(), *obj_t.elem_type.clone())));
2787
2788 res
2789 },
2790
2791 _ => unreachable!()
2792 }
2793 }
2794
2795 pub fn compiled_form_expr(
2796 &self, expr: &NessaExpr,
2797 root: bool
2798 ) -> Result<Vec<NessaInstruction>, NessaError> {
2799 return match expr {
2800 NessaExpr::Break(l) => {
2801 Ok(vec!(
2802 NessaInstruction::from(CompiledNessaExpr::Placeholder(PlaceholderType::Break)).set_loc(l) ))
2804 }
2805
2806 NessaExpr::Continue(l) => {
2807 Ok(vec!(
2808 NessaInstruction::from(CompiledNessaExpr::Placeholder(PlaceholderType::Continue)).set_loc(l) ))
2810 }
2811
2812 NessaExpr::Literal(l, obj) => {
2813 let mut res = NessaContext::compile_literal(obj);
2814
2815 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop));
2817 }
2818
2819 Ok(res.into_iter().map(|i| i.set_loc(l)).collect())
2820 },
2821
2822 NessaExpr::AttributeAccess(l, e, att_idx) => {
2823 let mut res = self.compiled_form_expr(e, root)?;
2824 let arg_type = self.infer_type(e)?;
2825
2826 if let Type::Basic(id) | Type::Template(id, _) = arg_type.deref_type() {
2827 let mut att_type = self.type_templates[*id].attributes[*att_idx].1.clone();
2828
2829 if let Type::Template(_, ts) = arg_type.deref_type() {
2831 att_type = att_type.sub_templates(&ts.iter().cloned().enumerate().collect());
2832 }
2833
2834 let opcode = match (&arg_type, &att_type) {
2835 (Type::MutRef(_), Type::Ref(_)) => CompiledNessaExpr::AttributeRef(*att_idx),
2836 (Type::MutRef(_), _) => CompiledNessaExpr::AttributeMut(*att_idx),
2837 (Type::Ref(_), _) => CompiledNessaExpr::AttributeRef(*att_idx),
2838 (_, _) => CompiledNessaExpr::AttributeMove(*att_idx)
2839 };
2840
2841 res.push(NessaInstruction::from(opcode).set_loc(l));
2842
2843 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
2845 }
2846
2847 Ok(res)
2848
2849 } else {
2850 unreachable!()
2851 }
2852 }
2853
2854 NessaExpr::CompiledLambda(l, i, c, a, r, _) => {
2855 let mut res = vec!();
2856
2857 for (_, i) in c.iter().rev() {
2858 res.extend(self.compiled_form_expr(i, false)?);
2859 }
2860
2861 res.push(NessaInstruction::from(CompiledNessaExpr::Lambda(
2862 *self.lambda_positions.get(i).unwrap(),
2863 c.len(),
2864 if a.len() == 1 {
2865 a[0].1.clone()
2866
2867 } else {
2868 Type::And(a.iter().map(|(_, t)| t).cloned().collect())
2869 },
2870 r.clone()
2871 )).set_loc(l));
2872
2873 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
2875 }
2876
2877 Ok(res)
2878 },
2879
2880 NessaExpr::DoBlock(l, lines, _) => {
2881 let mut res = self.compiled_form_body(lines)?;
2882 let length = res.len();
2883
2884 for (idx, i) in res.iter_mut().enumerate() {
2886 if let CompiledNessaExpr::Return = i.instruction {
2887 i.instruction = CompiledNessaExpr::RelativeJump((length - idx) as i32);
2888 }
2889 }
2890
2891 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
2893 }
2894
2895 Ok(res)
2896 }
2897
2898 NessaExpr::Tuple(l, e) => {
2899 let mut res = vec!();
2900
2901 for i in e.iter().rev() {
2902 res.extend(self.compiled_form_expr(i, false)?);
2903 }
2904
2905 res.push(NessaInstruction::from(CompiledNessaExpr::Tuple(e.len())).set_loc(l));
2906
2907 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
2909 }
2910
2911 Ok(res)
2912 }
2913
2914 NessaExpr::Variable(l, id, _, t) => {
2915 let mut res = vec!(
2916 if t.is_ref() {
2917 NessaInstruction::new_with_type(
2918 CompiledNessaExpr::CloneVariable(*id), "".into(), t.clone()
2919 ).set_loc(l)
2920
2921 } else {
2922 NessaInstruction::new_with_type(
2923 CompiledNessaExpr::GetVariable(*id), "".into(), t.clone()
2924 ).set_loc(l)
2925 }
2926 );
2927
2928 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
2930 }
2931
2932 Ok(res)
2933 },
2934
2935 NessaExpr::AttributeAssignment(l, a, b, att_idx) => {
2936 let mut res = self.compiled_form_expr(a, false)?;
2937 res.append(&mut self.compiled_form_expr(b, false)?);
2938
2939 res.push(NessaInstruction::from(CompiledNessaExpr::AttributeAssign(*att_idx)).set_loc(l));
2940
2941 Ok(res)
2942 }
2943
2944 NessaExpr::CompiledVariableDefinition(l, id, _, t, e) | NessaExpr::CompiledVariableAssignment(l, id, _, t, e) => {
2945 let mut res = self.compiled_form_expr(e, false)?;
2946 res.push(NessaInstruction::new_with_type(
2947 CompiledNessaExpr::StoreVariable(*id),
2948 String::new(),
2949 t.clone()
2950 ).set_loc(l));
2951
2952 Ok(res)
2953 },
2954
2955 NessaExpr::UnaryOperation(l, id, t, e) => {
2956 let mut res = self.compiled_form_expr(e, false)?;
2957
2958 let i_t = self.infer_type(e)?;
2959
2960 let ov_id = self.cache.overloads.unary.get_checked(&(*id, vec!(i_t.clone()), t.clone())).unwrap();
2961
2962 if let Some(pos) = self.cache.locations.unary.get_checked(&(*id, vec!(i_t.clone()), t.clone())) {
2963 res.push(NessaInstruction::from(CompiledNessaExpr::Call(pos)).set_loc(l));
2964
2965 } else if let Some((opcode, _)) = self.cache.opcodes.unary.get_checked(&(*id, ov_id)) {
2966 if opcode.needs_deref() && i_t.is_ref() {
2968 res.push(NessaInstruction::from(CompiledNessaExpr::Deref).set_loc(l));
2969 }
2970
2971 if opcode.needs_float() {
2973 if let Type::Basic(INT_ID) = i_t.deref_type() {
2974 res.push(NessaInstruction::from(CompiledNessaExpr::ToFloat).set_loc(l));
2975 }
2976 }
2977
2978 res.push(NessaInstruction::from(opcode).set_loc(l));
2979
2980 } else {
2981 res.push(NessaInstruction::from(CompiledNessaExpr::UnaryOperatorCall(*id, ov_id, t.clone())).set_loc(l));
2982 }
2983
2984 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
2986 }
2987
2988 Ok(res)
2989 },
2990
2991 NessaExpr::BinaryOperation(l, id, t, a, b) => {
2992 let mut res_a = self.compiled_form_expr(b, false)?;
2993 let mut res_b = self.compiled_form_expr(a, false)?;
2994
2995 let a_t = self.infer_type(a)?;
2996 let b_t = self.infer_type(b)?;
2997
2998 let ov_id = self.cache.overloads.binary.get_checked(&(*id, vec!(a_t.clone(), b_t.clone()), t.clone())).unwrap();
2999
3000 let res_op;
3001
3002 let mut short_circuit = false;
3004 let mut short_circuit_on = true;
3005 let mut translated_opcode = CompiledNessaExpr::Halt; if let Some(pos) = self.cache.locations.binary.get_checked(&(*id, vec!(a_t.clone(), b_t.clone()), t.clone())) {
3008 res_op = NessaInstruction::from(CompiledNessaExpr::Call(pos)).set_loc(l);
3009
3010 } else {
3011 if (*id == AND_BINOP_ID || *id == OR_BINOP_ID) && *a_t.deref_type() == BOOL && *b_t.deref_type() == BOOL {
3012 short_circuit = true;
3013 short_circuit_on = *id == OR_BINOP_ID; }
3015
3016 if let Some((opcode, _)) = self.cache.opcodes.binary.get_checked(&(*id, ov_id)) {
3017 translated_opcode = opcode.clone();
3018
3019 if opcode.needs_deref() {
3021 if a_t.is_ref() {
3022 res_b.push(NessaInstruction::from(CompiledNessaExpr::Deref).set_loc(l));
3023 }
3024
3025 if b_t.is_ref() {
3026 res_a.push(NessaInstruction::from(CompiledNessaExpr::Deref).set_loc(l));
3027 }
3028 }
3029
3030 if opcode.needs_float() {
3032 if let Type::Basic(INT_ID) = a_t.deref_type() {
3033 res_b.push(NessaInstruction::from(CompiledNessaExpr::ToFloat).set_loc(l));
3034 }
3035
3036 if let Type::Basic(INT_ID) = b_t.deref_type() {
3037 res_a.push(NessaInstruction::from(CompiledNessaExpr::ToFloat).set_loc(l));
3038 }
3039 }
3040
3041 res_op = NessaInstruction::from(opcode).set_loc(l);
3042
3043 } else {
3044 res_op = NessaInstruction::from(CompiledNessaExpr::BinaryOperatorCall(*id, ov_id, t.clone())).set_loc(l);
3045 }
3046 }
3047
3048 let mut res;
3049
3050 if short_circuit {
3051 res = res_b;
3052
3053 if short_circuit_on {
3054 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJumpIfTrue(res_a.len() + 2, true)).set_loc(l));
3055
3056 } else {
3057 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJumpIfFalse(res_a.len() + 2, true)).set_loc(l));
3058 }
3059
3060 res.append(&mut res_a);
3061
3062 } else {
3063 res = res_a;
3064 res.append(&mut res_b);
3065 }
3066
3067 res.push(res_op);
3068
3069 if root && !translated_opcode.needs_no_drop() { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
3071 }
3072
3073 Ok(res)
3074 },
3075
3076 NessaExpr::NaryOperation(l, id, t, a, b) => {
3077 let mut res = vec!();
3078
3079 for i in b.iter().rev() {
3080 res.extend(self.compiled_form_expr(i, false)?);
3081 }
3082
3083 res.extend(self.compiled_form_expr(a, false)?);
3084
3085 let a_t = self.infer_type(a)?;
3086 let b_t = b.iter().map(|i| self.infer_type(i)).collect::<Result<Vec<_>, _>>()?;
3087
3088 let mut arg_types = vec!(a_t.clone());
3089 arg_types.extend(b_t.iter().cloned());
3090
3091 let ov_id = self.cache.overloads.nary.get_checked(&(*id, arg_types.clone(), t.clone())).unwrap();
3092
3093 if let Some(pos) = self.cache.locations.nary.get_checked(&(*id, arg_types, t.clone())) {
3094 res.push(NessaInstruction::from(CompiledNessaExpr::Call(pos)).set_loc(l));
3095
3096 } else if let Some((opcode, _)) = self.cache.opcodes.nary.get_checked(&(*id, ov_id)) {
3097 res.push(NessaInstruction::from(opcode).set_loc(l));
3098
3099 } else {
3100 res.push(NessaInstruction::from(CompiledNessaExpr::NaryOperatorCall(*id, ov_id, t.clone())).set_loc(l));
3101 }
3102
3103 if root { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
3105 }
3106
3107 Ok(res)
3108 },
3109
3110 NessaExpr::If(l, ih, ib, ei, e) => {
3111 let mut res = self.compiled_form_expr(ih, false)?;
3112 let if_body = self.compiled_form_body(ib)?;
3113
3114 if self.infer_type(ih).unwrap().is_ref() {
3115 res.push(NessaInstruction::from(CompiledNessaExpr::Deref).set_loc(l));
3116 }
3117
3118 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJumpIfFalse(if_body.len() + 2, false)));
3119 res.extend(if_body);
3120
3121 let mut elif = vec!();
3122 let mut else_body = vec!();
3123 let mut complete_size = 1;
3124
3125 for (h, b) in ei {
3126 let cond = self.compiled_form_expr(h, false)?;
3127 let body = self.compiled_form_body(b)?;
3128 let needs_deref = self.infer_type(h).unwrap().is_ref();
3129
3130 complete_size += cond.len() + body.len() + 2 + needs_deref as usize;
3131
3132 elif.push((cond, body, needs_deref));
3133 }
3134
3135 if let Some(b) = e {
3136 else_body = self.compiled_form_body(b)?;
3137 complete_size += else_body.len();
3138 }
3139
3140 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJump(complete_size as i32)));
3141
3142 for (cond, body, needs_deref) in elif {
3143 complete_size -= cond.len() + body.len() + 2;
3144
3145 res.extend(cond);
3146
3147 if needs_deref {
3148 res.push(NessaInstruction::from(CompiledNessaExpr::Deref));
3149 }
3150
3151 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJumpIfFalse(body.len() + 2, false)));
3152 res.extend(body);
3153 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJump(complete_size as i32)));
3154 }
3155
3156 res.extend(else_body);
3157
3158 Ok(res)
3159 },
3160
3161 NessaExpr::While(l, c, b) => {
3162 let mut res = self.compiled_form_expr(c, false)?;
3164 let while_body = self.compiled_form_body(b)?;
3165
3166 if self.infer_type(c).unwrap().is_ref() {
3167 res.push(NessaInstruction::from(CompiledNessaExpr::Deref).set_loc(l));
3168 }
3169
3170 let beginning_jmp = CompiledNessaExpr::RelativeJump(-(while_body.len() as i32 + res.len() as i32 + 1));
3172
3173 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJumpIfFalse(while_body.len() + 2, false)));
3174 res.extend(while_body);
3175
3176 res.push(NessaInstruction::from(beginning_jmp));
3178
3179 let length = res.len();
3181
3182 for (idx, i) in res.iter_mut().enumerate() {
3183 if let CompiledNessaExpr::Placeholder(PlaceholderType::Break) = i.instruction {
3184 i.instruction = CompiledNessaExpr::RelativeJump((length - idx) as i32);
3185
3186 } else if let CompiledNessaExpr::Placeholder(PlaceholderType::Continue) = i.instruction {
3187 i.instruction = CompiledNessaExpr::RelativeJump(-(idx as i32));
3188 }
3189 }
3190
3191 Ok(res)
3192 },
3193
3194 NessaExpr::CompiledFor(l, it_var_id, elem_var_id, _, c, b) => {
3195 let t = self.infer_type(c)?;
3196
3197 let mut res = self.compiled_form_expr(c, false)?;
3198
3199 let (it_ov_id, it_type, it_native, it_args) = self.get_first_function_overload(ITERATOR_FUNC_ID, vec!(t.clone()), None, true, l)?;
3201
3202 let it_mut = Type::MutRef(Box::new(it_type.clone()));
3203
3204 let (next_ov_id, _, next_native, next_args) = self.get_first_function_overload(NEXT_FUNC_ID, vec!(it_mut.clone()), None, true, l)?;
3205 let (consumed_ov_id, consumed_res, consumed_native, consumed_args) = self.get_first_function_overload(IS_CONSUMED_FUNC_ID, vec!(it_mut.clone()), None, true, l)?;
3206
3207 if let Type::Basic(BOOL_ID) = consumed_res {
3208 let for_body = self.compiled_form_body(b)?;
3209 let for_body_len = for_body.len();
3210
3211 if it_native {
3213 res.push(NessaInstruction::from(CompiledNessaExpr::NativeFunctionCall(ITERATOR_FUNC_ID, it_ov_id, it_args)).set_loc(l));
3214
3215 } else {
3216 let pos = self.cache.locations.functions.get_checked(&(ITERATOR_FUNC_ID, vec!(t.clone()), it_args.clone())).unwrap();
3217 res.push(NessaInstruction::from(CompiledNessaExpr::Call(pos)).set_loc(l));
3218 }
3219
3220 res.push(NessaInstruction::from(CompiledNessaExpr::StoreVariable(*it_var_id)).set_loc(l));
3222
3223 res.push(NessaInstruction::from(CompiledNessaExpr::GetVariable(*it_var_id)).set_loc(l));
3225
3226 if consumed_native {
3227 res.push(NessaInstruction::from(CompiledNessaExpr::NativeFunctionCall(IS_CONSUMED_FUNC_ID, consumed_ov_id, consumed_args)).set_loc(l));
3228
3229 } else {
3230 let pos = self.cache.locations.functions.get_checked(&(IS_CONSUMED_FUNC_ID, vec!(it_mut.clone()), consumed_args.clone())).unwrap();
3231 res.push(NessaInstruction::from(CompiledNessaExpr::Call(pos)).set_loc(l));
3232 }
3233
3234 res.push(NessaInstruction::from(CompiledNessaExpr::RelativeJumpIfTrue(for_body_len + 5, false)));
3236
3237 res.push(NessaInstruction::from(CompiledNessaExpr::GetVariable(*it_var_id)).set_loc(l));
3239
3240 if next_native {
3241 res.push(NessaInstruction::from(CompiledNessaExpr::NativeFunctionCall(NEXT_FUNC_ID, next_ov_id, next_args)).set_loc(l));
3242
3243 } else {
3244 let pos = self.cache.locations.functions.get_checked(&(NEXT_FUNC_ID, vec!(it_mut.clone()), next_args.clone())).unwrap();
3245 res.push(NessaInstruction::from(CompiledNessaExpr::Call(pos)).set_loc(l));
3246 }
3247
3248 res.push(NessaInstruction::from(CompiledNessaExpr::StoreVariable(*elem_var_id)).set_loc(l));
3250
3251 let beginning_jmp = CompiledNessaExpr::RelativeJump(-(for_body_len as i32 + 6));
3253
3254 res.extend(for_body);
3255
3256 res.push(NessaInstruction::from(beginning_jmp));
3258
3259 let length = res.len();
3261
3262 for (idx, i) in res.iter_mut().enumerate() {
3263 if let CompiledNessaExpr::Placeholder(PlaceholderType::Break) = i.instruction {
3264 i.instruction = CompiledNessaExpr::RelativeJump((length - idx) as i32);
3265
3266 } else if let CompiledNessaExpr::Placeholder(PlaceholderType::Continue) = i.instruction {
3267 i.instruction = CompiledNessaExpr::RelativeJump((length - idx) as i32 - 1);
3268 }
3269 }
3270
3271 Ok(res)
3272
3273 } else {
3274 Err(NessaError::compiler_error(format!("Funtion overload is_consumed({}) returns {} (expected Bool)", it_mut.get_name(self), consumed_res.get_name(self)), l, vec!()))
3275 }
3276 },
3277
3278 NessaExpr::Return(l, e) => {
3279 let mut res = self.compiled_form_expr(e, false)?;
3280 res.push(NessaInstruction::from(CompiledNessaExpr::Return).set_loc(l));
3281
3282 Ok(res)
3283 },
3284
3285 NessaExpr::FunctionCall(l, id, t, a) => {
3286 let mut res = vec!();
3287
3288 for i in a.iter().rev() {
3289 res.extend(self.compiled_form_expr(i, false)?);
3290 }
3291
3292 let args_types = a.iter().map(|i| self.infer_type(i)).collect::<Result<Vec<_>, _>>()?;
3293
3294 let ov_id = self.cache.overloads.functions.get_checked(&(*id, args_types.clone(), t.clone())).unwrap();
3295 let mut translated_opcode = CompiledNessaExpr::Halt; if let Some(pos) = self.cache.locations.functions.get_checked(&(*id, args_types, t.clone())) {
3298 res.push(NessaInstruction::from(CompiledNessaExpr::Call(pos)).set_loc(l));
3299
3300 } else if let Some((mut opcode, _)) = self.cache.opcodes.functions.get_checked(&(*id, ov_id)) {
3301 opcode = match opcode {
3303 CompiledNessaExpr::Construct(id, length, _) => CompiledNessaExpr::Construct(id, length, t.clone()),
3305 _ => opcode
3306 };
3307
3308 translated_opcode = opcode.clone();
3309
3310 res.push(NessaInstruction::new_with_type(
3311 opcode,
3312 "".into(),
3313 self.functions[*id].overloads[ov_id].ret.clone()
3314 ).set_loc(l));
3315
3316 } else {
3317 res.push(NessaInstruction::from(CompiledNessaExpr::NativeFunctionCall(*id, ov_id, t.clone())).set_loc(l));
3318 }
3319
3320 if root && !translated_opcode.needs_no_drop() { res.push(NessaInstruction::from(CompiledNessaExpr::Drop).set_loc(l));
3322 }
3323
3324 Ok(res)
3325 }
3326
3327 _ => { Ok(vec!()) }
3328 };
3329 }
3330
3331 pub fn compiled_form_body(
3332 &self, lines: &[NessaExpr]
3333 ) -> Result<Vec<NessaInstruction>, NessaError> {
3334 return Ok(lines.iter().map(|i| self.compiled_form_expr(i, true)).flat_map(|i| i.unwrap()).collect());
3335 }
3336
3337 pub fn define_module_macro(&mut self, definition: NessaExpr, defined_macros: &mut FxHashSet<Location>) -> Result<bool, NessaError> {
3338 if let NessaExpr::Macro(l, an, n, t, p, m) = definition {
3339 if !defined_macros.contains(&l) {
3340 if self.macros.iter().any(|i| i.name == n) {
3341 return Err(NessaError::compiler_error(format!("Syntax with name '{n}' is already defined"), &l, vec!()));
3342 }
3343
3344 self.macros.push(NessaMacro {
3345 location: l.clone(),
3346 annotations: an,
3347 name: n,
3348 m_type: t,
3349 pattern: p,
3350 generator: m,
3351 });
3352
3353 defined_macros.insert(l.clone());
3354
3355 return Ok(true);
3356 }
3357 }
3358
3359 Ok(false)
3360 }
3361
3362 pub fn define_module_class(&mut self, definition: NessaExpr) -> Result<(), NessaError> {
3363 match definition {
3364 NessaExpr::ClassDefinition(l, an, n, t, a, al, p) => {
3365 let err = self.implicit_syntax_check(&n, &t, &a, &p);
3366
3367 if let Err(msg) = err {
3368 return Err(NessaError::compiler_error(msg, &l, vec!()));
3369 }
3370
3371 let n_templates = t.len();
3372 let arg_types = a.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
3373
3374 let err = if self.get_type_template(&n).is_some() {
3375 self.redefine_type(l.clone(), an.clone(), n.clone(), t, a.clone(), al, p, Some(
3376 |ctx, c_type, s| {
3377 if let Ok((_, o)) = ctx.parse_literal_type(c_type, Span::new(s.as_str()), &RefCell::default()) {
3378 return Ok(o);
3379 }
3380
3381 Err(format!("Unable to parse {} from {}", c_type.name, s))
3382 }
3383 ))
3384
3385 } else {
3386 self.define_type(l.clone(), an.clone(), n.clone(), t, a.clone(), al, p, Some(
3387 |ctx, c_type, s| {
3388 if let Ok((_, o)) = ctx.parse_literal_type(c_type, Span::new(s.as_str()), &RefCell::default()) {
3389 return Ok(o);
3390 }
3391
3392 Err(format!("Unable to parse {} from {}", c_type.name, s))
3393 }
3394 ))
3395 };
3396
3397 if let Err(msg) = err {
3398 return Err(NessaError::compiler_error(msg, &l, vec!()));
3399 }
3400
3401 let func_id = self.define_function(n.clone()).unwrap_or_default(); let class_id = self.get_type_id(n).unwrap();
3403
3404 if n_templates == 0 {
3405 let res = self.define_native_function_overload(func_id, 0, &arg_types, Type::Basic(class_id), |_, r, a, _| {
3407 if let Type::Basic(id) = r {
3408 return Ok(Object::new(TypeInstance {
3409 id: *id,
3410 params: vec!(),
3411 attributes: a
3412 }))
3413 }
3414
3415 unreachable!();
3416 });
3417
3418 if let Err(msg) = res {
3419 return Err(NessaError::compiler_error(msg, &l, vec!()));
3420
3421 } else {
3422 self.cache.opcodes.functions.insert((func_id, res.unwrap()), (CompiledNessaExpr::Construct(class_id, a.len(), vec!()), 0));
3423 }
3424
3425 } else {
3426 let templ = (0..n_templates).map(|i| Type::TemplateParam(i, vec!())).collect::<Vec<_>>();
3427
3428 let res = self.define_native_function_overload(func_id, n_templates, &arg_types, Type::Template(class_id, templ.clone()), |t, r, a, _| {
3430 if let Type::Template(id, _) = r {
3431 return Ok(Object::new(TypeInstance {
3432 id: *id,
3433 params: t.clone(),
3434 attributes: a
3435 }))
3436 }
3437
3438 unreachable!();
3439 });
3440
3441 if let Err(msg) = res {
3442 return Err(NessaError::compiler_error(msg, &l, vec!()));
3443
3444 } else {
3445 self.cache.opcodes.functions.insert((func_id, res.unwrap()), (CompiledNessaExpr::Construct(class_id, a.len(), vec!()), 0));
3446 }
3447 }
3448 },
3449
3450 _ => unreachable!()
3451 }
3452
3453 Ok(())
3454 }
3455
3456 pub fn define_module_macros(&mut self, code: &String) -> Result<(), NessaError> {
3457 let mut defined_macros = FxHashSet::default();
3458 let mut changed = true;
3459
3460 while changed {
3461 changed = false;
3462
3463 let ops = self.nessa_macros_parser(Span::new(code));
3464
3465 if let Err(err) = ops {
3466 return Err(NessaError::from(err).in_module(self.module_name.clone()));
3467 }
3468
3469 for i in ops.unwrap().1 {
3470 changed |= self.define_module_macro(i, &mut defined_macros)?;
3471 }
3472 }
3473
3474 Ok(())
3475 }
3476
3477 pub fn define_module_classes(&mut self, code: &String) -> Result<(), NessaError> {
3478 if let Ok((_, i_names)) = self.nessa_interface_definition_names_parser(Span::new(code)) {
3479 for i_name in i_names {
3480 self.define_interface(Location::none(), vec!(), i_name, vec!(), vec!(), vec!(), vec!(), vec!()).unwrap();
3481 }
3482
3483 if let Ok((_, names)) = self.nessa_class_names_parser(Span::new(code)) {
3484 for name in names {
3485 self.define_type(Location::none(), vec!(), name, vec!(), vec!(), None, vec!(), None).unwrap();
3486 }
3487
3488 let interfaces = self.nessa_interface_definition_parser(Span::new(code))?;
3489
3490 for i in interfaces.1 {
3491 if let NessaExpr::InterfaceDefinition(l, an, n, t, v, u, b, nr) = i {
3492 self.redefine_interface(l, an, n, t, v, u, b, nr).unwrap();
3493 }
3494 }
3495
3496 let interfaces_impl = self.nessa_interface_implementation_parser(Span::new(code))?;
3497
3498 for i in interfaces_impl.1 {
3499 if let NessaExpr::InterfaceImplementation(_, tm, t, n, i_tm) = i {
3500 self.define_interface_impl(n, tm, t, i_tm).unwrap();
3501 }
3502 }
3503
3504 let ops = self.nessa_class_parser(Span::new(code))?;
3505
3506 for i in ops.1 {
3507 self.define_module_class(i)?;
3508 }
3509 }
3510 }
3511
3512 Ok(())
3513 }
3514
3515 pub fn define_module_operators(&mut self, code: &String) -> Result<(), NessaError> {
3516 let ops = self.nessa_operators_parser(Span::new(code));
3517
3518 if let Err(err) = ops {
3519 return Err(NessaError::from(err).in_module(self.module_name.clone()));
3520 }
3521
3522 for i in ops.unwrap().1 {
3523 let (l, err) = match &i {
3524 NessaExpr::PrefixOperatorDefinition(l, n, p) => (l, self.define_unary_operator(n.clone(), true, *p)),
3525 NessaExpr::PostfixOperatorDefinition(l, n, p) => (l, self.define_unary_operator(n.clone(), false, *p)),
3526 NessaExpr::BinaryOperatorDefinition(l, n, f, p) => (l, self.define_binary_operator(n.clone(), *f, *p)),
3527 NessaExpr::NaryOperatorDefinition(l, o, c, p) => (l, self.define_nary_operator(o.clone(), c.clone(), *p)),
3528
3529 _ => unreachable!()
3530 };
3531
3532 if let Err(msg) = err {
3533 return Err(NessaError::compiler_error(msg, l, vec!()));
3534 }
3535 }
3536
3537 Ok(())
3538 }
3539
3540 pub fn define_module_functions(&mut self, code: &String) -> Result<(), NessaError> {
3541 let ops = self.nessa_function_headers_parser(Span::new(code));
3542
3543 if let Err(err) = ops {
3544 return Err(NessaError::from(err).in_module(self.module_name.clone()));
3545 }
3546
3547 for i in ops.unwrap().1 {
3548 self.define_function(i.0).unwrap_or_default();
3549 }
3550
3551 Ok(())
3552 }
3553
3554 pub fn define_module_operations(&mut self, code: &String) -> Result<(), NessaError> {
3555 let ops = self.nessa_operations_parser(Span::new(code));
3556
3557 if let Err(err) = ops {
3558 return Err(NessaError::from(err).in_module(self.module_name.clone()));
3559 }
3560
3561 for i in ops.unwrap().1 {
3562 let (l, err) = match &i {
3563 NessaExpr::PrefixOperationDefinition(l, an, id, tm, _a, t, r, _) |
3564 NessaExpr::PostfixOperationDefinition(l, an, id, tm, _a, t, r, _) => (l, self.define_unary_operation(l.clone(), an.clone(), *id, tm.len(), t.clone(), r.clone(), None)),
3565 NessaExpr::BinaryOperationDefinition(l, an, id, tm, (_a, ta), (_b, tb), r, _) => (l, self.define_binary_operation(l.clone(), an.clone(), *id, tm.len(), ta.clone(), tb.clone(), r.clone(), None)),
3566 NessaExpr::NaryOperationDefinition(l, an, id, tm, (_a, ta), v, r, _) => (l, self.define_nary_operation(l.clone(), an.clone(), *id, tm.len(), ta.clone(), &v.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>(), r.clone(), None)),
3567
3568 _ => unreachable!()
3569 };
3570
3571 if let Err(msg) = err {
3572 return Err(NessaError::compiler_error(msg, l, vec!()));
3573 }
3574 }
3575
3576 Ok(())
3577 }
3578
3579 pub fn define_module_function_overloads(&mut self, lines: &Vec<NessaExpr>) -> Result<(), NessaError> {
3580 for i in lines {
3581 if let NessaExpr::FunctionDefinition(l, an, id, t, a, r, _) = i {
3582 let arg_types = a.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
3583 let err = self.define_function_overload(l.clone(), an.clone(), *id, t.len(), &arg_types, r.clone(), None);
3584
3585 if let Err(msg) = err {
3586 return Err(NessaError::compiler_error(msg, l, vec!()));
3587 }
3588 }
3589 }
3590
3591 Ok(())
3592 }
3593
3594 pub fn parse_nessa_module(&mut self, code: &String) -> Result<Vec<NessaExpr>, NessaError> {
3595 return match self.nessa_parser(Span::new(code)) {
3596 Ok((_, lines)) => Ok(lines),
3597
3598 Err(nom::Err::Error(error)) |
3599 Err(nom::Err::Failure(error)) => Err(NessaError::from(error).in_module(self.module_name.clone())),
3600
3601 _ => unreachable!()
3602 };
3603 }
3604
3605 pub fn map_nessa_interface(&mut self, other: &NessaContext, id: usize, id_mapper: &mut IdMapper, l: &Location) -> Result<usize, String> {
3606 let other_i = &other.interfaces[id];
3607 let i_name = &other_i.name;
3608
3609 if !id_mapper.interfaces.contains_key(&id) {
3610 let interface_id;
3611
3612 if let Some(f) = self.get_interface(i_name) {
3614 interface_id = f.id;
3615
3616 } else { interface_id = self.interfaces.len();
3618 id_mapper.interfaces.entry(id).or_insert(interface_id);
3619
3620 let mapped_fns = other_i.fns.iter().map(|(an, n, t, a, r)| {
3621 (
3622 an.clone(),
3623 n.clone(),
3624 t.clone(),
3625 a.iter().map(|(n, t)| (n.clone(), t.map_type(self, other, id_mapper, l))).collect(),
3626 r.map_type(self, other, id_mapper, l)
3627 )
3628 }).collect::<Vec<_>>();
3629
3630 let mapped_uns = other_i.uns.iter().map(|(an, id, tm, a, at, ret)| {
3631 Result::<_, NessaError>::Ok((
3632 an.clone(),
3633 self.map_nessa_unary_operator(other, *id, id_mapper, l)?,
3634 tm.clone(),
3635 a.clone(),
3636 at.map_type(self, other, id_mapper, l),
3637 ret.map_type(self, other, id_mapper, l)
3638 ))
3639 }).collect::<Result<Vec<_>, _>>().unwrap();
3640
3641 let mapped_bin = other_i.bin.iter().map(|(an, id, tm, (a0, a0t), (a1, a1t), ret)| {
3642 Result::<_, NessaError>::Ok((
3643 an.clone(),
3644 self.map_nessa_binary_operator(other, *id, id_mapper, l)?,
3645 tm.clone(),
3646 (a0.clone(), a0t.map_type(self, other, id_mapper, l)),
3647 (a1.clone(), a1t.map_type(self, other, id_mapper, l)),
3648 ret.map_type(self, other, id_mapper, l)
3649 ))
3650 }).collect::<Result<Vec<_>, _>>().unwrap();
3651
3652 let mapped_nary = other_i.nary.iter().map(|(an, id, tm, (a0, a0t), a, ret)| {
3653 Result::<_, NessaError>::Ok((
3654 an.clone(),
3655 self.map_nessa_binary_operator(other, *id, id_mapper, l)?,
3656 tm.clone(),
3657 (a0.clone(), a0t.map_type(self, other, id_mapper, l)),
3658 a.iter().map(|(n, t)| (n.clone(), t.map_type(self, other, id_mapper, l))).collect(),
3659 ret.map_type(self, other, id_mapper, l)
3660 ))
3661 }).collect::<Result<Vec<_>, _>>().unwrap();
3662
3663 self.define_interface(other_i.location.clone(), other_i.annotations.clone(), i_name.clone(), other_i.params.clone(), mapped_fns, mapped_uns, mapped_bin, mapped_nary)?;
3664 }
3665
3666 return Ok(interface_id);
3667 }
3668
3669 Ok(id_mapper.interfaces[&id])
3670 }
3671
3672 pub fn map_nessa_class(&mut self, other: &NessaContext, id: usize, id_mapper: &mut IdMapper, l: &Location) -> Result<usize, String> {
3673 let other_cl = &other.type_templates[id];
3674 let c_name = &other_cl.name;
3675
3676 if !id_mapper.classes.contains_key(&id) {
3677 let class_id;
3678
3679 if let Some(f) = self.get_type_template(c_name) {
3681 class_id = f.id;
3682
3683 } else { class_id = self.type_templates.len();
3685 id_mapper.classes.entry(id).or_insert(class_id);
3686
3687 let mapped_attrs = other_cl.attributes.iter().map(|(n, t)| (n.clone(), t.map_type(self, other, id_mapper, l))).collect();
3688 let mapped_alias = other_cl.alias.as_ref().map(|i| i.map_type(self, other, id_mapper, l));
3689
3690 self.define_type(other_cl.location.clone(), other_cl.annotations.clone(), c_name.clone(), other_cl.params.clone(), mapped_attrs, mapped_alias, other_cl.patterns.clone(), other_cl.parser)?;
3691 }
3692
3693 return Ok(class_id);
3694 }
3695
3696 Ok(id_mapper.classes[&id])
3697 }
3698
3699 fn map_nessa_function(&mut self, other: &NessaContext, id: usize, id_mapper: &mut IdMapper, l: &Location) -> Result<usize, NessaError> {
3700 let f_name = &other.functions[id].name;
3701
3702 if !id_mapper.functions.contains_key(&id) {
3703 let fn_id;
3704
3705 if let Some(f) = self.get_function(f_name) {
3707 fn_id = f.id;
3708
3709 } else { fn_id = self.functions.len();
3711
3712 if let Err(err) = self.define_function(f_name.clone()) {
3713 return Err(NessaError::compiler_error(err, l, vec!()));
3714 }
3715 }
3716
3717 return Ok(*id_mapper.functions.entry(id).or_insert(fn_id));
3718 }
3719
3720 Ok(id_mapper.functions[&id])
3721 }
3722
3723 fn map_nessa_unary_operator(&mut self, other: &NessaContext, id: usize, id_mapper: &mut IdMapper, l: &Location) -> Result<usize, NessaError> {
3724 if let Operator::Unary{representation: r, prefix, precedence, ..} = &other.unary_ops[id] {
3725 if !id_mapper.unary_operators.contains_key(&id) {
3726 let mapped_op_id;
3727
3728 if let Some((op_id, _)) = self.unary_ops.iter()
3730 .map(|op| if let Operator::Unary{id: op_id, representation: op_rep, ..} = op { (op_id, op_rep) } else { unreachable!() }).find(|(_, op_rep)| *op_rep == r) {
3731 mapped_op_id = *op_id;
3732
3733 } else { mapped_op_id = self.unary_ops.len();
3735
3736 if let Err(err) = self.define_unary_operator(r.clone(), *prefix, *precedence) {
3737 return Err(NessaError::compiler_error(err, l, vec!()));
3738 }
3739 }
3740
3741 return Ok(*id_mapper.unary_operators.entry(id).or_insert(mapped_op_id));
3742 }
3743
3744 } else {
3745 return Err(NessaError::compiler_error(format!("Unable to find unary operator with id = {}", id), l, vec!()));
3746 }
3747
3748 Ok(id_mapper.unary_operators[&id])
3749 }
3750
3751 fn map_nessa_binary_operator(&mut self, other: &NessaContext, id: usize, id_mapper: &mut IdMapper, l: &Location) -> Result<usize, NessaError> {
3752 if let Operator::Binary{representation: r, right_associative, precedence, ..} = &other.binary_ops[id] {
3753 if !id_mapper.binary_operators.contains_key(&id) {
3754 let mapped_op_id;
3755
3756 if let Some((op_id, _)) = self.binary_ops.iter()
3758 .map(|op| if let Operator::Binary{id: op_id, representation: op_rep, ..} = op { (op_id, op_rep) } else { unreachable!() }).find(|(_, op_rep)| *op_rep == r) {
3759 mapped_op_id = *op_id;
3760
3761 } else { mapped_op_id = self.binary_ops.len();
3763
3764 if let Err(err) = self.define_binary_operator(r.clone(), *right_associative, *precedence) {
3765 return Err(NessaError::compiler_error(err, l, vec!()));
3766 }
3767 }
3768
3769 return Ok(*id_mapper.binary_operators.entry(id).or_insert(mapped_op_id));
3770 }
3771
3772 } else {
3773 return Err(NessaError::compiler_error(format!("Unable to find binary operator with id = {}", id), l, vec!()));
3774 }
3775
3776 Ok(id_mapper.binary_operators[&id])
3777 }
3778
3779 fn map_nessa_nary_operator(&mut self, other: &NessaContext, id: usize, id_mapper: &mut IdMapper, l: &Location) -> Result<usize, NessaError> {
3780 if let Operator::Nary{open_rep: or, close_rep: cr, precedence, ..} = &other.nary_ops[id] {
3781 if !id_mapper.nary_operators.contains_key(&id) {
3782 let mapped_op_id;
3783
3784 if let Some((op_id, _, _)) = self.nary_ops.iter()
3786 .map(|op| if let Operator::Nary{id: op_id, open_rep: op_or, close_rep: op_cr, ..} = op { (op_id, op_or, op_cr) } else { unreachable!() }).find(|(_, op_or, op_cr)| *op_or == or && *op_cr == cr) {
3787 mapped_op_id = *op_id;
3788
3789 } else { mapped_op_id = self.binary_ops.len();
3791
3792 if let Err(err) = self.define_nary_operator(or.clone(), cr.clone(), *precedence) {
3793 return Err(NessaError::compiler_error(err, l, vec!()));
3794 }
3795 }
3796
3797 return Ok(*id_mapper.nary_operators.entry(id).or_insert(mapped_op_id));
3798 }
3799
3800 } else {
3801 return Err(NessaError::compiler_error(format!("Unable to find binary operator with id = {}", id), l, vec!()));
3802 }
3803
3804 Ok(id_mapper.nary_operators[&id])
3805 }
3806
3807 pub fn map_nessa_expression(
3808 &mut self, expr: &mut NessaExpr, ctx: &NessaContext,
3809 id_mapper: &mut IdMapper
3810 ) -> Result<(), NessaError> {
3811 match expr {
3812 NessaExpr::Break(..) |
3813 NessaExpr::Continue(..) |
3814 NessaExpr::Literal(..) |
3815 NessaExpr::NameReference(..) |
3816 NessaExpr::PostfixOperatorDefinition(_, _, _) |
3817 NessaExpr::PrefixOperatorDefinition(_, _, _) |
3818 NessaExpr::BinaryOperatorDefinition(_, _, _, _) |
3819 NessaExpr::NaryOperatorDefinition(_, _, _, _) => {}
3820
3821 NessaExpr::VariableDefinition(l, _, t, e) => {
3822 *t = t.map_type(self, ctx, id_mapper, l);
3823
3824 self.map_nessa_expression(e, ctx, id_mapper)?;
3825 }
3826
3827 NessaExpr::VariableAssignment(_, _, e) => {
3828 self.map_nessa_expression(e, ctx, id_mapper)?;
3829 }
3830
3831 NessaExpr::Tuple(_, b) => {
3832 for arg in b {
3833 self.map_nessa_expression(arg, ctx, id_mapper)?;
3834 }
3835 }
3836
3837 NessaExpr::DoBlock(l, b, t) => {
3838 *t = t.map_type(self, ctx, id_mapper, l);
3839
3840 for arg in b {
3841 self.map_nessa_expression(arg, ctx, id_mapper)?;
3842 }
3843 }
3844
3845 NessaExpr::UnaryOperation(l, id, t, a) => {
3846 *id = self.map_nessa_unary_operator(ctx, *id, id_mapper, l)?;
3847
3848 *t = t.iter().map(|t| t.map_type(self, ctx, id_mapper, l)).collect();
3849
3850 self.map_nessa_expression(a, ctx, id_mapper)?;
3851 }
3852
3853 NessaExpr::BinaryOperation(l, id, t, a, b) => {
3854 *id = self.map_nessa_binary_operator(ctx, *id, id_mapper, l)?;
3855
3856 *t = t.iter().map(|t| t.map_type(self, ctx, id_mapper, l)).collect();
3857
3858 self.map_nessa_expression(a, ctx, id_mapper)?;
3859 self.map_nessa_expression(b, ctx, id_mapper)?;
3860 }
3861
3862 NessaExpr::NaryOperation(l, id, t, a, b) => {
3863 *id = self.map_nessa_nary_operator(ctx, *id, id_mapper, l)?;
3864
3865 *t = t.iter().map(|t| t.map_type(self, ctx, id_mapper, l)).collect();
3866
3867 self.map_nessa_expression(a, ctx, id_mapper)?;
3868
3869 for arg in b {
3870 self.map_nessa_expression(arg, ctx, id_mapper)?;
3871 }
3872 }
3873
3874 NessaExpr::FunctionCall(l, id, t, args) => {
3875 *id = self.map_nessa_function(ctx, *id, id_mapper, l)?;
3876
3877 *t = t.iter().map(|t| t.map_type(self, ctx, id_mapper, l)).collect();
3878
3879 for arg in args {
3880 self.map_nessa_expression(arg, ctx, id_mapper)?;
3881 }
3882 }
3883
3884 NessaExpr::If(_, ih, ib, ei, eb) => {
3885 self.map_nessa_expression(ih, ctx, id_mapper)?;
3886
3887 for line in ib {
3888 self.map_nessa_expression(line, ctx, id_mapper)?;
3889 }
3890
3891 for (ei_h, ei_b) in ei {
3892 self.map_nessa_expression(ei_h, ctx, id_mapper)?;
3893
3894 for line in ei_b {
3895 self.map_nessa_expression(line, ctx, id_mapper)?;
3896 }
3897 }
3898
3899 if let Some(eb_inner) = eb {
3900 for line in eb_inner {
3901 self.map_nessa_expression(line, ctx, id_mapper)?;
3902 }
3903 }
3904 }
3905
3906 NessaExpr::While(_, c, lines) |
3907 NessaExpr::For(_, _, c, lines) => {
3908 self.map_nessa_expression(c, ctx, id_mapper)?;
3909
3910 for line in lines {
3911 self.map_nessa_expression(line, ctx, id_mapper)?;
3912 }
3913 }
3914
3915 NessaExpr::Return(_, e) => {
3916 self.map_nessa_expression(e, ctx, id_mapper)?;
3917 }
3918
3919 NessaExpr::Lambda(l, _, a, ret, lines) => {
3920 for (_, t) in a {
3921 *t = t.map_type(self, ctx, id_mapper, l)
3922 }
3923
3924 *ret = ret.map_type(self, ctx, id_mapper, l);
3925
3926 for line in lines {
3927 self.map_nessa_expression(line, ctx, id_mapper)?;
3928 }
3929 },
3930
3931 e => unreachable!("{:?}", e)
3932 }
3933
3934 Ok(())
3935 }
3936
3937 pub fn import_code(
3938 &mut self,
3939 code: &[NessaExpr],
3940 source: &Vec<String>,
3941 ctx: &NessaContext,
3942 imports: &Imports
3943 ) -> Result<(Vec<NessaExpr>, Vec<String>), NessaError> {
3944 let mut res = vec!();
3945 let mut new_source = vec!();
3946 let mut id_mapper = IdMapper::default();
3947
3948 for (line_idx, (line, module)) in code.iter().zip(source).enumerate() {
3949 match line {
3950 NessaExpr::Macro(_, _, n, _, p, _) => {
3951 if needs_import(module, ImportType::Syntax, n, imports, &mut self.cache.imports.macros, (n.clone(), p.clone())) {
3952 self.define_module_macro(line.clone(), &mut FxHashSet::default()).map(|_| ())?;
3953 }
3954 }
3955
3956 NessaExpr::InterfaceImplementation(l, t, tp, n, ts) => {
3957 if needs_import(module, ImportType::Interface, n, imports, &mut self.cache.imports.interface_impl, (t.clone(), tp.clone(), n.clone(), ts.clone())) {
3958 let mapped_type = tp.map_type(self, ctx, &mut id_mapper, l);
3959 let mapped_args = ts.iter().map(|i| i.map_type(self, ctx, &mut id_mapper, l)).collect::<Vec<_>>();
3960
3961 self.define_interface_impl(n.clone(), t.clone(), mapped_type.clone(), mapped_args.clone()).unwrap();
3962
3963 let mapped_expr = NessaExpr::InterfaceImplementation(l.clone(), t.clone(), mapped_type, n.clone(), mapped_args);
3964
3965 res.push(mapped_expr);
3966 new_source.push(module.clone());
3967 }
3968 }
3969
3970 NessaExpr::InterfaceDefinition(l, an, n, t, fns, uns, bin, nary) => {
3971 if needs_import(module, ImportType::Interface, n, imports, &mut self.cache.imports.interface_def, (n.clone(), t.clone())) {
3972 self.map_nessa_interface(ctx, ctx.get_interface_id(n.clone()).unwrap(), &mut id_mapper, l).unwrap();
3973
3974 let mapped_fns = fns.iter().map(|(an, n, t, a, r)| {
3975 (
3976 an.clone(),
3977 n.clone(),
3978 t.clone(),
3979 a.iter().map(|(n, t)| (n.clone(), t.map_type(self, ctx, &mut id_mapper, l))).collect(),
3980 r.map_type(self, ctx, &mut id_mapper, l)
3981 )
3982 }).collect();
3983
3984 let mapped_uns = uns.iter().map(|(an, id, tm, a, at, ret)| {
3985 Result::<_, NessaError>::Ok((
3986 an.clone(),
3987 self.map_nessa_unary_operator(ctx, *id, &mut id_mapper, l)?,
3988 tm.clone(),
3989 a.clone(),
3990 at.map_type(self, ctx, &mut id_mapper, l),
3991 ret.map_type(self, ctx, &mut id_mapper, l)
3992 ))
3993 }).collect::<Result<Vec<_>, _>>()?;
3994
3995 let mapped_bin = bin.iter().map(|(an, id, tm, (a0, a0t), (a1, a1t), ret)| {
3996 Result::<_, NessaError>::Ok((
3997 an.clone(),
3998 self.map_nessa_binary_operator(ctx, *id, &mut id_mapper, l)?,
3999 tm.clone(),
4000 (a0.clone(), a0t.map_type(self, ctx, &mut id_mapper, l)),
4001 (a1.clone(), a1t.map_type(self, ctx, &mut id_mapper, l)),
4002 ret.map_type(self, ctx, &mut id_mapper, l)
4003 ))
4004 }).collect::<Result<Vec<_>, _>>().unwrap();
4005
4006 let mapped_nary = nary.iter().map(|(an, id, tm, (a0, a0t), a, ret)| {
4007 Result::<_, NessaError>::Ok((
4008 an.clone(),
4009 self.map_nessa_binary_operator(ctx, *id, &mut id_mapper, l)?,
4010 tm.clone(),
4011 (a0.clone(), a0t.map_type(self, ctx, &mut id_mapper, l)),
4012 a.iter().map(|(n, t)| (n.clone(), t.map_type(self, ctx, &mut id_mapper, l))).collect(),
4013 ret.map_type(self, ctx, &mut id_mapper, l)
4014 ))
4015 }).collect::<Result<Vec<_>, _>>().unwrap();
4016
4017 let mapped_expr = NessaExpr::InterfaceDefinition(l.clone(), an.clone(), n.clone(), t.clone(), mapped_fns, mapped_uns, mapped_bin, mapped_nary);
4018
4019 res.push(mapped_expr);
4020 new_source.push(module.clone());
4021 }
4022 }
4023
4024 NessaExpr::ClassDefinition(l, an, n, t, atts, al, p) => {
4025 if needs_import(module, ImportType::Class, n, imports, &mut self.cache.imports.classes, (n.clone(), t.clone())) {
4026 let mapped_atts = atts.iter().map(|(n, t)| (n.clone(), t.map_type(self, ctx, &mut id_mapper, l))).collect();
4027 let mapped_al = al.clone().map(|i| i.map_type(self, ctx, &mut id_mapper, l));
4028 let mapped_expr = NessaExpr::ClassDefinition(l.clone(), an.clone(), n.clone(), t.clone(), mapped_atts, mapped_al, p.clone());
4029
4030 self.define_module_class(mapped_expr.clone())?;
4031
4032 res.push(mapped_expr);
4033 new_source.push(module.clone());
4034 }
4035 }
4036
4037 NessaExpr::FunctionDefinition(l, an, id, t, a, r, b) => {
4038 let f_name = &ctx.functions[*id].name;
4039 let fn_id = self.map_nessa_function(ctx, *id, &mut id_mapper, l)?;
4040
4041 let mapped_args = a.iter().map(|(n, t)| (n.clone(), t.map_type(self, ctx, &mut id_mapper, l))).collect::<Vec<_>>();
4042 let mapped_return = r.map_type(self, ctx, &mut id_mapper, l);
4043
4044 if needs_import(module, ImportType::Fn, f_name, imports, &mut self.cache.imports.functions, (fn_id, t.clone(), mapped_args.clone(), mapped_return.clone())) {
4045 let mut mapped_body = b.clone();
4046
4047 for line in mapped_body.iter_mut() {
4049 self.map_nessa_expression(line, ctx, &mut id_mapper)?;
4050 }
4051
4052 let arg_types = mapped_args.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
4053
4054 if let Err(err) = self.define_function_overload(l.clone(), an.clone(), fn_id, t.len(), &arg_types, mapped_return.clone(), None) {
4055 return Err(NessaError::compiler_error(err, l, vec!()));
4056 }
4057
4058 res.push(NessaExpr::FunctionDefinition(l.clone(), an.clone(), fn_id, t.clone(), mapped_args.clone(), mapped_return, mapped_body));
4060 new_source.push(module.clone());
4061 }
4062 }
4063
4064 NessaExpr::PrefixOperationDefinition(l, an, id, t, arg, arg_t, r, body) |
4065 NessaExpr::PostfixOperationDefinition(l, an, id, t, arg, arg_t, r, body) => {
4066 let rep;
4067 let op_prefix;
4068 let op_import_type;
4069
4070 if let Operator::Unary { representation, prefix, .. } = &ctx.unary_ops[*id] {
4071 rep = representation;
4072 op_prefix = prefix;
4073 op_import_type = if *prefix { ImportType::Prefix } else { ImportType::Postfix };
4074
4075 } else {
4076 unreachable!();
4077 }
4078
4079 let op_id = self.map_nessa_unary_operator(ctx, *id, &mut id_mapper, l)?;
4080
4081 let mapped_arg_t = arg_t.map_type(self, ctx, &mut id_mapper, l);
4082 let mapped_return = r.map_type(self, ctx, &mut id_mapper, l);
4083
4084 if needs_import(module, op_import_type, rep, imports, &mut self.cache.imports.unary, (op_id, t.clone(), mapped_arg_t.clone(), mapped_return.clone())) {
4085 let mut mapped_body = body.clone();
4086
4087 for line in mapped_body.iter_mut() {
4089 self.map_nessa_expression(line, ctx, &mut id_mapper)?;
4090 }
4091
4092 if let Err(err) = self.define_unary_operation(l.clone(), an.clone(), *id, t.len(), mapped_arg_t.clone(), mapped_return.clone(), None) {
4093 return Err(NessaError::compiler_error(err, l, vec!()));
4094 }
4095
4096 if *op_prefix {
4098 res.push(NessaExpr::PrefixOperationDefinition(l.clone(), an.clone(), op_id, t.clone(), arg.clone(), mapped_arg_t, mapped_return, mapped_body));
4099
4100 } else {
4101 res.push(NessaExpr::PostfixOperationDefinition(l.clone(), an.clone(), op_id, t.clone(), arg.clone(), mapped_arg_t, mapped_return, mapped_body));
4102 }
4103
4104 new_source.push(module.clone());
4105 }
4106 },
4107
4108 NessaExpr::BinaryOperationDefinition(l, an, id, t, a, b, r, body) => {
4109 let rep = ctx.binary_ops[*id].get_repr();
4110
4111 let op_id = self.map_nessa_binary_operator(ctx, *id, &mut id_mapper, l)?;
4112
4113 let mapped_arg1 = (a.0.clone(), a.1.map_type(self, ctx, &mut id_mapper, l));
4114 let mapped_arg2 = (b.0.clone(), b.1.map_type(self, ctx, &mut id_mapper, l));
4115 let mapped_return = r.map_type(self, ctx, &mut id_mapper, l);
4116
4117 if needs_import(module, ImportType::Binary, &rep, imports, &mut self.cache.imports.binary, (op_id, t.clone(), mapped_arg1.1.clone(), mapped_arg2.1.clone(), mapped_return.clone())) {
4118 let mut mapped_body = body.clone();
4119
4120 for line in mapped_body.iter_mut() {
4122 self.map_nessa_expression(line, ctx, &mut id_mapper)?;
4123 }
4124
4125 if let Err(err) = self.define_binary_operation(l.clone(), an.clone(), *id, t.len(), mapped_arg1.1.clone(), mapped_arg2.1.clone(), mapped_return.clone(), None) {
4126 return Err(NessaError::compiler_error(err, l, vec!()));
4127 }
4128
4129 res.push(NessaExpr::BinaryOperationDefinition(l.clone(), an.clone(), op_id, t.clone(), mapped_arg1, mapped_arg2, mapped_return, mapped_body));
4131 new_source.push(module.clone());
4132 }
4133 },
4134
4135 NessaExpr::NaryOperationDefinition(l, an, id, t, arg, args, r, body) => {
4136 let rep = ctx.nary_ops[*id].get_repr();
4137
4138 let op_id = self.map_nessa_nary_operator(ctx, *id, &mut id_mapper, l)?;
4139
4140 let mapped_arg = (arg.0.clone(), arg.1.map_type(self, ctx, &mut id_mapper, l));
4141 let mapped_args = args.iter().map(|(n, t)| (n.clone(), t.map_type(self, ctx, &mut id_mapper, l))).collect::<Vec<_>>();
4142 let mapped_return = r.map_type(self, ctx, &mut id_mapper, l);
4143
4144 if needs_import(module, ImportType::Binary, &rep, imports, &mut self.cache.imports.nary, (*id, t.clone(), mapped_arg.1.clone(), mapped_args.clone(), mapped_return.clone())) {
4145 let mut mapped_body = body.clone();
4146
4147 for line in mapped_body.iter_mut() {
4149 self.map_nessa_expression(line, ctx, &mut id_mapper)?;
4150 }
4151
4152 let arg_types = mapped_args.iter().map(|(_, t)| t.clone()).collect::<Vec<_>>();
4153
4154 if let Err(err) = self.define_nary_operation(l.clone(), an.clone(), *id, t.len(), mapped_arg.1.clone(), &arg_types, mapped_return.clone(), None) {
4155 return Err(NessaError::compiler_error(err, l, vec!()));
4156 }
4157
4158 res.push(NessaExpr::NaryOperationDefinition(l.clone(), an.clone(), op_id, t.clone(), mapped_arg, mapped_args, mapped_return, mapped_body));
4160 new_source.push(module.clone());
4161 }
4162 },
4163
4164 expr => {
4165 if needs_line_import(module, line_idx, &mut self.cache.imports.lines) {
4166 let mut mapped_expr = expr.clone();
4167 self.map_nessa_expression(&mut mapped_expr, ctx, &mut id_mapper)?;
4168
4169 res.push(mapped_expr);
4170 new_source.push(module.clone());
4171 }
4172 }
4173 }
4174 }
4175
4176 Ok((res, new_source))
4177 }
4178
4179 fn cascade_imports(
4181 imports: &mut ImportMap,
4182 modules: &HashMap<String, &NessaModule>
4183 )
4184 {
4185 let mut res = HashMap::new();
4186
4187 while res != *imports {
4188 res = imports.clone();
4189
4190 for (name, _) in imports.iter() {
4191 for (d_name, d_deps) in &modules.get(name).unwrap().imports {
4192 for (t, n) in d_deps {
4193 res.entry(d_name.clone()).or_default().entry(t.clone()).or_default().extend(n.iter().cloned());
4194 }
4195 }
4196 }
4197
4198 *imports = res.clone();
4199 }
4200 }
4201
4202 fn map_import(&self, import: &ImportType, name: &String) -> usize {
4203 return match import {
4204 ImportType::Interface => self.get_interface_id(name.clone()).unwrap(),
4205 ImportType::Class => self.get_type_id(name.clone()).unwrap(),
4206 ImportType::Fn => self.get_function_id(name.clone()).unwrap(),
4207
4208 ImportType::Prefix |
4209 ImportType::Postfix => self.unary_ops.iter().find(|i| i.get_repr() == *name).unwrap().get_id(),
4210
4211 ImportType::Binary => self.binary_ops.iter().find(|i| i.get_repr() == *name).unwrap().get_id(),
4212 ImportType::Nary => self.nary_ops.iter().find(|i| i.get_repr() == *name).unwrap().get_id(),
4213
4214 _ => unimplemented!()
4215 };
4216 }
4217
4218 fn rev_map_import(&self, import: &ImportType, id: usize) -> String {
4219 match import {
4220 ImportType::Interface => self.interfaces[id].name.clone(),
4221 ImportType::Class => self.type_templates[id].name.clone(),
4222 ImportType::Fn => self.functions[id].name.clone(),
4223
4224 ImportType::Prefix |
4225 ImportType::Postfix => self.unary_ops[id].get_repr(),
4226
4227 ImportType::Binary => self.binary_ops[id].get_repr(),
4228 ImportType::Nary => self.nary_ops[id].get_repr(),
4229
4230 _ => unimplemented!()
4231 }
4232 }
4233
4234 fn cascade_imports_inner(
4236 imports: &mut ImportMap,
4237 modules: &HashMap<String, &NessaModule>
4238 )
4239 {
4240 for (m, imps) in imports {
4241 let mut new_imports = Imports::new();
4242 let module = &modules.get(m).unwrap();
4243
4244 for (t, names) in imps.iter() {
4245 if let ImportType::Syntax | ImportType::All = t { new_imports.entry(t.clone()).or_default().extend(names.iter().cloned());
4247
4248 } else {
4249 for name in names.iter() {
4250 if name == "*" {
4252 new_imports.entry(t.clone()).or_default().insert(name.clone());
4253
4254 } else {
4255 let id = module.ctx.map_import(t, name);
4256
4257 module.inner_dependencies.dfs(&(t.clone(), id), |(tp, id)| {
4258 let mapped_name = module.ctx.rev_map_import(tp, *id);
4259 new_imports.entry(tp.clone()).or_default().insert(mapped_name);
4260 });
4261 }
4262 }
4263 }
4264 }
4265
4266 for (t, names) in new_imports {
4267 imps.entry(t.clone()).or_default().extend(names);
4268 }
4269 }
4270 }
4271
4272 pub fn parse_with_dependencies(
4273 &mut self,
4274 name: &str,
4275 code: &String,
4276 modules: &HashMap<String, &NessaModule>
4277 ) -> Result<(Vec<NessaExpr>, Vec<String>), NessaError> {
4278 let mut res = vec!();
4279 let mut source = vec!();
4280 let mut imports = nessa_module_imports_parser(Span::new(code), self.module_name.clone()).unwrap().1; Self::cascade_imports(&mut imports, modules);
4283 Self::cascade_imports_inner(&mut imports, modules);
4284
4285 for (m, i) in imports {
4287 let other = modules.get(&m).unwrap();
4288
4289 let (mut new_code, mut new_source) = self.import_code(&other.code, &other.source, &other.ctx, &i)?;
4290 source.append(&mut new_source);
4291 res.append(&mut new_code);
4292 }
4293
4294 let mut main_code = self.parse_without_precompiling(code)?;
4295 source.extend(std::iter::repeat(name.to_owned()).take(main_code.len()));
4296 res.append(&mut main_code);
4297
4298 Ok((res, source))
4299 }
4300
4301 pub fn parse_without_precompiling(&mut self, code: &String) -> Result<Vec<NessaExpr>, NessaError> {
4302 self.define_module_macros(code)?;
4303 self.define_module_operators(code)?;
4304 self.define_module_classes(code)?;
4305 self.define_module_functions(code)?;
4306 self.define_module_operations(code)?;
4307
4308 let lines = self.parse_nessa_module(code)?;
4309
4310 self.define_module_function_overloads(&lines)?;
4311
4312 Ok(lines)
4313 }
4314
4315 pub fn precompile_module(&mut self, lines: &mut Vec<NessaExpr>) -> Result<(), NessaError> {
4316 self.compile(lines, &vec!())?;
4317
4318 for expr in lines.iter_mut() {
4320 self.static_check(expr)?;
4321 }
4322
4323 self.get_template_calls_body(lines)?;
4325
4326 if self.optimize {
4328 self.optimize(lines);
4330
4331 for body in self.cache.templates.functions.inner_borrow_mut().values_mut() {
4332 self.optimize(body);
4333 }
4334
4335 for body in self.cache.templates.unary.inner_borrow_mut().values_mut() {
4336 self.optimize(body);
4337 }
4338
4339 for body in self.cache.templates.binary.inner_borrow_mut().values_mut() {
4340 self.optimize(body);
4341 }
4342
4343 for body in self.cache.templates.nary.inner_borrow_mut().values_mut() {
4344 self.optimize(body);
4345 }
4346
4347 macro_rules! optimize_cache {
4349 ($cache: expr) => {
4350 let keys = $cache.inner_borrow_mut().keys().cloned().collect::<Vec<_>>();
4351
4352 for key in keys {
4353 let mut body = $cache.get_checked(&key).unwrap().clone();
4354
4355 self.late_optimize(&mut body);
4356
4357 $cache.insert(key, body);
4358 }
4359 };
4360 }
4361
4362 optimize_cache!(self.cache.templates.functions);
4363 optimize_cache!(self.cache.templates.unary);
4364 optimize_cache!(self.cache.templates.binary);
4365 optimize_cache!(self.cache.templates.nary);
4366
4367 self.late_optimize(lines);
4368 }
4369
4370 Ok(())
4371 }
4372
4373 pub fn parse_and_precompile(&mut self, code: &String) -> Result<Vec<NessaExpr>, NessaError> {
4374 let mut lines = self.parse_without_precompiling(code)?;
4375 self.precompile_module(&mut lines)?;
4376
4377 Ok(lines)
4378 }
4379
4380 pub fn parse_and_compile(&mut self, code: &String) -> Result<Vec<NessaInstruction>, NessaError> {
4381 let lines = self.parse_and_precompile(code)?;
4382
4383 self.compiled_form(&lines)
4384 }
4385}
4386
4387#[cfg(test)]
4394mod tests {
4395 use malachite::Integer;
4396
4397 use crate::object::*;
4398 use crate::parser::*;
4399 use crate::context::*;
4400
4401 #[test]
4402 fn function_names_and_calls() {
4403 let mut ctx = standard_ctx();
4404
4405 let code_1_str = "
4406 inc(5);
4407 ";
4408
4409 let code_str = "
4410 inc<Int>(5);
4411 ";
4412
4413 let (_, mut code) = ctx.nessa_parser(Span::new(code_1_str)).unwrap();
4414 ctx.compile(&mut code, &vec!()).unwrap();
4415
4416 assert_eq!(code, vec!(
4417 NessaExpr::FunctionCall(Location::none(), 0, vec!(), vec!(
4418 NessaExpr::Literal(Location::none(), Object::new(Integer::from(5)))
4419 ))
4420 ));
4421
4422 let (_, mut code) = ctx.nessa_parser(Span::new(code_str)).unwrap();
4423
4424 assert!(ctx.compile(&mut code, &vec!()).is_ok());
4425 }
4426
4427 #[test]
4428 fn compiled_form() {
4429 let mut ctx = standard_ctx();
4430
4431 let code_str = "
4432 fn test(a: Int) -> Int {
4433 if 0 < a {
4434 return test(a - 1) + a;
4435 }
4436
4437 return 0;
4438 }
4439
4440 let a = test(10);
4441 ";
4442
4443 let compiled_code = ctx.parse_and_compile(&code_str.into());
4444
4445 assert!(compiled_code.is_ok());
4446 }
4447}