From f9620e288afb83656865471bba06d6620d03b9c6 Mon Sep 17 00:00:00 2001 From: Jonathan Woollett-Light Date: Sun, 24 Dec 2023 18:10:00 +0000 Subject: [PATCH] inlining error --- src/ast.rs | 59 +++++++++++++++++---- src/backend.rs | 106 ++++++++++--------------------------- src/frontend.rs | 16 +++--- src/middle.rs | 20 ++++--- tests/integration_tests.rs | 4 +- 5 files changed, 96 insertions(+), 109 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index d64ddbd..b78e692 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -189,6 +189,13 @@ pub enum Register { W31, } +impl TryFrom<&Identifier> for Register { + type Error = (); + fn try_from(Identifier(bytes): &Identifier) -> Result { + Self::try_from(bytes.as_slice()) + } +} + impl TryFrom<&[u8]> for Register { type Error = (); fn try_from(bytes: &[u8]) -> Result { @@ -345,7 +352,7 @@ impl TryFrom<&Variable> for Register { ) -> Result { if *addressing == Addressing::Direct && *index == None - && let Ok(register) = Register::try_from(identifier.as_slice()) + && let Ok(register) = Register::try_from(identifier) { Ok(register) } else { @@ -398,7 +405,7 @@ impl Default for Literal { } } -#[derive(Default, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Hash, PartialEq, Eq)] pub struct Variable { pub addressing: Addressing, pub identifier: Identifier, @@ -442,7 +449,7 @@ impl std::fmt::Display for Variable { f, "{}{}{}", self.addressing, - std::str::from_utf8(&self.identifier).unwrap(), + self.identifier, self.index .as_ref() .map(|v| format!("[{v}]")) @@ -452,26 +459,50 @@ impl std::fmt::Display for Variable { } impl From<&str> for Variable { - fn from(bytes: &str) -> Self { + fn from(s: &str) -> Self { Self { addressing: Addressing::Direct, - identifier: Identifier::from(bytes.as_bytes()), + identifier: Identifier::from(s), index: None, } } } +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Default, Hash)] +pub struct Identifier(pub Vec); + +impl PartialEq<&str> for Identifier { + fn eq(&self, other: &&str) -> bool { + self.0 == other.as_bytes() + } +} -pub type Identifier = Vec; +impl Identifier { + pub fn new() -> Self { + Self(Vec::new()) + } + pub fn push(&mut self, x: u8) { + self.0.push(x); + } +} -impl std::fmt::Debug for Variable { +impl From<&str> for Identifier { + fn from(s: &str) -> Self { + Self(Vec::from(s.as_bytes())) + } +} + +impl std::fmt::Debug for Identifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Variable") - .field("addressing", &self.addressing) - .field("identifier", &std::str::from_utf8(&self.identifier)) - .field("index", &self.index) + f.debug_tuple("Identifier") + .field(&std::str::from_utf8(&self.0)) .finish() } } +impl std::fmt::Display for Identifier { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", std::str::from_utf8(&self.0).unwrap()) + } +} #[derive(Debug, Eq, PartialEq, Clone, Hash)] pub enum Index { @@ -592,6 +623,12 @@ pub enum Syscall { FTruncate, Mmap, } +impl TryFrom<&Identifier> for Syscall { + type Error = (); + fn try_from(identifier: &Identifier) -> Result { + Self::try_from(identifier.0.as_slice()) + } +} impl TryFrom<&[u8]> for Syscall { type Error = (); fn try_from(x: &[u8]) -> Result { diff --git a/src/backend.rs b/src/backend.rs index ce10659..05a0bdf 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -100,13 +100,7 @@ pub unsafe fn instruction_from_node( Op::Special(Special::Type) => match arg { [Value::Variable(Variable { identifier, .. }), Value::Type(value_type)] => { type_data.insert(identifier.clone(), value_type.clone()); - writeln!( - bss, - "{}: .skip {}", - std::str::from_utf8(identifier).unwrap(), - value_type.bytes() - ) - .unwrap(); + writeln!(bss, "{identifier}: .skip {}", value_type.bytes()).unwrap(); } [Value::Variable(Variable { identifier, .. }), Value::Type(value_type), Value::Literal(literal)] => { @@ -138,12 +132,7 @@ pub unsafe fn instruction_from_node( _ => todo!(), }; - writeln!( - data, - "{}: {data_value}", - std::str::from_utf8(identifier).unwrap(), - ) - .unwrap(); + writeln!(data, "{identifier}: {data_value}").unwrap(); } [Value::Variable(Variable { identifier, .. }), Value::Type(value_type), Value::Literal(literal), tail @ ..] => { @@ -188,12 +177,7 @@ pub unsafe fn instruction_from_node( _ => todo!(), }; - writeln!( - data, - "{}: {data_value}", - std::str::from_utf8(identifier).unwrap(), - ) - .unwrap(); + writeln!(data, "{identifier}: {data_value}").unwrap(); } _ => todo!(), }, @@ -217,12 +201,11 @@ pub unsafe fn instruction_from_node( &mut assembly, "\ mov x8, #{}\n\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ ldrb w0, [x0]\n\ svc #0\n\ ", - libc::SYS_exit, - std::str::from_utf8(identifier).unwrap() + libc::SYS_exit ) .unwrap(), _ => todo!(), @@ -239,21 +222,19 @@ pub unsafe fn instruction_from_node( Type::U8 => write!( assembly, "\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ mov w1, #{y}\n\ strb w1, [x0]\n\ - ", - std::str::from_utf8(identifier).unwrap() + " ) .unwrap(), Type::U64 => write!( assembly, "\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ mov x1, #{y}\n\ str x1, [x0]\n\ - ", - std::str::from_utf8(identifier).unwrap() + " ) .unwrap(), _ => todo!(), @@ -273,12 +254,7 @@ pub unsafe fn instruction_from_node( assert_eq!(vec.len(), bytes.len()); // Loads the address of the array. - writeln!( - assembly, - "ldr x0, ={}", - std::str::from_utf8(identifier).unwrap() - ) - .unwrap(); + writeln!(assembly, "ldr x0, ={identifier}").unwrap(); // Packs 2 bytes into stores of the full 32 bit register. let mut chunks = bytes.array_chunks::<2>(); @@ -321,12 +297,7 @@ pub unsafe fn instruction_from_node( assert_eq!(vec.len(), rest.len()); // Loads the address of the array. - writeln!( - assembly, - "ldr x0, ={}", - std::str::from_utf8(identifier).unwrap() - ) - .unwrap(); + writeln!(assembly, "ldr x0, ={identifier}").unwrap(); // Packs 2 bytes into stores of the full 32 bit register. let mut chunks = rest.array_chunks::<2>(); @@ -375,23 +346,21 @@ pub unsafe fn instruction_from_node( Type::U8 => write!( &mut assembly, "\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ ldr w1, [x0]\n\ add w1, w1, #{y}\n\ strb w1, [x0]\n\ - ", - std::str::from_utf8(identifier).unwrap() + " ) .unwrap(), Type::U64 => write!( &mut assembly, "\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ ldr x1, [x0]\n\ add x1, x1, #{y}\n\ str x1, [x0]\n\ - ", - std::str::from_utf8(identifier).unwrap() + " ) .unwrap(), _ => todo!(), @@ -409,23 +378,21 @@ pub unsafe fn instruction_from_node( Type::U8 => write!( &mut assembly, "\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ ldr w1, [x0]\n\ sub w1, w1, #{y}\n\ strb w1, [x0]\n\ - ", - std::str::from_utf8(identifier).unwrap() + " ) .unwrap(), Type::U64 => write!( &mut assembly, "\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ ldr x1, [x0]\n\ sub x1, x1, #{y}\n\ str x1, [x0]\n\ - ", - std::str::from_utf8(identifier).unwrap() + " ) .unwrap(), _ => todo!(), @@ -442,12 +409,11 @@ pub unsafe fn instruction_from_node( write!( &mut assembly, "\ - ldr x0, ={}\n\ + ldr x0, ={identifier}\n\ ldr x0, [x0]\n\ cmp w0, #{y}\n\ bne block{block_counter}\n\ - ", - std::str::from_utf8(identifier).unwrap(), + " ) .unwrap(); @@ -472,12 +438,11 @@ pub unsafe fn instruction_from_node( "\ mov x8, #{}\n\ mov x0, #{fd}\n\ - ldr x1, ={}\n\ + ldr x1, ={identifier}\n\ mov x2, #{}\n\ svc #0\n\ ", libc::SYS_read, - std::str::from_utf8(identifier).unwrap(), type_data.get(identifier).unwrap().bytes() ) .unwrap(); @@ -488,25 +453,18 @@ pub unsafe fn instruction_from_node( index: None, }), Value::Type(variable_type), Value::Literal(Literal::Integer(fd))] => { type_data.insert(identifier.clone(), variable_type.clone()); - writeln!( - bss, - "{}: .skip {}", - std::str::from_utf8(identifier).unwrap(), - variable_type.bytes() - ) - .unwrap(); + writeln!(bss, "{identifier}: .skip {}", variable_type.bytes()).unwrap(); write!( &mut assembly, "\ mov x8, #{}\n\ mov x0, #{fd}\n\ - ldr x1, ={}\n\ + ldr x1, ={identifier}\n\ mov x2, #{}\n\ svc #0\n\ ", libc::SYS_read, - std::str::from_utf8(identifier).unwrap(), variable_type.bytes() ) .unwrap(); @@ -524,12 +482,11 @@ pub unsafe fn instruction_from_node( "\ mov x8, #{}\n\ mov x0, #{fd}\n\ - ldr x1, ={}\n\ + ldr x1, ={identifier}\n\ mov x2, #{}\n\ svc #0\n\ ", libc::SYS_write, - std::str::from_utf8(identifier).unwrap(), type_data.get(identifier).unwrap().bytes() ) .unwrap(); @@ -551,11 +508,10 @@ pub unsafe fn instruction_from_node( ldr x0, =empty\n\ mov x1, #0\n\ svc #0\n\ - ldr x1, ={}\n\ + ldr x1, ={identifier}\n\ str w0, [x1, 4]\n\ ", libc::SYS_memfd_create, - std::str::from_utf8(identifier).unwrap() ) .unwrap(); @@ -573,11 +529,10 @@ pub unsafe fn instruction_from_node( ldr x0, =empty\n\ mov x1, #0\n\ svc #0\n\ - ldr x1, ={}\n\ + ldr x1, ={identifier}\n\ str w0, [x1]\n\ ", libc::SYS_memfd_create, - std::str::from_utf8(identifier).unwrap() ) .unwrap(); @@ -601,12 +556,7 @@ pub unsafe fn instruction_from_node( identifier, index: None, })] => { - writeln!( - &mut assembly, - "ldr {register}, ={}", - std::str::from_utf8(identifier).unwrap() - ) - .unwrap(); + writeln!(&mut assembly, "ldr {register}, ={identifier}",).unwrap(); } x @ _ => todo!("{x:?}"), }, diff --git a/src/frontend.rs b/src/frontend.rs index 414418b..146c8b5 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -52,7 +52,7 @@ pub fn get_type(bytes: &mut Peekable>) -> Type { #[cfg_attr(test, instrument(level = "TRACE", skip(bytes), ret))] pub fn get_variable(bytes: &mut Peekable>) -> Variable { // Get identifier - let mut identifier = Vec::new(); + let mut identifier = Identifier::new(); let addressing = match bytes.peek().map(|r| r.as_ref().unwrap()) { Some(b'&') => { @@ -69,8 +69,7 @@ pub fn get_variable(bytes: &mut Peekable>) -> Variable { Addressing::Direct } _ => panic!( - "{:?} {:?}", - std::str::from_utf8(&identifier), + "{identifier:?} {:?}", std::str::from_utf8(&bytes.map(Result::unwrap).collect::>()) ), }; @@ -141,8 +140,7 @@ pub fn get_variable(bytes: &mut Peekable>) -> Variable { } } _ => panic!( - "{:?} {:?}", - std::str::from_utf8(&identifier), + "{identifier:?} {:?}", std::str::from_utf8(&bytes.map(Result::unwrap).collect::>()) ), } @@ -441,7 +439,7 @@ pub fn get_statement(bytes: &mut Peekable>) -> Statement { // comptime = true; // } - match (variable.identifier.as_slice(), &variable.index) { + match (variable.identifier.0.as_slice(), &variable.index) { // Loop (b"loop", None) => Statement { comptime, @@ -558,7 +556,7 @@ pub fn get_statement(bytes: &mut Peekable>) -> Statement { addressing: Addressing::Direct, identifier, index: None, - }) if identifier == b"sizeof" => { + }) if identifier == "sizeof" => { let tail = get_values(bytes); Statement { comptime, @@ -572,9 +570,7 @@ pub fn get_statement(bytes: &mut Peekable>) -> Statement { addressing: Addressing::Direct, identifier, index: None, - }) if let Ok(syscall) = - Syscall::try_from(identifier.as_slice()) => - { + }) if let Ok(syscall) = Syscall::try_from(&identifier) => { let tail = get_values(bytes); Statement { comptime, diff --git a/src/middle.rs b/src/middle.rs index acab2b7..92017d1 100644 --- a/src/middle.rs +++ b/src/middle.rs @@ -1030,7 +1030,7 @@ pub struct VariableAlias { impl From<&str> for VariableAlias { fn from(s: &str) -> Self { Self { - identifier: Vec::from(s.as_bytes()), + identifier: Identifier::from(s), index: None, } } @@ -1138,7 +1138,7 @@ unsafe fn create_inline_variable>( ( VariableAlias { - identifier: Vec::from(b"in"), + identifier: Identifier::from("in"), index: Some(Box::new(Index::Offset(Offset::Integer(i as u64)))), }, VariableAlias::from(new_variable_identiier), @@ -1156,10 +1156,12 @@ pub unsafe fn inline_functions(node: NonNull) -> NonNull { // An iterator yielding unique identifiers. const N: u8 = b'z' - b'a'; let mut identifier_iterator = (0..).map(|index| { - (0..index / N) - .map(|_| b'z') - .chain(std::iter::once((index % N) + b'a')) - .collect::>() + Identifier( + (0..index / N) + .map(|_| b'z') + .chain(std::iter::once((index % N) + b'a')) + .collect::>(), + ) }); let mut stack = vec![( @@ -1170,7 +1172,8 @@ pub unsafe fn inline_functions(node: NonNull) -> NonNull { )]; while let Some((current, mut preceding, next_carry, variable_map)) = stack.pop() { - // dbg!(¤t.as_ref().statement.op); + eprintln!("op: {:?}", ¤t.as_ref().statement.op); + eprintln!("variable_map: {:?}", variable_map.borrow()); match current.as_ref().statement.op { // Function definition @@ -1226,7 +1229,7 @@ pub unsafe fn inline_functions(node: NonNull) -> NonNull { }); ( VariableAlias { - identifier: Vec::from(b"out"), + identifier: Identifier::from("out"), index: None, }, new_lhs, @@ -1602,6 +1605,7 @@ pub unsafe fn inline_functions(node: NonNull) -> NonNull { .filter_map(Value::variable_mut) { let var = VariableAlias::from(variable.clone()); + eprintln!("var: {var:?}"); let VariableAlias { identifier, index } = variable_map.borrow().get(&var).unwrap().clone(); diff --git a/tests/integration_tests.rs b/tests/integration_tests.rs index 40b91bc..c374f33 100644 --- a/tests/integration_tests.rs +++ b/tests/integration_tests.rs @@ -174,7 +174,7 @@ fn helloworld_new() { fn build_and_run(source: &[u8], expected_stdout: &[u8], expected_code: i32) { let directory = PathBuf::from(format!("/tmp/a{}", Uuid::new_v4())); let output = Command::new(BINARY) - .args(["--new", &directory.display().to_string()]) + .args(["new", &directory.display().to_string()]) .output() .unwrap(); assert_eq!(output.stderr, &[], "{}", from_utf8(&output.stderr).unwrap()); @@ -189,7 +189,7 @@ fn build_and_run(source: &[u8], expected_stdout: &[u8], expected_code: i32) { source_file.write_all(source).unwrap(); let output = Command::new(BINARY) - .args(["--run", &directory.display().to_string()]) + .args(["run", &directory.display().to_string()]) .output() .unwrap();