1use std::{collections::{HashMap, HashSet, VecDeque}, error::Error, rc::Rc};
2
3use crate::parsing::{ast::{expression::{BinaryOperator, IdentExpression, OptionalIdentifier, PConditionBody, PExpression, Parameter, PathIdent, UnaryOperator}, statement::{AssignmentName, DeclarationName, PStatement}, top_level::{BasicBody, Body, Bundle, Extension, FunctionSignature, MemberFunction, PFunction, Struct, ThisArg, TopLevel}, r#type::{forwarded_type_args, CortexType, TupleType, TypeError}}, codegen::r#trait::SimpleCodeGen};
4
5use super::{ast::{expression::RExpression, function::{FunctionDict, RBody, RFunction, RInterpretedBody}, function_address::FunctionAddress, statement::{RConditionBody, RStatement}}, error::PreprocessingError, module::{Module, ModuleError, TypeDefinition}, program::Program, type_checking_env::TypeCheckingEnvironment, type_env::TypeEnvironment};
6
7type CortexError = Box<dyn Error>;
8pub type CheckResult<T> = Result<(T, CortexType), CortexError>;
9
10pub struct CortexPreprocessor {
11 current_env: Option<Box<TypeCheckingEnvironment>>,
12 current_context: PathIdent,
13 current_type_env: Option<Box<TypeEnvironment>>,
14 function_dict: FunctionDict,
15 function_signature_map: HashMap<FunctionAddress, FunctionSignature>,
16 type_map: HashMap<PathIdent, TypeDefinition>,
17 loop_depth: u32,
18 temp_num: usize,
19}
20
21impl CortexPreprocessor {
22 pub fn new() -> Result<Self, CortexError> {
23 let mut this = CortexPreprocessor {
24 current_env: Some(Box::new(TypeCheckingEnvironment::base())),
25 current_context: PathIdent::empty(),
26 current_type_env: Some(Box::new(TypeEnvironment::base())),
27 function_dict: FunctionDict::new(),
28 function_signature_map: HashMap::new(),
29 type_map: HashMap::new(),
30 loop_depth: 0,
31 temp_num: 0,
32 };
33
34 macro_rules! add_core_type {
35 ($name:literal) => {
36 this.type_map.insert(PathIdent::simple(String::from($name)), TypeDefinition { fields: HashMap::new(), type_param_names: Vec::new(), is_heap_allocated: false });
37 }
38 }
39
40 add_core_type!("number");
41 add_core_type!("bool");
42 add_core_type!("string");
43 add_core_type!("void");
44 add_core_type!("none");
45
46 let mut global_module = Module::new();
47 Self::add_list_funcs(&mut global_module)?;
48 Self::add_string_funcs(&mut global_module)?;
49 Self::add_range_funcs(&mut global_module)?;
50
51 this.register_module(&PathIdent::empty(), global_module)?;
52
53 Ok(this)
54 }
55
56 pub(crate) fn get_function(&self, id: usize) -> Option<&Rc<RFunction>> {
57 self.function_dict.get(id)
58 }
59
60 pub(crate) fn determine_type(&mut self, expr: PExpression) -> Result<CortexType, CortexError> {
61 let (_, typ) = self.check_exp(expr)?;
62 Ok(typ)
63 }
64
65 pub fn run_top_level(&mut self, top_level: TopLevel) -> Result<(), CortexError> {
66 match top_level {
67 TopLevel::Import { name: _, is_string_import: _ } => {
68 todo!("Imports are currently not supported!")
69 },
70 TopLevel::Module { name, contents } => {
71 let module = Self::construct_module(contents)?;
72 self.register_module(&PathIdent::simple(name), module)?;
73 Ok(())
74 },
75 TopLevel::Function(function) => {
76 match &function.name {
77 OptionalIdentifier::Ident(func_name) => {
78 let addr = FunctionAddress {
79 own_module_path: PathIdent::simple(func_name.clone()),
80 target: None,
81 };
82 self.add_signature(&addr, &function)?;
83 self.add_function(addr, function)?;
84 Ok(())
85 },
86 OptionalIdentifier::Ignore => Ok(()),
87 }
88 },
89 TopLevel::Struct(struc) => {
90 let mut funcs = Vec::new();
91 self.add_struct(PathIdent::empty(), struc, &mut funcs)?;
92 for (addr, f) in &funcs {
93 self.add_signature(addr, &f)?;
94 }
95 for (addr, f) in funcs {
96 self.add_function(addr, f)?;
97 }
98 Ok(())
99 },
100 TopLevel::Bundle(bundle) => {
101 let mut funcs = Vec::new();
102 self.add_bundle(PathIdent::empty(), bundle, &mut funcs)?;
103 for (addr, f) in &funcs {
104 self.add_signature(addr, &f)?;
105 }
106 for (addr, f) in funcs {
107 self.add_function(addr, f)?;
108 }
109 Ok(())
110 },
111 TopLevel::Extension(extension) => {
112 let mut funcs = Vec::new();
113 self.add_extension(PathIdent::empty(), extension, &mut funcs)?;
114 for (addr, f) in &funcs {
115 self.add_signature(addr, &f)?;
116 }
117 for (addr, f) in funcs {
118 self.add_function(addr, f)?;
119 }
120 Ok(())
121 }
122 }
123 }
124
125 pub fn register_module(&mut self, path: &PathIdent, mut module: Module) -> Result<(), CortexError> {
126 for (path_end, m) in module.children_iter() {
127 let this_path = PathIdent::continued(path.clone(), path_end);
128 self.register_module(&this_path, m)?;
129 }
130
131 let mut functions = module
132 .take_functions()?
133 .into_iter()
134 .map(|f| {
135 match &f.name {
136 OptionalIdentifier::Ident(func_name) => {
137 let addr = FunctionAddress {
138 own_module_path: PathIdent::continued(path.clone(), func_name.clone()),
139 target: None,
140 };
141 Some((addr, f))
142 },
143 OptionalIdentifier::Ignore => None,
144 }
145 })
146 .filter_map(|x| x)
147 .collect::<Vec<(FunctionAddress, PFunction)>>();
148 let structs = module.take_structs()?;
149 let bundles = module.take_bundles()?;
150 let extensions = module.take_extensions()?;
151
152 let context_to_return_to = std::mem::replace(&mut self.current_context, path.clone());
153
154 for item in structs {
155 self.add_struct(path.clone(), item, &mut functions)?;
156 }
157
158 for item in bundles {
159 self.add_bundle(path.clone(), item, &mut functions)?;
160 }
161
162 for item in extensions {
163 self.add_extension(path.clone(), item, &mut functions)?;
164 }
165
166 for (addr, f) in &functions {
167 self.add_signature(addr, &f)?;
168 }
169
170 for (addr, f) in functions {
171 self.add_function(addr, f)?;
172 }
173
174 self.current_context = context_to_return_to;
175
176 Ok(())
177 }
178
179 fn add_signature(&mut self, addr: &FunctionAddress, f: &PFunction) -> Result<(), CortexError> {
180 let sig = f.signature();
181 if self.function_signature_map.contains_key(&addr) {
182 return Err(Box::new(ModuleError::FunctionAlreadyExists(addr.own_module_path.codegen(0))));
183 }
184 let mut seen_type_param_names = HashSet::new();
185 for t in &sig.type_param_names {
186 if seen_type_param_names.contains(t) {
187 return Err(Box::new(ModuleError::DuplicateTypeArgumentName(t.clone())));
188 }
189 seen_type_param_names.insert(t);
190 }
191 self.function_signature_map.insert(addr.clone(), sig);
192 Ok(())
193 }
194 fn add_function(&mut self, addr: FunctionAddress, f: PFunction) -> Result<(), CortexError> {
195 let name = f.name().clone();
196 let processed = self.preprocess_function(f)?;
197 match name {
198 OptionalIdentifier::Ident(_) => {
199 self.function_dict.add_function(addr, processed);
200 },
201 OptionalIdentifier::Ignore => {},
202 }
203 Ok(())
204 }
205
206 fn add_struct(&mut self, n: PathIdent, item: Struct, funcs_to_add: &mut Vec<(FunctionAddress, PFunction)>) -> Result<(), CortexError> {
207 match &item.name {
208 OptionalIdentifier::Ident(item_name) => {
209 let full_path = PathIdent::continued(n.clone(), item_name.clone());
210 if self.has_type(&full_path) {
211 Err(Box::new(ModuleError::TypeAlreadyExists(full_path.codegen(0))))
212 } else {
213 let has_loop = self.search_struct_for_loops(&item)?;
214 if has_loop {
215 return Err(Box::new(PreprocessingError::StructContainsCircularFields(full_path.codegen(0))));
216 }
217
218 Self::handle_member_functions(item.functions, n, &item.type_param_names, item_name, funcs_to_add)?;
219
220 let mut seen_type_param_names = HashSet::new();
221 for t in &item.type_param_names {
222 if seen_type_param_names.contains(t) {
223 return Err(Box::new(ModuleError::DuplicateTypeArgumentName(t.clone())));
224 }
225 seen_type_param_names.insert(t);
226 }
227
228 self.type_map.insert(full_path, TypeDefinition {
229 fields: item.fields,
230 is_heap_allocated: false,
231 type_param_names: item.type_param_names,
232 });
233 Ok(())
234 }
235 },
236 OptionalIdentifier::Ignore => Ok(()),
237 }
238 }
239 fn add_bundle(&mut self, n: PathIdent, item: Bundle, funcs_to_add: &mut Vec<(FunctionAddress, PFunction)>) -> Result<(), CortexError> {
240 match &item.name {
241 OptionalIdentifier::Ident(item_name) => {
242 let full_path = PathIdent::continued(n.clone(), item_name.clone());
243 if self.has_type(&full_path) {
244 Err(Box::new(ModuleError::TypeAlreadyExists(full_path.codegen(0))))
245 } else {
246 Self::handle_member_functions(item.functions, n, &item.type_param_names, item_name, funcs_to_add)?;
247
248 let mut seen_type_param_names = HashSet::new();
249 for t in &item.type_param_names {
250 if seen_type_param_names.contains(t) {
251 return Err(Box::new(ModuleError::DuplicateTypeArgumentName(t.clone())));
252 }
253 seen_type_param_names.insert(t);
254 }
255
256 self.type_map.insert(full_path, TypeDefinition {
257 fields: item.fields,
258 is_heap_allocated: true,
259 type_param_names: item.type_param_names,
260 });
261 Ok(())
262 }
263 },
264 OptionalIdentifier::Ignore => Ok(()),
265 }
266 }
267 fn handle_member_functions(functions: Vec<MemberFunction>, n: PathIdent, item_type_param_names: &Vec<String>, item_name: &String, funcs_to_add: &mut Vec<(FunctionAddress, PFunction)>) -> Result<(), CortexError> {
268 for func in functions {
269 match func.name {
270 OptionalIdentifier::Ident(func_name) => {
271 let new_param = Parameter::named("this", Self::this_arg_to_type(func.this_arg, item_name, item_type_param_names));
272 let mut param_list = vec![new_param];
273 param_list.extend(func.params);
274 let mut type_param_names = func.type_param_names;
275 let intersecting_type_param = item_type_param_names.iter().find(|t| type_param_names.contains(t));
276 if let Some(name) = intersecting_type_param {
277 return Err(Box::new(ModuleError::DuplicateTypeArgumentName(name.clone())));
278 }
279 type_param_names.extend(item_type_param_names.clone());
280 let new_func = PFunction::new(
281 OptionalIdentifier::Ident(func_name.clone()),
282 param_list,
283 func.return_type,
284 func.body,
285 type_param_names,
286 );
287 let addr = FunctionAddress {
288 own_module_path: PathIdent::continued(n.clone(), func_name),
289 target: Some(PathIdent::continued(n.clone(), item_name.clone())),
290 };
291 funcs_to_add.push((addr, new_func));
292 },
293 OptionalIdentifier::Ignore => (),
294 }
295 }
296 Ok(())
297 }
298
299 fn add_extension(&mut self, n: PathIdent, item: Extension, funcs_to_add: &mut Vec<(FunctionAddress, PFunction)>) -> Result<(), CortexError> {
300 let item_name = item.name.get_back()?;
301 let item_prefix = item.name.without_last();
302 for func in item.functions {
303 match func.name {
304 OptionalIdentifier::Ident(func_name) => {
305 let new_param = Parameter::named("this", Self::this_arg_to_type(func.this_arg, item_name, &item.type_param_names).with_prefix(&item_prefix));
306 let mut param_list = vec![new_param];
307 param_list.extend(func.params);
308 let mut type_param_names = func.type_param_names;
309 let intersecting_type_param = item.type_param_names.iter().find(|t| type_param_names.contains(t));
310 if let Some(name) = intersecting_type_param {
311 return Err(Box::new(ModuleError::DuplicateTypeArgumentName(name.clone())));
312 }
313 type_param_names.extend(item.type_param_names.clone());
314 let new_func = PFunction::new(
315 OptionalIdentifier::Ident(func_name.clone()),
316 param_list,
317 func.return_type,
318 func.body,
319 type_param_names,
320 );
321 let addr = FunctionAddress {
322 own_module_path: PathIdent::continued(n.clone(), func_name),
323 target: Some(PathIdent::concat(&n, &item.name)),
324 };
325 funcs_to_add.push((addr, new_func));
326 },
327 OptionalIdentifier::Ignore => (),
328 }
329 }
330 Ok(())
331 }
332
333 fn this_arg_to_type(this_arg: ThisArg, item_name: &String, type_param_names: &Vec<String>) -> CortexType {
334 match this_arg {
335 ThisArg::RefThis =>
336 CortexType::reference(
337 CortexType::basic(PathIdent::simple(item_name.clone()), false, forwarded_type_args(type_param_names)),
338 false,
339 ),
340 ThisArg::RefMutThis =>
341 CortexType::reference(
342 CortexType::basic(PathIdent::simple(item_name.clone()), false, forwarded_type_args(type_param_names)),
343 true,
344 ),
345 ThisArg::DirectThis => CortexType::basic(PathIdent::simple(item_name.clone()), false, forwarded_type_args(type_param_names)),
346 }
347 }
348
349 pub fn preprocess(&mut self, body: BasicBody) -> Result<Program, CortexError> {
350 let (body, _) = self.check_body(body)?;
351 Ok(Program { code: body })
352 }
353
354 fn construct_module(contents: Vec<TopLevel>) -> Result<Module, CortexError> {
355 let mut module = Module::new();
356 for item in contents.into_iter() {
357 match item {
358 TopLevel::Import { name: _, is_string_import: _ } => todo!("Imports are currently not supported!"),
359 TopLevel::Module { name: submod_name, contents } => {
360 let new_module = Self::construct_module(contents)?;
361 module.add_child(submod_name, new_module)?;
362 },
363 TopLevel::Function(function) => {
364 module.add_function(function)?;
365 },
366 TopLevel::Struct(item) => {
367 module.add_struct(item)?;
368 },
369 TopLevel::Bundle(item) => {
370 module.add_bundle(item)?;
371 },
372 TopLevel::Extension(item) => {
373 module.add_extension(item)?;
374 },
375 }
376 }
377 Ok(module)
378 }
379
380 pub fn preprocess_function(&mut self, function: PFunction) -> Result<RFunction, CortexError> {
381 let parent_env = self.current_env.take().ok_or(PreprocessingError::NoParentEnv)?;
382 let mut new_env = TypeCheckingEnvironment::new(*parent_env);
383 let mut params = Vec::new();
384 for p in function.params {
385 let param_type = self.clean_type(p.typ.clone().with_prefix_if_not_core(&self.current_context));
386 new_env.add(p.name.clone(), param_type, false)?;
387 params.push(p.name);
388 }
389 self.current_env = Some(Box::new(new_env));
390
391 let final_fn_body;
393 match function.body {
394 Body::Basic(body) => {
395 let (new_body, body_type) = self.check_body(body)?;
396 let return_type = self.clean_type(function.return_type.clone().with_prefix_if_not_core(&self.current_context));
397 if !body_type.is_subtype_of(&return_type) {
398 return Err(Box::new(PreprocessingError::ReturnTypeMismatch(return_type.codegen(0), body_type.codegen(0))));
399 }
400 final_fn_body = RBody::Interpreted(new_body);
401 },
402 Body::Native(native_body) => {
403 final_fn_body = RBody::Native(native_body);
404 },
405 }
406
407 self.current_env = Some(Box::new(self.current_env.take().unwrap().exit()?));
408
409 Ok(RFunction::new(params, final_fn_body))
410 }
411
412 fn check_statement(&mut self, statement: PStatement) -> Result<Vec<RStatement>, CortexError> {
413 let st_str = statement.codegen(0);
414 match statement {
415 PStatement::Expression(expression) => {
416 let (exp, _) = self.check_exp(expression)?;
417 Ok(vec![RStatement::Expression(exp)])
418 },
419 PStatement::Throw(expression) => {
420 let (exp, _) = self.check_exp(expression)?;
421 Ok(vec![RStatement::Throw(exp)])
422 },
423 PStatement::VariableDeclaration { name, is_const, typ, initial_value } => {
424 Ok(self.check_declaration_recursive(name, typ, is_const, initial_value, &st_str)?)
425 },
426 PStatement::Assignment { name, value } => {
427 Ok(self.check_assignment_recursive(name, value, &st_str)?)
428 },
429 PStatement::WhileLoop(condition_body) => {
430 let (cond, cond_type) = self.check_exp(condition_body.condition)?;
431 if !cond_type.is_subtype_of(&CortexType::boolean(false)) {
432 return Err(
433 Box::new(
434 PreprocessingError::MismatchedType(
435 String::from("bool"),
436 cond_type.codegen(0),
437 String::from("while condition"),
438 st_str,
439 )
440 )
441 );
442 }
443
444 self.loop_depth += 1;
445 let (body, body_type) = self.check_body_and_handle_env(condition_body.body)?;
446 if !body_type.is_subtype_of(&CortexType::void(false)) {
447 return Err(
448 Box::new(
449 PreprocessingError::LoopCannotHaveReturnValue
450 )
451 );
452 }
453 self.loop_depth -= 1;
454
455 Ok(vec![RStatement::WhileLoop(RConditionBody::new(cond, body))])
456 },
457 PStatement::Break => {
458 if self.loop_depth <= 0 {
459 Err(Box::new(PreprocessingError::BreakUsedInNonLoopContext))
460 } else {
461 Ok(vec![RStatement::Break])
462 }
463 },
464 PStatement::Continue => {
465 if self.loop_depth <= 0 {
466 Err(Box::new(PreprocessingError::ContinueUsedInNonLoopContext))
467 } else {
468 Ok(vec![RStatement::Continue])
469 }
470 },
471 }
472 }
473
474 fn check_declaration(&mut self, name: OptionalIdentifier, typ: Option<CortexType>, is_const: bool, initial_value: PExpression, st_str: &String) -> Result<Vec<RStatement>, CortexError> {
475 match name {
476 OptionalIdentifier::Ident(ident) => {
477 let (assigned_exp, assigned_type) = self.check_exp(initial_value)?;
478 let type_of_var = if let Some(mut declared_type) = typ {
479 declared_type = self.clean_type(declared_type.with_prefix_if_not_core(&self.current_context));
480 if !assigned_type.is_subtype_of(&declared_type) {
481 return Err(
482 Box::new(
483 PreprocessingError::MismatchedType(
484 declared_type.codegen(0),
485 assigned_type.codegen(0),
486 ident.clone(),
487 st_str.clone(),
488 )
489 )
490 );
491 }
492 declared_type.clone()
493 } else {
494 assigned_type
495 };
496
497 self.current_env.as_mut().unwrap().add(ident.clone(), type_of_var, is_const)?;
498
499 Ok(vec![RStatement::VariableDeclaration { name: ident, is_const: is_const, initial_value: assigned_exp }])
500 },
501 OptionalIdentifier::Ignore => {
502 let (exp, _) = self.check_exp(initial_value)?;
503 Ok(vec![RStatement::Expression(exp)])
504 },
505 }
506 }
507 fn check_declaration_recursive(&mut self, name: DeclarationName, typ: Option<CortexType>, is_const: bool, initial_value: PExpression, st_str: &String) -> Result<Vec<RStatement>, CortexError> {
508 match name {
509 DeclarationName::Single(name) => {
510 Ok(self.check_declaration(name, typ, is_const, initial_value, &st_str)?)
511 },
512 DeclarationName::Tuple(names) => {
513 let mut result = Vec::new();
514 let temp_name = self.next_temp();
516 let var_dec = self.check_statement(PStatement::VariableDeclaration {
518 name: DeclarationName::Single(OptionalIdentifier::Ident(temp_name.clone())),
519 is_const: true,
520 typ,
521 initial_value,
522 })?;
523 result.extend(var_dec);
524 let temp_expr = PExpression::PathIdent(PathIdent::simple(temp_name));
525 for (i, name) in names.into_iter().enumerate() {
526 let new_value = PExpression::MemberAccess(Box::new(temp_expr.clone()), format!("t{}", i));
527 result.extend(self.check_declaration_recursive(name, None, is_const, new_value, &st_str)?);
528 }
529 Ok(result)
530 },
531 }
532 }
533
534 fn check_assignment(&mut self, name: IdentExpression, value: PExpression, st_str: &String) -> Result<Vec<RStatement>, CortexError> {
535 let (assigned_exp, assigned_type) = self.check_exp(value)?;
536 if name.is_simple() {
537 let var_name = &name.base;
538 let var_type = &self.current_env.as_ref().unwrap().get(var_name)?.clone();
539 if !assigned_type.is_subtype_of(var_type) {
540 return Err(
541 Box::new(
542 PreprocessingError::MismatchedType(
543 var_type.codegen(0),
544 assigned_type.codegen(0),
545 var_name.clone(),
546 st_str.clone(),
547 )
548 )
549 );
550 }
551
552 if self.current_env.as_ref().unwrap().is_const(var_name)? {
553 return Err(
554 Box::new(
555 PreprocessingError::CannotModifyConst(var_name.clone())
556 )
557 )
558 }
559 } else {
560 let source_expr = name.clone().without_last()?.to_member_access_expr();
561 let (_, source_type) = self.check_exp(source_expr)?;
562 if let CortexType::RefType(r) = source_type {
563 if !r.mutable {
564 return Err(
565 Box::new(
566 PreprocessingError::CannotModifyFieldOnImmutableReference(r.contained.codegen(0))
567 )
568 );
569 }
570 }
571
572 let name_expr = name.clone().to_member_access_expr();
573 let (_, var_type) = self.check_exp(name_expr)?;
574 if !assigned_type.is_subtype_of(&var_type) {
575 return Err(
576 Box::new(
577 PreprocessingError::MismatchedType(
578 var_type.codegen(0),
579 assigned_type.codegen(0),
580 name.codegen(0),
581 st_str.clone(),
582 )
583 )
584 );
585 }
586 }
587
588 Ok(vec![RStatement::Assignment { name: name.into(), value: assigned_exp }])
589 }
590 fn check_assignment_recursive(&mut self, name: AssignmentName, value: PExpression, st_str: &String) -> Result<Vec<RStatement>, CortexError> {
591 match name {
592 AssignmentName::Single(name) => {
593 Ok(self.check_assignment(name, value, &st_str)?)
594 },
595 AssignmentName::Ignore => {
596 Ok(self.check_statement(PStatement::Expression(value))?)
597 },
598 AssignmentName::Tuple(names) => {
599 let mut result = Vec::new();
600 let temp_name = self.next_temp();
602 let var_dec = self.check_statement(PStatement::VariableDeclaration {
604 name: DeclarationName::Single(OptionalIdentifier::Ident(temp_name.clone())),
605 is_const: true,
606 typ: None,
607 initial_value: value,
608 })?;
609 result.extend(var_dec);
610 let temp_expr = PExpression::PathIdent(PathIdent::simple(temp_name));
611 for (i, name) in names.into_iter().enumerate() {
612 let new_value = PExpression::MemberAccess(Box::new(temp_expr.clone()), format!("t{}", i));
613 result.extend(self.check_assignment_recursive(name, new_value, &st_str)?);
614 }
615 Ok(result)
616 },
617 }
618 }
619
620 fn check_exp(&mut self, exp: PExpression) -> CheckResult<RExpression> {
621 let st_str = exp.codegen(0);
622 match exp {
623 PExpression::Number(v) => Ok((RExpression::Number(v), CortexType::number(false))),
624 PExpression::Boolean(v) => Ok((RExpression::Boolean(v), CortexType::boolean(false))),
625 PExpression::Void => Ok((RExpression::Void, CortexType::void(false))),
626 PExpression::None => Ok((RExpression::None, CortexType::none())),
627 PExpression::String(v) => Ok((RExpression::String(v), CortexType::string(false))),
628 PExpression::Char(v) => Ok((RExpression::Char(v), CortexType::char(false))),
629 PExpression::PathIdent(path_ident) => Ok((RExpression::Identifier(path_ident.get_back()?.clone()), self.get_variable_type(&path_ident)?)),
630 PExpression::Call { name: addr, args: arg_exps, type_args } => {
631 let prefix = addr.without_last();
632 let result = self.check_call(
633 addr.get_back()?,
634 arg_exps,
635 type_args,
636 prefix,
637 &st_str
638 );
639 result
640 },
641 PExpression::Construction { name, type_args, assignments } => {
642 self.check_construction(name, type_args, assignments, &st_str)
643 },
644 PExpression::IfStatement { first, conds, last } => {
645 self.check_if_statement(*first, conds, last.map(|b| *b), &st_str)
646 },
647 PExpression::UnaryOperation { op, exp } => {
648 let (exp, typ) = self.check_exp(*exp)?;
649 match op {
650 UnaryOperator::Negate => {
651 if typ == CortexType::number(false) {
652 Ok((RExpression::UnaryOperation { op: UnaryOperator::Negate, exp: Box::new(exp) }, CortexType::number(false)))
653 } else {
654 Err(Box::new(PreprocessingError::InvalidOperatorUnary("number")))
655 }
656 },
657 UnaryOperator::Invert => {
658 if typ == CortexType::boolean(false) {
659 Ok((RExpression::UnaryOperation { op: UnaryOperator::Invert, exp: Box::new(exp) }, CortexType::boolean(false)))
660 } else {
661 Err(Box::new(PreprocessingError::InvalidOperatorUnary("bool")))
662 }
663 },
664 }
665 },
666 PExpression::ListLiteral(items) => {
667 let mut contained_type = CortexType::Unknown(false);
668 let mut new_items = Vec::new();
669 for item in items {
670 let (item_exp, item_type) = self.check_exp(item)?;
671 let item_type_str = item_type.codegen(0);
672 let typ_str = contained_type.codegen(0);
673 contained_type = contained_type
674 .combine_with(item_type)
675 .ok_or(PreprocessingError::CannotDetermineListLiteralType(typ_str, item_type_str))?;
676 new_items.push(item_exp);
677 }
678 let true_type = CortexType::reference(CortexType::list(contained_type, false), true);
679 Ok((RExpression::ListLiteral(new_items), true_type))
680 },
681 PExpression::Bang(inner) => {
682 let (exp, typ) = self.check_exp(*inner)?;
683 Ok((RExpression::Bang(Box::new(exp)), typ.to_non_optional()))
684 },
685 PExpression::MemberAccess(inner, member) => {
686 let inner_as_string = inner.codegen(0);
687 let (atom_exp, atom_type) = self.check_exp(*inner)?;
688 match &atom_type {
689 CortexType::BasicType(_) |
690 CortexType::RefType(_) => {
691 if atom_type.is_non_composite() {
692 return Err(Box::new(PreprocessingError::CannotAccessMemberOfNonComposite));
693 }
694 if atom_type.optional() {
695 return Err(Box::new(PreprocessingError::CannotAccessMemberOfOptional(inner_as_string)));
696 }
697 Ok(self.check_composite_member_access(atom_exp, atom_type, member)?)
698 },
699 CortexType::Unknown(_) => Err(Box::new(TypeError::UnknownTypeNotValid)),
700 CortexType::TupleType(t) => {
701 if t.optional {
702 return Err(Box::new(PreprocessingError::CannotAccessMemberOfOptional(inner_as_string)));
703 }
704 Ok(self.check_tuple_member_access(atom_exp, t, member)?)
705 },
706 }
707 },
708 PExpression::MemberCall { callee, member, mut args, type_args } => {
709 let (_, atom_type) = self.check_exp(*callee.clone())?;
710
711 let caller_type = atom_type.name()?;
712 let caller_type_prefix = caller_type.without_last();
713 let non_extension_func_addr = FunctionAddress::member_func(
714 PathIdent::continued(caller_type_prefix.clone().subtract(&self.current_context)?, member.clone()),
715 caller_type.clone().subtract(&self.current_context)?);
716
717 args.insert(0, *callee);
718 let true_type_args;
719 if let Some(mut type_args) = type_args {
720 let typedef = self.lookup_type(caller_type)?;
721 let mut bindings = HashMap::new();
722 self.infer_arg(&CortexType::reference(
723 CortexType::basic(caller_type.clone(), false, forwarded_type_args(&typedef.type_param_names)),
724 true,
725 ), &atom_type, &typedef.type_param_names, &mut bindings, &String::from("this"), &st_str)?;
726 let mut beginning_type_args = Vec::new();
727 for a in &typedef.type_param_names {
728 beginning_type_args.push(bindings.remove(a).unwrap());
729 }
730 type_args.extend(beginning_type_args);
731 true_type_args = Some(type_args);
732 } else {
733 true_type_args = None;
734 }
735
736 let actual_func_addr;
737 if self.has_function(&non_extension_func_addr) {
738 actual_func_addr = non_extension_func_addr;
739 } else {
740 let attempted_extension_path = self.search_for_extension(&caller_type, &member)?;
741 if let Some(extension_func_path) = attempted_extension_path {
742 actual_func_addr = extension_func_path.clone();
743 } else {
744 return Err(Box::new(PreprocessingError::FunctionDoesNotExist(non_extension_func_addr.codegen(0))));
745 }
746 }
747
748 let call_exp = PExpression::Call {
749 name: actual_func_addr,
750 args,
751 type_args: true_type_args,
752 };
753 let result = self.check_exp(call_exp)?;
754 Ok(result)
755 },
756 PExpression::BinaryOperation { left, op, right } => {
757 let (left_exp, left_type) = self.check_exp(*left)?;
758 let (right_exp, right_type) = self.check_exp(*right)?;
759 let op_type = self.check_operator(left_type, &op, right_type)?;
760 Ok((RExpression::BinaryOperation { left: Box::new(left_exp), op: op, right: Box::new(right_exp) }, op_type))
761 },
762 PExpression::Tuple(items) => {
763 let results = items
764 .into_iter()
765 .map(|e| self.check_exp(e))
766 .collect::<Result<Vec<_>, _>>()?;
767 let (exps, types): (Vec<RExpression>, Vec<CortexType>) = results.into_iter().unzip();
768 Ok((RExpression::Tuple(exps), CortexType::tuple(types, false)))
769 },
770 PExpression::Range { start, end, step } => {
771 fn otov(o: Option<f64>) -> RExpression {
772 match o {
773 Some(v) => RExpression::Number(v),
774 None => RExpression::None,
775 }
776 }
777 let construction = RExpression::Construction {
778 assignments: vec![
779 (String::from("start"), otov(start)),
780 (String::from("end"), otov(end)),
781 (String::from("step"), otov(step)),
782 ],
783 is_heap_allocated: false,
784 };
785 Ok((construction, CortexType::range(false)))
786 },
787 }
788 }
789 fn check_composite_member_access(&mut self, atom_exp: RExpression, atom_type: CortexType, member: String) -> CheckResult<RExpression> {
790 let is_mutable;
791 match &atom_type {
792 CortexType::BasicType(_) |
793 CortexType::TupleType(_) => {
794 is_mutable = true;
795 },
796 CortexType::RefType(r) => {
797 is_mutable = r.mutable;
798 },
799 CortexType::Unknown(_) => {
800 return Err(Box::new(PreprocessingError::UnknownTypeFound));
801 },
802 }
803 let typedef = self.lookup_type(&atom_type.name()?.clone().subtract(&self.current_context)?)?;
804 if !typedef.fields.contains_key(&member) {
805 Err(Box::new(PreprocessingError::FieldDoesNotExist(member.clone(), atom_type.codegen(0))))
806 } else {
807 let mut member_type = typedef.fields.get(&member).unwrap().clone();
808 let bindings = Self::get_bindings(&typedef.type_param_names, &atom_type)?;
809 let prefix = atom_type.prefix();
810 member_type = TypeEnvironment::fill(member_type,
811 &bindings
812 .into_iter()
813 .map(|(k, v)| (k, v.subtract_if_possible(&prefix)))
814 .collect::<HashMap<_, _>>()
815 );
816 member_type = member_type.with_prefix_if_not_core(&prefix);
817 member_type = member_type.forward_immutability(is_mutable);
818 Ok((RExpression::MemberAccess(Box::new(atom_exp), member), member_type))
819 }
820 }
821 fn check_tuple_member_access(&mut self, atom_exp: RExpression, atom_type: &TupleType, member: String) -> CheckResult<RExpression> {
822 fn strip_t(s: &str) -> Option<usize> {
823 s.strip_prefix('t')?.parse().ok()
824 }
825
826 let index = strip_t(&member).ok_or(PreprocessingError::TupleMemberSyntaxInvalid(member))?;
827 if index > atom_type.types.len() {
828 return Err(Box::new(PreprocessingError::TupleIndexValueInvalid(atom_type.types.len(), index)));
829 }
830
831 let member_type = atom_type.types.get(index).unwrap().clone();
832
833 Ok((RExpression::MemberAccess(Box::new(atom_exp), format!("t{}", index)), member_type))
834 }
835
836 fn search_for_extension(&self, typ: &PathIdent, member: &String) -> Result<Option<&FunctionAddress>, CortexError> {
837 let candidates = self.function_signature_map.keys().filter_map(|p| {
841 if p.own_module_path.is_prefixed_by(&self.current_context) {
843 if let Some(target) = &p.target {
845 if target == typ {
846 let back = p.own_module_path.get_back();
848 match back {
849 Ok(back_name) => {
850 if back_name == member {
851 return Some(Ok::<_, CortexError>(p));
852 }
853 },
854 Err(err) => {
855 return Some(Err(Box::new(err)));
856 },
857 }
858 }
859 }
860 }
861 None
862 }).collect::<Result<Vec<_>, _>>()?;
863
864 if candidates.len() > 1 {
865 Err(Box::new(PreprocessingError::AmbiguousExtensionCall(member.clone(), typ.codegen(0))))
866 } else {
867 Ok(candidates.get(0).cloned())
868 }
869 }
870
871 fn check_call(&mut self, addr: FunctionAddress, arg_exps: Vec<PExpression>, type_args: Option<Vec<CortexType>>, prefix: PathIdent, st_str: &String) -> CheckResult<RExpression> {
872 let provided_arg_count = arg_exps.len();
873 let mut processed_args = Vec::new();
874 let mut arg_types = Vec::new();
875 for a in arg_exps.into_iter() {
876 let (arg, typ) = self.check_exp(a)?;
877 arg_types.push(typ);
878 processed_args.push(arg);
879 }
880
881 let extended_prefix = PathIdent::concat(&self.current_context, &prefix);
882 let sig = self.lookup_signature(&FunctionAddress::concat(&prefix, &addr))?.clone();
883
884 let full_path = FunctionAddress::concat(&extended_prefix, &addr);
885 if provided_arg_count != sig.params.len() {
886 return Err(Box::new(
887 PreprocessingError::MismatchedArgumentCount(full_path.codegen(0), sig.params.len(), provided_arg_count)
888 ));
889 }
890
891 let mut return_type = sig
892 .return_type
893 .clone();
894
895 let mut param_names = Vec::<String>::with_capacity(sig.params.len());
896 let mut param_types = Vec::<CortexType>::with_capacity(sig.params.len());
897 for param in &sig.params {
898 param_names.push(param.name.clone());
899 param_types.push(param.typ.clone().with_prefix_if_not_core(&extended_prefix));
900 }
901
902 let bindings;
903 if let Some(type_args) = type_args {
904 bindings = sig.type_param_names.iter().cloned().zip(type_args).collect();
905 } else {
906 bindings = self.infer_type_args(&sig, &arg_types, &full_path, st_str)?;
907 }
908 let parent_type_env = self.current_type_env.take().ok_or(PreprocessingError::NoParentEnv)?;
909 let mut new_type_env = TypeEnvironment::new(*parent_type_env);
910 for (name, typ) in &bindings {
911 new_type_env.add(name.clone(), typ.clone());
912 }
913 self.current_type_env = Some(Box::new(new_type_env));
914
915 for (i, arg_type) in arg_types.into_iter().enumerate() {
916 let arg_type = self.clean_type(arg_type);
917 let param_type = self.clean_type(param_types.get(i).unwrap().clone());
918 if !arg_type.is_subtype_of(¶m_type) {
919 return Err(
920 Box::new(
921 PreprocessingError::MismatchedType(
922 param_type.codegen(0),
923 arg_type.codegen(0),
924 param_names.get(i).unwrap().clone(),
925 st_str.clone(),
926 )
927 )
928 );
929 }
930 }
931
932 return_type = self.clean_type(return_type)
933 .with_prefix_if_not_core(&extended_prefix);
934
935 self.current_type_env = Some(Box::new(self.current_type_env.take().unwrap().exit()?));
936
937 let func_id = self.function_dict.add_call(full_path)?;
938
939 Ok((RExpression::Call(func_id, processed_args), return_type))
940 }
941 fn check_construction(&mut self, name: PathIdent, type_args: Vec<CortexType>, assignments: Vec<(String, PExpression)>, st_str: &String) -> CheckResult<RExpression> {
942 let typedef = self.lookup_type(&name)?;
943 let base_type = CortexType::basic(name.clone(), false, type_args.clone()).with_prefix_if_not_core(&self.current_context);
944
945 if type_args.len() != typedef.type_param_names.len() {
946 return Err(Box::new(PreprocessingError::MismatchedTypeArgCount(name.codegen(0), typedef.type_param_names.len(), type_args.len())));
947 }
948 let mut fields_to_assign = Vec::new();
949 for k in typedef.fields.keys() {
950 fields_to_assign.push(k.clone());
951 }
952
953 let is_heap_allocated = typedef.is_heap_allocated;
954 let fields = typedef.fields.clone();
955
956 let bindings = TypeEnvironment::create_bindings(&typedef.type_param_names, &type_args);
957 let bindings = bindings
958 .iter()
959 .map(|(k, v)| (k.clone(), v.clone().subtract_if_possible(&name.without_last())))
960 .collect::<HashMap<_, _>>();
961 let mut new_assignments = Vec::new();
962 for (fname, fvalue) in assignments {
963 let opt_typ = fields
964 .get(&fname)
965 .map(|t| t.clone());
966 if let Some(typ) = opt_typ {
967 let field_type = TypeEnvironment::fill(typ, &bindings)
968 .with_prefix_if_not_core(&self.current_context)
969 .with_prefix_if_not_core(&name.without_last());
970 let (exp, assigned_type) = self.check_exp(fvalue)?;
971 if !assigned_type.is_subtype_of(&field_type) {
972 return Err(
973 Box::new(
974 PreprocessingError::MismatchedType(
975 field_type.codegen(0),
976 assigned_type.codegen(0),
977 fname.clone(),
978 st_str.clone(),
979 )
980 )
981 );
982 }
983
984 new_assignments.push((fname.clone(), exp));
985
986 let index_opt = fields_to_assign.iter().position(|x| *x == *fname);
987 if let Some(index) = index_opt {
988 fields_to_assign.remove(index);
989 } else {
990 return Err(Box::new(PreprocessingError::MultipleFieldAssignment(fname.clone())));
991 }
992 } else {
993 return Err(Box::new(PreprocessingError::FieldDoesNotExist(fname.clone(), name.codegen(0))));
994 }
995 }
996
997 if fields_to_assign.is_empty() {
998 if is_heap_allocated {
999 Ok((RExpression::Construction { assignments: new_assignments, is_heap_allocated: true }, CortexType::reference(base_type, true)))
1000 } else {
1001 Ok((RExpression::Construction { assignments: new_assignments, is_heap_allocated: false }, base_type))
1002 }
1003 } else {
1004 Err(Box::new(PreprocessingError::NotAllFieldsAssigned(name.codegen(0), fields_to_assign.join(","))))
1005 }
1006 }
1007 fn check_if_statement(&mut self, first: PConditionBody, conds: Vec<PConditionBody>, last: Option<BasicBody>, st_str: &String) -> CheckResult<RExpression> {
1008 let (cond_exp, cond_typ) = self.check_exp(first.condition)?;
1009 if cond_typ != CortexType::boolean(false) {
1010 return Err(
1011 Box::new(
1012 PreprocessingError::MismatchedType(
1013 String::from("bool"),
1014 cond_typ.codegen(0),
1015 String::from("if condition"),
1016 st_str.clone(),
1017 )
1018 )
1019 );
1020 }
1021 let (first_body, mut the_type) = self.check_body_and_handle_env(first.body)?;
1022
1023 let mut condition_bodies = Vec::<RConditionBody>::new();
1024 for c in conds {
1025 let (cond, cond_typ) = self.check_exp(c.condition)?;
1026 if !cond_typ.is_subtype_of(&CortexType::boolean(false)) {
1027 return Err(
1028 Box::new(
1029 PreprocessingError::MismatchedType(
1030 String::from("bool"),
1031 cond_typ.codegen(0),
1032 String::from("else-if condition"),
1033 st_str.clone(),
1034 )
1035 )
1036 );
1037 }
1038 let (body, typ) = self.check_body_and_handle_env(c.body)?;
1039 let the_type_str = the_type.codegen(0);
1040 let typ_str = typ.codegen(0);
1041 let next = the_type.combine_with(typ);
1042 if let Some(t) = next {
1043 the_type = t;
1044 condition_bodies.push(RConditionBody::new(cond, body));
1045 } else {
1046 return Err(Box::new(PreprocessingError::IfArmsDoNotMatch(the_type_str, typ_str)));
1047 }
1048 }
1049 let mut final_body = None;
1050 if let Some(fin) = last {
1051 let (body, typ) = self.check_body_and_handle_env(fin)?;
1052 final_body = Some(Box::new(body));
1053 let the_type_str = the_type.codegen(0);
1054 let typ_str = typ.codegen(0);
1055 let next = the_type.combine_with(typ);
1056 if let Some(t) = next {
1057 the_type = t;
1058 } else {
1059 return Err(Box::new(PreprocessingError::IfArmsDoNotMatch(the_type_str, typ_str)));
1060 }
1061 } else if the_type != CortexType::void(false) {
1062 return Err(Box::new(PreprocessingError::IfRequiresElseBlock));
1063 }
1064
1065 Ok((RExpression::IfStatement {
1066 first: Box::new(RConditionBody::new(cond_exp, first_body)),
1067 conds: condition_bodies,
1068 last: final_body,
1069 }, the_type))
1070 }
1071
1072 fn check_body_and_handle_env(&mut self, body: BasicBody) -> CheckResult<RInterpretedBody> {
1073 let parent_env = self.current_env.take().ok_or(PreprocessingError::NoParentEnv)?;
1074 self.current_env = Some(Box::new(TypeCheckingEnvironment::new(*parent_env)));
1075
1076 let result = self.check_body(body);
1077
1078 self.current_env = Some(Box::new(self.current_env.take().unwrap().exit()?));
1079 result
1080 }
1081
1082 fn check_body(&mut self, body: BasicBody) -> CheckResult<RInterpretedBody> {
1083 let mut statements = Vec::new();
1084 for st in body.statements {
1085 let s = self.check_statement(st)?;
1086 statements.extend(s);
1087 }
1088 if let Some(exp) = body.result {
1089 let (exp, typ) = self.check_exp(exp)?;
1090 Ok((RInterpretedBody::new(statements, Some(exp)), typ))
1091 } else {
1092 Ok((RInterpretedBody::new(statements, None), CortexType::void(false)))
1093 }
1094 }
1095
1096 fn check_operator(&self, first: CortexType, op: &BinaryOperator, second: CortexType) -> Result<CortexType, CortexError> {
1097 let number = CortexType::number(false);
1098 let string = CortexType::string(false);
1099 let boolean = CortexType::boolean(false);
1100 match op {
1101 BinaryOperator::Add => {
1102 if first == number && second == number {
1103 Ok(number)
1104 } else if first == string && second == string {
1105 Ok(string)
1106 } else {
1107 Err(Box::new(PreprocessingError::InvalidOperator("number, string", "number, string")))
1108 }
1109 },
1110 BinaryOperator::Subtract => {
1111 if first == number && second == number {
1112 Ok(number)
1113 } else {
1114 Err(Box::new(PreprocessingError::InvalidOperator("number", "number")))
1115 }
1116 },
1117 BinaryOperator::Multiply => {
1118 if first == number && second == number {
1119 Ok(number)
1120 } else if first == number && second == string {
1121 Ok(string)
1122 } else if first == string && second == number {
1123 Ok(string)
1124 } else {
1125 Err(Box::new(PreprocessingError::InvalidOperator("number", "string")))
1126 }
1127 },
1128 BinaryOperator::Divide => {
1129 if first == number && second == number {
1130 Ok(number)
1131 } else {
1132 Err(Box::new(PreprocessingError::InvalidOperator("number", "number")))
1133 }
1134 },
1135 BinaryOperator::Remainder => {
1136 if first == number && second == number {
1137 Ok(number)
1138 } else {
1139 Err(Box::new(PreprocessingError::InvalidOperator("number", "number")))
1140 }
1141 },
1142 BinaryOperator::LogicAnd => {
1143 if first == boolean && second == boolean {
1144 Ok(boolean)
1145 } else {
1146 Err(Box::new(PreprocessingError::InvalidOperator("boolean", "boolean")))
1147 }
1148 },
1149 BinaryOperator::LogicOr => {
1150 if first == boolean && second == boolean {
1151 Ok(boolean)
1152 } else {
1153 Err(Box::new(PreprocessingError::InvalidOperator("boolean", "boolean")))
1154 }
1155 },
1156 BinaryOperator::IsEqual => {
1157 Ok(boolean)
1158 },
1159 BinaryOperator::IsNotEqual => {
1160 Ok(boolean)
1161 },
1162 BinaryOperator::IsLessThan => {
1163 if first == number && second == number {
1164 Ok(boolean)
1165 } else {
1166 Err(Box::new(PreprocessingError::InvalidOperator("number", "number")))
1167 }
1168 },
1169 BinaryOperator::IsGreaterThan => {
1170 if first == number && second == number {
1171 Ok(boolean)
1172 } else {
1173 Err(Box::new(PreprocessingError::InvalidOperator("number", "number")))
1174 }
1175 },
1176 BinaryOperator::IsLessThanOrEqualTo => {
1177 if first == number && second == number {
1178 Ok(boolean)
1179 } else {
1180 Err(Box::new(PreprocessingError::InvalidOperator("number", "number")))
1181 }
1182 },
1183 BinaryOperator::IsGreaterThanOrEqualTo => {
1184 if first == number && second == number {
1185 Ok(boolean)
1186 } else {
1187 Err(Box::new(PreprocessingError::InvalidOperator("number", "number")))
1188 }
1189 },
1190 }
1191 }
1192
1193 fn clean_type(&self, typ: CortexType) -> CortexType {
1195 self.current_type_env.as_ref().unwrap().fill_in(typ)
1196 }
1197
1198 fn get_bindings(type_param_names: &Vec<String>, typ: &CortexType) -> Result<HashMap<String, CortexType>, CortexError> {
1200 let mut type_args_handled = false;
1201 let mut typ = typ.clone();
1202 let mut bindings = HashMap::new();
1203 while !type_args_handled {
1204 if let CortexType::BasicType(b) = &typ {
1205 bindings = TypeEnvironment::create_bindings(type_param_names, &b.type_args);
1206 typ = TypeEnvironment::fill(typ, &bindings);
1207 type_args_handled = true;
1208 } else if let CortexType::RefType(r) = typ {
1209 typ = *r.contained;
1210 }
1211 }
1212 Ok(bindings)
1213 }
1214 fn infer_type_args(&self, sig: &FunctionSignature, args: &Vec<CortexType>, name: &FunctionAddress, st_str: &String) -> Result<HashMap<String, CortexType>, CortexError> {
1215 let mut bindings = HashMap::<String, CortexType>::new();
1216 for (arg, param) in args.iter().zip(&sig.params) {
1217 self.infer_arg(¶m.typ, &arg, &sig.type_param_names, &mut bindings, param.name(), st_str)?;
1218 }
1219
1220 if bindings.len() != sig.type_param_names.len() {
1221 Err(Box::new(PreprocessingError::CouldNotInferTypeBinding(name.codegen(0))))
1222 } else {
1223 Ok(bindings)
1224 }
1225 }
1226 fn infer_arg(&self, param_type: &CortexType, arg_type: &CortexType, type_param_names: &Vec<String>, bindings: &mut HashMap<String, CortexType>, param_name: &String, st_str: &String) -> Result<(), CortexError> {
1227 let correct;
1228 match (¶m_type, arg_type) {
1229 (CortexType::BasicType(b), arg_type) => {
1230 if let Some(name) = TypeEnvironment::does_arg_list_contain(type_param_names, ¶m_type) {
1231 let mut bound_type = arg_type.clone();
1233 if b.optional {
1234 bound_type = bound_type.to_non_optional();
1235 }
1236 if b.type_args.len() > 0 {
1237 return Err(Box::new(PreprocessingError::CannotHaveTypeArgsOnGeneric(param_type.codegen(0))));
1238 }
1239 if let Some(existing_binding) = bindings.get(name) {
1240 let combined = bound_type.combine_with(existing_binding.clone());
1241 if let Some(result) = combined {
1242 bindings.insert(name.clone(), result);
1243 correct = true;
1244 } else {
1245 correct = false;
1246 }
1247 } else {
1248 bindings.insert(name.clone(), bound_type);
1249 correct = true;
1250 }
1251 } else {
1252 if let CortexType::BasicType(b2) = arg_type {
1255 if b.type_args.len() == b2.type_args.len() {
1256 for (type_param, type_arg) in b.type_args.iter().zip(&b2.type_args) {
1257 self.infer_arg(type_param, type_arg, type_param_names, bindings, param_name, st_str)?;
1258 }
1259 correct = true;
1260 } else {
1261 correct = false;
1262 }
1263 } else {
1264 correct = true;
1265 }
1266 }
1267 },
1268 (CortexType::RefType(r), CortexType::RefType(r2)) => {
1269 self.infer_arg(&*r.contained, &*r2.contained, type_param_names, bindings, param_name, st_str)?;
1270 correct = true;
1271 },
1272 (CortexType::TupleType(t1), CortexType::TupleType(t2)) => {
1273 if t1.types.len() == t2.types.len() {
1274 for (type1, type2) in t1.types.iter().zip(&t2.types) {
1275 self.infer_arg(type1, type2, type_param_names, bindings, param_name, st_str)?;
1276 }
1277 correct = true;
1278 } else {
1279 correct = false;
1280 }
1281 },
1282 (_, _) => {
1283 correct = false;
1284 },
1285 }
1286 if correct {
1287 Ok(())
1288 } else {
1289 Err(Box::new(PreprocessingError::MismatchedType(param_type.codegen(0), arg_type.codegen(0), param_name.clone(), st_str.clone())))
1290 }
1291 }
1292
1293 fn search_struct_for_loops(&self, s: &Struct) -> Result<bool, CortexError> {
1294 match &s.name {
1295 OptionalIdentifier::Ident(name) => {
1296 let stype = CortexType::basic(PathIdent::simple(name.clone()), false, forwarded_type_args(&s.type_param_names));
1297 let mut q = VecDeque::new();
1298 for field in &s.fields {
1299 q.push_back(field.1.clone());
1300 }
1301 while !q.is_empty() {
1303 let typ = q.pop_front().unwrap();
1304 if typ == stype {
1305 return Ok(true);
1306 }
1307 if !typ.is_core() {
1308 let typ_name = typ.name()?;
1310
1311 if self.has_type(typ_name) {
1315 let struc = self.lookup_type(typ_name)?;
1316 for field in &struc.fields {
1317 q.push_back(field.1.clone());
1318 }
1319 }
1320 }
1321 }
1322 Ok(false)
1323 },
1324 OptionalIdentifier::Ignore => Ok(false),
1325 }
1326 }
1327
1328 fn get_variable_type(&self, path: &PathIdent) -> Result<CortexType, CortexError> {
1329 if path.is_final() {
1330 let front = path.get_front()?;
1332 Ok(self.current_env.as_ref().unwrap().get(front)?.clone())
1333 } else {
1334 Err(Box::new(PreprocessingError::ValueNotFound(path.codegen(0))))
1335 }
1336 }
1337
1338 fn has_function(&self, path: &FunctionAddress) -> bool {
1339 let full_path: FunctionAddress = FunctionAddress::concat(&self.current_context, &path);
1340 self.function_signature_map.contains_key(&full_path)
1341 }
1342 fn lookup_signature(&self, path: &FunctionAddress) -> Result<&FunctionSignature, CortexError> {
1343 let full_path: FunctionAddress = FunctionAddress::concat(&self.current_context, &path);
1344 if let Some(sig) = self.function_signature_map.get(&full_path) {
1345 Ok(sig)
1346 } else {
1347 Err(Box::new(PreprocessingError::FunctionDoesNotExist(full_path.codegen(0))))
1348 }
1349 }
1350
1351 fn lookup_type(&self, path: &PathIdent) -> Result<&TypeDefinition, CortexError> {
1352 let full_path = PathIdent::concat(&self.current_context, &path);
1353 if let Some(c) = self.type_map.get(&full_path) {
1354 Ok(c)
1355 } else {
1356 Err(Box::new(PreprocessingError::TypeDoesNotExist(full_path.codegen(0))))
1357 }
1358 }
1359 fn has_type(&self, path: &PathIdent) -> bool {
1360 let full_path = PathIdent::concat(&self.current_context, &path);
1361 self.type_map.contains_key(&full_path)
1362 }
1363
1364 fn next_temp(&mut self) -> String {
1365 let res = format!("$temp{}", self.temp_num);
1366 self.temp_num += 1;
1367 res
1368 }
1369}