1#![allow(clippy::too_many_arguments)]
2
3use crate::error::*;
4use crate::program::*;
5use std::collections::{HashMap, HashSet};
6
7pub trait DeepValidator {
8 fn filter_module(_module: &Module, _program: &Program, _validator: &Validator) -> bool {
9 true
10 }
11 fn filter_struct(
12 _struct_: &Struct,
13 _module: &Module,
14 _program: &Program,
15 _validator: &Validator,
16 ) -> bool {
17 true
18 }
19 fn filter_function(
20 _function: &Function,
21 _module: &Module,
22 _program: &Program,
23 _validator: &Validator,
24 ) -> bool {
25 true
26 }
27 fn filter_op(
28 _op: &Operation,
29 _function: &Function,
30 _module: &Module,
31 _program: &Program,
32 _validator: &Validator,
33 ) -> bool {
34 true
35 }
36 fn validate_program(_program: &Program, _validator: &Validator) -> SimpleResult<()> {
37 Ok(())
38 }
39 fn validate_module(
40 _module: &Module,
41 _program: &Program,
42 _validator: &Validator,
43 ) -> SimpleResult<()> {
44 Ok(())
45 }
46 fn validate_op(
47 _op: &Operation,
48 _function: &Function,
49 _module: &Module,
50 _program: &Program,
51 _rule: &Rule,
52 _validator: &Validator,
53 ) -> SimpleResult<()> {
54 Ok(())
55 }
56 fn transform_module(
57 module: Module,
58 _program: &Program,
59 _validator: &Validator,
60 ) -> SimpleResult<Module> {
61 Ok(module)
62 }
63}
64
65pub struct EmptyDeepValidator {}
66impl DeepValidator for EmptyDeepValidator {
67 fn transform_module(
68 module: Module,
69 _program: &Program,
70 _validator: &Validator,
71 ) -> SimpleResult<Module> {
72 transform_module_auto_types(module)
73 }
74}
75
76pub struct Rule {
77 pub id: String,
78 pub params: Vec<OpParam>,
79 pub targets: Vec<Type>,
80}
81
82impl Rule {
83 pub fn from_op_rule(rule: &OpRule) -> Self {
84 Self {
85 id: rule.id.clone(),
86 params: rule.params.clone(),
87 targets: rule.targets.clone(),
88 }
89 }
90}
91
92type ModuleTypeIDs = HashMap<String, Option<String>>;
93type ModuleFunctionIDs = HashMap<String, Option<Type>>;
94type FunctionVariablesIDs = HashMap<String, Type>;
95
96pub fn resolve_module_types(module: &Module, program: &Program) -> SimpleResult<ModuleTypeIDs> {
97 let mut types = HashMap::new();
98 types.insert("i8".to_owned(), None);
99 types.insert("i16".to_owned(), None);
100 types.insert("i32".to_owned(), None);
101 types.insert("i64".to_owned(), None);
102 types.insert("u8".to_owned(), None);
103 types.insert("i16".to_owned(), None);
104 types.insert("u32".to_owned(), None);
105 types.insert("u64".to_owned(), None);
106 types.insert("f32".to_owned(), None);
107 types.insert("f64".to_owned(), None);
108 types.insert("isize".to_owned(), None);
109 types.insert("usize".to_owned(), None);
110 for s in &module.structs {
111 if types.contains_key(&s.id) {
112 return Err(SimpleError::new(format!(
113 "Struct name already taken: {}",
114 s.id
115 )));
116 }
117 types.insert(s.id.clone(), Some(module.path.clone()));
118 }
119 for i in &module.imports {
120 if let Some(m) = program.find_module(&i.module) {
121 for n in &i.names {
122 if let Some(s) = m.find_struct(n) {
123 if types.contains_key(&s.id) {
124 return Err(SimpleError::new(format!(
125 "Struct name already taken: {}",
126 s.id
127 )));
128 }
129 types.insert(s.id.clone(), Some(m.path.clone()));
130 }
131 }
132 } else {
133 return Err(SimpleError::new(format!(
134 "There is no module: {}",
135 i.module
136 )));
137 }
138 }
139 Ok(types)
140}
141
142pub fn resolve_module_functions(
143 module: &Module,
144 program: &Program,
145) -> SimpleResult<ModuleFunctionIDs> {
146 let mut functions = HashMap::new();
147 for f in &module.functions {
148 if functions.contains_key(&f.header.id) {
149 return Err(SimpleError::new(format!(
150 "Function name already taken: {}",
151 f.header.id
152 )));
153 }
154 functions.insert(f.header.id.clone(), f.header.typeid.clone());
155 }
156 for i in &module.imports {
157 if let Some(m) = program.find_module(&i.module) {
158 for n in &i.names {
159 if let Some(f) = m.find_function(n) {
160 if functions.contains_key(&f.header.id) {
161 return Err(SimpleError::new(format!(
162 "Function name already taken: {}",
163 f.header.id
164 )));
165 }
166 functions.insert(f.header.id.clone(), f.header.typeid.clone());
167 }
168 }
169 } else {
170 return Err(SimpleError::new(format!(
171 "There is no module: {}",
172 i.module
173 )));
174 }
175 }
176 Ok(functions)
177}
178
179pub fn resolve_function_variables(
180 function: &Function,
181 module: &Module,
182) -> SimpleResult<FunctionVariablesIDs> {
183 let mut variables = HashMap::new();
184 for g in &module.globals {
185 if variables.contains_key(&g.id) {
186 return Err(SimpleError::new(format!(
187 "Variable name already taken: {}",
188 g.id
189 )));
190 }
191 variables.insert(g.id.clone(), g.typeid.clone());
192 }
193 if let Some(ref t) = function.header.typeid {
194 variables.insert("_".to_owned(), t.clone());
195 }
196 for p in &function.header.params {
197 if variables.contains_key(&p.id) {
198 return Err(SimpleError::new(format!(
199 "Function `{}`: Variable name already taken: {}",
200 function.header.id, p.id,
201 )));
202 }
203 variables.insert(p.id.clone(), p.typeid.clone());
204 }
205 for l in &function.locals {
206 if variables.contains_key(&l.id) {
207 return Err(SimpleError::new(format!(
208 "Function `{}`: Local variable name already taken: {}",
209 function.header.id, l.id,
210 )));
211 }
212 variables.insert(l.id.clone(), l.typeid.clone());
213 }
214 Ok(variables)
215}
216
217pub fn transform_module_auto_types(mut module: Module) -> SimpleResult<Module> {
218 let integer_type = if let Some(m) = module.meta.iter().find(|m| m.id == "auto_integer_type") {
219 if let Some(MetaValue::String(n)) = m.args.first() {
220 n.to_owned()
221 } else {
222 "i32".to_owned()
223 }
224 } else {
225 "i32".to_owned()
226 };
227 let float_type = if let Some(m) = module.meta.iter().find(|m| m.id == "auto_float_type") {
228 if let Some(MetaValue::String(n)) = m.args.first() {
229 n.to_owned()
230 } else {
231 "f32".to_owned()
232 }
233 } else {
234 "f32".to_owned()
235 };
236 let string_type = if let Some(m) = module.meta.iter().find(|m| m.id == "auto_string_type") {
237 if let Some(MetaValue::String(n)) = m.args.first() {
238 n.to_owned()
239 } else {
240 "u8".to_owned()
241 }
242 } else {
243 "u8".to_owned()
244 };
245 module.functions = module
246 .functions
247 .iter()
248 .map(|f| transform_function_auto_types(f.clone(), &integer_type, &float_type, &string_type))
249 .collect::<SimpleResult<Vec<_>>>()?;
250 Ok(module)
251}
252
253pub fn transform_function_auto_types(
254 mut function: Function,
255 integer_type: &str,
256 float_type: &str,
257 string_type: &str,
258) -> SimpleResult<Function> {
259 function.body = function
260 .body
261 .iter()
262 .map(|o| match o.clone() {
263 BlockOp::Operation(mut op) => {
264 op.params = op
265 .params
266 .iter()
267 .map(|v| {
268 transform_value_auto_types(v.clone(), integer_type, float_type, string_type)
269 })
270 .collect::<SimpleResult<Vec<_>>>()?;
271 op.targets = op
272 .targets
273 .iter()
274 .map(|v| {
275 transform_value_auto_types(v.clone(), integer_type, float_type, string_type)
276 })
277 .collect::<SimpleResult<Vec<_>>>()?;
278 Ok(BlockOp::Operation(op))
279 }
280 BlockOp::Label(n) => Ok(BlockOp::Label(n)),
281 })
282 .collect::<SimpleResult<Vec<_>>>()?;
283 Ok(function)
284}
285
286pub fn transform_value_auto_types(
287 value: Value,
288 integer_type: &str,
289 float_type: &str,
290 string_type: &str,
291) -> SimpleResult<Value> {
292 match value {
293 Value::Ref(v, a) => Ok(Value::Ref(
294 Box::new(transform_value_auto_types(
295 *v,
296 integer_type,
297 float_type,
298 string_type,
299 )?),
300 a,
301 )),
302 Value::Deref(v, a) => Ok(Value::Deref(
303 Box::new(transform_value_auto_types(
304 *v,
305 integer_type,
306 float_type,
307 string_type,
308 )?),
309 a,
310 )),
311 Value::FunctionCall(i, v, a) => Ok(Value::FunctionCall(
312 i,
313 v.into_iter()
314 .map(|v| transform_value_auto_types(v, integer_type, float_type, string_type))
315 .collect::<SimpleResult<Vec<_>>>()?,
316 a,
317 )),
318 Value::Tuple(v, a) => Ok(Value::Tuple(
319 v.into_iter()
320 .map(|v| transform_value_auto_types(v, integer_type, float_type, string_type))
321 .collect::<SimpleResult<Vec<_>>>()?,
322 a,
323 )),
324 Value::String(v, t) => {
325 if let Type::Pointer(t) = t {
326 if let Type::Identifier(i) = *t {
327 Ok(Value::String(
328 v,
329 Type::Pointer(Box::new(Type::Identifier(if i == "{string}" {
330 string_type.to_owned()
331 } else {
332 i
333 }))),
334 ))
335 } else {
336 Err(SimpleError::new(format!(
337 "Type is not identifier: {}",
338 t.to_string()
339 )))
340 }
341 } else {
342 Err(SimpleError::new(format!(
343 "Type is not pointer: {}",
344 t.to_string()
345 )))
346 }
347 }
348 Value::Number(v) => match v {
349 Number::Integer(v, t) => {
350 if let Type::Identifier(i) = t {
351 Ok(Value::Number(Number::Integer(
352 v,
353 Type::Identifier(if i == "{integer}" {
354 integer_type.to_owned()
355 } else {
356 i
357 }),
358 )))
359 } else {
360 Err(SimpleError::new(format!(
361 "Type is not identifier: {}",
362 t.to_string()
363 )))
364 }
365 }
366 Number::Float(v, t) => {
367 if let Type::Identifier(i) = t {
368 Ok(Value::Number(Number::Float(
369 v,
370 Type::Identifier(if i == "{float}" {
371 float_type.to_owned()
372 } else {
373 i
374 }),
375 )))
376 } else {
377 Err(SimpleError::new(format!(
378 "Type is not identifier: {}",
379 t.to_string()
380 )))
381 }
382 }
383 },
384 Value::OperationInline(i, v, a) => Ok(Value::OperationInline(
385 i,
386 v.into_iter()
387 .map(|v| transform_value_auto_types(v, integer_type, float_type, string_type))
388 .collect::<SimpleResult<Vec<_>>>()?,
389 a,
390 )),
391 Value::Variable(i, a) => Ok(Value::Variable(i, a)),
392 }
393}
394
395pub struct Validator {
396 meta: Vec<Meta>,
397 rules: Vec<Rule>,
398}
399
400impl Validator {
401 #[inline]
402 pub fn new(ops_descriptor: &OpsDescriptor) -> Self {
403 Self::with_filter(ops_descriptor, |_, _| true)
404 }
405
406 pub fn with_filter<F>(ops_descriptor: &OpsDescriptor, filter: F) -> Self
407 where
408 F: Fn(&OpRule, &OpsDescriptor) -> bool,
409 {
410 Self {
411 meta: ops_descriptor.meta.clone(),
412 rules: ops_descriptor
413 .rules
414 .iter()
415 .filter_map(|r| {
416 if filter(r, ops_descriptor) {
417 Some(Rule::from_op_rule(r))
418 } else {
419 None
420 }
421 })
422 .collect(),
423 }
424 }
425
426 pub fn meta(&self) -> &[Meta] {
427 &self.meta
428 }
429
430 pub fn rules(&self) -> &[Rule] {
431 &self.rules
432 }
433
434 pub fn filter_program<V>(&self, program: &mut Program)
435 where
436 V: DeepValidator,
437 {
438 let mut modules = program
439 .modules
440 .iter()
441 .filter(|m| V::filter_module(m, program, self))
442 .cloned()
443 .collect();
444 for m in &mut modules {
445 self.filter_module::<V>(m, program);
446 }
447 program.modules = modules;
448 }
449
450 fn filter_module<V>(&self, module: &mut Module, program: &Program)
451 where
452 V: DeepValidator,
453 {
454 let structs = module
455 .structs
456 .iter()
457 .filter(|s| V::filter_struct(s, module, program, self))
458 .cloned()
459 .collect();
460 let mut functions = module
461 .functions
462 .iter()
463 .filter(|f| V::filter_function(f, module, program, self))
464 .cloned()
465 .collect();
466 for f in &mut functions {
467 self.filter_function::<V>(f, module, program);
468 }
469 module.structs = structs;
470 module.functions = functions;
471 }
472
473 fn filter_function<V>(&self, function: &mut Function, module: &Module, program: &Program)
474 where
475 V: DeepValidator,
476 {
477 let body = function
478 .body
479 .iter()
480 .filter(|o| {
481 if let BlockOp::Operation(o) = o {
482 V::filter_op(&o, function, module, program, self)
483 } else {
484 true
485 }
486 })
487 .cloned()
488 .collect();
489 function.body = body;
490 }
491
492 pub fn validate_program<V>(&self, program: &Program) -> SimpleResult<()>
493 where
494 V: DeepValidator,
495 {
496 for module in &program.modules {
497 self.ensure_no_duplicates_module(module)?;
498 self.validate_module::<V>(module, program)?;
499 }
500 V::validate_program(program, self)
501 }
502
503 pub fn transform_program<V>(&self, program: &mut Program) -> SimpleResult<()>
504 where
505 V: DeepValidator,
506 {
507 program.modules = program
508 .modules
509 .iter()
510 .map(|m| V::transform_module(m.clone(), program, self))
511 .collect::<SimpleResult<Vec<Module>>>()?;
512 Ok(())
513 }
514
515 fn ensure_no_duplicates_module(&self, module: &Module) -> SimpleResult<()> {
516 let mut ids = HashSet::new();
517 for i in &module.imports {
518 for name in &i.names {
519 if ids.contains(name) {
520 return Err(SimpleError::new(format!(
521 "Import name `{}` is already taken",
522 name
523 )));
524 }
525 ids.insert(name.clone());
526 }
527 }
528 for g in &module.globals {
529 if ids.contains(&g.id) {
530 return Err(SimpleError::new(format!(
531 "Global name `{}` is already taken",
532 g.id
533 )));
534 }
535 ids.insert(g.id.clone());
536 }
537 for e in &module.externs {
538 if ids.contains(&e.item.id) {
539 return Err(SimpleError::new(format!(
540 "Export name `{}` is already taken",
541 e.item.id
542 )));
543 }
544 ids.insert(e.item.id.clone());
545 }
546 for s in &module.structs {
547 if ids.contains(&s.id) {
548 return Err(SimpleError::new(format!(
549 "Struct name `{}` is already taken",
550 s.id
551 )));
552 }
553 ids.insert(s.id.clone());
554 }
555 for f in &module.functions {
556 if ids.contains(&f.header.id) {
557 return Err(SimpleError::new(format!(
558 "Function name `{}` is already taken",
559 f.header.id
560 )));
561 }
562 ids.insert(f.header.id.clone());
563 }
564 Ok(())
565 }
566
567 fn validate_module<V>(&self, module: &Module, program: &Program) -> SimpleResult<()>
568 where
569 V: DeepValidator,
570 {
571 let types = resolve_module_types(module, program)?;
572 let functions = resolve_module_functions(module, program)?;
573 for s in &module.structs {
574 Self::validate_struct(s, program)?;
575 }
576 for g in &module.globals {
577 Self::validate_type(&g.typeid, &types)?;
578 }
579 for e in &module.externs {
580 Self::validate_function_header(&e.item, &types)?;
581 }
582 for f in &module.functions {
583 let variables = resolve_function_variables(f, module)?;
584 self.validate_function::<V>(f, module, program, &types, &functions, &variables)?;
585 }
586 V::validate_module(module, program, self)
587 }
588
589 fn validate_struct(struct_: &Struct, program: &Program) -> SimpleResult<()> {
590 let mut stack = vec![];
591 Self::validate_struct_inner(struct_, program, &mut stack)
592 }
593
594 fn validate_struct_inner(
595 struct_: &Struct,
596 program: &Program,
597 stack: &mut Vec<String>,
598 ) -> SimpleResult<()> {
599 stack.push(struct_.id.clone());
600 for f in &struct_.fields {
601 Self::validate_struct_type(&f.typeid, program, stack)?;
602 }
603 stack.pop();
604 Ok(())
605 }
606
607 fn validate_struct_type(
608 type_: &Type,
609 program: &Program,
610 stack: &mut Vec<String>,
611 ) -> SimpleResult<()> {
612 match type_ {
613 Type::Identifier(ref t) => {
614 if let Some(s) = program.find_struct(t) {
615 if stack.iter().any(|t| t == &s.id) {
616 return Err(SimpleError::new(format!(
617 "Type `{}` is found to be in infinite loop of fields types with chain: {}\nConsider using pointer to that type instead",
618 s.id,
619 stack.join(" => "),
620 )));
621 }
622 Self::validate_struct_inner(s, program, stack)?;
623 }
624 Ok(())
625 }
626 Type::Tuple(ref v) => {
627 for t in v {
628 Self::validate_struct_type(t, program, stack)?;
629 }
630 Ok(())
631 }
632 _ => Ok(()),
633 }
634 }
635
636 fn validate_function<V>(
637 &self,
638 function: &Function,
639 module: &Module,
640 program: &Program,
641 types: &ModuleTypeIDs,
642 functions: &ModuleFunctionIDs,
643 variables: &FunctionVariablesIDs,
644 ) -> SimpleResult<()>
645 where
646 V: DeepValidator,
647 {
648 Self::validate_function_header(&function.header, types)?;
649 for v in &function.locals {
650 Self::validate_type(&v.typeid, types)?;
651 }
652 for o in &function.body {
653 if let BlockOp::Operation(ref o) = o {
654 self.validate_op::<V>(o, function, module, program, types, functions, variables)?;
655 }
656 }
657 Ok(())
658 }
659
660 fn validate_function_header(
661 header: &FunctionHeader,
662 types: &ModuleTypeIDs,
663 ) -> SimpleResult<()> {
664 for p in &header.params {
665 Self::validate_type(&p.typeid, types)?;
666 }
667 if let Some(ref t) = header.typeid {
668 Self::validate_type(t, types)?;
669 }
670 Ok(())
671 }
672
673 fn validate_type(typeid: &Type, types: &ModuleTypeIDs) -> SimpleResult<()> {
674 match typeid {
675 Type::Identifier(ref t) => {
676 if !t.is_empty() && !types.contains_key(t) {
677 Err(SimpleError::new(format!("Found unknown type: `{}`", t)))
678 } else {
679 Ok(())
680 }
681 }
682 Type::Pointer(ref t) => Self::validate_type(t, types),
683 Type::Tuple(ref tt) => {
684 for t in tt {
685 Self::validate_type(t, types)?;
686 }
687 Ok(())
688 }
689 }
690 }
691
692 fn validate_op<V>(
693 &self,
694 op: &Operation,
695 function: &Function,
696 module: &Module,
697 program: &Program,
698 types: &ModuleTypeIDs,
699 functions: &ModuleFunctionIDs,
700 variables: &FunctionVariablesIDs,
701 ) -> SimpleResult<()>
702 where
703 V: DeepValidator,
704 {
705 if let Some(rule) = self.rules.iter().find(|r| r.id == op.id) {
706 if rule.params.len() != op.params.len() {
707 return Err(SimpleError::new(format!(
708 "Operation `{}` expects {} parameter(s)",
709 op.id,
710 rule.params.len()
711 )));
712 }
713 if rule.targets.len() != op.targets.len() {
714 return Err(SimpleError::new(format!(
715 "Operation `{}` expects {} target(s)",
716 op.id,
717 rule.targets.len()
718 )));
719 }
720 for i in 0..rule.params.len() {
721 let pr = &rule.params[i];
722 let po = &op.params[i];
723 match self.find_value_type(po, types, functions, variables, program) {
724 Ok(t) => {
725 if let Err(err) = Self::validate_type(&t, types) {
726 Err(SimpleError::new(format!(
727 "Operation `{}`: {}",
728 op.id, err.message
729 )))
730 } else if t == pr.typeid {
731 Ok(())
732 } else {
733 Err(SimpleError::new(format!(
734 "Operation `{}` parameter `{}` with type `{}` is not type of `{}`",
735 op.id,
736 pr.id,
737 t.to_string(),
738 pr.typeid.to_string(),
739 )))
740 }
741 }
742 Err(err) => Err(SimpleError::new(format!(
743 "Operation `{}`: {}",
744 op.id, err.message
745 ))),
746 }?;
747 }
748 for i in 0..rule.targets.len() {
749 let ta = &rule.targets[i];
750 let tb = &op.targets[i];
751 match self.find_value_type(tb, types, functions, variables, program) {
752 Ok(ref t) => {
753 if let Err(err) = Self::validate_type(&t, types) {
754 Err(SimpleError::new(format!(
755 "Operation `{}`: {}",
756 op.id, err.message
757 )))
758 } else if t == ta {
759 Ok(())
760 } else {
761 Err(SimpleError::new(format!(
762 "Operation `{}` target #`{}` with type `{}` is not type of `{}`",
763 op.id,
764 i,
765 t.to_string(),
766 ta.to_string(),
767 )))
768 }
769 }
770 Err(err) => Err(SimpleError::new(format!(
771 "Operation `{}`: {}",
772 op.id, err.message
773 ))),
774 }?;
775 }
776 if let Err(err) = V::validate_op(op, function, module, program, rule, self) {
777 Err(SimpleError::new(format!(
778 "Operation `{}`: {}",
779 op.id, err.message
780 )))
781 } else {
782 Ok(())
783 }
784 } else {
785 Err(SimpleError::new(format!(
786 "Operation is not supported: {}",
787 op.id
788 )))
789 }
790 }
791
792 fn find_value_type(
793 &self,
794 value: &Value,
795 types: &ModuleTypeIDs,
796 functions: &ModuleFunctionIDs,
797 variables: &FunctionVariablesIDs,
798 program: &Program,
799 ) -> SimpleResult<Type> {
800 match value {
801 Value::Ref(ref v, ref a) => {
802 let t = Type::Pointer(Box::new(
803 self.find_value_type(v, types, functions, variables, program)?,
804 ));
805 if let Some(ref a) = a {
806 self.find_access_value_type(&t, a, types, program)
807 } else {
808 Ok(t)
809 }
810 }
811 Value::Deref(ref v, ref a) => {
812 let t = self.find_value_type(v, types, functions, variables, program)?;
813 if let Type::Pointer(t) = t {
814 if let Some(ref a) = a {
815 self.find_access_value_type(&t, a, types, program)
816 } else {
817 Ok(*t)
818 }
819 } else {
820 Err(SimpleError::new(format!(
821 "Trying to dereference non-pointer type: {}",
822 t.to_string()
823 )))
824 }
825 }
826 Value::FunctionCall(ref fc, _, ref a) => {
827 self.find_function_call_value_type(fc, a, functions, types, program)
828 }
829 Value::Tuple(ref t, ref a) => {
830 self.find_tuple_value_type(t, a, types, functions, variables, program)
831 }
832 Value::String(_, ref t) => Ok(t.clone()),
833 Value::Number(ref n) => Ok(match n {
834 Number::Integer(_, ref t) => t.clone(),
835 Number::Float(_, ref t) => t.clone(),
836 }),
837 Value::OperationInline(ref n, _, ref a) => {
838 self.find_operation_inline_value_type(n, a, types, program)
839 }
840 Value::Variable(ref id, ref a) => {
841 if let Some(t) = variables.iter().find(|v| v.0 == id) {
842 if let Some(ref a) = a {
843 self.find_access_value_type(&t.1, a, types, program)
844 } else {
845 Ok(t.1.clone())
846 }
847 } else {
848 Err(SimpleError::new(format!(
849 "Could not find variable `{}` in scope",
850 id
851 )))
852 }
853 }
854 }
855 }
856
857 fn find_function_call_value_type(
858 &self,
859 id: &str,
860 access: &Option<Box<Access>>,
861 functions: &ModuleFunctionIDs,
862 types: &ModuleTypeIDs,
863 program: &Program,
864 ) -> SimpleResult<Type> {
865 if let Some(t) = functions.get(id) {
866 if let Some(t) = t {
867 if let Some(a) = access {
868 self.find_access_value_type(t, a, types, program)
869 } else {
870 Ok(t.clone())
871 }
872 } else if access.is_none() {
873 Ok(Type::default())
874 } else {
875 Err(SimpleError::new("Trying to access empty type".to_owned()))
876 }
877 } else {
878 Err(SimpleError::new(format!(
879 "Trying to call unknown function: {:?}",
880 id
881 )))
882 }
883 }
884
885 fn find_tuple_value_type(
886 &self,
887 values: &[Value],
888 access: &Option<Box<Access>>,
889 types: &ModuleTypeIDs,
890 functions: &ModuleFunctionIDs,
891 variables: &FunctionVariablesIDs,
892 program: &Program,
893 ) -> SimpleResult<Type> {
894 let result = Type::Tuple(
895 values
896 .iter()
897 .map(|t| self.find_value_type(t, types, functions, variables, program))
898 .collect::<Result<Vec<Type>, SimpleError>>()?,
899 );
900 if let Some(ref a) = access {
901 self.find_access_value_type(&result, a, types, program)
902 } else {
903 Ok(result)
904 }
905 }
906
907 fn find_access_value_type(
908 &self,
909 typeid: &Type,
910 access: &Access,
911 types: &ModuleTypeIDs,
912 program: &Program,
913 ) -> SimpleResult<Type> {
914 match access {
915 Access::Tuple(i, a) => match typeid {
916 Type::Tuple(ref t) => {
917 let i = *i as usize;
918 if i < t.len() {
919 if let Some(ref a) = a {
920 self.find_access_value_type(&t[i], a, types, program)
921 } else {
922 Ok(t[i].clone())
923 }
924 } else {
925 Err(SimpleError::new(format!(
926 "Tuple does not have field #{}",
927 i
928 )))
929 }
930 }
931 _ => Err(SimpleError::new(
932 "Only tuples can be accessed by index".to_owned(),
933 )),
934 },
935 Access::Variable(id, a) => match typeid {
936 Type::Identifier(ref i) => {
937 if let Some(m) = types.get(i).unwrap() {
938 if let Some(s) = program.find_module_struct(m, i) {
939 if let Some(v) = s.fields.iter().find(|v| &v.id == id) {
940 if let Some(a) = a {
941 self.find_access_value_type(&v.typeid, a, types, program)
942 } else {
943 Ok(v.typeid.clone())
944 }
945 } else {
946 Err(SimpleError::new(format!(
947 "Could not find field `{}` in type: {:?}",
948 id, s.id
949 )))
950 }
951 } else {
952 Err(SimpleError::new(format!(
953 "Atomic struct {} does not have any fields",
954 i
955 )))
956 }
957 } else {
958 Err(SimpleError::new(format!(
959 "Atomic struct {} does not have any fields",
960 i
961 )))
962 }
963 }
964 _ => Err(SimpleError::new(
965 "Only structs can be accessed by variable".to_owned(),
966 )),
967 },
968 }
969 }
970
971 fn find_operation_inline_value_type(
972 &self,
973 id: &str,
974 access: &Option<Box<Access>>,
975 types: &ModuleTypeIDs,
976 program: &Program,
977 ) -> SimpleResult<Type> {
978 if let Some(rule) = self.rules.iter().find(|r| r.id == id) {
979 if rule.targets.len() == 1 {
980 if let Some(a) = access {
981 self.find_access_value_type(&rule.targets[0], a, types, program)
982 } else {
983 Ok(rule.targets[0].clone())
984 }
985 } else {
986 Err(SimpleError::new(format!(
987 "Trying to inline operation of not one target: {}",
988 id
989 )))
990 }
991 } else {
992 Err(SimpleError::new(format!(
993 "Trying to inline unknown operation: {}",
994 id
995 )))
996 }
997 }
998}