Skip to content

Commit

Permalink
Nice circular reference errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-M-Lucas committed Jul 25, 2024
1 parent d544810 commit 68a28d7
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 21 deletions.
6 changes: 6 additions & 0 deletions .idea/git_toolbox_blame.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions build/out.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Binary file modified build/out.o
Binary file not shown.
Binary file modified build/out.out
Binary file not shown.
16 changes: 6 additions & 10 deletions main.why
Original file line number Diff line number Diff line change
@@ -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;
}
4 changes: 2 additions & 2 deletions src/root/errors/name_resolver_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
8 changes: 7 additions & 1 deletion src/root/name_resolver/resolve_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -131,7 +132,12 @@ pub fn resolve_names(ast: Vec<TopLevelTokens>, 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 {
Expand Down
14 changes: 10 additions & 4 deletions src/root/name_resolver/resolve_type_sizes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pub fn resolve_type_sizes(
final_types: &mut HashMap<TypeID, UserType>,
unsized_types: &mut HashMap<TypeID, UnsizedUserType>,
global_table: &GlobalDefinitionTable,
) -> Result<ByteSize, WErr> {
) -> Result<Result<ByteSize, Vec<(String, TypeID, Location)>>, WErr> {
let (id, name, attributes, location) = unsized_type.dissolve();

let mut size: ByteSize = ByteSize(0);
Expand All @@ -50,17 +50,23 @@ 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));
}

final_types.insert(id, UserType::new(id, name, size, processed_attributes, location));

Ok(size)
Ok(Ok(size))
}

0 comments on commit 68a28d7

Please sign in to comment.