diff --git a/.idea/git_toolbox_blame.xml b/.idea/git_toolbox_blame.xml new file mode 100644 index 0000000..7dc1249 --- /dev/null +++ b/.idea/git_toolbox_blame.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/build/out.asm b/build/out.asm index daff4f8..d0dc577 100644 --- a/build/out.asm +++ b/build/out.asm @@ -6,11 +6,9 @@ main: push rbp mov rbp, rsp mov qword [rbp-8], 3 - mov qword [rbp-24], 12 - mov qword [rbp-16], 13 mov rax, qword [rbp-8] - mov qword [rbp-32], rax - mov rax, qword [rbp-32] + mov qword [rbp-16], rax + mov rax, qword [rbp-16] leave ret diff --git a/build/out.o b/build/out.o index 4a2faf5..f141baa 100644 Binary files a/build/out.o and b/build/out.o differ diff --git a/build/out.out b/build/out.out index 23f50c7..25f56e7 100755 Binary files a/build/out.out and b/build/out.out differ diff --git a/main.why b/main.why index 78cf780..6fd114f 100644 --- a/main.why +++ b/main.why @@ -1,20 +1,16 @@ -struct TestStruct { - a: int, - b: int +struct StructA { + a: StructB } -impl TestStruct { - +struct StructB { + a: StructC } -fn test(a: int) -> int { - return a + 1; +struct StructC { + a: StructB } fn main() -> int { let y: int = 3; - - let x: TestStruct = TestStruct { a: 12, b: 13 }; - return y; } diff --git a/src/root/errors/name_resolver_errors.rs b/src/root/errors/name_resolver_errors.rs index 7b53b75..7b4067a 100644 --- a/src/root/errors/name_resolver_errors.rs +++ b/src/root/errors/name_resolver_errors.rs @@ -34,6 +34,6 @@ pub enum NRErrs { OpCantBePrefix(String), #[error("Operator ({0}) cannot be used as an infix operator")] OpCantBeInfix(String), - #[error("Size of type ({0}) cannot be determined due to circular definition with no indirection")] - CircularType(String) + #[error("Size of type ({0}) cannot be determined due to circular definition with no indirection ({1})")] + CircularType(String, String) } diff --git a/src/root/name_resolver/resolve_names.rs b/src/root/name_resolver/resolve_names.rs index 3e6acf9..285d955 100644 --- a/src/root/name_resolver/resolve_names.rs +++ b/src/root/name_resolver/resolve_names.rs @@ -2,6 +2,7 @@ use std::any::Any; use std::collections::HashMap; use derive_getters::Getters; +use itertools::Itertools; use crate::root::errors::name_resolver_errors::NRErrs; use crate::root::errors::WErr; @@ -131,7 +132,12 @@ pub fn resolve_names(ast: Vec, global_table: &mut GlobalDefiniti while !unsized_final_types.is_empty() { let next_type_id = *unsized_final_types.keys().next().unwrap(); let unsized_type = unsized_final_types.remove(&next_type_id).unwrap(); - resolve_type_sizes(unsized_type, &mut final_types, &mut unsized_final_types, global_table)?; + if let Err(mut e) = resolve_type_sizes(unsized_type, &mut final_types, &mut unsized_final_types, global_table)? { + let n = e.iter().rev().find(|(_, id, _)| *id == e.first().unwrap().1).unwrap(); + e.first_mut().unwrap().0 = n.0.clone(); + + return WErr::ne(NRErrs::CircularType(e.last().unwrap().0.clone(), e.iter().rev().map(|(s, _, _)| s).join(" -> ").to_string()), e.last().unwrap().2.clone()); + }; } for (id, user_type) in final_types { diff --git a/src/root/name_resolver/resolve_type_sizes.rs b/src/root/name_resolver/resolve_type_sizes.rs index a6b31cc..53ffffc 100644 --- a/src/root/name_resolver/resolve_type_sizes.rs +++ b/src/root/name_resolver/resolve_type_sizes.rs @@ -31,7 +31,7 @@ pub fn resolve_type_sizes( final_types: &mut HashMap, unsized_types: &mut HashMap, global_table: &GlobalDefinitionTable, -) -> Result { +) -> Result>, WErr> { let (id, name, attributes, location) = unsized_type.dissolve(); let mut size: ByteSize = ByteSize(0); @@ -50,11 +50,17 @@ pub fn resolve_type_sizes( size += sized_type.size(); } else if let Some(unsized_type) = unsized_types.remove(attribute_type.type_id()) { - size += resolve_type_sizes(unsized_type, final_types, unsized_types, global_table)?; + size += match resolve_type_sizes(unsized_type, final_types, unsized_types, global_table)? { + Ok(s) => s, + Err(mut e) => { + e.push((name, id, location)); + return Ok(Err(e)); + } + }; } else { // Type not in unsized_types or type table due to circular definition - return WErr::ne(NRErrs::CircularType(name), attribute_name.location().clone()); + return Ok(Err(vec![(String::new(), *attribute_type.type_id(), Location::builtin()), (name, id, location)])) } processed_attributes.push((offset, attribute_name, attribute_type)); @@ -62,5 +68,5 @@ pub fn resolve_type_sizes( final_types.insert(id, UserType::new(id, name, size, processed_attributes, location)); - Ok(size) + Ok(Ok(size)) }