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