From 03401a8e66069a624fc2c22d6e425c1f1e8ab338 Mon Sep 17 00:00:00 2001 From: lambda-0x Date: Sun, 12 Mar 2023 13:06:45 +0530 Subject: [PATCH 01/68] fix(huffup): Check if command exists before using it (#257) Co-authored-by: refcell.eth --- huffup/huffup | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/huffup/huffup b/huffup/huffup index cbb3e536..103cc9de 100755 --- a/huffup/huffup +++ b/huffup/huffup @@ -14,18 +14,22 @@ main() { need_cmd git need_cmd curl - # Uninstall npm typescript compiler if npm list doesn't contain empty for huffc - if ! [[ "$(npm list -g huffc)" =~ "empty" ]]; then - warn "It appears your system has an outdated installation of huffc via npm." - warn "Uninstalling huffc with npm to allow huffup to take precedence..." - npm uninstall -g huffc + # Uninstall npm typescript compiler if npm is present and npm list doesn't contain empty for huffc + if check_cmd npm; then + if ! [[ "$(npm list -g huffc)" =~ "empty" ]]; then + warn "It appears your system has an outdated installation of huffc via npm." + warn "Uninstalling huffc with npm to allow huffup to take precedence..." + npm uninstall -g huffc + fi fi - # Uninstall yarn typescript compiler if yarn list contains a huffc entry - if [[ "$(yarn global list)" =~ "huffc" ]]; then - warn "It appears your system has an outdated installation of huffc via yarn." - warn "Uninstalling huffc with yarn to allow huffup to take precedence..." - yarn global remove huffc + # Uninstall yarn typescript compiler if yarn is present and yarn list contains a huffc entry + if check_cmd yarn; then + if [[ "$(yarn global list)" =~ "huffc" ]]; then + warn "It appears your system has an outdated installation of huffc via yarn." + warn "Uninstalling huffc with yarn to allow huffup to take precedence..." + yarn global remove huffc + fi fi # Otherwise, continue with huffup script From c1ca5ba27b5f91cbcc4055b8f3cefccc596e932c Mon Sep 17 00:00:00 2001 From: Joshua Trujillo Date: Tue, 21 Mar 2023 12:40:11 -0700 Subject: [PATCH 02/68] update bench expected initcode --- huff_core/benches/huff_benchmark.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/huff_core/benches/huff_benchmark.rs b/huff_core/benches/huff_benchmark.rs index 567713b8..1668c287 100644 --- a/huff_core/benches/huff_benchmark.rs +++ b/huff_core/benches/huff_benchmark.rs @@ -114,7 +114,7 @@ fn codegen_erc20_benchmark(c: &mut Criterion) { cg.churn(file_source.clone(), vec![], &main_bytecode, &constructor_bytecode, has_custom_bootstrap).unwrap(); // Full expected bytecode output (generated from huffc) - let expected_bytecode = "336000556101ac806100116000396000f360003560E01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; + let expected_bytecode = "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; assert_eq!(artifact.bytecode.to_lowercase(), expected_bytecode.to_lowercase()); })); @@ -159,7 +159,7 @@ fn erc20_compilation_benchmark(c: &mut Criterion) { cg.churn(file_source.clone(), vec![], &main_bytecode, &constructor_bytecode, has_custom_bootstrap).unwrap(); // Full expected bytecode output (generated from huffc) - let expected_bytecode = "336000556101ac806100116000396000f360003560E01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; + let expected_bytecode = "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; assert_eq!(artifact.bytecode.to_lowercase(), expected_bytecode.to_lowercase()); })); @@ -204,7 +204,7 @@ fn erc721_compilation_benchmark(c: &mut Criterion) { cg.churn(file_source.clone(), vec![], &main_bytecode, &constructor_bytecode, has_custom_bootstrap).unwrap(); // Full expected bytecode output (generated from huffc) - let expected_bytecode = "336000556103b1806100116000396000f360003560e01c8063a9059cbb146100a057806342842e0e146101a3578063b88d4fde146101a9578063095ea7b31461027b578063a22cb46514610310578063081812fc146102f357806340c10f19146101af57806370a082311461025e5780636352211e1461039457806306fdde031461035e57806395d89b4114610364578063c87b56dd1461036a57806301ffc9a714610370578063e985e9c514610376575b6044356024356004358083600160005260006020015260406000205491146100c75761019d565b8033146101005733816000526000602001526040600020546101005782600260005260006020015260406000205433146101005761019d565b6001816003600052600060200152604060002054038160036000526000602001526040600020558160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a4005b60006000fd5b60006000fd5b60006000fd5b60005433146101be5760006000fd5b6024356004356000826001600052600060200152604060002054156101e257610258565b8160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60006000a4005b60006000fd5b600435600360005260006020015260406000205460005260206000f35b6024358060016000526000602001526040600020548033143382600052600060200152604060002054176102ae576102ed565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560006000a4005b60006000fd5b600435600260005260006020015260406000205460005260206000f35b60243560043533600052600060200152604060002055600435336024356000527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160006000a4005b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60243560043560005260006020015260406000205460005260206000f35b600435600160005260006020015260406000205460005260206000f3"; + let expected_bytecode = "336000556103b180600e3d393df360003560e01c8063a9059cbb146100a057806342842e0e146101a3578063b88d4fde146101a9578063095ea7b31461027b578063a22cb46514610310578063081812fc146102f357806340c10f19146101af57806370a082311461025e5780636352211e1461039457806306fdde031461035e57806395d89b4114610364578063c87b56dd1461036a57806301ffc9a714610370578063e985e9c514610376575b6044356024356004358083600160005260006020015260406000205491146100c75761019d565b8033146101005733816000526000602001526040600020546101005782600260005260006020015260406000205433146101005761019d565b6001816003600052600060200152604060002054038160036000526000602001526040600020558160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a4005b60006000fd5b60006000fd5b60006000fd5b60005433146101be5760006000fd5b6024356004356000826001600052600060200152604060002054156101e257610258565b8160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60006000a4005b60006000fd5b600435600360005260006020015260406000205460005260206000f35b6024358060016000526000602001526040600020548033143382600052600060200152604060002054176102ae576102ed565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560006000a4005b60006000fd5b600435600260005260006020015260406000205460005260206000f35b60243560043533600052600060200152604060002055600435336024356000527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160006000a4005b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60243560043560005260006020015260406000205460005260206000f35b600435600160005260006020015260406000205460005260206000f3"; assert_eq!(artifact.bytecode.to_lowercase(), expected_bytecode.to_lowercase()); })); From 5cc52027f5e1418d3b124f6dcabf36a57d3507e9 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 8 Mar 2023 15:05:44 -0700 Subject: [PATCH 03/68] initial rewrite lexer work using position instead of current span --- huff_lexer/src/lexer.rs | 85 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 huff_lexer/src/lexer.rs diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs new file mode 100644 index 00000000..28f5c412 --- /dev/null +++ b/huff_lexer/src/lexer.rs @@ -0,0 +1,85 @@ +/// Defines a context in which the lexing happens. +/// Allows to differientate between EVM types and opcodes that can either +/// be identical or the latter being a substring of the former (example : bytes32 and byte) +#[derive(Debug, PartialEq, Eq)] +pub enum Context { + /// global context + Global, + /// Macro definition context + MacroDefinition, + /// Macro's body context + MacroBody, + /// Macro's argument context (definition or being called) + MacroArgs, + /// ABI context + Abi, + /// Lexing args of functions inputs/outputs and events + AbiArgs, + /// constant context + Constant, + /// Code table context + CodeTableBody, +} + +/// ## Lexer +/// +/// The lexer encapsulated in a struct. +pub struct Lexer<'a> { + /// The source code as peekable chars. + /// WARN: SHOULD NEVER BE MODIFIED! + pub reference_chars: Peekable>, + position: Position, + done: bool, + /// Current context. + pub context: Context, +} + +impl<'a> Lexer<'a> { + fn new(source: &'a str) -> Self { + Lexer { + // We zip with the character index here to ensure the first char has index 0 + char_iter: source.chars().zip(0..).peekable(), + position: 0, + done: false, + } + } + + /// Consumes the next character + pub fn consume(&mut self) -> Option { + self.chars.next().map(|x| { + self.position += 1; + x + }) + } + + /// Peeks at the next char. Does not iterate the cursor + fn peek_char(&mut self) -> Option { + self.char_iter.peek().map(|(c, _)| *c) + } + + /// Dynamically consumes characters based on filters + pub fn dyn_consume(&mut self, f: impl Fn(&char) -> bool + Copy) { + while self.peek().map(|x| f(&x)).unwrap_or(false) { + self.consume(); + } + } + + fn next_token(&mut self) -> SpannedTokenResult { + match self.consume() { + + } + } + + +} + +impl<'a> Iterator for Lexer<'a> { + type Item = SpannedTokenResult; + fn next(&mut self) -> Option { + if self.done { + None + } else { + Some(self.next_token()) + } + } +} \ No newline at end of file From 119fb091b7eb43d3e16a0508eb8412232463a391 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 8 Mar 2023 16:27:54 -0700 Subject: [PATCH 04/68] initial work to redo lexer for working with position rather than shared span --- huff_lexer/src/lexer.rs | 216 +++++++++++++++++++++++++++++++++++++--- huff_lexer/src/lib.rs | 11 ++ huff_utils/src/token.rs | 10 ++ 3 files changed, 221 insertions(+), 16 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 28f5c412..a14fb4fa 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -1,3 +1,10 @@ +use huff_utils::prelude::*; +use regex::Regex; +use std::{ + iter::Peekable, + str::Chars, +}; + /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either /// be identical or the latter being a substring of the former (example : bytes32 and byte) @@ -24,23 +31,26 @@ pub enum Context { /// ## Lexer /// /// The lexer encapsulated in a struct. -pub struct Lexer<'a> { +pub struct LexerNew<'a> { /// The source code as peekable chars. /// WARN: SHOULD NEVER BE MODIFIED! - pub reference_chars: Peekable>, - position: Position, - done: bool, + pub chars: Peekable>, + position: u32, + eof: bool, /// Current context. pub context: Context, } -impl<'a> Lexer<'a> { +pub type TokenResult<'a> = Result>; + +impl<'a> LexerNew<'a> { fn new(source: &'a str) -> Self { - Lexer { + LexerNew { // We zip with the character index here to ensure the first char has index 0 - char_iter: source.chars().zip(0..).peekable(), + chars: source.chars().peekable(), position: 0, - done: false, + eof: false, + context: Context::Global, } } @@ -52,11 +62,24 @@ impl<'a> Lexer<'a> { }) } - /// Peeks at the next char. Does not iterate the cursor - fn peek_char(&mut self) -> Option { - self.char_iter.peek().map(|(c, _)| *c) + /// Try to peek at the next character from the source + pub fn peek(&mut self) -> Option { + self.chars.peek().copied() } + /// Consume characters until a sequence matches + // pub fn seq_consume(&mut self, word: &str) { + // let mut current_pos = self.current_span().start; + // while self.peek().is_some() { + // let peeked = self.peek_n_chars_from(word.len(), current_pos); + // if word == peeked { + // break + // } + // self.consume(); + // current_pos += 1; + // } + // } + /// Dynamically consumes characters based on filters pub fn dyn_consume(&mut self, f: impl Fn(&char) -> bool + Copy) { while self.peek().map(|x| f(&x)).unwrap_or(false) { @@ -64,19 +87,180 @@ impl<'a> Lexer<'a> { } } - fn next_token(&mut self) -> SpannedTokenResult { - match self.consume() { + fn next_token(&mut self) -> TokenResult { + // let start = self.position; + if let Some(ch) = self.consume() { + match ch { + '/' => { + if let Some(ch2) = self.peek() { + match ch2 { + '/' => { + // Consume until newline + // let c = self.eat_while(None, |c| *c != '\n'); + } + } + } + } + // # keywords + '#' => { + + } + // Alphabetical characters + ch if ch.is_alphabetic() || ch.eq(&'_') => { + + } + // If it's the start of a hex literal + ch if ch == '0' && self.peek().unwrap() == 'x' => { + + } + '=' => TokenKind::Assign, + '(' => { + + } + ')' => { + + } + '[' => TokenKind::OpenBracket, + ']' => TokenKind::CloseBracket, + '{' => { + if self.context == Context::MacroDefinition { + self.context = Context::MacroBody; + } + TokenKind::OpenBrace + } + '}' => { + if matches!(self.context, Context::MacroBody | Context::CodeTableBody) { + self.context = Context::Global; + } + TokenKind::CloseBrace + } + '+' => self.single_char_token(TokenKind::Add), + '-' => self.single_char_token(TokenKind::Sub), + '*' => self.single_char_token(TokenKind::Mul), + '<' => self.single_char_token(TokenKind::LeftAngle), + '>' => self.single_char_token(TokenKind::LeftAngle), + // NOTE: TokenKind::Div is lexed further up since it overlaps with comment + ':' => self.single_char_token(TokenKind::LeftAngle), + // identifiers + ',' => self.single_char_token(TokenKind::LeftAngle), + '0'..='9' => self.eat_digit(ch), + // Lexes Spaces and Newlines as Whitespace + ch if ch.is_ascii_whitespace() => { + self.eat_whitespace(); + self.next_token() + } + '"' => { + // loop { + // match self.peek() { + // Some('"') => { + // self.consume(); + // let str = self.slice(); + // break TokenKind::Str((str[1..str.len() - 1]).to_string()) + // } + // Some('\\') if matches!(self.nth_peek(1), Some('\\') | Some('"')) => { + // self.consume(); + // } + // Some(_) => {} + // None => { + // self.eof = true; + // tracing::error!(target: "lexer", "UNEXPECTED EOF SPAN"); + // return Some(Err(LexicalError::new( + // LexicalErrorKind::UnexpectedEof, + // self.current_span().clone(), + // ))) + // } + // } + // self.consume(); + // } + } + '\'' => { + } + ch => { + tracing::error!(target: "lexer", "UNSUPPORTED TOKEN '{}'", ch); + return Err(LexicalError::new( + LexicalErrorKind::InvalidCharacter(ch), + Span { start: self.position as usize, end: self.position as usize, file: None }, + )) + } + } + // TODO: change this to have a starting position + // Ok(Token { kind: token_kind, span: Span { start: self.position as usize, end: self.position as usize, file: None } }) + } else { + self.eof = true; + Ok(Token { kind: TokenKind::Eof, span: Span { start: self.position as usize, end: self.position as usize, file: None } } ) } } + fn single_char_token(&self, token_kind: TokenKind) -> TokenResult { + Ok(token_kind.into_single_span(self.position)) + } + + /// Keeps consuming tokens as long as the predicate is satisfied + fn eat_while bool>( + &mut self, + initial_char: Option, + predicate: F, + ) -> (String, u32, u32) { + let start = self.position; + + // This function is only called when we want to continue consuming a character of the same type. + // For example, we see a digit and we want to consume the whole integer + // Therefore, the current character which triggered this function will need to be appended + let mut word = String::new(); + if let Some(init_char) = initial_char { + word.push(init_char) + } + + // Keep checking that we are not at the EOF + while let Some(peek_char) = self.peek() { + // Then check for the predicate, if predicate matches append char and increment the cursor + // If not, return word. The next character will be analyzed on the next iteration of next_token, + // Which will increment the cursor + if !predicate(peek_char) { + return (word, start, self.position); + } + word.push(peek_char); + + // If we arrive at this point, then the char has been added to the word and we should increment the cursor + self.consume(); + } + + (word, start, self.position) + } + + + fn eat_digit(&mut self, initial_char: char) -> TokenResult { + let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { + ch.is_ascii_digit() + }); + + let integer = integer_str.parse().unwrap(); + + let integer_token = TokenKind::Num(integer); + let span = Span { start: start as usize, end: end as usize, file: None }; + Ok(Token { kind: integer_token, span }) + } + + /// Skips white space. They are not significant in the source language + fn eat_whitespace(&mut self) { + self.eat_while(None, |ch| ch.is_whitespace()); + } + + fn eat_string_literal(&mut self) -> SpannedToken { + let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"'); + let str_literal_token = Token::Str(str_literal); + self.next_char(); // Advance past the closing quote + str_literal_token.into_span(start_span, end_span) + } } -impl<'a> Iterator for Lexer<'a> { - type Item = SpannedTokenResult; +impl<'a> Iterator for LexerNew<'a> { + type Item = TokenResult<'a>; + fn next(&mut self) -> Option { - if self.done { + if self.eof { None } else { Some(self.next_token()) diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index 9a9f7a88..e54bfa83 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -13,6 +13,8 @@ use std::{ str::Chars, }; +mod lexer; + /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either /// be identical or the latter being a substring of the former (example : bytes32 and byte) @@ -58,6 +60,9 @@ pub struct Lexer<'a> { pub eof_returned: bool, /// Current context. pub context: Context, + + + pub position: u32, } impl<'a> Lexer<'a> { @@ -72,6 +77,7 @@ impl<'a> Lexer<'a> { eof: false, eof_returned: false, context: Context::Global, + position: 0, } } @@ -225,6 +231,7 @@ impl<'a> Lexer<'a> { pub fn consume(&mut self) -> Option { self.chars.next().map(|x| { self.current_span_mut().end += 1; + self.position += 1; x }) } @@ -641,7 +648,11 @@ impl<'a> Iterator for Lexer<'a> { // identifiers ',' => TokenKind::Comma, '0'..='9' => { + dbg!(self.position); + dbg!(self.current_span()); self.dyn_consume(char::is_ascii_digit); + dbg!(self.position); + dbg!(self.current_span()); TokenKind::Num(self.slice().parse().unwrap()) } // Lexes Spaces and Newlines as Whitespace diff --git a/huff_utils/src/token.rs b/huff_utils/src/token.rs index 9fe7336f..5f43e26a 100644 --- a/huff_utils/src/token.rs +++ b/huff_utils/src/token.rs @@ -131,6 +131,16 @@ pub enum TokenKind { Storage, } +impl TokenKind { + pub fn into_single_span(self, position: u32) -> Token { + self.into_span(position, position) + } + + pub fn into_span(self, start: u32, end: u32) -> Token { + Token { kind: self, span: Span { start: start as usize, end: end as usize, file: None } } + } +} + impl fmt::Display for TokenKind { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let x = match self { From b3231db0840fd2510b4e6da75f1c676816bdd216 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 8 Mar 2023 16:39:40 -0700 Subject: [PATCH 05/68] more eat methods --- huff_lexer/src/lexer.rs | 81 +++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index a14fb4fa..71d6a51c 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -111,28 +111,38 @@ impl<'a> LexerNew<'a> { } // If it's the start of a hex literal ch if ch == '0' && self.peek().unwrap() == 'x' => { - + self.eat_hex_digit(ch) } - '=' => TokenKind::Assign, + '=' => self.single_char_token(TokenKind::Assign), '(' => { - + match self.context { + Context::Abi => self.context = Context::AbiArgs, + Context::MacroBody => self.context = Context::MacroArgs, + _ => {} + } + self.single_char_token(TokenKind::OpenParen) } ')' => { - + match self.context { + Context::AbiArgs => self.context = Context::Abi, + Context::MacroArgs => self.context = Context::MacroBody, + _ => {} + } + self.single_char_token(TokenKind::CloseParen) } - '[' => TokenKind::OpenBracket, - ']' => TokenKind::CloseBracket, + '[' => self.single_char_token(TokenKind::OpenBracket), + ']' => self.single_char_token(TokenKind::CloseBracket), '{' => { if self.context == Context::MacroDefinition { self.context = Context::MacroBody; } - TokenKind::OpenBrace + self.single_char_token(TokenKind::OpenBrace) } '}' => { if matches!(self.context, Context::MacroBody | Context::CodeTableBody) { self.context = Context::Global; } - TokenKind::CloseBrace + self.single_char_token(TokenKind::CloseBrace) } '+' => self.single_char_token(TokenKind::Add), '-' => self.single_char_token(TokenKind::Sub), @@ -149,32 +159,9 @@ impl<'a> LexerNew<'a> { self.eat_whitespace(); self.next_token() } - '"' => { - // loop { - // match self.peek() { - // Some('"') => { - // self.consume(); - // let str = self.slice(); - // break TokenKind::Str((str[1..str.len() - 1]).to_string()) - // } - // Some('\\') if matches!(self.nth_peek(1), Some('\\') | Some('"')) => { - // self.consume(); - // } - // Some(_) => {} - // None => { - // self.eof = true; - // tracing::error!(target: "lexer", "UNEXPECTED EOF SPAN"); - // return Some(Err(LexicalError::new( - // LexicalErrorKind::UnexpectedEof, - // self.current_span().clone(), - // ))) - // } - // } - // self.consume(); - // } - } - '\'' => { - + // String literals. String literals can also be wrapped by single quotes + '"' | '\'' => { + Ok(self.eat_string_literal()) } ch => { tracing::error!(target: "lexer", "UNSUPPORTED TOKEN '{}'", ch); @@ -184,8 +171,6 @@ impl<'a> LexerNew<'a> { )) } } - // TODO: change this to have a starting position - // Ok(Token { kind: token_kind, span: Span { start: self.position as usize, end: self.position as usize, file: None } }) } else { self.eof = true; Ok(Token { kind: TokenKind::Eof, span: Span { start: self.position as usize, end: self.position as usize, file: None } } ) @@ -242,15 +227,33 @@ impl<'a> LexerNew<'a> { Ok(Token { kind: integer_token, span }) } + fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult { + let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { + ch.is_ascii_hexdigit() | (ch == 'x') + }); + + let kind = if self.context == Context::CodeTableBody { + // In codetables, the bytecode provided is of arbitrary length. We pass + // the code as an Ident, and it is appended to the end of the runtime + // bytecode in codegen. + TokenKind::Ident(integer_str) + } else { + TokenKind::Literal(str_to_bytes32(&integer_str.as_ref())) + }; + + let span = Span { start: start as usize, end: end as usize, file: None }; + Ok(Token { kind, span }) + } + /// Skips white space. They are not significant in the source language fn eat_whitespace(&mut self) { self.eat_while(None, |ch| ch.is_whitespace()); } - fn eat_string_literal(&mut self) -> SpannedToken { + fn eat_string_literal(&mut self) -> Token { let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"'); - let str_literal_token = Token::Str(str_literal); - self.next_char(); // Advance past the closing quote + let str_literal_token = TokenKind::Str(str_literal); + self.consume(); // Advance past the closing quote str_literal_token.into_span(start_span, end_span) } From a39fe89a0d404e7b454d35e468d423e8e43db34d Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 8 Mar 2023 17:19:26 -0700 Subject: [PATCH 06/68] pound keyword check --- huff_lexer/src/lexer.rs | 46 +++++++++++++++++++++++++++++++++++++++++ huff_lexer/src/lib.rs | 4 ++++ 2 files changed, 50 insertions(+) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 71d6a51c..e871ae38 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -103,7 +103,36 @@ impl<'a> LexerNew<'a> { } // # keywords '#' => { + let (word, start, end) = self.eat_while(Some(ch), |ch| { + ch.is_ascii_alphabetic() + }); + let mut found_kind: Option = None; + + let keys = [TokenKind::Define, TokenKind::Include]; + for kind in keys.into_iter() { + let key = kind.to_string(); + let token_length = key.len() - 1; + let peeked = word; + + if key == peeked { + found_kind = Some(kind); + break + } + } + + if let Some(kind) = &found_kind { + Ok(kind.clone().into_span(start, end)) + } else if self.context == Context::Global && self.peek().unwrap() == '[' { + Ok(TokenKind::Pound.into_single_span(self.position)) + } else { + // Otherwise we don't support # prefixed indentifiers + tracing::error!(target: "lexer", "INVALID '#' CHARACTER USAGE"); + return Err(LexicalError::new( + LexicalErrorKind::InvalidCharacter('#'), + Span { start: self.position as usize, end: self.position as usize, file: None }, + )) + } } // Alphabetical characters ch if ch.is_alphabetic() || ch.eq(&'_') => { @@ -257,6 +286,23 @@ impl<'a> LexerNew<'a> { str_literal_token.into_span(start_span, end_span) } + /// Try to peek at next n characters from the source + // pub fn peek_n_chars(&mut self, n: usize) -> String { + // let cur_span: Ref = self.current_span(); + // // Break with an empty string if the bounds are exceeded + // if cur_span.end + n > self.source.source.len() { + // return String::default() + // } + // self.source.source[cur_span.start..cur_span.end + n].to_string() + // } + + // fn eat_alphabetic(&mut self, initial_char: char) -> (String, u32, u32) { + // let (word, start, end) = self.eat_while(Some(initial_char), |ch| { + // ch.is_ascii_alphabetic() + // }); + // (word, start, end) + // } + } impl<'a> Iterator for LexerNew<'a> { diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index e54bfa83..6f614256 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -361,12 +361,16 @@ impl<'a> Iterator for Lexer<'a> { let keys = [TokenKind::Define, TokenKind::Include]; for kind in keys.into_iter() { + dbg!(self.current_span()); + dbg!(self.position); let key = kind.to_string(); let token_length = key.len() - 1; let peeked = self.peek_n_chars(token_length); if key == peeked { self.nconsume(token_length); + dbg!(self.current_span()); + dbg!(self.position); found_kind = Some(kind); break } From 53404742a0eceb997ea64bbaf95d5289ec88a457 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 8 Mar 2023 17:18:11 -0700 Subject: [PATCH 07/68] add comment logic --- huff_lexer/src/lexer.rs | 12 +++++++++++- huff_lexer/src/lib.rs | 9 --------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index e871ae38..6467f001 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -96,10 +96,20 @@ impl<'a> LexerNew<'a> { match ch2 { '/' => { // Consume until newline - // let c = self.eat_while(None, |c| *c != '\n'); + let (comment_string, start, end) = self.eat_while(None, |c| c != '\n'); + Ok(TokenKind::Comment(comment_string).into_span(start, end)) } + '*' => { + let (comment_string, start, end) = self.eat_while(None, |c| c != '*' && self.peek() != Some('/')); + + Ok(TokenKind::Comment(comment_string).into_span(start, end)) + } + _ => self.single_char_token(TokenKind::Div) } } + else { + self.single_char_token(TokenKind::Div) + } } // # keywords '#' => { diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index 6f614256..3d61d377 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -60,9 +60,6 @@ pub struct Lexer<'a> { pub eof_returned: bool, /// Current context. pub context: Context, - - - pub position: u32, } impl<'a> Lexer<'a> { @@ -77,7 +74,6 @@ impl<'a> Lexer<'a> { eof: false, eof_returned: false, context: Context::Global, - position: 0, } } @@ -231,7 +227,6 @@ impl<'a> Lexer<'a> { pub fn consume(&mut self) -> Option { self.chars.next().map(|x| { self.current_span_mut().end += 1; - self.position += 1; x }) } @@ -652,11 +647,7 @@ impl<'a> Iterator for Lexer<'a> { // identifiers ',' => TokenKind::Comma, '0'..='9' => { - dbg!(self.position); - dbg!(self.current_span()); self.dyn_consume(char::is_ascii_digit); - dbg!(self.position); - dbg!(self.current_span()); TokenKind::Num(self.slice().parse().unwrap()) } // Lexes Spaces and Newlines as Whitespace From 48cbe4ad5e747e05fc335521d2828f20d374e185 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 8 Mar 2023 18:00:04 -0700 Subject: [PATCH 08/68] some of the alphabetical characters lexer --- huff_lexer/src/lexer.rs | 157 +++++++++++++++++++++++++++++++++++++--- huff_lexer/src/lib.rs | 4 + 2 files changed, 149 insertions(+), 12 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 6467f001..eb925c87 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -36,6 +36,9 @@ pub struct LexerNew<'a> { /// WARN: SHOULD NEVER BE MODIFIED! pub chars: Peekable>, position: u32, + /// The previous lexed Token. + /// NOTE: Cannot be a whitespace. + pub lookback: Option, eof: bool, /// Current context. pub context: Context, @@ -49,6 +52,7 @@ impl<'a> LexerNew<'a> { // We zip with the character index here to ensure the first char has index 0 chars: source.chars().peekable(), position: 0, + lookback: None, eof: false, context: Context::Global, } @@ -90,7 +94,7 @@ impl<'a> LexerNew<'a> { fn next_token(&mut self) -> TokenResult { // let start = self.position; if let Some(ch) = self.consume() { - match ch { + let token = match ch { '/' => { if let Some(ch2) = self.peek() { match ch2 { @@ -122,7 +126,6 @@ impl<'a> LexerNew<'a> { let keys = [TokenKind::Define, TokenKind::Include]; for kind in keys.into_iter() { let key = kind.to_string(); - let token_length = key.len() - 1; let peeked = word; if key == peeked { @@ -146,6 +149,81 @@ impl<'a> LexerNew<'a> { } // Alphabetical characters ch if ch.is_alphabetic() || ch.eq(&'_') => { + let (word, start, end) = self.eat_while(Some(ch), |c| { + c.is_alphanumeric() || c == '_' + }); + + let mut found_kind: Option = None; + let keys = [ + TokenKind::Macro, + TokenKind::Fn, + TokenKind::Test, + TokenKind::Function, + TokenKind::Constant, + TokenKind::Error, + TokenKind::Takes, + TokenKind::Returns, + TokenKind::Event, + TokenKind::NonPayable, + TokenKind::Payable, + TokenKind::Indexed, + TokenKind::View, + TokenKind::Pure, + // First check for packed jump table + TokenKind::JumpTablePacked, + // Match with jump table if not + TokenKind::JumpTable, + TokenKind::CodeTable, + ]; + for kind in keys.into_iter() { + if self.context == Context::MacroBody { + break + } + let key = kind.to_string(); + let peeked = word; + + if key == peeked { + found_kind = Some(kind); + break + } + } + + // Check to see if the found kind is, in fact, a keyword and not the name of + // a function. If it is, set `found_kind` to `None` so that it is set to a + // `TokenKind::Ident` in the following control flow. + if !self.check_keyword_rules(&found_kind) { + found_kind = None; + } + + if let Some(kind) = &found_kind { + match kind { + TokenKind::Macro | TokenKind::Fn | TokenKind::Test => { + self.context = Context::MacroDefinition + } + TokenKind::Function | TokenKind::Event | TokenKind::Error => { + self.context = Context::Abi + } + TokenKind::Constant => self.context = Context::Constant, + TokenKind::CodeTable => self.context = Context::CodeTableBody, + _ => (), + } + } + + // Check for free storage pointer builtin + let fsp = "FREE_STORAGE_POINTER"; + if fsp == word { + // Consume the parenthesis following the FREE_STORAGE_POINTER + // Note: This will consume `FREE_STORAGE_POINTER)` or + // `FREE_STORAGE_POINTER(` as well + if let Some('(') = self.peek() { + self.consume(); + } + if let Some(')') = self.peek() { + self.consume(); + } + found_kind = Some(TokenKind::FreeStoragePointer); + } + } // If it's the start of a hex literal @@ -209,7 +287,13 @@ impl<'a> LexerNew<'a> { Span { start: self.position as usize, end: self.position as usize, file: None }, )) } + }?; + + if token.kind != TokenKind::Whitespace { + self.lookback = Some(token.clone()); } + + return Ok(token) } else { self.eof = true; Ok(Token { kind: TokenKind::Eof, span: Span { start: self.position as usize, end: self.position as usize, file: None } } ) @@ -270,6 +354,7 @@ impl<'a> LexerNew<'a> { let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { ch.is_ascii_hexdigit() | (ch == 'x') }); + // TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34 let kind = if self.context == Context::CodeTableBody { // In codetables, the bytecode provided is of arbitrary length. We pass @@ -296,16 +381,6 @@ impl<'a> LexerNew<'a> { str_literal_token.into_span(start_span, end_span) } - /// Try to peek at next n characters from the source - // pub fn peek_n_chars(&mut self, n: usize) -> String { - // let cur_span: Ref = self.current_span(); - // // Break with an empty string if the bounds are exceeded - // if cur_span.end + n > self.source.source.len() { - // return String::default() - // } - // self.source.source[cur_span.start..cur_span.end + n].to_string() - // } - // fn eat_alphabetic(&mut self, initial_char: char) -> (String, u32, u32) { // let (word, start, end) = self.eat_while(Some(initial_char), |ch| { // ch.is_ascii_alphabetic() @@ -313,6 +388,64 @@ impl<'a> LexerNew<'a> { // (word, start, end) // } + /// Checks the previous token kind against the input. + pub fn checked_lookback(&self, kind: TokenKind) -> bool { + self.lookback.clone().and_then(|t| if t.kind == kind { Some(true) } else { None }).is_some() + } + + /// Check if a given keyword follows the keyword rules in the `source`. If not, it is a + /// `TokenKind::Ident`. + /// + /// Rules: + /// - The `macro`, `fn`, `test`, `function`, `constant`, `event`, `jumptable`, + /// `jumptable__packed`, and `table` keywords must be preceded by a `#define` keyword. + /// - The `takes` keyword must be preceded by an assignment operator: `=`. + /// - The `nonpayable`, `payable`, `view`, and `pure` keywords must be preceeded by one of these + /// keywords or a close paren. + /// - The `returns` keyword must be succeeded by an open parenthesis and must *not* be succeeded + /// by a colon or preceded by the keyword `function` + pub fn check_keyword_rules(&mut self, found_kind: &Option) -> bool { + match found_kind { + Some(TokenKind::Macro) | + Some(TokenKind::Fn) | + Some(TokenKind::Test) | + Some(TokenKind::Function) | + Some(TokenKind::Constant) | + Some(TokenKind::Error) | + Some(TokenKind::Event) | + Some(TokenKind::JumpTable) | + Some(TokenKind::JumpTablePacked) | + Some(TokenKind::CodeTable) => self.checked_lookback(TokenKind::Define), + Some(TokenKind::NonPayable) | + Some(TokenKind::Payable) | + Some(TokenKind::View) | + Some(TokenKind::Pure) => { + let keys = [ + TokenKind::NonPayable, + TokenKind::Payable, + TokenKind::View, + TokenKind::Pure, + TokenKind::CloseParen, + ]; + for key in keys { + if self.checked_lookback(key) { + return true + } + } + false + } + Some(TokenKind::Takes) => self.checked_lookback(TokenKind::Assign), + Some(TokenKind::Returns) => { + let cur_span_end = self.position; + self.eat_whitespace(); + // Allow for loose and tight syntax (e.g. `returns (0)`, `returns(0)`, ...) + self.peek().unwrap_or(')') == '(' && + !self.checked_lookback(TokenKind::Function) + } + _ => true, + } + } + } impl<'a> Iterator for LexerNew<'a> { diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index 3d61d377..2abe43b4 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -60,6 +60,8 @@ pub struct Lexer<'a> { pub eof_returned: bool, /// Current context. pub context: Context, + + pub position: u32, } impl<'a> Lexer<'a> { @@ -74,6 +76,7 @@ impl<'a> Lexer<'a> { eof: false, eof_returned: false, context: Context::Global, + position: 0, } } @@ -227,6 +230,7 @@ impl<'a> Lexer<'a> { pub fn consume(&mut self) -> Option { self.chars.next().map(|x| { self.current_span_mut().end += 1; + self.position += 1; x }) } From afc09fe130fbd2e105f90ab3669693c8602bf5c5 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 8 Mar 2023 18:13:18 -0700 Subject: [PATCH 09/68] lex fsp and jump label --- huff_lexer/src/lexer.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index eb925c87..53954137 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -224,6 +224,13 @@ impl<'a> LexerNew<'a> { found_kind = Some(TokenKind::FreeStoragePointer); } + if let Some(':') = self.peek() { + found_kind = Some(TokenKind::Label(word)); + self.consume(); + } + + + } // If it's the start of a hex literal From 933deb6c5f1e4962408391dbfd01f84420baead8 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Wed, 8 Mar 2023 19:07:44 -0700 Subject: [PATCH 10/68] word clone --- huff_lexer/src/lexer.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 53954137..a1e206a7 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -4,7 +4,7 @@ use std::{ iter::Peekable, str::Chars, }; - +/* hiehgsebgoiesgoiseg */ /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either /// be identical or the latter being a substring of the former (example : bytes32 and byte) @@ -105,7 +105,7 @@ impl<'a> LexerNew<'a> { } '*' => { let (comment_string, start, end) = self.eat_while(None, |c| c != '*' && self.peek() != Some('/')); - + Ok(TokenKind::Comment(comment_string).into_span(start, end)) } _ => self.single_char_token(TokenKind::Div) @@ -126,7 +126,7 @@ impl<'a> LexerNew<'a> { let keys = [TokenKind::Define, TokenKind::Include]; for kind in keys.into_iter() { let key = kind.to_string(); - let peeked = word; + let peeked = word.clone(); if key == peeked { found_kind = Some(kind); @@ -180,7 +180,7 @@ impl<'a> LexerNew<'a> { break } let key = kind.to_string(); - let peeked = word; + let peeked = word.clone(); if key == peeked { found_kind = Some(kind); @@ -229,7 +229,7 @@ impl<'a> LexerNew<'a> { self.consume(); } - + } From 1b0fa46d3e039044eb142962e9ca66ef12f87720 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 8 Mar 2023 17:59:57 -0700 Subject: [PATCH 11/68] wip --- huff_lexer/src/lib.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index 2abe43b4..6d457acf 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -13,8 +13,6 @@ use std::{ str::Chars, }; -mod lexer; - /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either /// be identical or the latter being a substring of the former (example : bytes32 and byte) @@ -360,16 +358,12 @@ impl<'a> Iterator for Lexer<'a> { let keys = [TokenKind::Define, TokenKind::Include]; for kind in keys.into_iter() { - dbg!(self.current_span()); - dbg!(self.position); let key = kind.to_string(); let token_length = key.len() - 1; let peeked = self.peek_n_chars(token_length); if key == peeked { self.nconsume(token_length); - dbg!(self.current_span()); - dbg!(self.position); found_kind = Some(kind); break } From 7063470a27db9e405025bd0e547ee3691cb967f6 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 8 Mar 2023 18:54:00 -0700 Subject: [PATCH 12/68] working! --- huff_lexer/src/lexer.rs | 45 +++++++++++++++++++++++++++++++++++++++++ huff_lexer/src/lib.rs | 11 ++++++++++ 2 files changed, 56 insertions(+) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index a1e206a7..9f50927f 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -96,6 +96,8 @@ impl<'a> LexerNew<'a> { if let Some(ch) = self.consume() { let token = match ch { '/' => { + + if let Some(ch2) = self.peek() { match ch2 { '/' => { @@ -104,6 +106,29 @@ impl<'a> LexerNew<'a> { Ok(TokenKind::Comment(comment_string).into_span(start, end)) } '*' => { + self.consume(); + let mut depth = 1usize; + while let Some(c) = self.consume() { + match c { + '/' if self.peek() == Some('*') => { + self.consume(); + depth += 1; + } + '*' if self.peek() == Some('/') => { + self.consume(); + depth -= 1; + if depth == 0 { + + break; + } + } + _ => (), + + + } + } + + let (comment_string, start, end) = self.eat_while(None, |c| c != '*' && self.peek() != Some('/')); Ok(TokenKind::Comment(comment_string).into_span(start, end)) @@ -115,6 +140,7 @@ impl<'a> LexerNew<'a> { self.single_char_token(TokenKind::Div) } } + // # keywords '#' => { let (word, start, end) = self.eat_while(Some(ch), |ch| { @@ -232,6 +258,25 @@ impl<'a> LexerNew<'a> { + if !(self.context != Context::MacroBody || found_kind.is_some()) { + if let Some(o) = OPCODES_MAP.get(&word) { + found_kind = Some(TokenKind::Opcode(o.to_owned())); + } + } + + if let Some(kind) = &found_kind { + return Ok(kind.clone().into_span(start, end)) + } + + // let slice = self.slice(); + let kind = if self.context == Context::MacroBody && + BuiltinFunctionKind::try_from(&word).is_ok() { + TokenKind::BuiltinFunction(word) + } else { + TokenKind::Ident(word) + }; + + Ok(kind.into_span(start, end)) } // If it's the start of a hex literal ch if ch == '0' && self.peek().unwrap() == 'x' => { diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index 6d457acf..6f614256 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -13,6 +13,8 @@ use std::{ str::Chars, }; +mod lexer; + /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either /// be identical or the latter being a substring of the former (example : bytes32 and byte) @@ -59,6 +61,7 @@ pub struct Lexer<'a> { /// Current context. pub context: Context, + pub position: u32, } @@ -358,12 +361,16 @@ impl<'a> Iterator for Lexer<'a> { let keys = [TokenKind::Define, TokenKind::Include]; for kind in keys.into_iter() { + dbg!(self.current_span()); + dbg!(self.position); let key = kind.to_string(); let token_length = key.len() - 1; let peeked = self.peek_n_chars(token_length); if key == peeked { self.nconsume(token_length); + dbg!(self.current_span()); + dbg!(self.position); found_kind = Some(kind); break } @@ -645,7 +652,11 @@ impl<'a> Iterator for Lexer<'a> { // identifiers ',' => TokenKind::Comma, '0'..='9' => { + dbg!(self.position); + dbg!(self.current_span()); self.dyn_consume(char::is_ascii_digit); + dbg!(self.position); + dbg!(self.current_span()); TokenKind::Num(self.slice().parse().unwrap()) } // Lexes Spaces and Newlines as Whitespace From 6a8cb27a8ba9adb48a43ae57a6bf2e578ca33166 Mon Sep 17 00:00:00 2001 From: jimboj Date: Wed, 8 Mar 2023 19:07:26 -0700 Subject: [PATCH 13/68] handle comments --- huff_lexer/src/lexer.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 9f50927f..8dae0df9 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -106,6 +106,7 @@ impl<'a> LexerNew<'a> { Ok(TokenKind::Comment(comment_string).into_span(start, end)) } '*' => { + // ref: https://github.com/rust-lang/rust/blob/900c3540378c8422b8087ffa3db60fa6c8abfcad/compiler/rustc_lexer/src/lib.rs#L474 self.consume(); let mut depth = 1usize; while let Some(c) = self.consume() { @@ -118,20 +119,19 @@ impl<'a> LexerNew<'a> { self.consume(); depth -= 1; if depth == 0 { - + // This block comment is closed, so for a construction like "/* */ */" + // there will be a successfully parsed block comment "/* */" + // and " */" will be processed separately. break; } } _ => (), - } } - - - let (comment_string, start, end) = self.eat_while(None, |c| c != '*' && self.peek() != Some('/')); - - Ok(TokenKind::Comment(comment_string).into_span(start, end)) + + // TODO add string or just not store comments + self.single_char_token(TokenKind::Comment("".to_owned())) } _ => self.single_char_token(TokenKind::Div) } @@ -153,7 +153,6 @@ impl<'a> LexerNew<'a> { for kind in keys.into_iter() { let key = kind.to_string(); let peeked = word.clone(); - if key == peeked { found_kind = Some(kind); break From 5cadc3860b070cd76c3e4d7a96f86e7d212cb972 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 11:08:05 -0700 Subject: [PATCH 14/68] remove lifetime refs from lexicalerrors, start checking new lexer tests --- huff_lexer/src/lexer.rs | 24 +++++++++--------------- huff_lexer/src/lib.rs | 2 +- huff_lexer/tests/hex.rs | 2 ++ huff_utils/src/error.rs | 28 ++++++++++++++-------------- 4 files changed, 26 insertions(+), 30 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 8dae0df9..33ce725f 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -31,7 +31,7 @@ pub enum Context { /// ## Lexer /// /// The lexer encapsulated in a struct. -pub struct LexerNew<'a> { +pub struct LexerNew<'a, 'e> { /// The source code as peekable chars. /// WARN: SHOULD NEVER BE MODIFIED! pub chars: Peekable>, @@ -46,8 +46,8 @@ pub struct LexerNew<'a> { pub type TokenResult<'a> = Result>; -impl<'a> LexerNew<'a> { - fn new(source: &'a str) -> Self { +impl<'a, 'e> LexerNew<'a, 'e> { + pub fn new(source: &'a str) -> Self { LexerNew { // We zip with the character index here to ensure the first char has index 0 chars: source.chars().peekable(), @@ -96,8 +96,6 @@ impl<'a> LexerNew<'a> { if let Some(ch) = self.consume() { let token = match ch { '/' => { - - if let Some(ch2) = self.peek() { match ch2 { '/' => { @@ -250,15 +248,12 @@ impl<'a> LexerNew<'a> { } if let Some(':') = self.peek() { - found_kind = Some(TokenKind::Label(word)); + found_kind = Some(TokenKind::Label(word.clone())); self.consume(); } - - - if !(self.context != Context::MacroBody || found_kind.is_some()) { - if let Some(o) = OPCODES_MAP.get(&word) { + if let Some(o) = OPCODES_MAP.get(&word.clone()) { found_kind = Some(TokenKind::Opcode(o.to_owned())); } } @@ -325,7 +320,7 @@ impl<'a> LexerNew<'a> { // Lexes Spaces and Newlines as Whitespace ch if ch.is_ascii_whitespace() => { self.eat_whitespace(); - self.next_token() + self.single_char_token(TokenKind::Whitespace) } // String literals. String literals can also be wrapped by single quotes '"' | '\'' => { @@ -351,7 +346,7 @@ impl<'a> LexerNew<'a> { } } - fn single_char_token(&self, token_kind: TokenKind) -> TokenResult { + fn single_char_token(&self, token_kind: TokenKind) -> TokenResult<'a> { Ok(token_kind.into_single_span(self.position)) } @@ -487,7 +482,6 @@ impl<'a> LexerNew<'a> { } Some(TokenKind::Takes) => self.checked_lookback(TokenKind::Assign), Some(TokenKind::Returns) => { - let cur_span_end = self.position; self.eat_whitespace(); // Allow for loose and tight syntax (e.g. `returns (0)`, `returns(0)`, ...) self.peek().unwrap_or(')') == '(' && @@ -499,8 +493,8 @@ impl<'a> LexerNew<'a> { } -impl<'a> Iterator for LexerNew<'a> { - type Item = TokenResult<'a>; +impl<'a, 'e> Iterator for LexerNew<'a, 'e> { + type Item = TokenResult<'e>; fn next(&mut self) -> Option { if self.eof { diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index 6f614256..d6b2959b 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -13,7 +13,7 @@ use std::{ str::Chars, }; -mod lexer; +pub mod lexer; /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either diff --git a/huff_lexer/tests/hex.rs b/huff_lexer/tests/hex.rs index afca00a4..149022d8 100644 --- a/huff_lexer/tests/hex.rs +++ b/huff_lexer/tests/hex.rs @@ -1,4 +1,5 @@ use huff_lexer::*; +use huff_lexer::lexer::LexerNew; use huff_utils::prelude::*; use std::ops::Deref; @@ -7,6 +8,7 @@ fn parses_single_hex() { let source = "0xa57B"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; let mut lexer = Lexer::new(flattened_source); + let mut lexer_new = LexerNew::new(flattened_source.source); // The first and only token should be lexed as Literal(0xa57B) let tok = lexer.next().unwrap().unwrap(); diff --git a/huff_utils/src/error.rs b/huff_utils/src/error.rs index 4e71186d..ea9f574e 100644 --- a/huff_utils/src/error.rs +++ b/huff_utils/src/error.rs @@ -67,41 +67,41 @@ pub enum ParserErrorKind { /// A Lexing Error #[derive(Debug, PartialEq, Eq, Clone)] -pub struct LexicalError<'a> { +pub struct LexicalError { /// The kind of error - pub kind: LexicalErrorKind<'a>, + pub kind: LexicalErrorKind, /// The span where the error occurred pub span: Span, } -impl<'a> LexicalError<'a> { +impl<'a> LexicalError { /// Public associated function to instatiate a new LexicalError. - pub fn new(kind: LexicalErrorKind<'a>, span: Span) -> Self { + pub fn new(kind: LexicalErrorKind, span: Span) -> Self { Self { kind, span } } } /// A Lexical Error Kind -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum LexicalErrorKind<'a> { +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum LexicalErrorKind { /// Unexpected end of file UnexpectedEof, /// Invalid character InvalidCharacter(char), /// Invalid Array Size /// String param expected to be usize parsable - InvalidArraySize(&'a str), + InvalidArraySize(String), /// Invalid Primitive EVM Type - InvalidPrimitiveType(&'a str), + InvalidPrimitiveType(String), } -impl<'a> Spanned for LexicalError<'a> { +impl<'a> Spanned for LexicalError { fn span(&self) -> Span { self.span.clone() } } -impl<'a, W: Write> Report for LexicalError<'a> { +impl<'a, W: Write> Report for LexicalError { fn report(&self, f: &mut Reporter<'_, W>) -> std::io::Result<()> { match self.kind { LexicalErrorKind::InvalidCharacter(ch) => write!(f.out, "Invalid character '{ch}'"), @@ -249,9 +249,9 @@ impl Report for CodegenError { /// CompilerError #[derive(Debug, Clone, PartialEq, Eq)] -pub enum CompilerError<'a> { +pub enum CompilerError { /// Failed to Lex Source - LexicalError(LexicalError<'a>), + LexicalError(LexicalError), /// File unpacking error FileUnpackError(UnpackError), /// Parsing Error @@ -261,10 +261,10 @@ pub enum CompilerError<'a> { /// Bytecode Generation Error CodegenError(CodegenError), /// Multiple Failed Compiles - FailedCompiles(Vec>), + FailedCompiles(Vec), } -impl<'a> fmt::Display for CompilerError<'a> { +impl<'a> fmt::Display for CompilerError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { CompilerError::LexicalError(le) => match le.kind { From a5e3099dfed9200b5ebfb65ba66dead0bcdedc3e Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 11:56:43 -0700 Subject: [PATCH 15/68] fix errors and add test PASS CORE TESTS --- huff_core/benches/huff_benchmark.rs | 32 ++++++++++++++++++++ huff_core/src/lib.rs | 20 ++++++------ huff_core/tests/compiling.rs | 3 +- huff_lexer/src/lexer.rs | 35 ++++++++++++--------- huff_lexer/src/lib.rs | 14 ++------- huff_parser/tests/macro.rs | 47 ++++++++++++++++++----------- huff_tests/src/errors.rs | 2 +- huff_utils/src/error.rs | 4 +-- huff_utils/src/file_provider.rs | 12 ++++---- 9 files changed, 106 insertions(+), 63 deletions(-) diff --git a/huff_core/benches/huff_benchmark.rs b/huff_core/benches/huff_benchmark.rs index 1668c287..861c3689 100644 --- a/huff_core/benches/huff_benchmark.rs +++ b/huff_core/benches/huff_benchmark.rs @@ -37,6 +37,37 @@ fn lex_erc20_from_source_benchmark(c: &mut Criterion) { }); } +fn lex_erc20_from_source_benchmark_new(c: &mut Criterion) { + let file_provider = Arc::new(FileSystemFileProvider::new()); + let file_sources: Vec> = Compiler::fetch_sources( + vec![PathBuf::from("../huff-examples/erc20/contracts/ERC20.huff".to_string())], + file_provider.clone(), + ) + .into_iter() + .map(|p| p.unwrap()) + .collect(); + + // Recurse file deps + generate flattened source + let file_source = file_sources.get(0).unwrap(); + let recursed_file_source = + Compiler::recurse_deps(Arc::clone(file_source), &files::Remapper::new("./"), file_provider) + .unwrap(); + let flattened = FileSource::fully_flatten(Arc::clone(&recursed_file_source)); + let full_source = FullFileSource { + source: &flattened.0, + file: Some(Arc::clone(file_source)), + spans: flattened.1, + }; + + // Isolate lexing to benchmark + c.bench_function("Lexer_New: ERC-20", |b| { + b.iter(|| { + let lexer = lexer::LexerNew::new(full_source.source); + let _ = lexer.into_iter().map(|x| x.unwrap()).collect::>(); + }) + }); +} + fn parse_erc20_benchmark(c: &mut Criterion) { let file_provider = Arc::new(FileSystemFileProvider::new()); let file_sources: Vec> = Compiler::fetch_sources( @@ -213,6 +244,7 @@ fn erc721_compilation_benchmark(c: &mut Criterion) { criterion_group!( benches, lex_erc20_from_source_benchmark, + lex_erc20_from_source_benchmark_new, parse_erc20_benchmark, codegen_erc20_benchmark, erc20_compilation_benchmark, diff --git a/huff_core/src/lib.rs b/huff_core/src/lib.rs index 99ca92f1..7dd7944c 100644 --- a/huff_core/src/lib.rs +++ b/huff_core/src/lib.rs @@ -166,7 +166,7 @@ impl<'a> Compiler<'a> { /// 4. For each top-level file [Parallelized], generate the artifact using /// [gen_artifact](Compiler::gen_artifact). /// 5. Return the compiling error(s) or successfully generated artifacts. - pub fn execute(&self) -> Result>, Arc>> { + pub fn execute(&self) -> Result>, Arc> { // Grab the input files let file_paths: Vec = self.file_provider.transform_paths(&self.sources)?; @@ -214,7 +214,7 @@ impl<'a> Compiler<'a> { None => { tracing::debug!(target: "core", "FINISHED RECURSING DEPENDENCIES!"); // Parallel Dependency Resolution - let recursed_file_sources: Vec, Arc>>> = + let recursed_file_sources: Vec, Arc>> = files .into_par_iter() .map(|v| { @@ -240,10 +240,10 @@ impl<'a> Compiler<'a> { tracing::info!(target: "core", "COMPILER RECURSED {} FILE DEPENDENCIES", files.len()); // Parallel Compilation - let potential_artifacts: Vec>> = + let potential_artifacts: Vec> = files.into_par_iter().map(|f| self.gen_artifact(f)).collect(); - let mut gen_errors: Vec> = vec![]; + let mut gen_errors: Vec = vec![]; // Output errors + return OR print # of successfully compiled files for r in potential_artifacts { @@ -275,7 +275,7 @@ impl<'a> Compiler<'a> { /// 3. Recurse file dependencies in parallel with [recurse_deps](Compiler::recurse_deps). /// 4. For each top-level file, parse its contents and return a vec of [Contract](Contract) /// ASTs. - pub fn grab_contracts(&self) -> Result, Arc>> { + pub fn grab_contracts(&self) -> Result, Arc> { // Grab the input files let file_paths: Vec = self.file_provider.transform_paths(&self.sources)?; @@ -297,7 +297,7 @@ impl<'a> Compiler<'a> { .filter_map(|fs| fs.as_ref().map(Arc::clone).ok()) .collect::>>(); - let recursed_file_sources: Vec, Arc>>> = files + let recursed_file_sources: Vec, Arc>> = files .into_par_iter() .map(|f| { Self::recurse_deps( @@ -360,13 +360,13 @@ impl<'a> Compiler<'a> { tracing::info!(target: "core", "PARSED CONTRACT [{}]", file.path); Ok(contract) }) - .collect::, Arc>>>() + .collect::, Arc>>() } /// Artifact Generation /// /// Compiles a FileSource into an Artifact. - pub fn gen_artifact(&self, file: Arc) -> Result> { + pub fn gen_artifact(&self, file: Arc) -> Result { // Fully Flatten a file into a source string containing source code of file and all // its dependencies let flattened = FileSource::fully_flatten(Arc::clone(&file)); @@ -498,7 +498,7 @@ impl<'a> Compiler<'a> { pub fn fetch_sources( paths: Vec, reader: Arc>, - ) -> Vec, CompilerError<'a>>> { + ) -> Vec, CompilerError>> { paths.into_par_iter().map(|pb| reader.read_file(pb)).collect() } @@ -507,7 +507,7 @@ impl<'a> Compiler<'a> { fs: Arc, remapper: &Remapper, reader: Arc>, - ) -> Result, Arc>> { + ) -> Result, Arc> { tracing::debug!(target: "core", "RECURSING DEPENDENCIES FOR {}", fs.path); let mut new_fs = FileSource { path: fs.path.clone(), ..Default::default() }; let file_source = if let Some(s) = &fs.source { diff --git a/huff_core/tests/compiling.rs b/huff_core/tests/compiling.rs index 4e1349d9..54fdba6c 100644 --- a/huff_core/tests/compiling.rs +++ b/huff_core/tests/compiling.rs @@ -40,7 +40,8 @@ const SOURCE: &str = r#" fn compiles_constructor_bytecode() { // Lex and Parse the source code let flattened_source = FullFileSource { source: SOURCE, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + //let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 33ce725f..22c8be09 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -1,8 +1,9 @@ use huff_utils::prelude::*; use regex::Regex; use std::{ - iter::Peekable, + iter::{Peekable, Zip}, str::Chars, + ops::RangeFrom, }; /* hiehgsebgoiesgoiseg */ /// Defines a context in which the lexing happens. @@ -31,10 +32,10 @@ pub enum Context { /// ## Lexer /// /// The lexer encapsulated in a struct. -pub struct LexerNew<'a, 'e> { +pub struct LexerNew<'a> { /// The source code as peekable chars. /// WARN: SHOULD NEVER BE MODIFIED! - pub chars: Peekable>, + pub chars: Peekable, RangeFrom>>, position: u32, /// The previous lexed Token. /// NOTE: Cannot be a whitespace. @@ -44,13 +45,14 @@ pub struct LexerNew<'a, 'e> { pub context: Context, } -pub type TokenResult<'a> = Result>; +pub type TokenResult = Result; -impl<'a, 'e> LexerNew<'a, 'e> { +impl<'a> LexerNew<'a> { pub fn new(source: &'a str) -> Self { LexerNew { // We zip with the character index here to ensure the first char has index 0 - chars: source.chars().peekable(), + //chars: source.chars().peekable(), + chars: source.chars().zip(0..).peekable(), position: 0, lookback: None, eof: false, @@ -60,15 +62,20 @@ impl<'a, 'e> LexerNew<'a, 'e> { /// Consumes the next character pub fn consume(&mut self) -> Option { - self.chars.next().map(|x| { - self.position += 1; - x - }) + // self.chars.next().map(|x| { + // self.position += 1; + // x + // }) + + let (c, index) = self.chars.next()?; + self.position = index; + Some(c) } /// Try to peek at the next character from the source pub fn peek(&mut self) -> Option { - self.chars.peek().copied() + //self.chars.peek().copied() + self.chars.peek().map(|(c, _) | *c) } /// Consume characters until a sequence matches @@ -346,7 +353,7 @@ impl<'a, 'e> LexerNew<'a, 'e> { } } - fn single_char_token(&self, token_kind: TokenKind) -> TokenResult<'a> { + fn single_char_token(&self, token_kind: TokenKind) -> TokenResult { Ok(token_kind.into_single_span(self.position)) } @@ -493,8 +500,8 @@ impl<'a, 'e> LexerNew<'a, 'e> { } -impl<'a, 'e> Iterator for LexerNew<'a, 'e> { - type Item = TokenResult<'e>; +impl<'a> Iterator for LexerNew<'a> { + type Item = TokenResult; fn next(&mut self) -> Option { if self.eof { diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index d6b2959b..b6a05f88 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -326,7 +326,7 @@ impl<'a> Lexer<'a> { } impl<'a> Iterator for Lexer<'a> { - type Item = Result>; + type Item = Result; /// Iterates over the source code fn next(&mut self) -> Option { @@ -361,16 +361,12 @@ impl<'a> Iterator for Lexer<'a> { let keys = [TokenKind::Define, TokenKind::Include]; for kind in keys.into_iter() { - dbg!(self.current_span()); - dbg!(self.position); let key = kind.to_string(); let token_length = key.len() - 1; let peeked = self.peek_n_chars(token_length); if key == peeked { self.nconsume(token_length); - dbg!(self.current_span()); - dbg!(self.position); found_kind = Some(kind); break } @@ -542,7 +538,7 @@ impl<'a> Iterator for Lexer<'a> { .map_err(|_| { let err = LexicalError { kind: LexicalErrorKind::InvalidArraySize( - &words[1], + words[1].clone(), ), span: self.current_span().clone(), }; @@ -559,7 +555,7 @@ impl<'a> Iterator for Lexer<'a> { found_kind = Some(TokenKind::ArrayType(primitive, size_vec)); } else { let err = LexicalError { - kind: LexicalErrorKind::InvalidPrimitiveType(&words[0]), + kind: LexicalErrorKind::InvalidPrimitiveType(words[0].clone()), span: self.current_span().clone(), }; tracing::error!(target: "lexer", "{}", format!("{err:?}")); @@ -652,11 +648,7 @@ impl<'a> Iterator for Lexer<'a> { // identifiers ',' => TokenKind::Comma, '0'..='9' => { - dbg!(self.position); - dbg!(self.current_span()); self.dyn_consume(char::is_ascii_digit); - dbg!(self.position); - dbg!(self.current_span()); TokenKind::Num(self.slice().parse().unwrap()) } // Lexes Spaces and Newlines as Whitespace diff --git a/huff_parser/tests/macro.rs b/huff_parser/tests/macro.rs index 421e14d9..83d6b80a 100644 --- a/huff_parser/tests/macro.rs +++ b/huff_parser/tests/macro.rs @@ -1,13 +1,24 @@ -use huff_lexer::*; +use huff_lexer::{*, lexer::LexerNew}; use huff_parser::*; use huff_utils::{evm::Opcode, prelude::*}; +use tracing::debug; #[test] fn empty_macro() { let source = "#define macro HELLO_WORLD() = takes(0) returns(4) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + //let lexer = Lexer::new(flattened_source.clone()); + let lexer = lexer::LexerNew::new(flattened_source.source); + // let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); + + //dbg!(tokens.clone()); + // dbg!(tokensNew.clone()); + // if tokens.clone() == tokensNew.clone() { + // println!("FUCK YES") + // } else { + // println!("FUCK NO") + // } let mut parser = Parser::new(tokens, None); // Grab the first macro @@ -20,22 +31,22 @@ fn empty_macro() { takes: 0, returns: 4, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 13, file: None }, - Span { start: 14, end: 25, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 26, end: 27, file: None }, - Span { start: 28, end: 29, file: None }, - Span { start: 30, end: 35, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 36, end: 37, file: None }, - Span { start: 37, end: 38, file: None }, - Span { start: 39, end: 46, file: None }, - Span { start: 46, end: 47, file: None }, - Span { start: 47, end: 48, file: None }, - Span { start: 48, end: 49, file: None }, - Span { start: 50, end: 51, file: None }, - Span { start: 51, end: 52, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 12, file: None }, + Span { start: 14, end: 24, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 26, end: 26, file: None }, + Span { start: 28, end: 28, file: None }, + Span { start: 30, end: 34, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 36, end: 36, file: None }, + Span { start: 37, end: 37, file: None }, + Span { start: 39, end: 45, file: None }, + Span { start: 46, end: 46, file: None }, + Span { start: 47, end: 47, file: None }, + Span { start: 48, end: 48, file: None }, + Span { start: 50, end: 50, file: None }, + Span { start: 51, end: 51, file: None }, ]), outlined: false, test: false, diff --git a/huff_tests/src/errors.rs b/huff_tests/src/errors.rs index c2959bb9..6491044d 100644 --- a/huff_tests/src/errors.rs +++ b/huff_tests/src/errors.rs @@ -15,7 +15,7 @@ impl fmt::Display for RunnerError { } /// Convert a `CompilerError` to a `RunnerError` -impl From> for RunnerError { +impl From for RunnerError { fn from(e: CompilerError) -> Self { RunnerError(e.to_string()) } diff --git a/huff_utils/src/error.rs b/huff_utils/src/error.rs index ea9f574e..68f5c397 100644 --- a/huff_utils/src/error.rs +++ b/huff_utils/src/error.rs @@ -103,7 +103,7 @@ impl<'a> Spanned for LexicalError { impl<'a, W: Write> Report for LexicalError { fn report(&self, f: &mut Reporter<'_, W>) -> std::io::Result<()> { - match self.kind { + match &self.kind { LexicalErrorKind::InvalidCharacter(ch) => write!(f.out, "Invalid character '{ch}'"), LexicalErrorKind::UnexpectedEof => write!(f.out, "Found unexpected EOF"), LexicalErrorKind::InvalidArraySize(str) => { @@ -267,7 +267,7 @@ pub enum CompilerError { impl<'a> fmt::Display for CompilerError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { - CompilerError::LexicalError(le) => match le.kind { + CompilerError::LexicalError(le) => match &le.kind { LexicalErrorKind::UnexpectedEof => { write!( f, diff --git a/huff_utils/src/file_provider.rs b/huff_utils/src/file_provider.rs index 887069f7..78fb0ac6 100644 --- a/huff_utils/src/file_provider.rs +++ b/huff_utils/src/file_provider.rs @@ -15,10 +15,10 @@ use uuid::Uuid; /// Provides functions to supply file contents by paths. pub trait FileProvider<'a>: Send + Sync + Debug { /// Returns a FileSource containing the file contents referred to by the supplied path. - fn read_file(&self, pb: PathBuf) -> Result, CompilerError<'a>>; + fn read_file(&self, pb: PathBuf) -> Result, CompilerError>; /// Takes a list of strings and returns a transformed list PathBufs. - fn transform_paths(&self, sources: &[String]) -> Result, CompilerError<'a>>; + fn transform_paths(&self, sources: &[String]) -> Result, CompilerError>; } /// A FileReader that reads files from the filesystem. @@ -39,7 +39,7 @@ impl FileSystemFileProvider { } impl<'a> FileProvider<'a> for FileSystemFileProvider { - fn read_file(&self, pb: PathBuf) -> Result, CompilerError<'a>> { + fn read_file(&self, pb: PathBuf) -> Result, CompilerError> { let file_loc = String::from(pb.to_string_lossy()); match std::fs::read_to_string(&file_loc) { Ok(source) => Ok(Arc::new(FileSource { @@ -56,7 +56,7 @@ impl<'a> FileProvider<'a> for FileSystemFileProvider { } } - fn transform_paths(&self, sources: &[String]) -> Result, CompilerError<'a>> { + fn transform_paths(&self, sources: &[String]) -> Result, CompilerError> { let mut paths = vec![]; for f in sources { // If the file is huff, use the path, otherwise unpack @@ -100,7 +100,7 @@ impl InMemoryFileProvider { } impl<'a> FileProvider<'a> for InMemoryFileProvider { - fn read_file(&self, pb: PathBuf) -> Result, CompilerError<'a>> { + fn read_file(&self, pb: PathBuf) -> Result, CompilerError> { let path = pb.to_str().unwrap_or_default(); let localized = strip_path_prefix(path); match self.sources.get(localized) { @@ -118,7 +118,7 @@ impl<'a> FileProvider<'a> for InMemoryFileProvider { } } - fn transform_paths(&self, sources: &[String]) -> Result, CompilerError<'a>> { + fn transform_paths(&self, sources: &[String]) -> Result, CompilerError> { let mut paths = vec![]; for f in sources { // If the file is huff, use the path, otherwise ignore From 99605194385ebcadbc5e2cfa583487bf269d9bb9 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 12:06:29 -0700 Subject: [PATCH 16/68] 180x speedup baby --- huff_lexer/src/lexer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 22c8be09..90132f7d 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -415,7 +415,7 @@ impl<'a> LexerNew<'a> { // bytecode in codegen. TokenKind::Ident(integer_str) } else { - TokenKind::Literal(str_to_bytes32(&integer_str.as_ref())) + TokenKind::Literal(str_to_bytes32(&integer_str[2..].as_ref())) }; let span = Span { start: start as usize, end: end as usize, file: None }; From cd71da67c5f72dc79564cfa86de8c6d4154011bc Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 12:51:39 -0700 Subject: [PATCH 17/68] wip/migrate tests --- huff_lexer/tests/arg_calls.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/huff_lexer/tests/arg_calls.rs b/huff_lexer/tests/arg_calls.rs index 7cc96f65..ebae91d4 100644 --- a/huff_lexer/tests/arg_calls.rs +++ b/huff_lexer/tests/arg_calls.rs @@ -17,8 +17,7 @@ fn lexes_arg_calls() { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; // Parse tokens - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Eat Tokens let _ = lexer.next(); // Whitespace From 2fb06e42eceb286ddd2abf1dabdfbbf7b5a07972 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 15:12:10 -0700 Subject: [PATCH 18/68] abi args logic and fix setting lookback --- huff_lexer/src/lexer.rs | 95 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 90132f7d..02700ac7 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -179,7 +179,7 @@ impl<'a> LexerNew<'a> { } // Alphabetical characters ch if ch.is_alphabetic() || ch.eq(&'_') => { - let (word, start, end) = self.eat_while(Some(ch), |c| { + let (word, start, mut end) = self.eat_while(Some(ch), |c| { c.is_alphanumeric() || c == '_' }); @@ -265,16 +265,93 @@ impl<'a> LexerNew<'a> { } } - if let Some(kind) = &found_kind { - return Ok(kind.clone().into_span(start, end)) - } + if self.context == Context::AbiArgs { + let curr_char = self.peek().unwrap(); + if !['(', ')'].contains(&curr_char) { + let (partial_raw_type, _, abi_args_end) = self + .eat_while(Some(ch), |c| { + c.is_alphanumeric() || c == '[' || c == ']' + }); + let raw_type = word.clone() + &partial_raw_type[1..]; + + if raw_type == TokenKind::Calldata.to_string() { + found_kind = Some(TokenKind::Calldata); + } else if raw_type == TokenKind::Memory.to_string() { + found_kind = Some(TokenKind::Memory); + } else if raw_type == TokenKind::Storage.to_string() { + found_kind = Some(TokenKind::Storage); + } else if EVM_TYPE_ARRAY_REGEX.is_match(&raw_type) { + // split to get array size and type + // TODO: support multi-dimensional arrays + let words: Vec = Regex::new(r"\[") + .unwrap() + .split(&raw_type) + .map(|x| x.replace(']', "")) + .collect(); + let mut size_vec: Vec = Vec::new(); + // go over all array sizes + let sizes = words.get(1..words.len()).unwrap(); + for size in sizes.iter() { + match size.is_empty() { + true => size_vec.push(0), + false => { + let arr_size: usize = size + .parse::() + .map_err(|_| { + let err = LexicalError { + kind: LexicalErrorKind::InvalidArraySize( + words[1].clone(), + ), + span: Span { start: start as usize, end: end as usize, file: None }, + }; + tracing::error!(target: "lexer", "{}", format!("{err:?}")); + err + }) + .unwrap(); + size_vec.push(arr_size); + } + } + } + let primitive = PrimitiveEVMType::try_from(words[0].clone()); + if let Ok(primitive) = primitive { + found_kind = Some(TokenKind::ArrayType(primitive, size_vec)); + } else { + let err = LexicalError { + kind: LexicalErrorKind::InvalidPrimitiveType( + words[0].clone(), + ), + span: Span { + start: start as usize, + end: end as usize, + file: None, + }, + }; + tracing::error!(target: "lexer", "{}", format!("{err:?}")); + } + } + end = abi_args_end; + } else { + // We don't want to consider any argument names or the "indexed" + // keyword here. + let primitive = PrimitiveEVMType::try_from(word.clone()); + if let Ok(primitive) = primitive { + found_kind = Some(TokenKind::PrimitiveType(primitive)); + } + } + } - // let slice = self.slice(); - let kind = if self.context == Context::MacroBody && - BuiltinFunctionKind::try_from(&word).is_ok() { - TokenKind::BuiltinFunction(word) + let kind = if let Some(kind) = &found_kind { + kind.clone() } else { - TokenKind::Ident(word) + let kind = if self.context == Context::MacroBody + && BuiltinFunctionKind::try_from(&word).is_ok() + { + TokenKind::BuiltinFunction(word) + } else { + TokenKind::Ident(word) + }; + + kind }; Ok(kind.into_span(start, end)) From 19d787c1dcdcee6415ddc73fe3e82b55bb7bb878 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 15:25:11 -0700 Subject: [PATCH 19/68] fix bytes32 in an event context --- huff_lexer/src/lexer.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 02700ac7..8a8cfacc 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -264,9 +264,10 @@ impl<'a> LexerNew<'a> { found_kind = Some(TokenKind::Opcode(o.to_owned())); } } - + println!("self.context: {:?}", self.context); if self.context == Context::AbiArgs { let curr_char = self.peek().unwrap(); + dbg!(curr_char); if !['(', ')'].contains(&curr_char) { let (partial_raw_type, _, abi_args_end) = self .eat_while(Some(ch), |c| { @@ -328,6 +329,13 @@ impl<'a> LexerNew<'a> { }; tracing::error!(target: "lexer", "{}", format!("{err:?}")); } + } else { + // We don't want to consider any argument names or the "indexed" + // keyword here. + let primitive = PrimitiveEVMType::try_from(word.clone()); + if let Ok(primitive) = primitive { + found_kind = Some(TokenKind::PrimitiveType(primitive)); + } } end = abi_args_end; } else { From d44d61612ac4901ed5c0276d5b30038c79072331 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 13:57:28 -0700 Subject: [PATCH 20/68] add comment body support --- huff_lexer/src/lexer.rs | 37 ++++++++++++----- huff_lexer/tests/arg_calls.rs | 18 +++------ huff_lexer/tests/builtins.rs | 27 +++++-------- huff_lexer/tests/comments.rs | 75 +++++++++++++++-------------------- 4 files changed, 74 insertions(+), 83 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 8a8cfacc..5a0ef041 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -40,7 +40,8 @@ pub struct LexerNew<'a> { /// The previous lexed Token. /// NOTE: Cannot be a whitespace. pub lookback: Option, - eof: bool, + /// Bool indicating if we have reached EOF + pub eof: bool, /// Current context. pub context: Context, } @@ -103,40 +104,53 @@ impl<'a> LexerNew<'a> { if let Some(ch) = self.consume() { let token = match ch { '/' => { + let mut comment_string = String::new(); + let start = self.position; + comment_string.push(ch); if let Some(ch2) = self.peek() { match ch2 { '/' => { // Consume until newline - let (comment_string, start, end) = self.eat_while(None, |c| c != '\n'); + comment_string.push(ch2); + let (comment_string, start, end) = self.eat_while(Some(ch), |c| c != '\n'); Ok(TokenKind::Comment(comment_string).into_span(start, end)) } '*' => { // ref: https://github.com/rust-lang/rust/blob/900c3540378c8422b8087ffa3db60fa6c8abfcad/compiler/rustc_lexer/src/lib.rs#L474 - self.consume(); + let c = self.consume(); + comment_string.push(c.unwrap()); let mut depth = 1usize; while let Some(c) = self.consume() { match c { '/' if self.peek() == Some('*') => { - self.consume(); + comment_string.push(c); + let c2 = self.consume(); + comment_string.push(c2.unwrap()); depth += 1; } '*' if self.peek() == Some('/') => { - self.consume(); + comment_string.push(c); + let c2 = self.consume(); + comment_string.push(c2.unwrap()); depth -= 1; if depth == 0 { // This block comment is closed, so for a construction like "/* */ */" // there will be a successfully parsed block comment "/* */" // and " */" will be processed separately. - break; + + break; } } - _ => (), + _ => { + comment_string.push(c); + }, } } + Ok(TokenKind::Comment(comment_string).into_span(start, self.position)) // TODO add string or just not store comments - self.single_char_token(TokenKind::Comment("".to_owned())) + // self.single_char_token(TokenKind::Comment("".to_owned())) } _ => self.single_char_token(TokenKind::Div) } @@ -403,14 +417,15 @@ impl<'a> LexerNew<'a> { '-' => self.single_char_token(TokenKind::Sub), '*' => self.single_char_token(TokenKind::Mul), '<' => self.single_char_token(TokenKind::LeftAngle), - '>' => self.single_char_token(TokenKind::LeftAngle), + '>' => self.single_char_token(TokenKind::RightAngle), // NOTE: TokenKind::Div is lexed further up since it overlaps with comment - ':' => self.single_char_token(TokenKind::LeftAngle), + ':' => self.single_char_token(TokenKind::Colon), // identifiers - ',' => self.single_char_token(TokenKind::LeftAngle), + ',' => self.single_char_token(TokenKind::Comma), '0'..='9' => self.eat_digit(ch), // Lexes Spaces and Newlines as Whitespace ch if ch.is_ascii_whitespace() => { + dbg!("Are we hitting this?"); self.eat_whitespace(); self.single_char_token(TokenKind::Whitespace) } diff --git a/huff_lexer/tests/arg_calls.rs b/huff_lexer/tests/arg_calls.rs index ebae91d4..91cf0eae 100644 --- a/huff_lexer/tests/arg_calls.rs +++ b/huff_lexer/tests/arg_calls.rs @@ -38,7 +38,6 @@ fn lexes_arg_calls() { let _ = lexer.next(); // paren let _ = lexer.next(); // Whitespace let _ = lexer.next(); // returns - let _ = lexer.next(); // Whitespace let _ = lexer.next(); // paren let _ = lexer.next(); // 3 let _ = lexer.next(); // paren @@ -65,25 +64,22 @@ fn lexes_arg_calls() { // We should find a left angle let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::LeftAngle, Span::new(184..185, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(184..185, None)); + assert_eq!(tok, Token::new(TokenKind::LeftAngle, Span::new(184..184, None))); + // The we should have an Ident let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Ident("error".to_string()), Span::new(185..190, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(185..190, None)); + assert_eq!(tok, Token::new(TokenKind::Ident("error".to_string()), Span::new(185..189, None))); // Then should find a right angle let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::RightAngle, Span::new(190..191, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(190..191, None)); + assert_eq!(tok, Token::new(TokenKind::RightAngle, Span::new(190..190, None))); let _ = lexer.next(); // Whitespace // Jumpi Opcode let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Opcode(Opcode::Jumpi), Span::new(192..197, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(192..197, None)); + assert_eq!(tok, Token::new(TokenKind::Opcode(Opcode::Jumpi), Span::new(192..196, None))); // Eat the rest of the tokens let _ = lexer.next(); // Whitespace @@ -92,11 +88,9 @@ fn lexes_arg_calls() { // Get an EOF token let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Eof, Span::new(source.len()..source.len(), None))); - assert_eq!(lexer.current_span().deref(), &Span::new(source.len()..source.len(), None)); + assert_eq!(tok, Token::new(TokenKind::Eof, Span::new(source.len()-1..source.len()-1, None))); // We should have reached EOF now - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); assert!(lexer.next().is_none()); } diff --git a/huff_lexer/tests/builtins.rs b/huff_lexer/tests/builtins.rs index d9257ba6..33906b04 100644 --- a/huff_lexer/tests/builtins.rs +++ b/huff_lexer/tests/builtins.rs @@ -1,4 +1,4 @@ -use huff_lexer::Lexer; +use huff_lexer::*; use huff_utils::prelude::{FullFileSource, Span, Token, TokenKind}; use std::ops::Deref; @@ -25,8 +25,7 @@ fn parses_builtin_function_in_macro_body() { "{", "}", ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); let _ = lexer.next(); // whitespace let _ = lexer.next(); // #define @@ -55,12 +54,11 @@ fn parses_builtin_function_in_macro_body() { // The builtin fn should be parsed as a `TokenKind::BuiltinFunction` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let builtin_span = Span::new(74..74 + builtin.len(), None); + let builtin_span = Span::new(74..74 + builtin.len()-1, None); assert_eq!( unwrapped, Token::new(TokenKind::BuiltinFunction(builtin.to_string()), builtin_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &builtin_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // MAIN @@ -68,9 +66,9 @@ fn parses_builtin_function_in_macro_body() { let _ = lexer.next(); // whitespace let _ = lexer.next(); // } let _ = lexer.next(); // whitespace - + let _ = lexer.next(); // eof + // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } @@ -92,24 +90,21 @@ fn fails_to_parse_builtin_outside_macro_body() { for builtin in builtin_funcs { let source = &format!("{builtin}(MAIN)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(0..builtin.len(), None); + let fn_name_span = Span::new(0..builtin.len()-1, None); assert_eq!( unwrapped, Token::new(TokenKind::BuiltinFunction(builtin.to_string()), fn_name_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &fn_name_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // MAIN let _ = lexer.next(); // close parenthesis // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } @@ -129,8 +124,7 @@ fn fails_to_parse_invalid_builtin() { "{", "}", ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); let _ = lexer.next(); // whitespace let _ = lexer.next(); // #define @@ -159,12 +153,11 @@ fn fails_to_parse_invalid_builtin() { // The builtin fn should be parsed as a `TokenKind::BuiltinFunction` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let builtin_span = Span::new(74..74 + builtin.len(), None); + let builtin_span = Span::new(74..74 + builtin.len()-1, None); assert_eq!( unwrapped, Token::new(TokenKind::BuiltinFunction(builtin.to_string()), builtin_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &builtin_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // MAIN @@ -172,9 +165,9 @@ fn fails_to_parse_invalid_builtin() { let _ = lexer.next(); // whitespace let _ = lexer.next(); // } let _ = lexer.next(); // whitespace + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } diff --git a/huff_lexer/tests/comments.rs b/huff_lexer/tests/comments.rs index a003e4cf..64b0367b 100644 --- a/huff_lexer/tests/comments.rs +++ b/huff_lexer/tests/comments.rs @@ -15,9 +15,7 @@ use std::ops::Deref; fn instantiates() { let source = "#define macro HELLO_WORLD()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); - assert_eq!(lexer.current_span().deref(), &Span::default()); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); assert!(!lexer.eof); } @@ -25,151 +23,142 @@ fn instantiates() { fn single_line_comments() { let source = "// comment contents \n#define macro HELLO_WORLD()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); // The first token should be a single line comment let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); assert_eq!( unwrapped, - Token::new(TokenKind::Comment("// comment contents ".to_string()), Span::new(0..20, None)) + Token::new(TokenKind::Comment("// comment contents ".to_string()), Span::new(0..19, None)) ); - assert_eq!(lexer.current_span().deref(), &Span::new(0..20, None)); // The second token should be the newline character parsed as a whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(20..21, None); + let define_span = Span::new(20..20, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // This token should be a Define identifier let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(21..28, None); + let define_span = Span::new(21..27, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(28..29, None); + let define_span = Span::new(28..28, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // Then we should parse the macro keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let macro_span = Span::new(29..34, None); + let macro_span = Span::new(29..33, None); assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span.clone())); - assert_eq!(lexer.current_span().deref(), ¯o_span); // The next token should be another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let ws_span = Span::new(34..35, None); + let ws_span = Span::new(34..34, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span.clone())); - assert_eq!(lexer.current_span().deref(), &ws_span); // Then we should get the function name let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let function_span = Span::new(35..46, None); + let function_span = Span::new(35..45, None); assert_eq!( unwrapped, Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), function_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &function_span); // Then we should have an open paren let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let open_paren_span = Span::new(46..47, None); + let open_paren_span = Span::new(46..46, None); assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, open_paren_span.clone())); - assert_eq!(lexer.current_span().deref(), &open_paren_span); // Lastly, we should have a closing parenthesis let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let close_paren_span = Span::new(47..48, None); + let close_paren_span = Span::new(47..47, None); assert_eq!(unwrapped, Token::new(TokenKind::CloseParen, close_paren_span.clone())); - assert_eq!(lexer.current_span().deref(), &close_paren_span); + + let tok = lexer.next(); + let unwrapped = tok.unwrap().unwrap(); + let eof_span = Span::new(47..47, None); + assert_eq!(unwrapped, Token::new(TokenKind::Eof, eof_span.clone())); // We covered the whole source assert!(lexer.eof); - assert_eq!(source.len(), 48); + assert_eq!(source.len()-1, 47); } #[test] fn multi_line_comments() { let source = "/* comment contents*/#define macro HELLO_WORLD()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); // The first token should be a single line comment let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); assert_eq!( unwrapped, - Token::new(TokenKind::Comment("/* comment contents*/".to_string()), Span::new(0..21, None)) + Token::new(TokenKind::Comment("/* comment contents*/".to_string()), Span::new(0..20, None)) ); - assert_eq!(lexer.current_span().deref(), &Span::new(0..21, None)); // This token should be a Define identifier let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(21..28, None); + let define_span = Span::new(21..27, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(28..29, None); + let define_span = Span::new(28..28, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // Then we should parse the macro keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let macro_span = Span::new(29..34, None); + let macro_span = Span::new(29..33, None); assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span.clone())); - assert_eq!(lexer.current_span().deref(), ¯o_span); // The next token should be another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let ws_span = Span::new(34..35, None); + let ws_span = Span::new(34..34, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span.clone())); - assert_eq!(lexer.current_span().deref(), &ws_span); // Then we should get the function name let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let function_span = Span::new(35..46, None); + let function_span = Span::new(35..45, None); assert_eq!( unwrapped, Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), function_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &function_span); // Then we should have an open paren let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let open_paren_span = Span::new(46..47, None); + let open_paren_span = Span::new(46..46, None); assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, open_paren_span.clone())); - assert_eq!(lexer.current_span().deref(), &open_paren_span); // Lastly, we should have a closing parenthesis let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let close_paren_span = Span::new(47..48, None); + let close_paren_span = Span::new(47..47, None); assert_eq!(unwrapped, Token::new(TokenKind::CloseParen, close_paren_span.clone())); - assert_eq!(lexer.current_span().deref(), &close_paren_span); + + let tok = lexer.next(); + let unwrapped = tok.unwrap().unwrap(); + let eof_span = Span::new(47..47, None); + assert_eq!(unwrapped, Token::new(TokenKind::Eof, eof_span.clone())); // We covered the whole source assert!(lexer.eof); - assert_eq!(source.len(), 48); + assert_eq!(source.len()-1, 47); } From 84885f3ac38c5ca78841984ee0132a8e243477b3 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 14:55:54 -0700 Subject: [PATCH 21/68] fix most lexer tests --- huff_lexer/src/lexer.rs | 93 ++++++++++++++++++++- huff_lexer/tests/context.rs | 2 +- huff_lexer/tests/decorators.rs | 30 +++---- huff_lexer/tests/eof.rs | 7 +- huff_lexer/tests/fsp.rs | 10 +-- huff_lexer/tests/function_type.rs | 8 +- huff_lexer/tests/hex.rs | 22 ++--- huff_lexer/tests/imports.rs | 50 ++++++----- huff_lexer/tests/keywords.rs | 132 +++++++++++++----------------- huff_lexer/tests/labels.rs | 4 +- huff_lexer/tests/numbers.rs | 16 ++-- huff_lexer/tests/opcodes.rs | 2 +- huff_lexer/tests/symbols.rs | 79 +++++++----------- huff_lexer/tests/tables.rs | 8 +- 14 files changed, 244 insertions(+), 219 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 5a0ef041..17d2206c 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -242,6 +242,7 @@ impl<'a> LexerNew<'a> { if let Some(kind) = &found_kind { match kind { TokenKind::Macro | TokenKind::Fn | TokenKind::Test => { + dbg!("found macro!"); self.context = Context::MacroDefinition } TokenKind::Function | TokenKind::Event | TokenKind::Error => { @@ -265,6 +266,7 @@ impl<'a> LexerNew<'a> { if let Some(')') = self.peek() { self.consume(); } + end = end + 2; found_kind = Some(TokenKind::FreeStoragePointer); } @@ -273,6 +275,16 @@ impl<'a> LexerNew<'a> { self.consume(); } + // Syntax sugar: true evaluates to 0x01, false evaluates to 0x00 + if matches!(word.as_str(), "true" | "false") { + found_kind = Some(TokenKind::Literal(str_to_bytes32( + if word.as_str() == "true" { "1" } else { "0" }, + ))); + self.eat_while(None, |c| { + c.is_alphanumeric() + }); + } + if !(self.context != Context::MacroBody || found_kind.is_some()) { if let Some(o) = OPCODES_MAP.get(&word.clone()) { found_kind = Some(TokenKind::Opcode(o.to_owned())); @@ -504,7 +516,7 @@ impl<'a> LexerNew<'a> { } fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult { - let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { + let (integer_str, mut start, end) = self.eat_while(Some(initial_char), |ch| { ch.is_ascii_hexdigit() | (ch == 'x') }); // TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34 @@ -515,9 +527,11 @@ impl<'a> LexerNew<'a> { // bytecode in codegen. TokenKind::Ident(integer_str) } else { + TokenKind::Literal(str_to_bytes32(&integer_str[2..].as_ref())) }; + start = start + 2; let span = Span { start: start as usize, end: end as usize, file: None }; Ok(Token { kind, span }) } @@ -528,10 +542,10 @@ impl<'a> LexerNew<'a> { } fn eat_string_literal(&mut self) -> Token { - let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"'); + let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"' && ch != '\''); let str_literal_token = TokenKind::Str(str_literal); self.consume(); // Advance past the closing quote - str_literal_token.into_span(start_span, end_span) + str_literal_token.into_span(start_span, end_span + 1) } // fn eat_alphabetic(&mut self, initial_char: char) -> (String, u32, u32) { @@ -598,6 +612,79 @@ impl<'a> LexerNew<'a> { } } + /// Lex all imports + /// Example import: `// #include "./Utils.huff"` + pub fn lex_imports(source: &str) -> Vec { + let mut imports = vec![]; + let mut peekable_source = source.chars().peekable(); + let mut include_chars_iterator = "#include".chars().peekable(); + while peekable_source.peek().is_some() { + while let Some(nc) = peekable_source.next() { + if nc.eq(&'/') { + if let Some(nnc) = peekable_source.peek() { + if nnc.eq(&'/') { + // Iterate until newline + while let Some(lc) = &peekable_source.next() { + if lc.eq(&'\n') { + break + } + } + } else if nnc.eq(&'*') { + // Iterate until '*/' + while let Some(lc) = peekable_source.next() { + if lc.eq(&'*') { + if let Some(llc) = peekable_source.peek() { + if *llc == '/' { + break + } + } + } + } + } + } + } + if include_chars_iterator.peek().is_none() { + // Reset the include chars iterator + include_chars_iterator = "#include".chars().peekable(); + + // Skip over whitespace + while peekable_source.peek().is_some() { + if !peekable_source.peek().unwrap().is_whitespace() { + break + } else { + peekable_source.next(); + } + } + + // Then we should have an import path between quotes + if let Some(char) = peekable_source.peek() { + match char { + '"' | '\'' => { + peekable_source.next(); + let mut import = String::new(); + while peekable_source.peek().is_some() { + if let Some(c) = peekable_source.next() { + if matches!(c, '"' | '\'') { + imports.push(import); + break + } else { + import.push(c); + } + } + } + } + _ => { /* Ignore non-include tokens */ } + } + } + } else if nc.ne(&include_chars_iterator.next().unwrap()) { + include_chars_iterator = "#include".chars().peekable(); + break + } + } + } + imports + } + } impl<'a> Iterator for LexerNew<'a> { diff --git a/huff_lexer/tests/context.rs b/huff_lexer/tests/context.rs index 5ed6dabe..fb992f38 100644 --- a/huff_lexer/tests/context.rs +++ b/huff_lexer/tests/context.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn function_context() { let source = "#define function test(bytes32) {} returns (address)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_lexer/tests/decorators.rs b/huff_lexer/tests/decorators.rs index bc0ca15a..e2b8c94d 100644 --- a/huff_lexer/tests/decorators.rs +++ b/huff_lexer/tests/decorators.rs @@ -1,4 +1,4 @@ -use huff_lexer::Lexer; +use huff_lexer::*; use huff_utils::prelude::{str_to_bytes32, FullFileSource, Span, Token, TokenKind}; use std::ops::Deref; @@ -18,64 +18,58 @@ fn parses_decorator() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); let _ = lexer.next(); // whitespace // # let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(13..14, None); + let returns_span = Span::new(13..13, None); assert_eq!(unwrapped, Token::new(TokenKind::Pound, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); // [ let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(14..15, None); + let returns_span = Span::new(14..14, None); assert_eq!(unwrapped, Token::new(TokenKind::OpenBracket, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); // calldata let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(15..23, None); + let returns_span = Span::new(15..22, None); assert_eq!( unwrapped, Token::new(TokenKind::Ident(String::from("calldata")), returns_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &returns_span); // ( let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(23..24, None); + let returns_span = Span::new(23..23, None); assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); + // 0x01 let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(26..28, None); + let returns_span = Span::new(26..27, None); assert_eq!( unwrapped, Token::new(TokenKind::Literal(str_to_bytes32("01")), returns_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &returns_span); // ) let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(28..29, None); + let returns_span = Span::new(28..28, None); assert_eq!(unwrapped, Token::new(TokenKind::CloseParen, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); // ] let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(29..30, None); + let returns_span = Span::new(29..29, None); assert_eq!(unwrapped, Token::new(TokenKind::CloseBracket, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); let _ = lexer.next(); // whitespace' let _ = lexer.next(); // define @@ -108,9 +102,9 @@ fn parses_decorator() { let _ = lexer.next(); // whitespace let _ = lexer.next(); // } let _ = lexer.next(); // whitespace + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } @@ -132,7 +126,7 @@ fn fails_to_parse_decorator_in_body() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); for token in lexer.by_ref() { if let Err(e) = token { diff --git a/huff_lexer/tests/eof.rs b/huff_lexer/tests/eof.rs index 99474ec2..17826ea6 100644 --- a/huff_lexer/tests/eof.rs +++ b/huff_lexer/tests/eof.rs @@ -6,8 +6,7 @@ use std::ops::Deref; fn end_of_file() { let source = " "; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); // Eats the whitespace let _ = lexer.next(); @@ -15,11 +14,9 @@ fn end_of_file() { // Get an EOF token let tok = lexer.next(); let tok = tok.unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Eof, Span::new(1..1, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(1..1, None)); + assert_eq!(tok, Token::new(TokenKind::Eof, Span::new(0..0, None))); // We should have reached EOF now - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); assert!(lexer.next().is_none()); } diff --git a/huff_lexer/tests/fsp.rs b/huff_lexer/tests/fsp.rs index c33df71d..3506e46b 100644 --- a/huff_lexer/tests/fsp.rs +++ b/huff_lexer/tests/fsp.rs @@ -7,18 +7,18 @@ use std::ops::Deref; fn free_storage_pointer() { let source = "FREE_STORAGE_POINTER() "; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); // The first token should be the fsp let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::FreeStoragePointer, Span::new(0..22, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(0..22, None)); + assert_eq!(tok, Token::new(TokenKind::FreeStoragePointer, Span::new(0..21, None))); // Eats the whitespace let _ = lexer.next(); + let tok = lexer.next().unwrap().unwrap(); + assert_eq!(tok, Token::new(TokenKind::Eof, Span::new(22..22, None))); + // We should have reached EOF now - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } diff --git a/huff_lexer/tests/function_type.rs b/huff_lexer/tests/function_type.rs index 6326ec20..6e49c017 100644 --- a/huff_lexer/tests/function_type.rs +++ b/huff_lexer/tests/function_type.rs @@ -14,8 +14,7 @@ fn parses_function_type() { for (fn_type, fn_type_kind) in fn_types { let source = &format!("#define function test() {fn_type} returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source.clone()); - assert_eq!(lexer.source, flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -28,9 +27,8 @@ fn parses_function_type() { // Lex view first let tok = lexer.next().unwrap().unwrap(); - let type_span = Span::new(24..24 + fn_type.len(), None); + let type_span = Span::new(24..24 + fn_type.len()-1, None); assert_eq!(tok, Token::new(fn_type_kind, type_span.clone())); - assert_eq!(lexer.current_span().deref(), &type_span); let _ = lexer.next(); // whitespace let _ = lexer.next(); // returns @@ -38,9 +36,9 @@ fn parses_function_type() { let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // uint256 let _ = lexer.next(); // close parenthesis + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } diff --git a/huff_lexer/tests/hex.rs b/huff_lexer/tests/hex.rs index 149022d8..ba072a5f 100644 --- a/huff_lexer/tests/hex.rs +++ b/huff_lexer/tests/hex.rs @@ -7,17 +7,14 @@ use std::ops::Deref; fn parses_single_hex() { let source = "0xa57B"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); - let mut lexer_new = LexerNew::new(flattened_source.source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); // The first and only token should be lexed as Literal(0xa57B) let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("a57B")), Span::new(2..6, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(2..6, None)); + assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("a57B")), Span::new(2..5, None))); // We covered the whole source lexer.next(); - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -25,23 +22,20 @@ fn parses_single_hex() { fn parses_bool() { let source = "false true"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); // The first token should be lexed as a Literal representing 0x00 let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("0")), Span::new(0..5, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(0..5, None)); + assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("0")), Span::new(0..4, None))); let _ = lexer.next(); // Whitespace // The second token should be lexed as a Literal representing 0x01 let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("1")), Span::new(6..10, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(6..10, None)); + assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("1")), Span::new(6..9, None))); // We covered the whole source lexer.next(); - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -49,16 +43,14 @@ fn parses_bool() { fn parses_odd_len_hex() { let source = "0x1"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); // The first and only token should be lexed as Literal(0x1) let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("1")), Span::new(2..3, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(2..3, None)); + assert_eq!(tok, Token::new(TokenKind::Literal(str_to_bytes32("1")), Span::new(2..2, None))); // We covered the whole source lexer.next(); - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } diff --git a/huff_lexer/tests/imports.rs b/huff_lexer/tests/imports.rs index 7fe26c95..bf6082bf 100644 --- a/huff_lexer/tests/imports.rs +++ b/huff_lexer/tests/imports.rs @@ -1,4 +1,4 @@ -use huff_lexer::*; +use huff_lexer::lexer::LexerNew; use huff_utils::prelude::*; use std::ops::Deref; @@ -6,7 +6,7 @@ use std::ops::Deref; fn single_lex_imports() { let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = format!("#include \"{import_str}\""); - let lexed_imports = Lexer::lex_imports(&source); + let lexed_imports = LexerNew::lex_imports(&source); assert_eq!(lexed_imports.len(), 1); assert_eq!(lexed_imports[0], import_str); } @@ -24,7 +24,7 @@ fn commented_lex_imports() { "# ); - let lexed_imports = Lexer::lex_imports(&source); + let lexed_imports = LexerNew::lex_imports(&source); assert_eq!(lexed_imports.len(), 1); assert_eq!(lexed_imports[0], import_str); } @@ -42,7 +42,7 @@ fn multiple_lex_imports() { "# ); - let lexed_imports = Lexer::lex_imports(&source); + let lexed_imports = LexerNew::lex_imports(&source); assert_eq!(lexed_imports.len(), 3); for i in lexed_imports { assert_eq!(i, import_str); @@ -59,7 +59,7 @@ fn multiple_lex_imports_single_quotes() { "# ); - let lexed_imports = Lexer::lex_imports(&source); + let lexed_imports = LexerNew::lex_imports(&source); assert_eq!(lexed_imports.len(), 2); for i in lexed_imports { assert_eq!(i, import_str); @@ -70,7 +70,7 @@ fn multiple_lex_imports_single_quotes() { fn lex_imports_no_ending_quote() { let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = format!("#include '{import_str}"); - let lexed_imports = Lexer::lex_imports(&source); + let lexed_imports = LexerNew::lex_imports(&source); assert_eq!(lexed_imports.len(), 0); } @@ -78,7 +78,7 @@ fn lex_imports_no_ending_quote() { fn lex_imports_no_starting_quote() { let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = format!("#include {import_str}'"); - let lexed_imports = Lexer::lex_imports(&source); + let lexed_imports = LexerNew::lex_imports(&source); assert_eq!(lexed_imports.len(), 0); } @@ -86,7 +86,7 @@ fn lex_imports_no_starting_quote() { fn lex_imports_empty_quotes() { // let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = "#include ''"; - let lexed_imports = Lexer::lex_imports(source); + let lexed_imports = LexerNew::lex_imports(source); assert_eq!(lexed_imports.len(), 1); assert_eq!(lexed_imports[0], ""); } @@ -95,13 +95,13 @@ fn lex_imports_empty_quotes() { fn include_no_quotes() { let source = "#include"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = LexerNew::new(flattened_source.source); // The first token should be a single line comment let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - assert_eq!(unwrapped, Token::new(TokenKind::Include, Span::new(0..8, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(0..8, None)); + assert_eq!(unwrapped, Token::new(TokenKind::Include, Span::new(0..7, None))); + lexer.next(); assert!(lexer.eof); } @@ -109,25 +109,23 @@ fn include_no_quotes() { fn include_with_string() { let source = "#include \"../huff-examples/erc20/contracts/utils/Ownable.huff\""; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = LexerNew::new(flattened_source.source); // The first token should be a single line comment let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - assert_eq!(unwrapped, Token::new(TokenKind::Include, Span::new(0..8, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(0..8, None)); + assert_eq!(unwrapped, Token::new(TokenKind::Include, Span::new(0..7, None))); // Lex the whitespace char let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let literal_span = Span::new(8..9, None); + let literal_span = Span::new(8..8, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, literal_span.clone())); - assert_eq!(lexer.current_span().deref(), &literal_span); // Then we should parse the string literal let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let literal_span = Span::new(9..62, None); + let literal_span = Span::new(9..61, None); assert_eq!( unwrapped, Token::new( @@ -135,10 +133,10 @@ fn include_with_string() { literal_span.clone() ) ); - assert_eq!(lexer.current_span().deref(), &literal_span); + + lexer.next(); // We should have reached EOF now - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -146,25 +144,23 @@ fn include_with_string() { fn include_with_string_single_quote() { let source = "#include '../huff-examples/erc20/contracts/utils/Ownable.huff'"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = LexerNew::new(flattened_source.source); // The first token should be a single line comment let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - assert_eq!(unwrapped, Token::new(TokenKind::Include, Span::new(0..8, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(0..8, None)); + assert_eq!(unwrapped, Token::new(TokenKind::Include, Span::new(0..7, None))); // Lex the whitespace char let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let literal_span = Span::new(8..9, None); + let literal_span = Span::new(8..8, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, literal_span.clone())); - assert_eq!(lexer.current_span().deref(), &literal_span); // Then we should parse the string literal let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let literal_span = Span::new(9..62, None); + let literal_span = Span::new(9..61, None); assert_eq!( unwrapped, Token::new( @@ -172,9 +168,9 @@ fn include_with_string_single_quote() { literal_span.clone() ) ); - assert_eq!(lexer.current_span().deref(), &literal_span); + + lexer.next(); // We should have reached EOF now - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } diff --git a/huff_lexer/tests/keywords.rs b/huff_lexer/tests/keywords.rs index 38c58ff9..5d2b61f8 100644 --- a/huff_lexer/tests/keywords.rs +++ b/huff_lexer/tests/keywords.rs @@ -6,31 +6,29 @@ use std::ops::Deref; fn parses_macro_keyword() { let source = "#define macro"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(7..8, None); + let whitespace_span = Span::new(7..7, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Lastly we should parse the macro keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let macro_span = Span::new(8..13, None); + let macro_span = Span::new(8..12, None); assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span.clone())); - assert_eq!(lexer.current_span().deref(), ¯o_span); + + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -38,31 +36,29 @@ fn parses_macro_keyword() { fn parses_fn_keyword() { let source = "#define fn"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(7..8, None); + let whitespace_span = Span::new(7..7, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Lastly we should parse the fn keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_span = Span::new(8..10, None); + let fn_span = Span::new(8..9, None); assert_eq!(unwrapped, Token::new(TokenKind::Fn, fn_span.clone())); - assert_eq!(lexer.current_span().deref(), &fn_span); + + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -70,31 +66,29 @@ fn parses_fn_keyword() { fn parses_test_keyword() { let source = "#define test"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(7..8, None); + let whitespace_span = Span::new(7..7, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Lastly we should parse the fn keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let test_span = Span::new(8..12, None); + let test_span = Span::new(8..11, None); assert_eq!(unwrapped, Token::new(TokenKind::Test, test_span.clone())); - assert_eq!(lexer.current_span().deref(), &test_span); + + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -102,31 +96,30 @@ fn parses_test_keyword() { fn parses_function_keyword() { let source = "#define function"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(7..8, None); + let whitespace_span = Span::new(7..7, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Lastly we should parse the function keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let function_span = Span::new(8..16, None); + let function_span = Span::new(8..15, None); assert_eq!(unwrapped, Token::new(TokenKind::Function, function_span.clone())); - assert_eq!(lexer.current_span().deref(), &function_span); + + lexer.next(); + // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -134,37 +127,35 @@ fn parses_function_keyword() { fn parses_event_keyword() { let source = "#define event TestEvent(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(7..8, None); + let whitespace_span = Span::new(7..7, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Lastly we should parse the event keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let event_span = Span::new(8..13, None); + let event_span = Span::new(8..12, None); assert_eq!(unwrapped, Token::new(TokenKind::Event, event_span.clone())); - assert_eq!(lexer.current_span().deref(), &event_span); let _ = lexer.next(); // whitespace let _ = lexer.next(); // event name let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // uint256 let _ = lexer.next(); // close parenthesis + let _ = lexer.next(); // eof + // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -172,31 +163,29 @@ fn parses_event_keyword() { fn parses_constant_keyword() { let source = "#define constant"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(7..8, None); + let whitespace_span = Span::new(7..7, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Lastly we should parse the constant keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let constant_span = Span::new(8..16, None); + let constant_span = Span::new(8..15, None); assert_eq!(unwrapped, Token::new(TokenKind::Constant, constant_span.clone())); - assert_eq!(lexer.current_span().deref(), &constant_span); + + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -204,7 +193,7 @@ fn parses_constant_keyword() { fn parses_takes_and_returns_keywords() { let source = "#define macro TEST() = takes (0) returns (0)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -220,9 +209,8 @@ fn parses_takes_and_returns_keywords() { // Lex Takes First let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let takes_span = Span::new(23..28, None); + let takes_span = Span::new(23..27, None); assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span.clone())); - assert_eq!(lexer.current_span().deref(), &takes_span); // Lex the middle 5 chars let _ = lexer.next(); // whitespace @@ -234,18 +222,17 @@ fn parses_takes_and_returns_keywords() { // Lex Returns let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(37..44, None); + let returns_span = Span::new(37..43, None); assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); // Lex the last 4 chars let _ = lexer.next(); // whitespace let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // 0 let _ = lexer.next(); // close parenthesis + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -253,7 +240,7 @@ fn parses_takes_and_returns_keywords() { fn parses_takes_and_returns_keywords_tight_syntax() { let source = "#define macro TEST() = takes(0) returns(0)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -269,9 +256,8 @@ fn parses_takes_and_returns_keywords_tight_syntax() { // Lex Takes First let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let takes_span = Span::new(23..28, None); + let takes_span = Span::new(23..27, None); assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span.clone())); - assert_eq!(lexer.current_span().deref(), &takes_span); // Lex the next 4 chars let _ = lexer.next(); // open parenthesis @@ -282,17 +268,16 @@ fn parses_takes_and_returns_keywords_tight_syntax() { // Lex Returns let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(32..39, None); + let returns_span = Span::new(32..38, None); assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); // Lex the last 3 chars let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // 0 let _ = lexer.next(); // close parenthesis + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -300,7 +285,7 @@ fn parses_takes_and_returns_keywords_tight_syntax() { fn parses_function_type_keywords() { let source = "#define function test() view returns (uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -313,9 +298,8 @@ fn parses_function_type_keywords() { // Lex view first let tok = lexer.next().unwrap().unwrap(); - let view_span = Span::new(24..28, None); + let view_span = Span::new(24..27, None); assert_eq!(tok, Token::new(TokenKind::View, view_span.clone())); - assert_eq!(lexer.current_span().deref(), &view_span); // Lex the next 4 chars let _ = lexer.next(); // whitespace @@ -324,9 +308,9 @@ fn parses_function_type_keywords() { let _ = lexer.next(); // paren let _ = lexer.next(); // uint256 let _ = lexer.next(); // paren + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -355,7 +339,7 @@ fn parses_function_definition_with_keyword_name() { for s in key_words { let source = &format!("#define function {s}(uint256) view returns(uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let end_span_s = 17 + s.len(); @@ -367,9 +351,8 @@ fn parses_function_definition_with_keyword_name() { // Keyword as a function name (s) let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let ident_span = Span::new(17..end_span_s, None); + let ident_span = Span::new(17..end_span_s-1, None); assert_eq!(unwrapped, Token::new(TokenKind::Ident(s.to_string()), ident_span.clone())); - assert_eq!(lexer.current_span().deref(), &ident_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // uint256 @@ -381,16 +364,15 @@ fn parses_function_definition_with_keyword_name() { // Ensure that this "returns" is lexed as a `TokenKind::Returns` let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new((end_span_s + 15)..(end_span_s + 22), None); + let returns_span = Span::new((end_span_s + 15)..(end_span_s + 21), None); assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // uint256 let _ = lexer.next(); // close parenthesis + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } @@ -429,28 +411,26 @@ fn parses_label_with_keyword_name() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(0..s.len(), None); + let fn_name_span = Span::new(0..s.len()-1, None); assert_eq!(unwrapped, Token::new(TokenKind::Label(s.to_string()), fn_name_span.clone())); - assert_eq!(lexer.current_span().deref(), &fn_name_span); let _ = lexer.next(); // colon let _ = lexer.next(); // whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new((s.len() + 14)..(s.len() * 2 + 14), None); + let fn_name_span = Span::new((s.len() + 14)..(s.len() * 2 + 13), None); assert_eq!(unwrapped, Token::new(TokenKind::Ident(s.to_uppercase()), fn_name_span.clone())); - assert_eq!(lexer.current_span().deref(), &fn_name_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // close parenthesis + //let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } diff --git a/huff_lexer/tests/labels.rs b/huff_lexer/tests/labels.rs index ab6cb946..1c7b33d2 100644 --- a/huff_lexer/tests/labels.rs +++ b/huff_lexer/tests/labels.rs @@ -6,7 +6,7 @@ fn parse_label() { let source = "#define macro HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add cool_label:\n0x01\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -25,7 +25,7 @@ fn parse_label_with_opcode_name() { let source = "#define macro HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add cool_label_return_swap1_mload:\n0x01\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_lexer/tests/numbers.rs b/huff_lexer/tests/numbers.rs index 0842a279..202bda40 100644 --- a/huff_lexer/tests/numbers.rs +++ b/huff_lexer/tests/numbers.rs @@ -6,15 +6,15 @@ use std::ops::Deref; fn lexes_zero_prefixed_numbers() { let source = "00"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // The first and only token should be lexed as 0 let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Num(0), Span::new(0..2, None))); - assert_eq!(lexer.current_span().deref(), &Span::new(0..2, None)); + assert_eq!(tok, Token::new(TokenKind::Num(0), Span::new(0..1, None))); + + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -22,14 +22,14 @@ fn lexes_zero_prefixed_numbers() { fn lexes_large_numbers() { let source = &format!("{}", usize::MAX); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // The first and only token should be lexed let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Num(usize::MAX), Span::new(0..source.len(), None))); - assert_eq!(lexer.current_span().deref(), &Span::new(0..source.len(), None)); + assert_eq!(tok, Token::new(TokenKind::Num(usize::MAX), Span::new(0..source.len()-1, None))); + + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } diff --git a/huff_lexer/tests/opcodes.rs b/huff_lexer/tests/opcodes.rs index 6199b322..f6836498 100644 --- a/huff_lexer/tests/opcodes.rs +++ b/huff_lexer/tests/opcodes.rs @@ -18,7 +18,7 @@ fn opcodes() { "{", "}", ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() diff --git a/huff_lexer/tests/symbols.rs b/huff_lexer/tests/symbols.rs index d8cf6940..9a207ff0 100644 --- a/huff_lexer/tests/symbols.rs +++ b/huff_lexer/tests/symbols.rs @@ -6,62 +6,55 @@ use std::ops::Deref; fn lexes_assign_op() { let source = "#define constant TRANSFER_EVENT_SIGNATURE ="; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // This token should be a Define identifier let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(7..8, None); + let define_span = Span::new(7..7, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // Then we should parse the constant keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let constant_span = Span::new(8..16, None); + let constant_span = Span::new(8..15, None); assert_eq!(unwrapped, Token::new(TokenKind::Constant, constant_span.clone())); - assert_eq!(lexer.current_span().deref(), &constant_span); // The next token should be another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let ws_span = Span::new(16..17, None); + let ws_span = Span::new(16..16, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span.clone())); - assert_eq!(lexer.current_span().deref(), &ws_span); // Then we should get the function name let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let function_span = Span::new(17..41, None); + let function_span = Span::new(17..40, None); assert_eq!( unwrapped, Token::new(TokenKind::Ident("TRANSFER_EVENT_SIGNATURE".to_string()), function_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &function_span); // Then we should have another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(41..42, None); + let whitespace_span = Span::new(41..41, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Finally, we have our assign operator let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let assign_span = Span::new(42..43, None); + let assign_span = Span::new(42..42, None); assert_eq!(unwrapped, Token::new(TokenKind::Assign, assign_span.clone())); - assert_eq!(lexer.current_span().deref(), &assign_span); + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -69,38 +62,35 @@ fn lexes_assign_op() { fn lexes_brackets() { let source = "[TOTAL_SUPPLY_LOCATION] sload"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // This token should be the open bracket let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let bracket_span = Span::new(0..1, None); + let bracket_span = Span::new(0..0, None); assert_eq!(unwrapped, Token::new(TokenKind::OpenBracket, bracket_span.clone())); - assert_eq!(lexer.current_span().deref(), &bracket_span); // The next token should be the location identifier let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let loc_span = Span::new(1..22, None); + let loc_span = Span::new(1..21, None); assert_eq!( unwrapped, Token::new(TokenKind::Ident("TOTAL_SUPPLY_LOCATION".to_string()), loc_span.clone()) ); - assert_eq!(lexer.current_span().deref(), &loc_span); // Then we should parse the closing bracket let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let bracket_span = Span::new(22..23, None); + let bracket_span = Span::new(22..22, None); assert_eq!(unwrapped, Token::new(TokenKind::CloseBracket, bracket_span.clone())); - assert_eq!(lexer.current_span().deref(), &bracket_span); // Eat the last tokens let _ = lexer.next(); // whitespace let _ = lexer.next(); // sload opcode + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -115,7 +105,7 @@ fn lexes_braces() { "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Eat the non-brace tokens let _ = lexer.next(); // whitespace @@ -143,9 +133,8 @@ fn lexes_braces() { // This token should be the open brace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let brace_span = Span::new(51..52, None); + let brace_span = Span::new(51..51, None); assert_eq!(unwrapped, Token::new(TokenKind::OpenBrace, brace_span.clone())); - assert_eq!(lexer.current_span().deref(), &brace_span); // Eat the characters in between braces let _ = lexer.next(); // whitespace @@ -159,15 +148,14 @@ fn lexes_braces() { // We should now have the closing brace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let brace_span = Span::new(131..132, None); + let brace_span = Span::new(131..131, None); assert_eq!(unwrapped, Token::new(TokenKind::CloseBrace, brace_span.clone())); - assert_eq!(lexer.current_span().deref(), &brace_span); // Eat the last whitespace let _ = lexer.next(); // whitespace + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -176,7 +164,7 @@ fn lexes_math_ops() { // MATHS let source = r#"100 + 10 - 20 * 5 / 4"#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Eat the number and whitespace let _ = lexer.next(); @@ -185,9 +173,8 @@ fn lexes_math_ops() { // This token should be an addition let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let add_span = Span::new(4..5, None); + let add_span = Span::new(4..4, None); assert_eq!(unwrapped, Token::new(TokenKind::Add, add_span.clone())); - assert_eq!(lexer.current_span().deref(), &add_span); // Eat the number and whitespaces let _ = lexer.next(); @@ -197,9 +184,8 @@ fn lexes_math_ops() { // This token should be a subtraction let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let sub_span = Span::new(9..10, None); + let sub_span = Span::new(9..9, None); assert_eq!(unwrapped, Token::new(TokenKind::Sub, sub_span.clone())); - assert_eq!(lexer.current_span().deref(), &sub_span); // Eat the number and whitespaces let _ = lexer.next(); @@ -209,9 +195,8 @@ fn lexes_math_ops() { // This token should be a multiplication let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let mul_span = Span::new(14..15, None); + let mul_span = Span::new(14..14, None); assert_eq!(unwrapped, Token::new(TokenKind::Mul, mul_span.clone())); - assert_eq!(lexer.current_span().deref(), &mul_span); // Eat the number and whitespace let _ = lexer.next(); @@ -221,16 +206,15 @@ fn lexes_math_ops() { // This token should be a division let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let div_span = Span::new(18..19, None); + let div_span = Span::new(18..18, None); assert_eq!(unwrapped, Token::new(TokenKind::Div, div_span.clone())); - assert_eq!(lexer.current_span().deref(), &div_span); // Eat the number and whitespace let _ = lexer.next(); let _ = lexer.next(); + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -238,23 +222,21 @@ fn lexes_math_ops() { fn lexes_commas() { let source = "test,test"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); - + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Eat alphanumerics let _ = lexer.next(); // This token should be the comma let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let comma_span = Span::new(4..5, None); + let comma_span = Span::new(4..4, None); assert_eq!(unwrapped, Token::new(TokenKind::Comma, comma_span.clone())); - assert_eq!(lexer.current_span().deref(), &comma_span); // Eat alphanumerics let _ = lexer.next(); + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } @@ -262,7 +244,7 @@ fn lexes_commas() { fn lexes_comma_sparse() { let source = "test , test"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let _ = lexer.next(); // alphanumerics let _ = lexer.next(); // whitespace @@ -270,14 +252,13 @@ fn lexes_comma_sparse() { // This token should be the comma let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let comma_span = Span::new(5..6, None); + let comma_span = Span::new(5..5, None); assert_eq!(unwrapped, Token::new(TokenKind::Comma, comma_span.clone())); - assert_eq!(lexer.current_span().deref(), &comma_span); let _ = lexer.next(); // whitespace let _ = lexer.next(); // alphanumerics + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } diff --git a/huff_lexer/tests/tables.rs b/huff_lexer/tests/tables.rs index 5eb271ed..2bcaf38a 100644 --- a/huff_lexer/tests/tables.rs +++ b/huff_lexer/tests/tables.rs @@ -1,11 +1,11 @@ -use huff_lexer::Lexer; +use huff_lexer::*; use huff_utils::prelude::*; #[test] fn parses_jump_table() { let source = "#define jumptable JUMP_TABLE()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -23,7 +23,7 @@ fn parses_jump_table() { fn parses_packed_jump_table() { let source = "#define jumptable__packed JUMP_TABLE_PACKED()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -41,7 +41,7 @@ fn parses_packed_jump_table() { fn parses_code_table() { let source = "#define table CODE_TABLE()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) From d434ba8489ba92601de6c950d8d80f9b3e28d370 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 15:03:27 -0700 Subject: [PATCH 22/68] wip/parser tests --- .../tests/breaking_param_invocation.rs | 4 ++-- huff_parser/tests/constant.rs | 24 +++++++++---------- huff_parser/tests/error.rs | 12 +++++----- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/huff_parser/tests/breaking_param_invocation.rs b/huff_parser/tests/breaking_param_invocation.rs index 8da26a1d..e1d429bd 100644 --- a/huff_parser/tests/breaking_param_invocation.rs +++ b/huff_parser/tests/breaking_param_invocation.rs @@ -19,7 +19,7 @@ fn test_breaking_param_invocation() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -44,7 +44,7 @@ fn test_breaking_param_commas() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_parser/tests/constant.rs b/huff_parser/tests/constant.rs index 6ee42555..81cfd642 100644 --- a/huff_parser/tests/constant.rs +++ b/huff_parser/tests/constant.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn test_parses_free_storage_pointer_constant() { let source = "#define constant FSP_LOCATION = FREE_STORAGE_POINTER()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); @@ -19,11 +19,11 @@ fn test_parses_free_storage_pointer_constant() { name: "FSP_LOCATION".to_string(), value: ConstVal::FreeStoragePointer(FreeStoragePointer {}), span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 16, file: None }, - Span { start: 17, end: 29, file: None }, - Span { start: 30, end: 31, file: None }, - Span { start: 32, end: 54, file: None } + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 15, file: None }, + Span { start: 17, end: 28, file: None }, + Span { start: 30, end: 30, file: None }, + Span { start: 32, end: 53, file: None } ]) } ); @@ -33,7 +33,7 @@ fn test_parses_free_storage_pointer_constant() { fn test_parses_literal_constant() { let source = "#define constant LITERAL = 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); @@ -51,11 +51,11 @@ fn test_parses_literal_constant() { name: "LITERAL".to_string(), value: ConstVal::Literal(arr), span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 16, file: None }, - Span { start: 17, end: 24, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 29, end: 93, file: None } + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 15, file: None }, + Span { start: 17, end: 23, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 29, end: 92, file: None } ]) } ); diff --git a/huff_parser/tests/error.rs b/huff_parser/tests/error.rs index 7e1502db..e0fa939a 100644 --- a/huff_parser/tests/error.rs +++ b/huff_parser/tests/error.rs @@ -42,7 +42,7 @@ fn test_error_sel_no_param() { let source = "#define error NotOwner()"; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let contract = parser.parse().unwrap(); @@ -57,11 +57,11 @@ fn test_error_sel_no_param() { selector: [48, 205, 116, 113], parameters: vec![], span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 13, file: None }, - Span { start: 14, end: 22, file: None }, - Span { start: 22, end: 23, file: None }, - Span { start: 23, end: 24, file: None } + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 12, file: None }, + Span { start: 14, end: 21, file: None }, + Span { start: 22, end: 22, file: None }, + Span { start: 23, end: 23, file: None } ]) } ); From c7682f82534cca00fc9409fcf9106e6af67c0e15 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 15:24:53 -0700 Subject: [PATCH 23/68] wip/fix tests --- huff_lexer/tests/context.rs | 4 ++-- huff_lexer/tests/evm_types.rs | 8 ++++---- huff_lexer/tests/keywords.rs | 4 ++-- huff_parser/tests/abi.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/huff_lexer/tests/context.rs b/huff_lexer/tests/context.rs index fb992f38..e72f3fa1 100644 --- a/huff_lexer/tests/context.rs +++ b/huff_lexer/tests/context.rs @@ -26,7 +26,7 @@ fn function_context() { fn event_context() { let source = "#define event Transfer(bytes32,address)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -44,7 +44,7 @@ fn event_context() { fn macro_context() { let source = "#define macro TEST() = takes (0) returns (0) {byte}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_lexer/tests/evm_types.rs b/huff_lexer/tests/evm_types.rs index 15adf261..fcab1998 100644 --- a/huff_lexer/tests/evm_types.rs +++ b/huff_lexer/tests/evm_types.rs @@ -16,7 +16,7 @@ fn primitive_type_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -42,7 +42,7 @@ fn bounded_array_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -68,7 +68,7 @@ fn unbounded_array_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -93,7 +93,7 @@ fn multidim_array_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_lexer/tests/keywords.rs b/huff_lexer/tests/keywords.rs index 5d2b61f8..af9630cf 100644 --- a/huff_lexer/tests/keywords.rs +++ b/huff_lexer/tests/keywords.rs @@ -413,13 +413,14 @@ fn parses_label_with_keyword_name() { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; let mut lexer = lexer::LexerNew::new(flattened_source.source); + let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let fn_name_span = Span::new(0..s.len()-1, None); assert_eq!(unwrapped, Token::new(TokenKind::Label(s.to_string()), fn_name_span.clone())); let _ = lexer.next(); // colon - let _ = lexer.next(); // whitespace + let a = lexer.next(); // whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); @@ -428,7 +429,6 @@ fn parses_label_with_keyword_name() { let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // close parenthesis - //let _ = lexer.next(); // eof // We covered the whole source assert!(lexer.eof); diff --git a/huff_parser/tests/abi.rs b/huff_parser/tests/abi.rs index 7197dd23..00fff606 100644 --- a/huff_parser/tests/abi.rs +++ b/huff_parser/tests/abi.rs @@ -7,7 +7,7 @@ fn build_abi_from_ast() { let source = "#define function test(uint256[2][],string) view returns(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) From d47f8165133a264cd527b16c6e05805d1ec6a637 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 16:14:25 -0700 Subject: [PATCH 24/68] wip/fix parser tests --- huff_lexer/src/lexer.rs | 8 +- huff_lexer/tests/keywords.rs | 81 +++++------------ huff_parser/tests/error.rs | 16 ++-- huff_parser/tests/event.rs | 140 ++++++++++++++--------------- huff_parser/tests/function.rs | 161 +++++++++++++++++----------------- 5 files changed, 184 insertions(+), 222 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index 17d2206c..a7cb1d29 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -438,8 +438,8 @@ impl<'a> LexerNew<'a> { // Lexes Spaces and Newlines as Whitespace ch if ch.is_ascii_whitespace() => { dbg!("Are we hitting this?"); - self.eat_whitespace(); - self.single_char_token(TokenKind::Whitespace) + let (_, start, end) = self.eat_whitespace(); + Ok(TokenKind::Whitespace.into_span(start, end)) } // String literals. String literals can also be wrapped by single quotes '"' | '\'' => { @@ -537,8 +537,8 @@ impl<'a> LexerNew<'a> { } /// Skips white space. They are not significant in the source language - fn eat_whitespace(&mut self) { - self.eat_while(None, |ch| ch.is_whitespace()); + fn eat_whitespace(&mut self) -> (String, u32, u32) { + self.eat_while(None, |ch| ch.is_whitespace()) } fn eat_string_literal(&mut self) -> Token { diff --git a/huff_lexer/tests/keywords.rs b/huff_lexer/tests/keywords.rs index af9630cf..90c9fabd 100644 --- a/huff_lexer/tests/keywords.rs +++ b/huff_lexer/tests/keywords.rs @@ -413,14 +413,13 @@ fn parses_label_with_keyword_name() { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; let mut lexer = lexer::LexerNew::new(flattened_source.source); - let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let fn_name_span = Span::new(0..s.len()-1, None); assert_eq!(unwrapped, Token::new(TokenKind::Label(s.to_string()), fn_name_span.clone())); - let _ = lexer.next(); // colon - let a = lexer.next(); // whitespace + // let _ = lexer.next(); // colon + let _ = lexer.next(); // whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); @@ -429,6 +428,7 @@ fn parses_label_with_keyword_name() { let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // close parenthesis + let _ = lexer.next(); // eof // We covered the whole source assert!(lexer.eof); @@ -461,7 +461,7 @@ fn parses_function_with_keyword_name() { let source = &format!("dup1 0x7c09063f eq {s} jumpi"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let _ = lexer.next(); // dup1 let _ = lexer.next(); // whitespace @@ -473,15 +473,14 @@ fn parses_function_with_keyword_name() { // The keyword should be parsed as a `TokenKind::Ident` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(19..19 + s.len(), None); + let fn_name_span = Span::new(19..19 + s.len()-1, None); assert_eq!(unwrapped, Token::new(TokenKind::Ident(s.to_string()), fn_name_span.clone())); - assert_eq!(lexer.current_span().deref(), &fn_name_span); let _ = lexer.next(); // whitespace let _ = lexer.next(); // jumpi + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } @@ -519,7 +518,7 @@ fn parses_function_with_keyword_name_in_macro() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let _ = lexer.next(); // whitespace let _ = lexer.next(); // #define @@ -528,9 +527,8 @@ fn parses_function_with_keyword_name_in_macro() { // Ensure "macro" is parsed as a keyword here let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let takes_span = Span::new(21..26, None); + let takes_span = Span::new(21..25, None); assert_eq!(unwrapped, Token::new(TokenKind::Macro, takes_span.clone())); - assert_eq!(lexer.current_span().deref(), &takes_span); let _ = lexer.next(); // whitespace let _ = lexer.next(); // NUMS @@ -543,9 +541,8 @@ fn parses_function_with_keyword_name_in_macro() { // Ensure "takes" is parsed as a keyword here let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let takes_span = Span::new(36..41, None); + let takes_span = Span::new(36..40, None); assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span.clone())); - assert_eq!(lexer.current_span().deref(), &takes_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // 0 @@ -555,9 +552,8 @@ fn parses_function_with_keyword_name_in_macro() { // Ensure "returns" is parsed as a keyword here let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(45..52, None); + let returns_span = Span::new(45..51, None); assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // 1 @@ -573,16 +569,15 @@ fn parses_function_with_keyword_name_in_macro() { // The keyword should be parsed as a `TokenKind::Ident` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(84..84 + s.len(), None); + let fn_name_span = Span::new(84..84 + s.len()-1, None); assert_eq!(unwrapped, Token::new(TokenKind::Ident(s.to_string()), fn_name_span.clone())); - assert_eq!(lexer.current_span().deref(), &fn_name_span); let _ = lexer.next(); // whitespace let _ = lexer.next(); // } let _ = lexer.next(); // whitespace + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } @@ -603,31 +598,29 @@ fn parses_keyword_arbitrary_whitespace() { let source = &format!("#define {key}"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let define_span = Span::new(0..7, None); + let define_span = Span::new(0..6, None); assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); - assert_eq!(lexer.current_span().deref(), &define_span); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let whitespace_span = Span::new(7..12, None); + let whitespace_span = Span::new(7..11, None); assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); - assert_eq!(lexer.current_span().deref(), &whitespace_span); // Lastly we should parse the constant keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let constant_span = Span::new(12..12 + key.len(), None); + let constant_span = Span::new(12..12 + key.len()-1, None); assert_eq!(unwrapped, Token::new(kind, constant_span.clone())); - assert_eq!(lexer.current_span().deref(), &constant_span); + + lexer.next(); // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } } @@ -636,7 +629,7 @@ fn parses_keyword_arbitrary_whitespace() { fn parses_takes_keyword_arbitrary_whitespace() { let source = "#define macro TEST() = takes (0) returns (0)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); + let mut lexer = lexer::LexerNew::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -652,9 +645,8 @@ fn parses_takes_keyword_arbitrary_whitespace() { // Lex Takes First let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let takes_span = Span::new(28..33, None); + let takes_span = Span::new(28..32, None); assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span.clone())); - assert_eq!(lexer.current_span().deref(), &takes_span); // Lex the middle 5 chars let _ = lexer.next(); // whitespace @@ -666,45 +658,16 @@ fn parses_takes_keyword_arbitrary_whitespace() { // Lex Returns let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let returns_span = Span::new(38..45, None); + let returns_span = Span::new(38..44, None); assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); - assert_eq!(lexer.current_span().deref(), &returns_span); // Lex the last 4 chars let _ = lexer.next(); // whitespace let _ = lexer.next(); // open parenthesis let _ = lexer.next(); // 0 let _ = lexer.next(); // close parenthesis + let _ = lexer.next(); // eof // We covered the whole source - assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); } - -#[test] -fn parses_define_with_extra_suffix() { - let source = "#defineabc"; - let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); - - // Define Identifier first - let tok = lexer.next(); - let unwrapped = tok.unwrap().unwrap(); - let span = Span::new(0..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, span.clone())); - assert_eq!(lexer.current_span().deref(), &span); -} - -#[test] -fn parses_include_with_extra_suffix() { - let source = "#includeabc"; - let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = Lexer::new(flattened_source); - - // Define Identifier first - let tok = lexer.next(); - let unwrapped = tok.unwrap().unwrap(); - let span = Span::new(0..8, None); - assert_eq!(unwrapped, Token::new(TokenKind::Include, span.clone())); - assert_eq!(lexer.current_span().deref(), &span); -} diff --git a/huff_parser/tests/error.rs b/huff_parser/tests/error.rs index e0fa939a..dd1ed3b9 100644 --- a/huff_parser/tests/error.rs +++ b/huff_parser/tests/error.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn test_parses_custom_error() { let source = "#define error TestError(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); @@ -22,16 +22,16 @@ fn test_parses_custom_error() { arg_type: Some(String::from("uint256")), name: None, indexed: false, - span: AstSpan(vec![Span { start: 24, end: 31, file: None }]), + span: AstSpan(vec![Span { start: 24, end: 30, file: None }]), arg_location: None, }], span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 13, file: None }, - Span { start: 14, end: 23, file: None }, - Span { start: 23, end: 24, file: None }, - Span { start: 24, end: 31, file: None }, - Span { start: 31, end: 32, file: None } + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 12, file: None }, + Span { start: 14, end: 22, file: None }, + Span { start: 23, end: 23, file: None }, + Span { start: 24, end: 30, file: None }, + Span { start: 31, end: 31, file: None } ]) } ); diff --git a/huff_parser/tests/event.rs b/huff_parser/tests/event.rs index ab3e384e..ab586bac 100644 --- a/huff_parser/tests/event.rs +++ b/huff_parser/tests/event.rs @@ -6,64 +6,64 @@ use huff_utils::{ast::Event, prelude::*}; fn test_prefix_event_arg_names_with_reserved_keywords() { let source: &str = "#define event TestEvent(bytes4 indexed interfaceId, uint256 uintTest, bool stringMe, string boolean)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let expected_tokens: Vec = vec![ - Token { kind: TokenKind::Define, span: Span { start: 0, end: 7, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 7, end: 8, file: None } }, - Token { kind: TokenKind::Event, span: Span { start: 8, end: 13, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 13, end: 14, file: None } }, + Token { kind: TokenKind::Define, span: Span { start: 0, end: 6, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 7, end: 7, file: None } }, + Token { kind: TokenKind::Event, span: Span { start: 8, end: 12, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 13, end: 13, file: None } }, Token { kind: TokenKind::Ident("TestEvent".to_string()), - span: Span { start: 14, end: 23, file: None }, + span: Span { start: 14, end: 22, file: None }, }, - Token { kind: TokenKind::OpenParen, span: Span { start: 23, end: 24, file: None } }, + Token { kind: TokenKind::OpenParen, span: Span { start: 23, end: 23, file: None } }, Token { kind: TokenKind::PrimitiveType(PrimitiveEVMType::Bytes(4)), - span: Span { start: 24, end: 30, file: None }, + span: Span { start: 24, end: 29, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 30, end: 31, file: None } }, - Token { kind: TokenKind::Indexed, span: Span { start: 31, end: 38, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 38, end: 39, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 30, end: 30, file: None } }, + Token { kind: TokenKind::Indexed, span: Span { start: 31, end: 37, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 38, end: 38, file: None } }, Token { kind: TokenKind::Ident("interfaceId".to_string()), - span: Span { start: 39, end: 50, file: None }, + span: Span { start: 39, end: 49, file: None }, }, - Token { kind: TokenKind::Comma, span: Span { start: 50, end: 51, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 51, end: 52, file: None } }, + Token { kind: TokenKind::Comma, span: Span { start: 50, end: 50, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 51, end: 51, file: None } }, Token { kind: TokenKind::PrimitiveType(PrimitiveEVMType::Uint(256)), - span: Span { start: 52, end: 59, file: None }, + span: Span { start: 52, end: 58, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 59, end: 60, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 59, end: 59, file: None } }, Token { kind: TokenKind::Ident("uintTest".to_string()), - span: Span { start: 60, end: 68, file: None }, + span: Span { start: 60, end: 67, file: None }, }, - Token { kind: TokenKind::Comma, span: Span { start: 68, end: 69, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 69, end: 70, file: None } }, + Token { kind: TokenKind::Comma, span: Span { start: 68, end: 68, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 69, end: 69, file: None } }, Token { kind: TokenKind::PrimitiveType(PrimitiveEVMType::Bool), - span: Span { start: 70, end: 74, file: None }, + span: Span { start: 70, end: 73, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 74, end: 75, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 74, end: 74, file: None } }, Token { kind: TokenKind::Ident("stringMe".to_string()), - span: Span { start: 75, end: 83, file: None }, + span: Span { start: 75, end: 82, file: None }, }, - Token { kind: TokenKind::Comma, span: Span { start: 83, end: 84, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 84, end: 85, file: None } }, + Token { kind: TokenKind::Comma, span: Span { start: 83, end: 83, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 84, end: 84, file: None } }, Token { kind: TokenKind::PrimitiveType(PrimitiveEVMType::String), - span: Span { start: 85, end: 91, file: None }, + span: Span { start: 85, end: 90, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 91, end: 92, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 91, end: 91, file: None } }, Token { kind: TokenKind::Ident("boolean".to_string()), - span: Span { start: 92, end: 99, file: None }, + span: Span { start: 92, end: 98, file: None }, }, - Token { kind: TokenKind::CloseParen, span: Span { start: 99, end: 100, file: None } }, - Token { kind: TokenKind::Eof, span: Span { start: 100, end: 100, file: None } }, + Token { kind: TokenKind::CloseParen, span: Span { start: 99, end: 99, file: None } }, + Token { kind: TokenKind::Eof, span: Span { start: 99, end: 99, file: None } }, ]; assert_eq!(expected_tokens, tokens); let mut parser = Parser::new(tokens, None); @@ -85,11 +85,11 @@ fn test_parse_event() { arg_location: None, span: AstSpan(vec![ // "uint256" - Span { start: 24, end: 31, file: None }, + Span { start: 24, end: 30, file: None }, // "indexed" - Span { start: 32, end: 39, file: None }, + Span { start: 32, end: 38, file: None }, // "a" - Span { start: 40, end: 41, file: None }, + Span { start: 40, end: 40, file: None }, ]), }, Argument { @@ -99,35 +99,35 @@ fn test_parse_event() { arg_location: None, span: AstSpan(vec![ // "uint8" - Span { start: 42, end: 47, file: None }, + Span { start: 42, end: 46, file: None }, // "indexed" - Span { start: 48, end: 55, file: None }, + Span { start: 48, end: 54, file: None }, ]), }, ], span: AstSpan(vec![ // "#define" - Span { start: 0, end: 7, file: None }, + Span { start: 0, end: 6, file: None }, // "event" - Span { start: 8, end: 13, file: None }, + Span { start: 8, end: 12, file: None }, // "TestEvent" - Span { start: 14, end: 23, file: None }, + Span { start: 14, end: 22, file: None }, // "(" - Span { start: 23, end: 24, file: None }, + Span { start: 23, end: 23, file: None }, // "uint256" - Span { start: 24, end: 31, file: None }, + Span { start: 24, end: 30, file: None }, // "indexed" - Span { start: 32, end: 39, file: None }, + Span { start: 32, end: 38, file: None }, // "a" - Span { start: 40, end: 41, file: None }, + Span { start: 40, end: 40, file: None }, // "," - Span { start: 41, end: 42, file: None }, + Span { start: 41, end: 41, file: None }, // "uint8" - Span { start: 42, end: 47, file: None }, + Span { start: 42, end: 46, file: None }, // "indexed" - Span { start: 48, end: 55, file: None }, + Span { start: 48, end: 54, file: None }, // ")" - Span { start: 55, end: 56, file: None }, + Span { start: 55, end: 55, file: None }, ]), hash: [ 96, 60, 104, 14, 131, 197, 151, 167, 15, 107, 26, 61, 1, 186, 238, 67, 62, 152, @@ -147,7 +147,7 @@ fn test_parse_event() { arg_location: None, span: AstSpan(vec![ // "uint256" - Span { start: 24, end: 31, file: None }, + Span { start: 24, end: 30, file: None }, ]), }, Argument { @@ -157,31 +157,31 @@ fn test_parse_event() { arg_location: None, span: AstSpan(vec![ // "uint8" - Span { start: 32, end: 37, file: None }, + Span { start: 32, end: 36, file: None }, // "b" - Span { start: 38, end: 39, file: None }, + Span { start: 38, end: 38, file: None }, ]), }, ], span: AstSpan(vec![ // "#define" - Span { start: 0, end: 7, file: None }, + Span { start: 0, end: 6, file: None }, // "event" - Span { start: 8, end: 13, file: None }, + Span { start: 8, end: 12, file: None }, // "TestEvent" - Span { start: 14, end: 23, file: None }, + Span { start: 14, end: 22, file: None }, // "(" - Span { start: 23, end: 24, file: None }, + Span { start: 23, end: 23, file: None }, // "uint256" - Span { start: 24, end: 31, file: None }, + Span { start: 24, end: 30, file: None }, // "," - Span { start: 31, end: 32, file: None }, + Span { start: 31, end: 31, file: None }, // "uint8" - Span { start: 32, end: 37, file: None }, + Span { start: 32, end: 36, file: None }, // "b" - Span { start: 38, end: 39, file: None }, + Span { start: 38, end: 38, file: None }, // ")" - Span { start: 39, end: 40, file: None }, + Span { start: 39, end: 39, file: None }, ]), hash: [ 96, 60, 104, 14, 131, 197, 151, 167, 15, 107, 26, 61, 1, 186, 238, 67, 62, 152, @@ -201,9 +201,9 @@ fn test_parse_event() { arg_location: None, span: AstSpan(vec![ // "uint256" - Span { start: 24, end: 31, file: None }, + Span { start: 24, end: 30, file: None }, // "indexed" - Span { start: 32, end: 39, file: None }, + Span { start: 32, end: 38, file: None }, ]), }, Argument { @@ -213,29 +213,29 @@ fn test_parse_event() { arg_location: None, span: AstSpan(vec![ // "uint8" - Span { start: 40, end: 45, file: None }, + Span { start: 40, end: 44, file: None }, ]), }, ], span: AstSpan(vec![ // "#define" - Span { start: 0, end: 7, file: None }, + Span { start: 0, end: 6, file: None }, // "event" - Span { start: 8, end: 13, file: None }, + Span { start: 8, end: 12, file: None }, // "TestEvent" - Span { start: 14, end: 23, file: None }, + Span { start: 14, end: 22, file: None }, // "(" - Span { start: 23, end: 24, file: None }, + Span { start: 23, end: 23, file: None }, // "uint256" - Span { start: 24, end: 31, file: None }, + Span { start: 24, end: 30, file: None }, // "indexed" - Span { start: 32, end: 39, file: None }, + Span { start: 32, end: 38, file: None }, // "," - Span { start: 39, end: 40, file: None }, + Span { start: 39, end: 39, file: None }, // "uint8" - Span { start: 40, end: 45, file: None }, + Span { start: 40, end: 44, file: None }, // ")" - Span { start: 45, end: 46, file: None }, + Span { start: 45, end: 45, file: None }, ]), hash: [ 96, 60, 104, 14, 131, 197, 151, 167, 15, 107, 26, 61, 1, 186, 238, 67, 62, 152, @@ -247,7 +247,7 @@ fn test_parse_event() { for (source, expected) in sources { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_parser/tests/function.rs b/huff_parser/tests/function.rs index 4813429e..a3855af9 100644 --- a/huff_parser/tests/function.rs +++ b/huff_parser/tests/function.rs @@ -25,7 +25,7 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 22, end: 29, file: None }]), + span: AstSpan(vec![Span { start: 22, end: 28, file: None }]), }, Argument { name: Some(String::from("b")), @@ -33,8 +33,8 @@ fn parses_valid_function_definition() { indexed: false, arg_location: None, span: AstSpan(vec![ - Span { start: 30, end: 34, file: None }, - Span { start: 35, end: 36, file: None }, + Span { start: 30, end: 33, file: None }, + Span { start: 35, end: 35, file: None }, ]), }, ], @@ -44,24 +44,24 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 51, end: 58, file: None }]), + span: AstSpan(vec![Span { start: 51, end: 57, file: None }]), }], signature: [84, 204, 215, 119], span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 16, file: None }, - Span { start: 17, end: 21, file: None }, - Span { start: 21, end: 22, file: None }, - Span { start: 22, end: 29, file: None }, - Span { start: 29, end: 30, file: None }, - Span { start: 30, end: 34, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 36, end: 37, file: None }, - Span { start: 38, end: 42, file: None }, - Span { start: 43, end: 50, file: None }, - Span { start: 50, end: 51, file: None }, - Span { start: 51, end: 58, file: None }, - Span { start: 58, end: 59, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 15, file: None }, + Span { start: 17, end: 20, file: None }, + Span { start: 21, end: 21, file: None }, + Span { start: 22, end: 28, file: None }, + Span { start: 29, end: 29, file: None }, + Span { start: 30, end: 33, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 36, end: 36, file: None }, + Span { start: 38, end: 41, file: None }, + Span { start: 43, end: 49, file: None }, + Span { start: 50, end: 50, file: None }, + Span { start: 51, end: 57, file: None }, + Span { start: 58, end: 58, file: None }, ]), }, ), @@ -74,7 +74,7 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 22, end: 29, file: None }]), + span: AstSpan(vec![Span { start: 22, end: 28, file: None }]), }], fn_type: FunctionType::Pure, outputs: vec![Argument { @@ -82,21 +82,21 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 44, end: 51, file: None }]), + span: AstSpan(vec![Span { start: 44, end: 50, file: None }]), }], signature: [41, 233, 159, 7], span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 16, file: None }, - Span { start: 17, end: 21, file: None }, - Span { start: 21, end: 22, file: None }, - Span { start: 22, end: 29, file: None }, - Span { start: 29, end: 30, file: None }, - Span { start: 31, end: 35, file: None }, - Span { start: 36, end: 43, file: None }, - Span { start: 43, end: 44, file: None }, - Span { start: 44, end: 51, file: None }, - Span { start: 51, end: 52, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 15, file: None }, + Span { start: 17, end: 20, file: None }, + Span { start: 21, end: 21, file: None }, + Span { start: 22, end: 28, file: None }, + Span { start: 29, end: 29, file: None }, + Span { start: 31, end: 34, file: None }, + Span { start: 36, end: 42, file: None }, + Span { start: 43, end: 43, file: None }, + Span { start: 44, end: 50, file: None }, + Span { start: 51, end: 51, file: None }, ]), }, ), @@ -109,7 +109,7 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 22, end: 29, file: None }]), + span: AstSpan(vec![Span { start: 22, end: 28, file: None }]), }], fn_type: FunctionType::NonPayable, outputs: vec![Argument { @@ -117,21 +117,21 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 50, end: 57, file: None }]), + span: AstSpan(vec![Span { start: 50, end: 56, file: None }]), }], signature: [41, 233, 159, 7], span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 16, file: None }, - Span { start: 17, end: 21, file: None }, - Span { start: 21, end: 22, file: None }, - Span { start: 22, end: 29, file: None }, - Span { start: 29, end: 30, file: None }, - Span { start: 31, end: 41, file: None }, - Span { start: 42, end: 49, file: None }, - Span { start: 49, end: 50, file: None }, - Span { start: 50, end: 57, file: None }, - Span { start: 57, end: 58, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 15, file: None }, + Span { start: 17, end: 20, file: None }, + Span { start: 21, end: 21, file: None }, + Span { start: 22, end: 28, file: None }, + Span { start: 29, end: 29, file: None }, + Span { start: 31, end: 40, file: None }, + Span { start: 42, end: 48, file: None }, + Span { start: 49, end: 49, file: None }, + Span { start: 50, end: 56, file: None }, + Span { start: 57, end: 57, file: None }, ]), }, ), @@ -144,7 +144,7 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 22, end: 29, file: None }]), + span: AstSpan(vec![Span { start: 22, end: 28, file: None }]), }], fn_type: FunctionType::Payable, outputs: vec![Argument { @@ -152,21 +152,21 @@ fn parses_valid_function_definition() { arg_type: Some(String::from("uint256")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 47, end: 54, file: None }]), + span: AstSpan(vec![Span { start: 47, end: 53, file: None }]), }], signature: [41, 233, 159, 7], span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 16, file: None }, - Span { start: 17, end: 21, file: None }, - Span { start: 21, end: 22, file: None }, - Span { start: 22, end: 29, file: None }, - Span { start: 29, end: 30, file: None }, - Span { start: 31, end: 38, file: None }, - Span { start: 39, end: 46, file: None }, - Span { start: 46, end: 47, file: None }, - Span { start: 47, end: 54, file: None }, - Span { start: 54, end: 55, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 15, file: None }, + Span { start: 17, end: 20, file: None }, + Span { start: 21, end: 21, file: None }, + Span { start: 22, end: 28, file: None }, + Span { start: 29, end: 29, file: None }, + Span { start: 31, end: 37, file: None }, + Span { start: 39, end: 45, file: None }, + Span { start: 46, end: 46, file: None }, + Span { start: 47, end: 53, file: None }, + Span { start: 54, end: 54, file: None }, ]), }, ), @@ -197,7 +197,7 @@ fn parses_valid_function_definition() { for (index, source) in sources.into_iter().enumerate() { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -217,7 +217,7 @@ fn parses_valid_function_definition() { fn cannot_parse_invalid_function_definition() { let source = "#define function test(uint256) returns(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); @@ -229,7 +229,7 @@ fn test_functions_with_keyword_arg_names_errors() { // The function parameter's name is a reserved keyword; this should throw an error let source: &str = "#define function myFunc(uint256 uint256) pure returns(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); @@ -239,7 +239,7 @@ fn test_functions_with_keyword_arg_names_errors() { fn test_functions_with_argument_locations() { let source: &str = "#define function myFunc(string calldata test, uint256[] storage) pure returns(bytes memory)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); @@ -249,40 +249,39 @@ fn test_functions_with_argument_locations() { fn test_can_prefix_function_arg_names_with_reserved_keywords() { let source: &str = "#define function supportsInterface(bytes4 interfaceId) view returns (bool)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let expected_tokens: Vec = vec![ - Token { kind: TokenKind::Define, span: Span { start: 0, end: 7, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 7, end: 8, file: None } }, - Token { kind: TokenKind::Function, span: Span { start: 8, end: 16, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 16, end: 17, file: None } }, + Token { kind: TokenKind::Define, span: Span { start: 0, end: 6, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 7, end: 7, file: None } }, + Token { kind: TokenKind::Function, span: Span { start: 8, end: 15, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 16, end: 16, file: None } }, Token { kind: TokenKind::Ident("supportsInterface".to_string()), - span: Span { start: 17, end: 34, file: None }, + span: Span { start: 17, end: 33, file: None }, }, - Token { kind: TokenKind::OpenParen, span: Span { start: 34, end: 35, file: None } }, + Token { kind: TokenKind::OpenParen, span: Span { start: 34, end: 34, file: None } }, Token { kind: TokenKind::PrimitiveType(PrimitiveEVMType::Bytes(4)), - span: Span { start: 35, end: 41, file: None }, + span: Span { start: 35, end: 40, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 41, end: 42, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 41, end: 41, file: None } }, Token { kind: TokenKind::Ident("interfaceId".to_string()), - span: Span { start: 42, end: 53, file: None }, + span: Span { start: 42, end: 52, file: None }, }, - Token { kind: TokenKind::CloseParen, span: Span { start: 53, end: 54, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 54, end: 55, file: None } }, - Token { kind: TokenKind::View, span: Span { start: 55, end: 59, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 59, end: 60, file: None } }, - Token { kind: TokenKind::Returns, span: Span { start: 60, end: 67, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 67, end: 68, file: None } }, - Token { kind: TokenKind::OpenParen, span: Span { start: 68, end: 69, file: None } }, + Token { kind: TokenKind::CloseParen, span: Span { start: 53, end: 53, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 54, end: 54, file: None } }, + Token { kind: TokenKind::View, span: Span { start: 55, end: 58, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 59, end: 59, file: None } }, + Token { kind: TokenKind::Returns, span: Span { start: 60, end: 66, file: None } }, + Token { kind: TokenKind::OpenParen, span: Span { start: 68, end: 68, file: None } }, Token { kind: TokenKind::PrimitiveType(PrimitiveEVMType::Bool), - span: Span { start: 69, end: 73, file: None }, + span: Span { start: 69, end: 72, file: None }, }, - Token { kind: TokenKind::CloseParen, span: Span { start: 73, end: 74, file: None } }, - Token { kind: TokenKind::Eof, span: Span { start: 74, end: 74, file: None } }, + Token { kind: TokenKind::CloseParen, span: Span { start: 73, end: 73, file: None } }, + Token { kind: TokenKind::Eof, span: Span { start: 73, end: 73, file: None } }, ]; assert_eq!(expected_tokens, tokens); let mut parser = Parser::new(tokens, None); From 6d4d308b51fd92f0e671b211b937cf08cdffc8b6 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 16:12:58 -0700 Subject: [PATCH 25/68] some parser test updates --- huff_lexer/src/lexer.rs | 1 - huff_parser/tests/opcodes.rs | 10 ++-- .../tests/storage_pointer_derivation.rs | 32 ++++++------ huff_parser/tests/table.rs | 49 ++++++++++--------- 4 files changed, 48 insertions(+), 44 deletions(-) diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index a7cb1d29..df2ff991 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -272,7 +272,6 @@ impl<'a> LexerNew<'a> { if let Some(':') = self.peek() { found_kind = Some(TokenKind::Label(word.clone())); - self.consume(); } // Syntax sugar: true evaluates to 0x01, false evaluates to 0x00 diff --git a/huff_parser/tests/opcodes.rs b/huff_parser/tests/opcodes.rs index b44fab15..a54d355a 100644 --- a/huff_parser/tests/opcodes.rs +++ b/huff_parser/tests/opcodes.rs @@ -17,13 +17,16 @@ fn not_mistaken_as_opcode() { "# ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) .filter(|x| !matches!(x.kind, TokenKind::Whitespace)) .collect::>(); + + dbg!(tokens.clone()); + let actual_label_arg = tokens[tokens.len() - 7].kind.clone(); let actual_label = tokens[tokens.len() - 5].kind.clone(); let mut parser = Parser::new(tokens, None); @@ -48,7 +51,7 @@ fn test_invalid_push_non_literal() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -68,7 +71,8 @@ fn test_push_literals() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); + // let lexer = Lexer::new(flattened_source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let expected_tokens = vec![ diff --git a/huff_parser/tests/storage_pointer_derivation.rs b/huff_parser/tests/storage_pointer_derivation.rs index 7908780c..c8f1e2d1 100644 --- a/huff_parser/tests/storage_pointer_derivation.rs +++ b/huff_parser/tests/storage_pointer_derivation.rs @@ -8,7 +8,7 @@ fn derives_storage_pointers() { "#define constant FSP_LOCATION = FREE_STORAGE_POINTER()\n#define constant FSP_LOCATION_2 = FREE_STORAGE_POINTER()\n#define constant NUM = 0xa57B"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -22,11 +22,11 @@ fn derives_storage_pointers() { name: "FSP_LOCATION".to_string(), value: ConstVal::FreeStoragePointer(FreeStoragePointer {}), span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 16, file: None }, - Span { start: 17, end: 29, file: None }, - Span { start: 30, end: 31, file: None }, - Span { start: 32, end: 54, file: None } + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 15, file: None }, + Span { start: 17, end: 28, file: None }, + Span { start: 30, end: 30, file: None }, + Span { start: 32, end: 53, file: None } ]) } ); @@ -38,11 +38,11 @@ fn derives_storage_pointers() { name: "FSP_LOCATION_2".to_string(), value: ConstVal::FreeStoragePointer(FreeStoragePointer {}), span: AstSpan(vec![ - Span { start: 55, end: 62, file: None }, - Span { start: 63, end: 71, file: None }, - Span { start: 72, end: 86, file: None }, - Span { start: 87, end: 88, file: None }, - Span { start: 89, end: 111, file: None } + Span { start: 55, end: 61, file: None }, + Span { start: 63, end: 70, file: None }, + Span { start: 72, end: 85, file: None }, + Span { start: 87, end: 87, file: None }, + Span { start: 89, end: 110, file: None } ]) } ); @@ -54,11 +54,11 @@ fn derives_storage_pointers() { name: "NUM".to_string(), value: ConstVal::Literal(str_to_bytes32("a57B")), span: AstSpan(vec![ - Span { start: 112, end: 119, file: None }, - Span { start: 120, end: 128, file: None }, - Span { start: 129, end: 132, file: None }, - Span { start: 133, end: 134, file: None }, - Span { start: 137, end: 141, file: None } + Span { start: 112, end: 118, file: None }, + Span { start: 120, end: 127, file: None }, + Span { start: 129, end: 131, file: None }, + Span { start: 133, end: 133, file: None }, + Span { start: 137, end: 140, file: None } ]) } ); diff --git a/huff_parser/tests/table.rs b/huff_parser/tests/table.rs index e77c23a0..ad41a993 100644 --- a/huff_parser/tests/table.rs +++ b/huff_parser/tests/table.rs @@ -9,7 +9,7 @@ fn table_with_no_body() { for kind in table_kinds { let source = &format!("#define {kind} TEST_TABLE() = {}{}", "{", "}"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -25,14 +25,14 @@ fn table_with_no_body() { statements: vec![], size: Literal::default(), span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: kind_offset, file: None }, - Span { start: kind_offset + 1, end: kind_offset + 11, file: None }, - Span { start: kind_offset + 11, end: kind_offset + 12, file: None }, - Span { start: kind_offset + 12, end: kind_offset + 13, file: None }, - Span { start: kind_offset + 14, end: kind_offset + 15, file: None }, - Span { start: kind_offset + 16, end: kind_offset + 17, file: None }, - Span { start: kind_offset + 17, end: kind_offset + 18, file: None } + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: kind_offset - 1, file: None }, + Span { start: kind_offset + 1, end: kind_offset + 10, file: None }, + Span { start: kind_offset + 11, end: kind_offset + 11, file: None }, + Span { start: kind_offset + 12, end: kind_offset + 12, file: None }, + Span { start: kind_offset + 14, end: kind_offset + 14, file: None }, + Span { start: kind_offset + 16, end: kind_offset + 16, file: None }, + Span { start: kind_offset + 17, end: kind_offset + 17, file: None } ]), } ); @@ -54,7 +54,8 @@ fn table_with_body() { let lb2_start = source.find("label_call_2").unwrap_or(0); let lb3_start = source.find("label_call_3").unwrap_or(0); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + // let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -72,7 +73,7 @@ fn table_with_body() { ty: StatementType::LabelCall("label_call_1".to_string()), span: AstSpan(vec![Span { start: lb1_start, - end: lb1_start + "label_call_1".len(), + end: lb1_start + "label_call_1".len() - 1, file: None }]), }, @@ -80,7 +81,7 @@ fn table_with_body() { ty: StatementType::LabelCall("label_call_2".to_string()), span: AstSpan(vec![Span { start: lb2_start, - end: lb2_start + "label_call_2".len(), + end: lb2_start + "label_call_2".len() - 1, file: None }]), }, @@ -88,24 +89,24 @@ fn table_with_body() { ty: StatementType::LabelCall("label_call_3".to_string()), span: AstSpan(vec![Span { start: lb3_start, - end: lb3_start + "label_call_3".len(), + end: lb3_start + "label_call_3".len() - 1, file: None }]), }, ], size: str_to_bytes32(expected_size), span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: kind_offset, file: None }, - Span { start: kind_offset + 1, end: kind_offset + 11, file: None }, - Span { start: kind_offset + 11, end: kind_offset + 12, file: None }, - Span { start: kind_offset + 12, end: kind_offset + 13, file: None }, - Span { start: kind_offset + 14, end: kind_offset + 15, file: None }, - Span { start: kind_offset + 16, end: kind_offset + 17, file: None }, - Span { start: kind_offset + 18, end: kind_offset + 30, file: None }, - Span { start: kind_offset + 31, end: kind_offset + 43, file: None }, - Span { start: kind_offset + 44, end: kind_offset + 56, file: None }, - Span { start: kind_offset + 57, end: kind_offset + 58, file: None } + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: kind_offset - 1, file: None }, + Span { start: kind_offset + 1, end: kind_offset + 10, file: None }, + Span { start: kind_offset + 11, end: kind_offset + 11, file: None }, + Span { start: kind_offset + 12, end: kind_offset + 12, file: None }, + Span { start: kind_offset + 14, end: kind_offset + 14, file: None }, + Span { start: kind_offset + 16, end: kind_offset + 16, file: None }, + Span { start: kind_offset + 18, end: kind_offset + 29, file: None }, + Span { start: kind_offset + 31, end: kind_offset + 42, file: None }, + Span { start: kind_offset + 44, end: kind_offset + 55, file: None }, + Span { start: kind_offset + 57, end: kind_offset + 57, file: None } ]), } ); From 1fff0ff5f517434f9ded852ab69ca2581faf27a7 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 16:34:54 -0700 Subject: [PATCH 26/68] more macro tests --- huff_parser/tests/macro.rs | 748 ++++++++++++++++++------------------- 1 file changed, 371 insertions(+), 377 deletions(-) diff --git a/huff_parser/tests/macro.rs b/huff_parser/tests/macro.rs index 83d6b80a..317cb81c 100644 --- a/huff_parser/tests/macro.rs +++ b/huff_parser/tests/macro.rs @@ -7,18 +7,8 @@ use tracing::debug; fn empty_macro() { let source = "#define macro HELLO_WORLD() = takes(0) returns(4) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - //let lexer = Lexer::new(flattened_source.clone()); let lexer = lexer::LexerNew::new(flattened_source.source); - // let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); - - //dbg!(tokens.clone()); - // dbg!(tokensNew.clone()); - // if tokens.clone() == tokensNew.clone() { - // println!("FUCK YES") - // } else { - // println!("FUCK NO") - // } let mut parser = Parser::new(tokens, None); // Grab the first macro @@ -59,7 +49,7 @@ fn empty_macro() { fn empty_macro_without_takes_returns() { let source = "#define macro HELLO_WORLD() = {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -73,14 +63,14 @@ fn empty_macro_without_takes_returns() { takes: 0, returns: 0, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 13, file: None }, - Span { start: 14, end: 25, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 26, end: 27, file: None }, - Span { start: 28, end: 29, file: None }, - Span { start: 30, end: 31, file: None }, - Span { start: 31, end: 32, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 12, file: None }, + Span { start: 14, end: 24, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 26, end: 26, file: None }, + Span { start: 28, end: 28, file: None }, + Span { start: 30, end: 30, file: None }, + Span { start: 31, end: 31, file: None }, ]), outlined: false, test: false, @@ -131,7 +121,7 @@ fn empty_macro_only_takes() { fn empty_macro_only_returns() { let source = "#define macro HELLO_WORLD() = returns(10) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -145,18 +135,18 @@ fn empty_macro_only_returns() { takes: 0, returns: 10, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 13, file: None }, - Span { start: 14, end: 25, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 26, end: 27, file: None }, - Span { start: 28, end: 29, file: None }, - Span { start: 30, end: 37, file: None }, - Span { start: 37, end: 38, file: None }, - Span { start: 38, end: 40, file: None }, - Span { start: 40, end: 41, file: None }, - Span { start: 42, end: 43, file: None }, - Span { start: 43, end: 44, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 12, file: None }, + Span { start: 14, end: 24, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 26, end: 26, file: None }, + Span { start: 28, end: 28, file: None }, + Span { start: 30, end: 36, file: None }, + Span { start: 37, end: 37, file: None }, + Span { start: 38, end: 39, file: None }, + Span { start: 40, end: 40, file: None }, + Span { start: 42, end: 42, file: None }, + Span { start: 43, end: 43, file: None }, ]), outlined: false, test: false, @@ -170,7 +160,7 @@ fn macro_with_simple_body() { let source = "#define macro HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -183,49 +173,49 @@ fn macro_with_simple_body() { statements: vec![ Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 54, end: 56, file: None }]), + span: AstSpan(vec![Span { start: 54, end: 55, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Mstore), - span: AstSpan(vec![Span { start: 57, end: 63, file: None }]), + span: AstSpan(vec![Span { start: 57, end: 62, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("01")), - span: AstSpan(vec![Span { start: 67, end: 69, file: None }]), + span: AstSpan(vec![Span { start: 67, end: 68, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("02")), - span: AstSpan(vec![Span { start: 72, end: 74, file: None }]), + span: AstSpan(vec![Span { start: 72, end: 73, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Add), - span: AstSpan(vec![Span { start: 75, end: 78, file: None }]), + span: AstSpan(vec![Span { start: 75, end: 77, file: None }]), }, ], takes: 3, returns: 0, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 13, file: None }, - Span { start: 14, end: 25, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 26, end: 27, file: None }, - Span { start: 28, end: 29, file: None }, - Span { start: 30, end: 35, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 36, end: 37, file: None }, - Span { start: 37, end: 38, file: None }, - Span { start: 39, end: 46, file: None }, - Span { start: 46, end: 47, file: None }, - Span { start: 47, end: 48, file: None }, - Span { start: 48, end: 49, file: None }, - Span { start: 50, end: 51, file: None }, - Span { start: 54, end: 56, file: None }, - Span { start: 57, end: 63, file: None }, - Span { start: 67, end: 69, file: None }, - Span { start: 72, end: 74, file: None }, - Span { start: 75, end: 78, file: None }, - Span { start: 79, end: 80, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 12, file: None }, + Span { start: 14, end: 24, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 26, end: 26, file: None }, + Span { start: 28, end: 28, file: None }, + Span { start: 30, end: 34, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 36, end: 36, file: None }, + Span { start: 37, end: 37, file: None }, + Span { start: 39, end: 45, file: None }, + Span { start: 46, end: 46, file: None }, + Span { start: 47, end: 47, file: None }, + Span { start: 48, end: 48, file: None }, + Span { start: 50, end: 50, file: None }, + Span { start: 54, end: 55, file: None }, + Span { start: 57, end: 62, file: None }, + Span { start: 67, end: 68, file: None }, + Span { start: 72, end: 73, file: None }, + Span { start: 75, end: 77, file: None }, + Span { start: 79, end: 79, file: None }, ]), outlined: false, test: false, @@ -260,7 +250,7 @@ fn macro_with_arg_calls() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -273,141 +263,141 @@ fn macro_with_arg_calls() { name: Some("error".to_string()), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 67, end: 72, file: None }]), + span: AstSpan(vec![Span { start: 67, end: 71, file: None }]), }], decorator: None, statements: vec![ Statement { ty: StatementType::Opcode(Opcode::Dup2), - span: AstSpan(vec![Span { start: 209, end: 213, file: None }]), + span: AstSpan(vec![Span { start: 209, end: 212, file: None }]), }, Statement { ty: StatementType::Constant("BALANCE_LOCATION".to_string()), - span: AstSpan(vec![Span { start: 265, end: 281, file: None }]), + span: AstSpan(vec![Span { start: 265, end: 280, file: None }]), }, Statement { ty: StatementType::MacroInvocation(MacroInvocation { macro_name: "LOAD_ELEMENT_FROM_KEYS".to_string(), args: vec![MacroArg::Literal(str_to_bytes32("00"))], span: AstSpan(vec![ - Span { start: 283, end: 305, file: None }, - Span { start: 305, end: 306, file: None }, - Span { start: 308, end: 310, file: None }, - Span { start: 310, end: 311, file: None }, + Span { start: 283, end: 304, file: None }, + Span { start: 305, end: 305, file: None }, + Span { start: 308, end: 309, file: None }, + Span { start: 310, end: 310, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 283, end: 305, file: None }, - Span { start: 305, end: 306, file: None }, - Span { start: 308, end: 310, file: None }, - Span { start: 310, end: 311, file: None }, + Span { start: 283, end: 304, file: None }, + Span { start: 305, end: 305, file: None }, + Span { start: 308, end: 309, file: None }, + Span { start: 310, end: 310, file: None }, ]), }, Statement { ty: StatementType::Opcode(Opcode::Dup1), - span: AstSpan(vec![Span { start: 351, end: 355, file: None }]), + span: AstSpan(vec![Span { start: 351, end: 354, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Dup3), - span: AstSpan(vec![Span { start: 418, end: 422, file: None }]), + span: AstSpan(vec![Span { start: 418, end: 421, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Gt), - span: AstSpan(vec![Span { start: 492, end: 494, file: None }]), + span: AstSpan(vec![Span { start: 492, end: 493, file: None }]), }, Statement { ty: StatementType::ArgCall("error".to_string()), - span: AstSpan(vec![Span { start: 566, end: 571, file: None }]), + span: AstSpan(vec![Span { start: 566, end: 570, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Jumpi), - span: AstSpan(vec![Span { start: 573, end: 578, file: None }]), + span: AstSpan(vec![Span { start: 573, end: 577, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Dup2), - span: AstSpan(vec![Span { start: 715, end: 719, file: None }]), + span: AstSpan(vec![Span { start: 715, end: 718, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Swap1), - span: AstSpan(vec![Span { start: 780, end: 785, file: None }]), + span: AstSpan(vec![Span { start: 780, end: 784, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Sub), - span: AstSpan(vec![Span { start: 845, end: 848, file: None }]), + span: AstSpan(vec![Span { start: 845, end: 847, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Dup3), - span: AstSpan(vec![Span { start: 911, end: 915, file: None }]), + span: AstSpan(vec![Span { start: 911, end: 914, file: None }]), }, Statement { ty: StatementType::Constant("BALANCE_LOCATION".to_string()), - span: AstSpan(vec![Span { start: 982, end: 998, file: None }]), + span: AstSpan(vec![Span { start: 982, end: 997, file: None }]), }, Statement { ty: StatementType::MacroInvocation(MacroInvocation { macro_name: "STORE_ELEMENT_FROM_KEYS".to_string(), args: vec![MacroArg::Literal(str_to_bytes32("00"))], span: AstSpan(vec![ - Span { start: 1000, end: 1023, file: None }, - Span { start: 1023, end: 1024, file: None }, - Span { start: 1026, end: 1028, file: None }, - Span { start: 1028, end: 1029, file: None }, + Span { start: 1000, end: 1022, file: None }, + Span { start: 1023, end: 1023, file: None }, + Span { start: 1026, end: 1027, file: None }, + Span { start: 1028, end: 1028, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 1000, end: 1023, file: None }, - Span { start: 1023, end: 1024, file: None }, - Span { start: 1026, end: 1028, file: None }, - Span { start: 1028, end: 1029, file: None }, + Span { start: 1000, end: 1022, file: None }, + Span { start: 1023, end: 1023, file: None }, + Span { start: 1026, end: 1027, file: None }, + Span { start: 1028, end: 1028, file: None }, ]), }, ], takes: 3, returns: 3, span: AstSpan(vec![ - Span { start: 34, end: 41, file: None }, - Span { start: 42, end: 47, file: None }, - Span { start: 48, end: 66, file: None }, - Span { start: 66, end: 67, file: None }, - Span { start: 67, end: 72, file: None }, - Span { start: 72, end: 73, file: None }, - Span { start: 74, end: 75, file: None }, - Span { start: 76, end: 81, file: None }, - Span { start: 81, end: 82, file: None }, - Span { start: 82, end: 83, file: None }, - Span { start: 83, end: 84, file: None }, - Span { start: 85, end: 92, file: None }, - Span { start: 93, end: 94, file: None }, - Span { start: 94, end: 95, file: None }, - Span { start: 95, end: 96, file: None }, - Span { start: 97, end: 98, file: None }, - Span { start: 209, end: 213, file: None }, - Span { start: 264, end: 265, file: None }, - Span { start: 265, end: 281, file: None }, - Span { start: 281, end: 282, file: None }, - Span { start: 283, end: 305, file: None }, - Span { start: 305, end: 306, file: None }, - Span { start: 308, end: 310, file: None }, - Span { start: 310, end: 311, file: None }, - Span { start: 351, end: 355, file: None }, - Span { start: 418, end: 422, file: None }, - Span { start: 492, end: 494, file: None }, - Span { start: 565, end: 566, file: None }, - Span { start: 566, end: 571, file: None }, - Span { start: 571, end: 572, file: None }, - Span { start: 573, end: 578, file: None }, - Span { start: 715, end: 719, file: None }, - Span { start: 780, end: 785, file: None }, - Span { start: 845, end: 848, file: None }, - Span { start: 911, end: 915, file: None }, - Span { start: 981, end: 982, file: None }, - Span { start: 982, end: 998, file: None }, - Span { start: 998, end: 999, file: None }, - Span { start: 1000, end: 1023, file: None }, - Span { start: 1023, end: 1024, file: None }, - Span { start: 1026, end: 1028, file: None }, - Span { start: 1028, end: 1029, file: None }, - Span { start: 1055, end: 1056, file: None }, + Span { start: 34, end: 40, file: None }, + Span { start: 42, end: 46, file: None }, + Span { start: 48, end: 65, file: None }, + Span { start: 66, end: 66, file: None }, + Span { start: 67, end: 71, file: None }, + Span { start: 72, end: 72, file: None }, + Span { start: 74, end: 74, file: None }, + Span { start: 76, end: 80, file: None }, + Span { start: 81, end: 81, file: None }, + Span { start: 82, end: 82, file: None }, + Span { start: 83, end: 83, file: None }, + Span { start: 85, end: 91, file: None }, + Span { start: 93, end: 93, file: None }, + Span { start: 94, end: 94, file: None }, + Span { start: 95, end: 95, file: None }, + Span { start: 97, end: 97, file: None }, + Span { start: 209, end: 212, file: None }, + Span { start: 264, end: 264, file: None }, + Span { start: 265, end: 280, file: None }, + Span { start: 281, end: 281, file: None }, + Span { start: 283, end: 304, file: None }, + Span { start: 305, end: 305, file: None }, + Span { start: 308, end: 309, file: None }, + Span { start: 310, end: 310, file: None }, + Span { start: 351, end: 354, file: None }, + Span { start: 418, end: 421, file: None }, + Span { start: 492, end: 493, file: None }, + Span { start: 565, end: 565, file: None }, + Span { start: 566, end: 570, file: None }, + Span { start: 571, end: 571, file: None }, + Span { start: 573, end: 577, file: None }, + Span { start: 715, end: 718, file: None }, + Span { start: 780, end: 784, file: None }, + Span { start: 845, end: 847, file: None }, + Span { start: 911, end: 914, file: None }, + Span { start: 981, end: 981, file: None }, + Span { start: 982, end: 997, file: None }, + Span { start: 998, end: 998, file: None }, + Span { start: 1000, end: 1022, file: None }, + Span { start: 1023, end: 1023, file: None }, + Span { start: 1026, end: 1027, file: None }, + Span { start: 1028, end: 1028, file: None }, + Span { start: 1055, end: 1055, file: None }, ]), outlined: false, test: false, @@ -431,7 +421,8 @@ fn macro_labels() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + // let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -451,48 +442,48 @@ fn macro_labels() { macro_name: "TRANSFER_GIVE_TO".to_string(), args: vec![], span: AstSpan(vec![ - Span { start: 89, end: 105, file: None }, - Span { start: 105, end: 106, file: None }, - Span { start: 106, end: 107, file: None }, + Span { start: 89, end: 104, file: None }, + Span { start: 105, end: 105, file: None }, + Span { start: 106, end: 106, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 89, end: 105, file: None }, - Span { start: 105, end: 106, file: None }, - Span { start: 106, end: 107, file: None }, + Span { start: 89, end: 104, file: None }, + Span { start: 105, end: 105, file: None }, + Span { start: 106, end: 106, file: None }, ]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 122, end: 124, file: None }]), + span: AstSpan(vec![Span { start: 122, end: 123, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 127, end: 129, file: None }]), + span: AstSpan(vec![Span { start: 127, end: 128, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Revert), - span: AstSpan(vec![Span { start: 130, end: 136, file: None }]), + span: AstSpan(vec![Span { start: 130, end: 135, file: None }]), }, ], span: AstSpan(vec![ - Span { start: 66, end: 75, file: None }, - Span { start: 89, end: 105, file: None }, - Span { start: 105, end: 106, file: None }, - Span { start: 106, end: 107, file: None }, - Span { start: 122, end: 124, file: None }, - Span { start: 127, end: 129, file: None }, - Span { start: 130, end: 136, file: None }, + Span { start: 66, end: 74, file: None }, + Span { start: 89, end: 104, file: None }, + Span { start: 105, end: 105, file: None }, + Span { start: 106, end: 106, file: None }, + Span { start: 122, end: 123, file: None }, + Span { start: 127, end: 128, file: None }, + Span { start: 130, end: 135, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 66, end: 75, file: None }, - Span { start: 89, end: 105, file: None }, - Span { start: 105, end: 106, file: None }, - Span { start: 106, end: 107, file: None }, - Span { start: 122, end: 124, file: None }, - Span { start: 127, end: 129, file: None }, - Span { start: 130, end: 136, file: None }, + Span { start: 66, end: 74, file: None }, + Span { start: 89, end: 104, file: None }, + Span { start: 105, end: 105, file: None }, + Span { start: 106, end: 106, file: None }, + Span { start: 122, end: 123, file: None }, + Span { start: 127, end: 128, file: None }, + Span { start: 130, end: 135, file: None }, ]), }, Statement { @@ -504,86 +495,86 @@ fn macro_labels() { macro_name: "TRANSFER_GIVE_TO".to_string(), args: vec![], span: AstSpan(vec![ - Span { start: 164, end: 180, file: None }, - Span { start: 180, end: 181, file: None }, - Span { start: 181, end: 182, file: None }, + Span { start: 164, end: 179, file: None }, + Span { start: 180, end: 180, file: None }, + Span { start: 181, end: 181, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 164, end: 180, file: None }, - Span { start: 180, end: 181, file: None }, - Span { start: 181, end: 182, file: None }, + Span { start: 164, end: 179, file: None }, + Span { start: 180, end: 180, file: None }, + Span { start: 181, end: 181, file: None }, ]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 197, end: 199, file: None }]), + span: AstSpan(vec![Span { start: 197, end: 198, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 202, end: 204, file: None }]), + span: AstSpan(vec![Span { start: 202, end: 203, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Revert), - span: AstSpan(vec![Span { start: 205, end: 211, file: None }]), + span: AstSpan(vec![Span { start: 205, end: 210, file: None }]), }, ], span: AstSpan(vec![ - Span { start: 145, end: 150, file: None }, - Span { start: 164, end: 180, file: None }, - Span { start: 180, end: 181, file: None }, - Span { start: 181, end: 182, file: None }, - Span { start: 197, end: 199, file: None }, - Span { start: 202, end: 204, file: None }, - Span { start: 205, end: 211, file: None }, + Span { start: 145, end: 149, file: None }, + Span { start: 164, end: 179, file: None }, + Span { start: 180, end: 180, file: None }, + Span { start: 181, end: 181, file: None }, + Span { start: 197, end: 198, file: None }, + Span { start: 202, end: 203, file: None }, + Span { start: 205, end: 210, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 145, end: 150, file: None }, - Span { start: 164, end: 180, file: None }, - Span { start: 180, end: 181, file: None }, - Span { start: 181, end: 182, file: None }, - Span { start: 197, end: 199, file: None }, - Span { start: 202, end: 204, file: None }, - Span { start: 205, end: 211, file: None }, + Span { start: 145, end: 149, file: None }, + Span { start: 164, end: 179, file: None }, + Span { start: 180, end: 180, file: None }, + Span { start: 181, end: 181, file: None }, + Span { start: 197, end: 198, file: None }, + Span { start: 202, end: 203, file: None }, + Span { start: 205, end: 210, file: None }, ]), }, ], takes: 0, returns: 0, span: AstSpan(vec![ - Span { start: 5, end: 12, file: None }, - Span { start: 13, end: 18, file: None }, - Span { start: 19, end: 31, file: None }, - Span { start: 31, end: 32, file: None }, - Span { start: 32, end: 33, file: None }, - Span { start: 34, end: 35, file: None }, - Span { start: 36, end: 41, file: None }, - Span { start: 41, end: 42, file: None }, - Span { start: 42, end: 43, file: None }, - Span { start: 43, end: 44, file: None }, - Span { start: 45, end: 52, file: None }, - Span { start: 52, end: 53, file: None }, - Span { start: 53, end: 54, file: None }, - Span { start: 54, end: 55, file: None }, - Span { start: 56, end: 57, file: None }, - Span { start: 66, end: 75, file: None }, - Span { start: 75, end: 76, file: None }, - Span { start: 89, end: 105, file: None }, - Span { start: 105, end: 106, file: None }, - Span { start: 106, end: 107, file: None }, - Span { start: 122, end: 124, file: None }, - Span { start: 127, end: 129, file: None }, - Span { start: 130, end: 136, file: None }, - Span { start: 145, end: 150, file: None }, - Span { start: 150, end: 151, file: None }, - Span { start: 164, end: 180, file: None }, - Span { start: 180, end: 181, file: None }, - Span { start: 181, end: 182, file: None }, - Span { start: 197, end: 199, file: None }, - Span { start: 202, end: 204, file: None }, - Span { start: 205, end: 211, file: None }, - Span { start: 216, end: 217, file: None }, + Span { start: 5, end: 11, file: None }, + Span { start: 13, end: 17, file: None }, + Span { start: 19, end: 30, file: None }, + Span { start: 31, end: 31, file: None }, + Span { start: 32, end: 32, file: None }, + Span { start: 34, end: 34, file: None }, + Span { start: 36, end: 40, file: None }, + Span { start: 41, end: 41, file: None }, + Span { start: 42, end: 42, file: None }, + Span { start: 43, end: 43, file: None }, + Span { start: 45, end: 51, file: None }, + Span { start: 52, end: 52, file: None }, + Span { start: 53, end: 53, file: None }, + Span { start: 54, end: 54, file: None }, + Span { start: 56, end: 56, file: None }, + Span { start: 66, end: 74, file: None }, + Span { start: 75, end: 75, file: None }, + Span { start: 89, end: 104, file: None }, + Span { start: 105, end: 105, file: None }, + Span { start: 106, end: 106, file: None }, + Span { start: 122, end: 123, file: None }, + Span { start: 127, end: 128, file: None }, + Span { start: 130, end: 135, file: None }, + Span { start: 145, end: 149, file: None }, + Span { start: 150, end: 150, file: None }, + Span { start: 164, end: 179, file: None }, + Span { start: 180, end: 180, file: None }, + Span { start: 181, end: 181, file: None }, + Span { start: 197, end: 198, file: None }, + Span { start: 202, end: 203, file: None }, + Span { start: 205, end: 210, file: None }, + Span { start: 216, end: 216, file: None }, ]), outlined: false, test: false, @@ -606,7 +597,7 @@ fn macro_invocation_with_arg_call() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -620,7 +611,7 @@ fn macro_invocation_with_arg_call() { name: Some("error".to_string()), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 28, end: 33, file: None }]), + span: AstSpan(vec![Span { start: 28, end: 32, file: None }]), }], statements: vec![ Statement { @@ -628,21 +619,21 @@ fn macro_invocation_with_arg_call() { macro_name: "TRANSFER_TAKE_FROM".to_string(), args: vec![MacroArg::ArgCall("error".to_string())], span: AstSpan(vec![ - Span { start: 67, end: 85, file: None }, - Span { start: 85, end: 86, file: None }, - Span { start: 86, end: 87, file: None }, - Span { start: 87, end: 92, file: None }, - Span { start: 92, end: 93, file: None }, - Span { start: 93, end: 94, file: None }, + Span { start: 67, end: 84, file: None }, + Span { start: 85, end: 85, file: None }, + Span { start: 86, end: 86, file: None }, + Span { start: 87, end: 91, file: None }, + Span { start: 92, end: 92, file: None }, + Span { start: 93, end: 93, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 67, end: 85, file: None }, - Span { start: 85, end: 86, file: None }, - Span { start: 86, end: 87, file: None }, - Span { start: 87, end: 92, file: None }, - Span { start: 92, end: 93, file: None }, - Span { start: 93, end: 94, file: None }, + Span { start: 67, end: 84, file: None }, + Span { start: 85, end: 85, file: None }, + Span { start: 86, end: 86, file: None }, + Span { start: 87, end: 91, file: None }, + Span { start: 92, end: 92, file: None }, + Span { start: 93, end: 93, file: None }, ]), }, Statement { @@ -650,86 +641,86 @@ fn macro_invocation_with_arg_call() { macro_name: "TRANSFER_GIVE_TO".to_string(), args: vec![MacroArg::ArgCall("error".to_string())], span: AstSpan(vec![ - Span { start: 103, end: 119, file: None }, - Span { start: 119, end: 120, file: None }, - Span { start: 120, end: 121, file: None }, - Span { start: 121, end: 126, file: None }, - Span { start: 126, end: 127, file: None }, - Span { start: 127, end: 128, file: None }, + Span { start: 103, end: 118, file: None }, + Span { start: 119, end: 119, file: None }, + Span { start: 120, end: 120, file: None }, + Span { start: 121, end: 125, file: None }, + Span { start: 126, end: 126, file: None }, + Span { start: 127, end: 127, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 103, end: 119, file: None }, - Span { start: 119, end: 120, file: None }, - Span { start: 120, end: 121, file: None }, - Span { start: 121, end: 126, file: None }, - Span { start: 126, end: 127, file: None }, - Span { start: 127, end: 128, file: None }, + Span { start: 103, end: 118, file: None }, + Span { start: 119, end: 119, file: None }, + Span { start: 120, end: 120, file: None }, + Span { start: 121, end: 125, file: None }, + Span { start: 126, end: 126, file: None }, + Span { start: 127, end: 127, file: None }, ]), }, Statement { ty: StatementType::Literal(str_to_bytes32("01")), - span: AstSpan(vec![Span { start: 140, end: 142, file: None }]), + span: AstSpan(vec![Span { start: 140, end: 141, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 145, end: 147, file: None }]), + span: AstSpan(vec![Span { start: 145, end: 146, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Mstore), - span: AstSpan(vec![Span { start: 148, end: 154, file: None }]), + span: AstSpan(vec![Span { start: 148, end: 153, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("20")), - span: AstSpan(vec![Span { start: 165, end: 167, file: None }]), + span: AstSpan(vec![Span { start: 165, end: 166, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 170, end: 172, file: None }]), + span: AstSpan(vec![Span { start: 170, end: 171, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Return), - span: AstSpan(vec![Span { start: 173, end: 179, file: None }]), + span: AstSpan(vec![Span { start: 173, end: 178, file: None }]), }, ], takes: 0, returns: 0, span: AstSpan(vec![ - Span { start: 5, end: 12, file: None }, - Span { start: 13, end: 18, file: None }, - Span { start: 19, end: 27, file: None }, - Span { start: 27, end: 28, file: None }, - Span { start: 28, end: 33, file: None }, - Span { start: 33, end: 34, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 37, end: 42, file: None }, - Span { start: 42, end: 43, file: None }, - Span { start: 43, end: 44, file: None }, - Span { start: 44, end: 45, file: None }, - Span { start: 46, end: 53, file: None }, - Span { start: 53, end: 54, file: None }, - Span { start: 54, end: 55, file: None }, - Span { start: 55, end: 56, file: None }, - Span { start: 57, end: 58, file: None }, - Span { start: 67, end: 85, file: None }, - Span { start: 85, end: 86, file: None }, - Span { start: 86, end: 87, file: None }, - Span { start: 87, end: 92, file: None }, - Span { start: 92, end: 93, file: None }, - Span { start: 93, end: 94, file: None }, - Span { start: 103, end: 119, file: None }, - Span { start: 119, end: 120, file: None }, - Span { start: 120, end: 121, file: None }, - Span { start: 121, end: 126, file: None }, - Span { start: 126, end: 127, file: None }, - Span { start: 127, end: 128, file: None }, - Span { start: 140, end: 142, file: None }, - Span { start: 145, end: 147, file: None }, - Span { start: 148, end: 154, file: None }, - Span { start: 165, end: 167, file: None }, - Span { start: 170, end: 172, file: None }, - Span { start: 173, end: 179, file: None }, - Span { start: 184, end: 185, file: None }, + Span { start: 5, end: 11, file: None }, + Span { start: 13, end: 17, file: None }, + Span { start: 19, end: 26, file: None }, + Span { start: 27, end: 27, file: None }, + Span { start: 28, end: 32, file: None }, + Span { start: 33, end: 33, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 37, end: 41, file: None }, + Span { start: 42, end: 42, file: None }, + Span { start: 43, end: 43, file: None }, + Span { start: 44, end: 44, file: None }, + Span { start: 46, end: 52, file: None }, + Span { start: 53, end: 53, file: None }, + Span { start: 54, end: 54, file: None }, + Span { start: 55, end: 55, file: None }, + Span { start: 57, end: 57, file: None }, + Span { start: 67, end: 84, file: None }, + Span { start: 85, end: 85, file: None }, + Span { start: 86, end: 86, file: None }, + Span { start: 87, end: 91, file: None }, + Span { start: 92, end: 92, file: None }, + Span { start: 93, end: 93, file: None }, + Span { start: 103, end: 118, file: None }, + Span { start: 119, end: 119, file: None }, + Span { start: 120, end: 120, file: None }, + Span { start: 121, end: 125, file: None }, + Span { start: 126, end: 126, file: None }, + Span { start: 127, end: 127, file: None }, + Span { start: 140, end: 141, file: None }, + Span { start: 145, end: 146, file: None }, + Span { start: 148, end: 153, file: None }, + Span { start: 165, end: 166, file: None }, + Span { start: 170, end: 171, file: None }, + Span { start: 173, end: 178, file: None }, + Span { start: 184, end: 184, file: None }, ]), outlined: false, test: false, @@ -748,7 +739,7 @@ fn test_macro_opcode_arguments() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -763,42 +754,42 @@ fn test_macro_opcode_arguments() { macro_name: "RETURN1".to_string(), args: vec![MacroArg::Ident("returndatasize".to_string())], span: AstSpan(vec![ - Span { start: 58, end: 65, file: None }, - Span { start: 65, end: 66, file: None }, - Span { start: 66, end: 80, file: None }, - Span { start: 80, end: 81, file: None }, + Span { start: 58, end: 64, file: None }, + Span { start: 65, end: 65, file: None }, + Span { start: 66, end: 79, file: None }, + Span { start: 80, end: 80, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 58, end: 65, file: None }, - Span { start: 65, end: 66, file: None }, - Span { start: 66, end: 80, file: None }, - Span { start: 80, end: 81, file: None }, + Span { start: 58, end: 64, file: None }, + Span { start: 65, end: 65, file: None }, + Span { start: 66, end: 79, file: None }, + Span { start: 80, end: 80, file: None }, ]), }], takes: 0, returns: 0, span: AstSpan(vec![ - Span { start: 5, end: 12, file: None }, - Span { start: 13, end: 18, file: None }, - Span { start: 19, end: 23, file: None }, - Span { start: 23, end: 24, file: None }, - Span { start: 24, end: 25, file: None }, - Span { start: 26, end: 27, file: None }, - Span { start: 28, end: 33, file: None }, - Span { start: 33, end: 34, file: None }, - Span { start: 34, end: 35, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 37, end: 44, file: None }, - Span { start: 44, end: 45, file: None }, - Span { start: 45, end: 46, file: None }, - Span { start: 46, end: 47, file: None }, - Span { start: 48, end: 49, file: None }, - Span { start: 58, end: 65, file: None }, - Span { start: 65, end: 66, file: None }, - Span { start: 66, end: 80, file: None }, - Span { start: 80, end: 81, file: None }, - Span { start: 86, end: 87, file: None }, + Span { start: 5, end: 11, file: None }, + Span { start: 13, end: 17, file: None }, + Span { start: 19, end: 22, file: None }, + Span { start: 23, end: 23, file: None }, + Span { start: 24, end: 24, file: None }, + Span { start: 26, end: 26, file: None }, + Span { start: 28, end: 32, file: None }, + Span { start: 33, end: 33, file: None }, + Span { start: 34, end: 34, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 37, end: 43, file: None }, + Span { start: 44, end: 44, file: None }, + Span { start: 45, end: 45, file: None }, + Span { start: 46, end: 46, file: None }, + Span { start: 48, end: 48, file: None }, + Span { start: 58, end: 64, file: None }, + Span { start: 65, end: 65, file: None }, + Span { start: 66, end: 79, file: None }, + Span { start: 80, end: 80, file: None }, + Span { start: 86, end: 86, file: None }, ]), outlined: false, test: false, @@ -818,7 +809,8 @@ fn macro_with_builtin_fn_call() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); + let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -836,41 +828,41 @@ fn macro_with_builtin_fn_call() { name: Some("TEST".to_string()), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 77, end: 81, file: None }]), + span: AstSpan(vec![Span { start: 77, end: 80, file: None }]), }], span: AstSpan(vec![ - Span { start: 66, end: 76, file: None }, - Span { start: 77, end: 81, file: None }, + Span { start: 66, end: 75, file: None }, + Span { start: 77, end: 80, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 66, end: 76, file: None }, - Span { start: 77, end: 81, file: None }, + Span { start: 66, end: 75, file: None }, + Span { start: 77, end: 80, file: None }, ]), }], takes: 0, returns: 0, span: AstSpan(vec![ - Span { start: 5, end: 12, file: None }, - Span { start: 13, end: 18, file: None }, - Span { start: 19, end: 31, file: None }, - Span { start: 31, end: 32, file: None }, - Span { start: 32, end: 33, file: None }, - Span { start: 34, end: 35, file: None }, - Span { start: 36, end: 41, file: None }, - Span { start: 41, end: 42, file: None }, - Span { start: 42, end: 43, file: None }, - Span { start: 43, end: 44, file: None }, - Span { start: 45, end: 52, file: None }, - Span { start: 52, end: 53, file: None }, - Span { start: 53, end: 54, file: None }, - Span { start: 54, end: 55, file: None }, - Span { start: 56, end: 57, file: None }, - Span { start: 66, end: 76, file: None }, - Span { start: 76, end: 77, file: None }, - Span { start: 77, end: 81, file: None }, - Span { start: 81, end: 82, file: None }, - Span { start: 87, end: 88, file: None }, + Span { start: 5, end: 11, file: None }, + Span { start: 13, end: 17, file: None }, + Span { start: 19, end: 30, file: None }, + Span { start: 31, end: 31, file: None }, + Span { start: 32, end: 32, file: None }, + Span { start: 34, end: 34, file: None }, + Span { start: 36, end: 40, file: None }, + Span { start: 41, end: 41, file: None }, + Span { start: 42, end: 42, file: None }, + Span { start: 43, end: 43, file: None }, + Span { start: 45, end: 51, file: None }, + Span { start: 52, end: 52, file: None }, + Span { start: 53, end: 53, file: None }, + Span { start: 54, end: 54, file: None }, + Span { start: 56, end: 56, file: None }, + Span { start: 66, end: 75, file: None }, + Span { start: 76, end: 76, file: None }, + Span { start: 77, end: 80, file: None }, + Span { start: 81, end: 81, file: None }, + Span { start: 87, end: 87, file: None }, ]), outlined: false, test: false, @@ -885,7 +877,8 @@ fn macro_with_builtin_fn_call() { fn empty_outlined_macro() { let source = "#define fn HELLO_WORLD() = takes(0) returns(4) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); + let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -899,22 +892,22 @@ fn empty_outlined_macro() { takes: 0, returns: 4, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 10, file: None }, - Span { start: 11, end: 22, file: None }, - Span { start: 22, end: 23, file: None }, - Span { start: 23, end: 24, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 27, end: 32, file: None }, - Span { start: 32, end: 33, file: None }, - Span { start: 33, end: 34, file: None }, - Span { start: 34, end: 35, file: None }, - Span { start: 36, end: 43, file: None }, - Span { start: 43, end: 44, file: None }, - Span { start: 44, end: 45, file: None }, - Span { start: 45, end: 46, file: None }, - Span { start: 47, end: 48, file: None }, - Span { start: 48, end: 49, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 9, file: None }, + Span { start: 11, end: 21, file: None }, + Span { start: 22, end: 22, file: None }, + Span { start: 23, end: 23, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 27, end: 31, file: None }, + Span { start: 32, end: 32, file: None }, + Span { start: 33, end: 33, file: None }, + Span { start: 34, end: 34, file: None }, + Span { start: 36, end: 42, file: None }, + Span { start: 43, end: 43, file: None }, + Span { start: 44, end: 44, file: None }, + Span { start: 45, end: 45, file: None }, + Span { start: 47, end: 47, file: None }, + Span { start: 48, end: 48, file: None }, ]), outlined: true, test: false, @@ -927,7 +920,8 @@ fn empty_outlined_macro() { fn outlined_macro_with_simple_body() { let source = "#define fn HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + // let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -940,49 +934,49 @@ fn outlined_macro_with_simple_body() { statements: vec![ Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 51, end: 53, file: None }]), + span: AstSpan(vec![Span { start: 51, end: 52, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Mstore), - span: AstSpan(vec![Span { start: 54, end: 60, file: None }]), + span: AstSpan(vec![Span { start: 54, end: 59, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("01")), - span: AstSpan(vec![Span { start: 64, end: 66, file: None }]), + span: AstSpan(vec![Span { start: 64, end: 65, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("02")), - span: AstSpan(vec![Span { start: 69, end: 71, file: None }]), + span: AstSpan(vec![Span { start: 69, end: 70, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Add), - span: AstSpan(vec![Span { start: 72, end: 75, file: None }]), + span: AstSpan(vec![Span { start: 72, end: 74, file: None }]), }, ], takes: 3, returns: 0, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 10, file: None }, - Span { start: 11, end: 22, file: None }, - Span { start: 22, end: 23, file: None }, - Span { start: 23, end: 24, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 27, end: 32, file: None }, - Span { start: 32, end: 33, file: None }, - Span { start: 33, end: 34, file: None }, - Span { start: 34, end: 35, file: None }, - Span { start: 36, end: 43, file: None }, - Span { start: 43, end: 44, file: None }, - Span { start: 44, end: 45, file: None }, - Span { start: 45, end: 46, file: None }, - Span { start: 47, end: 48, file: None }, - Span { start: 51, end: 53, file: None }, - Span { start: 54, end: 60, file: None }, - Span { start: 64, end: 66, file: None }, - Span { start: 69, end: 71, file: None }, - Span { start: 72, end: 75, file: None }, - Span { start: 76, end: 77, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 9, file: None }, + Span { start: 11, end: 21, file: None }, + Span { start: 22, end: 22, file: None }, + Span { start: 23, end: 23, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 27, end: 31, file: None }, + Span { start: 32, end: 32, file: None }, + Span { start: 33, end: 33, file: None }, + Span { start: 34, end: 34, file: None }, + Span { start: 36, end: 42, file: None }, + Span { start: 43, end: 43, file: None }, + Span { start: 44, end: 44, file: None }, + Span { start: 45, end: 45, file: None }, + Span { start: 47, end: 47, file: None }, + Span { start: 51, end: 52, file: None }, + Span { start: 54, end: 59, file: None }, + Span { start: 64, end: 65, file: None }, + Span { start: 69, end: 70, file: None }, + Span { start: 72, end: 74, file: None }, + Span { start: 76, end: 76, file: None }, ]), outlined: true, test: false, From b6e43f28bbd6f44b6c59353f9c037be004c602ab Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 16:40:41 -0700 Subject: [PATCH 27/68] all spans matching lexer for macros test in parser --- huff_parser/tests/macro.rs | 199 ++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 100 deletions(-) diff --git a/huff_parser/tests/macro.rs b/huff_parser/tests/macro.rs index 317cb81c..8cc46f22 100644 --- a/huff_parser/tests/macro.rs +++ b/huff_parser/tests/macro.rs @@ -920,7 +920,6 @@ fn empty_outlined_macro() { fn outlined_macro_with_simple_body() { let source = "#define fn HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - // let lexer = Lexer::new(flattened_source); let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -989,7 +988,7 @@ fn outlined_macro_with_simple_body() { fn empty_test() { let source = "#define test HELLO_WORLD() = takes(0) returns(4) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -1003,22 +1002,22 @@ fn empty_test() { takes: 0, returns: 4, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 12, file: None }, - Span { start: 13, end: 24, file: None }, - Span { start: 24, end: 25, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 27, end: 28, file: None }, - Span { start: 29, end: 34, file: None }, - Span { start: 34, end: 35, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 36, end: 37, file: None }, - Span { start: 38, end: 45, file: None }, - Span { start: 45, end: 46, file: None }, - Span { start: 46, end: 47, file: None }, - Span { start: 47, end: 48, file: None }, - Span { start: 49, end: 50, file: None }, - Span { start: 50, end: 51, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 11, file: None }, + Span { start: 13, end: 23, file: None }, + Span { start: 24, end: 24, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 27, end: 27, file: None }, + Span { start: 29, end: 33, file: None }, + Span { start: 34, end: 34, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 36, end: 36, file: None }, + Span { start: 38, end: 44, file: None }, + Span { start: 45, end: 45, file: None }, + Span { start: 46, end: 46, file: None }, + Span { start: 47, end: 47, file: None }, + Span { start: 49, end: 49, file: None }, + Span { start: 50, end: 50, file: None }, ]), outlined: false, test: true, @@ -1032,7 +1031,7 @@ fn test_with_simple_body() { let source = "#define test HELLO_WORLD() = takes(3) returns(0) {\n0x00 0x00 mstore\n 0x01 0x02 add\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -1048,63 +1047,63 @@ fn test_with_simple_body() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]), - span: AstSpan(vec![Span { start: 53, end: 55, file: None }]), + span: AstSpan(vec![Span { start: 53, end: 54, file: None }]), }, Statement { ty: StatementType::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]), - span: AstSpan(vec![Span { start: 58, end: 60, file: None }]), + span: AstSpan(vec![Span { start: 58, end: 59, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Mstore), - span: AstSpan(vec![Span { start: 61, end: 67, file: None }]), + span: AstSpan(vec![Span { start: 61, end: 66, file: None }]), }, Statement { ty: StatementType::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, ]), - span: AstSpan(vec![Span { start: 71, end: 73, file: None }]), + span: AstSpan(vec![Span { start: 71, end: 72, file: None }]), }, Statement { ty: StatementType::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, ]), - span: AstSpan(vec![Span { start: 76, end: 78, file: None }]), + span: AstSpan(vec![Span { start: 76, end: 77, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Add), - span: AstSpan(vec![Span { start: 79, end: 82, file: None }]), + span: AstSpan(vec![Span { start: 79, end: 81, file: None }]), }, ], takes: 3, returns: 0, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 12, file: None }, - Span { start: 13, end: 24, file: None }, - Span { start: 24, end: 25, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 27, end: 28, file: None }, - Span { start: 29, end: 34, file: None }, - Span { start: 34, end: 35, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 36, end: 37, file: None }, - Span { start: 38, end: 45, file: None }, - Span { start: 45, end: 46, file: None }, - Span { start: 46, end: 47, file: None }, - Span { start: 47, end: 48, file: None }, - Span { start: 49, end: 50, file: None }, - Span { start: 53, end: 55, file: None }, - Span { start: 58, end: 60, file: None }, - Span { start: 61, end: 67, file: None }, - Span { start: 71, end: 73, file: None }, - Span { start: 76, end: 78, file: None }, - Span { start: 79, end: 82, file: None }, - Span { start: 83, end: 84, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 11, file: None }, + Span { start: 13, end: 23, file: None }, + Span { start: 24, end: 24, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 27, end: 27, file: None }, + Span { start: 29, end: 33, file: None }, + Span { start: 34, end: 34, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 36, end: 36, file: None }, + Span { start: 38, end: 44, file: None }, + Span { start: 45, end: 45, file: None }, + Span { start: 46, end: 46, file: None }, + Span { start: 47, end: 47, file: None }, + Span { start: 49, end: 49, file: None }, + Span { start: 53, end: 54, file: None }, + Span { start: 58, end: 59, file: None }, + Span { start: 61, end: 66, file: None }, + Span { start: 71, end: 72, file: None }, + Span { start: 76, end: 77, file: None }, + Span { start: 79, end: 81, file: None }, + Span { start: 83, end: 83, file: None }, ]), outlined: false, test: true, @@ -1120,7 +1119,7 @@ fn empty_test_with_decorator() { #define test MY_TEST() = takes(0) returns(0) {} "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -1139,29 +1138,29 @@ fn empty_test_with_decorator() { takes: 0, returns: 0, span: AstSpan(vec![ - Span { start: 5, end: 6, file: None }, - Span { start: 6, end: 7, file: None }, - Span { start: 7, end: 12, file: None }, - Span { start: 12, end: 13, file: None }, - Span { start: 15, end: 17, file: None }, - Span { start: 17, end: 18, file: None }, - Span { start: 18, end: 19, file: None }, - Span { start: 24, end: 31, file: None }, - Span { start: 32, end: 36, file: None }, - Span { start: 37, end: 44, file: None }, - Span { start: 44, end: 45, file: None }, - Span { start: 45, end: 46, file: None }, - Span { start: 47, end: 48, file: None }, - Span { start: 49, end: 54, file: None }, - Span { start: 54, end: 55, file: None }, - Span { start: 55, end: 56, file: None }, - Span { start: 56, end: 57, file: None }, - Span { start: 58, end: 65, file: None }, - Span { start: 65, end: 66, file: None }, - Span { start: 66, end: 67, file: None }, - Span { start: 67, end: 68, file: None }, - Span { start: 69, end: 70, file: None }, - Span { start: 70, end: 71, file: None }, + Span { start: 5, end: 5, file: None }, + Span { start: 6, end: 6, file: None }, + Span { start: 7, end: 11, file: None }, + Span { start: 12, end: 12, file: None }, + Span { start: 15, end: 16, file: None }, + Span { start: 17, end: 17, file: None }, + Span { start: 18, end: 18, file: None }, + Span { start: 24, end: 30, file: None }, + Span { start: 32, end: 35, file: None }, + Span { start: 37, end: 43, file: None }, + Span { start: 44, end: 44, file: None }, + Span { start: 45, end: 45, file: None }, + Span { start: 47, end: 47, file: None }, + Span { start: 49, end: 53, file: None }, + Span { start: 54, end: 54, file: None }, + Span { start: 55, end: 55, file: None }, + Span { start: 56, end: 56, file: None }, + Span { start: 58, end: 64, file: None }, + Span { start: 65, end: 65, file: None }, + Span { start: 66, end: 66, file: None }, + Span { start: 67, end: 67, file: None }, + Span { start: 69, end: 69, file: None }, + Span { start: 70, end: 70, file: None }, ]), outlined: false, test: true, @@ -1177,7 +1176,7 @@ fn empty_test_with_multi_flag_decorator() { #define test MY_TEST() = takes(0) returns(0) {} "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -1199,34 +1198,34 @@ fn empty_test_with_multi_flag_decorator() { takes: 0, returns: 0, span: AstSpan(vec![ - Span { start: 5, end: 6, file: None }, - Span { start: 6, end: 7, file: None }, - Span { start: 7, end: 15, file: None }, - Span { start: 15, end: 16, file: None }, - Span { start: 16, end: 22, file: None }, - Span { start: 22, end: 23, file: None }, - Span { start: 23, end: 24, file: None }, - Span { start: 25, end: 30, file: None }, - Span { start: 30, end: 31, file: None }, - Span { start: 33, end: 35, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 36, end: 37, file: None }, - Span { start: 42, end: 49, file: None }, - Span { start: 50, end: 54, file: None }, - Span { start: 55, end: 62, file: None }, - Span { start: 62, end: 63, file: None }, - Span { start: 63, end: 64, file: None }, - Span { start: 65, end: 66, file: None }, - Span { start: 67, end: 72, file: None }, - Span { start: 72, end: 73, file: None }, - Span { start: 73, end: 74, file: None }, - Span { start: 74, end: 75, file: None }, - Span { start: 76, end: 83, file: None }, - Span { start: 83, end: 84, file: None }, - Span { start: 84, end: 85, file: None }, - Span { start: 85, end: 86, file: None }, - Span { start: 87, end: 88, file: None }, - Span { start: 88, end: 89, file: None }, + Span { start: 5, end: 5, file: None }, + Span { start: 6, end: 6, file: None }, + Span { start: 7, end: 14, file: None }, + Span { start: 15, end: 15, file: None }, + Span { start: 16, end: 21, file: None }, + Span { start: 22, end: 22, file: None }, + Span { start: 23, end: 23, file: None }, + Span { start: 25, end: 29, file: None }, + Span { start: 30, end: 30, file: None }, + Span { start: 33, end: 34, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 36, end: 36, file: None }, + Span { start: 42, end: 48, file: None }, + Span { start: 50, end: 53, file: None }, + Span { start: 55, end: 61, file: None }, + Span { start: 62, end: 62, file: None }, + Span { start: 63, end: 63, file: None }, + Span { start: 65, end: 65, file: None }, + Span { start: 67, end: 71, file: None }, + Span { start: 72, end: 72, file: None }, + Span { start: 73, end: 73, file: None }, + Span { start: 74, end: 74, file: None }, + Span { start: 76, end: 82, file: None }, + Span { start: 83, end: 83, file: None }, + Span { start: 84, end: 84, file: None }, + Span { start: 85, end: 85, file: None }, + Span { start: 87, end: 87, file: None }, + Span { start: 88, end: 88, file: None }, ]), outlined: false, test: true, From 8e781fafe5c616a13962b564626e45a97d47de68 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 16:28:41 -0700 Subject: [PATCH 28/68] finish my part of parser tests --- huff_parser/tests/imports.rs | 4 +- huff_parser/tests/labels.rs | 314 +++++++++++++++++------------------ 2 files changed, 159 insertions(+), 159 deletions(-) diff --git a/huff_parser/tests/imports.rs b/huff_parser/tests/imports.rs index 30e51d41..273797df 100644 --- a/huff_parser/tests/imports.rs +++ b/huff_parser/tests/imports.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn parses_import() { let source = " /* .,*./. */ #include \"../huff-examples/erc20/contracts/ERC20.huff\""; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); @@ -25,7 +25,7 @@ fn parses_deep_imports() { #include "../huff-examples/erc20/contracts/utils/Ownable.huff" "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); diff --git a/huff_parser/tests/labels.rs b/huff_parser/tests/labels.rs index e3940cac..5fb57ae5 100644 --- a/huff_parser/tests/labels.rs +++ b/huff_parser/tests/labels.rs @@ -14,7 +14,7 @@ fn multiline_labels() { } "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -27,23 +27,23 @@ fn multiline_labels() { statements: vec![ Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 65, end: 67, file: None }]), + span: AstSpan(vec![Span { start: 65, end: 66, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Mstore), - span: AstSpan(vec![Span { start: 68, end: 74, file: None }]), + span: AstSpan(vec![Span { start: 68, end: 73, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("01")), - span: AstSpan(vec![Span { start: 83, end: 85, file: None }]), + span: AstSpan(vec![Span { start: 83, end: 84, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("02")), - span: AstSpan(vec![Span { start: 88, end: 90, file: None }]), + span: AstSpan(vec![Span { start: 88, end: 89, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Add), - span: AstSpan(vec![Span { start: 91, end: 94, file: None }]), + span: AstSpan(vec![Span { start: 91, end: 93, file: None }]), }, Statement { ty: StatementType::Label(Label { @@ -54,48 +54,48 @@ fn multiline_labels() { macro_name: "HELLO".to_string(), args: vec![], span: AstSpan(vec![ - Span { start: 121, end: 126, file: None }, - Span { start: 126, end: 127, file: None }, - Span { start: 127, end: 128, file: None }, + Span { start: 121, end: 125, file: None }, + Span { start: 126, end: 126, file: None }, + Span { start: 127, end: 127, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 121, end: 126, file: None }, - Span { start: 126, end: 127, file: None }, - Span { start: 127, end: 128, file: None }, + Span { start: 121, end: 125, file: None }, + Span { start: 126, end: 126, file: None }, + Span { start: 127, end: 127, file: None }, ]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 139, end: 141, file: None }]), + span: AstSpan(vec![Span { start: 139, end: 140, file: None }]), }, Statement { ty: StatementType::Literal(str_to_bytes32("00")), - span: AstSpan(vec![Span { start: 144, end: 146, file: None }]), + span: AstSpan(vec![Span { start: 144, end: 145, file: None }]), }, Statement { ty: StatementType::Opcode(Opcode::Revert), - span: AstSpan(vec![Span { start: 147, end: 153, file: None }]), + span: AstSpan(vec![Span { start: 147, end: 152, file: None }]), }, ], span: AstSpan(vec![ - Span { start: 101, end: 111, file: None }, - Span { start: 121, end: 126, file: None }, - Span { start: 126, end: 127, file: None }, - Span { start: 127, end: 128, file: None }, - Span { start: 139, end: 141, file: None }, - Span { start: 144, end: 146, file: None }, - Span { start: 147, end: 153, file: None }, + Span { start: 101, end: 110, file: None }, + Span { start: 121, end: 125, file: None }, + Span { start: 126, end: 126, file: None }, + Span { start: 127, end: 127, file: None }, + Span { start: 139, end: 140, file: None }, + Span { start: 144, end: 145, file: None }, + Span { start: 147, end: 152, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 101, end: 111, file: None }, - Span { start: 121, end: 126, file: None }, - Span { start: 126, end: 127, file: None }, - Span { start: 127, end: 128, file: None }, - Span { start: 139, end: 141, file: None }, - Span { start: 144, end: 146, file: None }, - Span { start: 147, end: 153, file: None }, + Span { start: 101, end: 110, file: None }, + Span { start: 121, end: 125, file: None }, + Span { start: 126, end: 126, file: None }, + Span { start: 127, end: 127, file: None }, + Span { start: 139, end: 140, file: None }, + Span { start: 144, end: 145, file: None }, + Span { start: 147, end: 152, file: None }, ]), }, ], @@ -103,63 +103,63 @@ fn multiline_labels() { returns: 0, span: AstSpan(vec![ // "#define" - Span { start: 5, end: 12, file: None }, + Span { start: 5, end: 11, file: None }, // "macro" - Span { start: 13, end: 18, file: None }, + Span { start: 13, end: 17, file: None }, // "HELLO_WORLD" - Span { start: 19, end: 30, file: None }, + Span { start: 19, end: 29, file: None }, // "(" - Span { start: 30, end: 31, file: None }, + Span { start: 30, end: 30, file: None }, // ")" - Span { start: 31, end: 32, file: None }, + Span { start: 31, end: 31, file: None }, // "=" - Span { start: 33, end: 34, file: None }, + Span { start: 33, end: 33, file: None }, // "takes" - Span { start: 35, end: 40, file: None }, + Span { start: 35, end: 39, file: None }, // "(" - Span { start: 40, end: 41, file: None }, + Span { start: 40, end: 40, file: None }, // "0" - Span { start: 41, end: 42, file: None }, + Span { start: 41, end: 41, file: None }, // ")" - Span { start: 42, end: 43, file: None }, + Span { start: 42, end: 42, file: None }, // "returns" - Span { start: 44, end: 51, file: None }, + Span { start: 44, end: 50, file: None }, // "(" - Span { start: 51, end: 52, file: None }, + Span { start: 51, end: 51, file: None }, // "0" - Span { start: 52, end: 53, file: None }, + Span { start: 52, end: 52, file: None }, // ")" - Span { start: 53, end: 54, file: None }, + Span { start: 53, end: 53, file: None }, // "{" - Span { start: 55, end: 56, file: None }, + Span { start: 55, end: 55, file: None }, // "0x00" - Span { start: 65, end: 67, file: None }, + Span { start: 65, end: 66, file: None }, // "mstore" - Span { start: 68, end: 74, file: None }, + Span { start: 68, end: 73, file: None }, // "0x01" - Span { start: 83, end: 85, file: None }, + Span { start: 83, end: 84, file: None }, // "0x02" - Span { start: 88, end: 90, file: None }, + Span { start: 88, end: 89, file: None }, // "add" - Span { start: 91, end: 94, file: None }, + Span { start: 91, end: 93, file: None }, // "cool_label" - Span { start: 101, end: 111, file: None }, + Span { start: 101, end: 110, file: None }, // ":" - Span { start: 111, end: 112, file: None }, + Span { start: 111, end: 111, file: None }, // "HELLO" - Span { start: 121, end: 126, file: None }, + Span { start: 121, end: 125, file: None }, // "(" - Span { start: 126, end: 127, file: None }, + Span { start: 126, end: 126, file: None }, // ")" - Span { start: 127, end: 128, file: None }, + Span { start: 127, end: 127, file: None }, // "0x00" - Span { start: 139, end: 141, file: None }, + Span { start: 139, end: 140, file: None }, // "0x00" - Span { start: 144, end: 146, file: None }, + Span { start: 144, end: 145, file: None }, // "revert" - Span { start: 147, end: 153, file: None }, + Span { start: 147, end: 152, file: None }, // "}" - Span { start: 158, end: 159, file: None }, + Span { start: 158, end: 158, file: None }, ]), outlined: false, test: false, @@ -204,7 +204,7 @@ pub fn builtins_under_labels() { } "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -226,16 +226,16 @@ pub fn builtins_under_labels() { name: Some(String::from("TEST_TABLE")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 342, end: 352, file: None }]), + span: AstSpan(vec![Span { start: 342, end: 351, file: None }]), }], span: AstSpan(vec![ - Span { start: 329, end: 341, file: None }, - Span { start: 342, end: 352, file: None }, + Span { start: 329, end: 340, file: None }, + Span { start: 342, end: 351, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 329, end: 341, file: None }, - Span { start: 342, end: 352, file: None }, + Span { start: 329, end: 340, file: None }, + Span { start: 342, end: 351, file: None }, ]), }, Statement { @@ -246,16 +246,16 @@ pub fn builtins_under_labels() { name: Some(String::from("TEST_TABLE")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 378, end: 388, file: None }]), + span: AstSpan(vec![Span { start: 378, end: 387, file: None }]), }], span: AstSpan(vec![ - Span { start: 366, end: 377, file: None }, - Span { start: 378, end: 388, file: None }, + Span { start: 366, end: 376, file: None }, + Span { start: 378, end: 387, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 366, end: 377, file: None }, - Span { start: 378, end: 388, file: None }, + Span { start: 366, end: 376, file: None }, + Span { start: 378, end: 387, file: None }, ]), }, Statement { @@ -266,16 +266,16 @@ pub fn builtins_under_labels() { name: Some(String::from("SMALL_MACRO")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 413, end: 424, file: None }]), + span: AstSpan(vec![Span { start: 413, end: 423, file: None }]), }], span: AstSpan(vec![ - Span { start: 402, end: 412, file: None }, - Span { start: 413, end: 424, file: None }, + Span { start: 402, end: 411, file: None }, + Span { start: 413, end: 423, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 402, end: 412, file: None }, - Span { start: 413, end: 424, file: None }, + Span { start: 402, end: 411, file: None }, + Span { start: 413, end: 423, file: None }, ]), }, Statement { @@ -286,16 +286,16 @@ pub fn builtins_under_labels() { name: Some(String::from("myFunc")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 449, end: 455, file: None }]), + span: AstSpan(vec![Span { start: 449, end: 454, file: None }]), }], span: AstSpan(vec![ - Span { start: 438, end: 448, file: None }, - Span { start: 449, end: 455, file: None }, + Span { start: 438, end: 447, file: None }, + Span { start: 449, end: 454, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 438, end: 448, file: None }, - Span { start: 449, end: 455, file: None }, + Span { start: 438, end: 447, file: None }, + Span { start: 449, end: 454, file: None }, ]), }, Statement { @@ -306,16 +306,16 @@ pub fn builtins_under_labels() { name: Some(String::from("TestError")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 477, end: 486, file: None }]), + span: AstSpan(vec![Span { start: 477, end: 485, file: None }]), }], span: AstSpan(vec![ - Span { start: 469, end: 476, file: None }, - Span { start: 477, end: 486, file: None }, + Span { start: 469, end: 475, file: None }, + Span { start: 477, end: 485, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 469, end: 476, file: None }, - Span { start: 477, end: 486, file: None }, + Span { start: 469, end: 475, file: None }, + Span { start: 477, end: 485, file: None }, ]), }, Statement { @@ -326,96 +326,96 @@ pub fn builtins_under_labels() { name: Some(String::from("bb")), indexed: false, arg_location: None, - span: AstSpan(vec![Span { start: 513, end: 515, file: None }]), + span: AstSpan(vec![Span { start: 513, end: 514, file: None }]), }], span: AstSpan(vec![ - Span { start: 500, end: 510, file: None }, - Span { start: 513, end: 515, file: None }, + Span { start: 500, end: 509, file: None }, + Span { start: 513, end: 514, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 500, end: 510, file: None }, - Span { start: 513, end: 515, file: None }, + Span { start: 500, end: 509, file: None }, + Span { start: 513, end: 514, file: None }, ]), }, ], span: AstSpan(vec![ - Span { start: 307, end: 315, file: None }, - Span { start: 329, end: 341, file: None }, - Span { start: 342, end: 352, file: None }, - Span { start: 366, end: 377, file: None }, - Span { start: 378, end: 388, file: None }, - Span { start: 402, end: 412, file: None }, - Span { start: 413, end: 424, file: None }, - Span { start: 438, end: 448, file: None }, - Span { start: 449, end: 455, file: None }, - Span { start: 469, end: 476, file: None }, - Span { start: 477, end: 486, file: None }, - Span { start: 500, end: 510, file: None }, - Span { start: 513, end: 515, file: None }, + Span { start: 307, end: 314, file: None }, + Span { start: 329, end: 340, file: None }, + Span { start: 342, end: 351, file: None }, + Span { start: 366, end: 376, file: None }, + Span { start: 378, end: 387, file: None }, + Span { start: 402, end: 411, file: None }, + Span { start: 413, end: 423, file: None }, + Span { start: 438, end: 447, file: None }, + Span { start: 449, end: 454, file: None }, + Span { start: 469, end: 475, file: None }, + Span { start: 477, end: 485, file: None }, + Span { start: 500, end: 509, file: None }, + Span { start: 513, end: 514, file: None }, ]), }), span: AstSpan(vec![ - Span { start: 307, end: 315, file: None }, - Span { start: 329, end: 341, file: None }, - Span { start: 342, end: 352, file: None }, - Span { start: 366, end: 377, file: None }, - Span { start: 378, end: 388, file: None }, - Span { start: 402, end: 412, file: None }, - Span { start: 413, end: 424, file: None }, - Span { start: 438, end: 448, file: None }, - Span { start: 449, end: 455, file: None }, - Span { start: 469, end: 476, file: None }, - Span { start: 477, end: 486, file: None }, - Span { start: 500, end: 510, file: None }, - Span { start: 513, end: 515, file: None }, + Span { start: 307, end: 314, file: None }, + Span { start: 329, end: 340, file: None }, + Span { start: 342, end: 351, file: None }, + Span { start: 366, end: 376, file: None }, + Span { start: 378, end: 387, file: None }, + Span { start: 402, end: 411, file: None }, + Span { start: 413, end: 423, file: None }, + Span { start: 438, end: 447, file: None }, + Span { start: 449, end: 454, file: None }, + Span { start: 469, end: 475, file: None }, + Span { start: 477, end: 485, file: None }, + Span { start: 500, end: 509, file: None }, + Span { start: 513, end: 514, file: None }, ]), }], takes: 3, returns: 0, span: AstSpan(vec![ - Span { start: 247, end: 254, file: None }, - Span { start: 255, end: 260, file: None }, - Span { start: 261, end: 272, file: None }, - Span { start: 272, end: 273, file: None }, - Span { start: 273, end: 274, file: None }, - Span { start: 275, end: 276, file: None }, - Span { start: 277, end: 282, file: None }, - Span { start: 282, end: 283, file: None }, - Span { start: 283, end: 284, file: None }, - Span { start: 284, end: 285, file: None }, - Span { start: 286, end: 293, file: None }, - Span { start: 293, end: 294, file: None }, - Span { start: 294, end: 295, file: None }, - Span { start: 295, end: 296, file: None }, - Span { start: 297, end: 298, file: None }, - Span { start: 307, end: 315, file: None }, - Span { start: 315, end: 316, file: None }, - Span { start: 329, end: 341, file: None }, - Span { start: 341, end: 342, file: None }, - Span { start: 342, end: 352, file: None }, - Span { start: 352, end: 353, file: None }, - Span { start: 366, end: 377, file: None }, - Span { start: 377, end: 378, file: None }, - Span { start: 378, end: 388, file: None }, - Span { start: 388, end: 389, file: None }, - Span { start: 402, end: 412, file: None }, - Span { start: 412, end: 413, file: None }, - Span { start: 413, end: 424, file: None }, - Span { start: 424, end: 425, file: None }, - Span { start: 438, end: 448, file: None }, - Span { start: 448, end: 449, file: None }, - Span { start: 449, end: 455, file: None }, - Span { start: 455, end: 456, file: None }, - Span { start: 469, end: 476, file: None }, - Span { start: 476, end: 477, file: None }, - Span { start: 477, end: 486, file: None }, - Span { start: 486, end: 487, file: None }, - Span { start: 500, end: 510, file: None }, - Span { start: 510, end: 511, file: None }, - Span { start: 513, end: 515, file: None }, - Span { start: 515, end: 516, file: None }, - Span { start: 521, end: 522, file: None }, + Span { start: 247, end: 253, file: None }, + Span { start: 255, end: 259, file: None }, + Span { start: 261, end: 271, file: None }, + Span { start: 272, end: 272, file: None }, + Span { start: 273, end: 273, file: None }, + Span { start: 275, end: 275, file: None }, + Span { start: 277, end: 281, file: None }, + Span { start: 282, end: 282, file: None }, + Span { start: 283, end: 283, file: None }, + Span { start: 284, end: 284, file: None }, + Span { start: 286, end: 292, file: None }, + Span { start: 293, end: 293, file: None }, + Span { start: 294, end: 294, file: None }, + Span { start: 295, end: 295, file: None }, + Span { start: 297, end: 297, file: None }, + Span { start: 307, end: 314, file: None }, + Span { start: 315, end: 315, file: None }, + Span { start: 329, end: 340, file: None }, + Span { start: 341, end: 341, file: None }, + Span { start: 342, end: 351, file: None }, + Span { start: 352, end: 352, file: None }, + Span { start: 366, end: 376, file: None }, + Span { start: 377, end: 377, file: None }, + Span { start: 378, end: 387, file: None }, + Span { start: 388, end: 388, file: None }, + Span { start: 402, end: 411, file: None }, + Span { start: 412, end: 412, file: None }, + Span { start: 413, end: 423, file: None }, + Span { start: 424, end: 424, file: None }, + Span { start: 438, end: 447, file: None }, + Span { start: 448, end: 448, file: None }, + Span { start: 449, end: 454, file: None }, + Span { start: 455, end: 455, file: None }, + Span { start: 469, end: 475, file: None }, + Span { start: 476, end: 476, file: None }, + Span { start: 477, end: 485, file: None }, + Span { start: 486, end: 486, file: None }, + Span { start: 500, end: 509, file: None }, + Span { start: 510, end: 510, file: None }, + Span { start: 513, end: 514, file: None }, + Span { start: 515, end: 515, file: None }, + Span { start: 521, end: 521, file: None }, ]), outlined: false, test: false, From c00172a7f0120358c003e9d1e5c6ca910f65b4b4 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 16:33:21 -0700 Subject: [PATCH 29/68] wip/integrate with core tests --- huff_core/tests/alternative_constructor_macro.rs | 2 +- huff_core/tests/alternative_main_macro.rs | 2 +- huff_core/tests/breaking_jumptable.rs | 2 +- huff_core/tests/builtins.rs | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/huff_core/tests/alternative_constructor_macro.rs b/huff_core/tests/alternative_constructor_macro.rs index 8249fdf2..74f842ee 100644 --- a/huff_core/tests/alternative_constructor_macro.rs +++ b/huff_core/tests/alternative_constructor_macro.rs @@ -18,7 +18,7 @@ fn test_alternative_constructor_macro_provided() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/alternative_main_macro.rs b/huff_core/tests/alternative_main_macro.rs index 7c3e3ff4..b7d43643 100644 --- a/huff_core/tests/alternative_main_macro.rs +++ b/huff_core/tests/alternative_main_macro.rs @@ -18,7 +18,7 @@ fn test_alternative_main_macro_provided() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/breaking_jumptable.rs b/huff_core/tests/breaking_jumptable.rs index eb182a5f..bd7035f2 100644 --- a/huff_core/tests/breaking_jumptable.rs +++ b/huff_core/tests/breaking_jumptable.rs @@ -133,7 +133,7 @@ fn test_breaking_jump_table() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index 18450060..cbf4f571 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -24,7 +24,7 @@ fn test_codesize_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -60,7 +60,7 @@ fn test_dyn_constructor_arg_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -149,7 +149,7 @@ fn test_tablesize_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); From 240c8850ee4ab15ad4be81a63a9407f9478fba55 Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 16:44:57 -0700 Subject: [PATCH 30/68] wip --- huff_core/tests/builtins.rs | 16 ++++++------- huff_core/tests/codegen_errors.rs | 40 +++++++++++++++---------------- huff_core/tests/compiling.rs | 3 +-- huff_core/tests/erc20.rs | 2 +- huff_core/tests/erc721.rs | 2 +- huff_core/tests/exports_events.rs | 8 +++---- huff_lexer/src/lexer.rs | 2 +- huff_parser/src/lib.rs | 1 + 8 files changed, 37 insertions(+), 37 deletions(-) diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index cbf4f571..bc2b8ce9 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -213,7 +213,7 @@ fn test_tablestart_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -278,7 +278,7 @@ fn test_jump_table_exhaustive_usage() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -338,7 +338,7 @@ fn test_jump_table_packed_exhaustive_usage() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -405,7 +405,7 @@ fn test_label_clashing() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -449,7 +449,7 @@ fn test_func_sig_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -494,7 +494,7 @@ fn test_event_hash_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -569,7 +569,7 @@ fn test_error_selector_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -612,7 +612,7 @@ fn test_rightpad_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/codegen_errors.rs b/huff_core/tests/codegen_errors.rs index efb0f401..74eb0d96 100644 --- a/huff_core/tests/codegen_errors.rs +++ b/huff_core/tests/codegen_errors.rs @@ -33,7 +33,7 @@ fn test_storage_pointers_not_derived() { // let const_end = const_start + "UNKNOWN_CONSTANT_DEFINITION".len(); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let contract = parser.parse().unwrap(); @@ -47,11 +47,11 @@ fn test_storage_pointers_not_derived() { CodegenError { kind: CodegenErrorKind::StoragePointersNotDerived, span: AstSpan(vec![ - Span { start: 5, end: 12, file: None }, - Span { start: 13, end: 21, file: None }, - Span { start: 22, end: 43, file: None }, - Span { start: 44, end: 45, file: None }, - Span { start: 46, end: 68, file: None } + Span { start: 5, end: 11, file: None }, + Span { start: 13, end: 20, file: None }, + Span { start: 22, end: 42, file: None }, + Span { start: 44, end: 44, file: None }, + Span { start: 46, end: 67, file: None } ]), token: None } @@ -89,10 +89,10 @@ fn test_invalid_constant_definition() { "#; let const_start = source.find("UNKNOWN_CONSTANT_DEFINITION").unwrap_or(0); - let const_end = const_start + "UNKNOWN_CONSTANT_DEFINITION".len(); + let const_end = const_start + "UNKNOWN_CONSTANT_DEFINITION".len() - 1; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -135,7 +135,7 @@ fn test_missing_constructor() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -168,7 +168,7 @@ fn test_missing_main() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -201,7 +201,7 @@ fn test_missing_when_alternative_main_provided() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -244,7 +244,7 @@ fn test_unknown_macro_definition() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -259,9 +259,9 @@ fn test_unknown_macro_definition() { CodegenError { kind: CodegenErrorKind::InvalidMacroInvocation("UNKNOWN".to_string()), span: AstSpan(vec![ - Span { start: 344, end: 351, file: None }, - Span { start: 351, end: 352, file: None }, - Span { start: 352, end: 353, file: None } + Span { start: 344, end: 350, file: None }, + Span { start: 351, end: 351, file: None }, + Span { start: 352, end: 352, file: None } ]), token: None } @@ -291,7 +291,7 @@ fn test_unmatched_jump_label() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -306,10 +306,10 @@ fn test_unmatched_jump_label() { CodegenError { kind: CodegenErrorKind::UnmatchedJumpLabel, span: AstSpan(vec![ - Span { start: 372, end: 376, file: None }, - Span { start: 376, end: 377, file: None }, - Span { start: 377, end: 380, file: None }, - Span { start: 380, end: 381, file: None } + Span { start: 372, end: 375, file: None }, + Span { start: 376, end: 376, file: None }, + Span { start: 377, end: 379, file: None }, + Span { start: 380, end: 380, file: None } ]), token: None } diff --git a/huff_core/tests/compiling.rs b/huff_core/tests/compiling.rs index 54fdba6c..9eeda85a 100644 --- a/huff_core/tests/compiling.rs +++ b/huff_core/tests/compiling.rs @@ -40,7 +40,6 @@ const SOURCE: &str = r#" fn compiles_constructor_bytecode() { // Lex and Parse the source code let flattened_source = FullFileSource { source: SOURCE, file: None, spans: vec![] }; - //let lexer = Lexer::new(flattened_source); let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -68,7 +67,7 @@ fn compiles_constructor_bytecode() { fn compiles_runtime_bytecode() { // Lex and Parse the source code let flattened_source = FullFileSource { source: SOURCE, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/erc20.rs b/huff_core/tests/erc20.rs index 5817db8b..96d83ca5 100644 --- a/huff_core/tests/erc20.rs +++ b/huff_core/tests/erc20.rs @@ -28,7 +28,7 @@ fn test_erc20_compile() { file: Some(Arc::clone(file_source)), spans: flattened.1, }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("../huff-examples/erc20/contracts".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/erc721.rs b/huff_core/tests/erc721.rs index 145425ad..ca70928c 100644 --- a/huff_core/tests/erc721.rs +++ b/huff_core/tests/erc721.rs @@ -28,7 +28,7 @@ fn test_erc721_compile() { file: Some(Arc::clone(file_source)), spans: flattened.1, }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("../huff-examples/erc20/contracts".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/exports_events.rs b/huff_core/tests/exports_events.rs index 7e4f0d6b..406c5345 100644 --- a/huff_core/tests/exports_events.rs +++ b/huff_core/tests/exports_events.rs @@ -16,7 +16,7 @@ fn test_abi_uint_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -84,7 +84,7 @@ fn test_abi_int_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -152,7 +152,7 @@ fn test_abi_simple_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -211,7 +211,7 @@ fn test_abi_tuple_array_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index df2ff991..ed8cec7d 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -289,7 +289,7 @@ impl<'a> LexerNew<'a> { found_kind = Some(TokenKind::Opcode(o.to_owned())); } } - println!("self.context: {:?}", self.context); + if self.context == Context::AbiArgs { let curr_char = self.peek().unwrap(); dbg!(curr_char); diff --git a/huff_parser/src/lib.rs b/huff_parser/src/lib.rs index 7f2c02e4..592484bb 100644 --- a/huff_parser/src/lib.rs +++ b/huff_parser/src/lib.rs @@ -1110,6 +1110,7 @@ impl Parser { let new_spans = vec![self.current_token.span.clone()]; match &self.current_token.kind { TokenKind::Ident(ident_str) => { + dbg!(ident_str); statements.push(Statement { ty: if is_code_table { if code_statement_regex.is_match(ident_str) { From 6d668ea5c35f8e0525e474c96c54e801166dedcd Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 16:51:00 -0700 Subject: [PATCH 31/68] integrate lexer into core tests --- huff_core/tests/exports_events.rs | 2 +- huff_lexer/src/lexer.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/huff_core/tests/exports_events.rs b/huff_core/tests/exports_events.rs index 406c5345..32cab88e 100644 --- a/huff_core/tests/exports_events.rs +++ b/huff_core/tests/exports_events.rs @@ -270,7 +270,7 @@ fn test_abi_nested_tuple_array_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs index ed8cec7d..fa0cd239 100644 --- a/huff_lexer/src/lexer.rs +++ b/huff_lexer/src/lexer.rs @@ -524,7 +524,11 @@ impl<'a> LexerNew<'a> { // In codetables, the bytecode provided is of arbitrary length. We pass // the code as an Ident, and it is appended to the end of the runtime // bytecode in codegen. - TokenKind::Ident(integer_str) + if &integer_str[0..2] == "0x" { + TokenKind::Ident(integer_str[2..].to_owned()) + } else { + TokenKind::Ident(integer_str) + } } else { TokenKind::Literal(str_to_bytes32(&integer_str[2..].as_ref())) From 07abe8c0f98b57d98878a3cffddedba25b75aacb Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 17:03:25 -0700 Subject: [PATCH 32/68] integrate new lexer into tests --- huff_core/tests/file_resolution.rs | 6 ++--- huff_core/tests/free_storage_pointer.rs | 4 +-- huff_core/tests/functions.rs | 6 ++--- huff_core/tests/macro_invoc_args.rs | 16 +++++------ huff_core/tests/parser_errors.rs | 28 ++++++++++---------- huff_core/tests/push_overrides.rs | 6 ++--- huff_core/tests/recurse_bytecode.rs | 4 +-- huff_core/tests/test_circular_constructor.rs | 8 +++--- huff_core/tests/tests.rs | 4 +-- huff_core/tests/verbatim.rs | 4 +-- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/huff_core/tests/file_resolution.rs b/huff_core/tests/file_resolution.rs index 0eef8e2a..d3ec9385 100644 --- a/huff_core/tests/file_resolution.rs +++ b/huff_core/tests/file_resolution.rs @@ -33,7 +33,7 @@ fn test_get_outputs_with_output() { #[test] fn test_transform_paths() { let file_provider = FileSystemFileProvider {}; - let path_bufs: Result, CompilerError<'_>> = file_provider.transform_paths(&[ + let path_bufs: Result, CompilerError> = file_provider.transform_paths(&[ "../huff-examples/erc20/contracts/ERC20.huff".to_string(), "../huff-examples/erc20/contracts/utils/".to_string(), ]); @@ -66,7 +66,7 @@ fn test_transform_paths() { #[test] fn test_transform_paths_non_huff() { let file_provider = FileSystemFileProvider {}; - let path_bufs: Result, CompilerError<'_>> = + let path_bufs: Result, CompilerError> = file_provider.transform_paths(&["./ERC20.txt".to_string()]); assert!(path_bufs.is_err()); match path_bufs { @@ -82,7 +82,7 @@ fn test_transform_paths_non_huff() { #[test] fn test_transform_paths_no_dir() { let file_provider = FileSystemFileProvider {}; - let path_bufs: Result, CompilerError<'_>> = + let path_bufs: Result, CompilerError> = file_provider.transform_paths(&["./examples/random_dir/".to_string()]); assert!(path_bufs.is_err()); match path_bufs { diff --git a/huff_core/tests/free_storage_pointer.rs b/huff_core/tests/free_storage_pointer.rs index 3e0f3a37..66cdc72e 100644 --- a/huff_core/tests/free_storage_pointer.rs +++ b/huff_core/tests/free_storage_pointer.rs @@ -1,5 +1,5 @@ use huff_codegen::Codegen; -use huff_lexer::Lexer; +use huff_lexer::*; use huff_parser::Parser; use huff_utils::{prelude::FullFileSource, token::Token}; @@ -21,7 +21,7 @@ fn test_set_free_storage_pointers() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/functions.rs b/huff_core/tests/functions.rs index 572e095e..ef620de5 100644 --- a/huff_core/tests/functions.rs +++ b/huff_core/tests/functions.rs @@ -1,5 +1,5 @@ use huff_codegen::Codegen; -use huff_lexer::Lexer; +use huff_lexer::*; use huff_parser::Parser; use huff_utils::prelude::{FileSource, FullFileSource, Token}; use std::sync::Arc; @@ -93,7 +93,7 @@ fn test_function() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -187,7 +187,7 @@ fn test_nested_function() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/macro_invoc_args.rs b/huff_core/tests/macro_invoc_args.rs index 0b498432..4ac61630 100644 --- a/huff_core/tests/macro_invoc_args.rs +++ b/huff_core/tests/macro_invoc_args.rs @@ -1,5 +1,5 @@ use huff_codegen::Codegen; -use huff_lexer::Lexer; +use huff_lexer::*; use huff_parser::Parser; use huff_utils::prelude::*; use std::str::FromStr; @@ -19,7 +19,7 @@ fn test_opcode_macro_args() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -55,7 +55,7 @@ fn test_all_opcodes_in_macro_args() { // Lex + Parse let flattened_source = FullFileSource { source: &source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -91,7 +91,7 @@ fn test_constant_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -129,7 +129,7 @@ fn test_bubbled_label_call_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -166,7 +166,7 @@ fn test_bubbled_literal_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -203,7 +203,7 @@ fn test_bubbled_opcode_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -242,7 +242,7 @@ fn test_bubbled_constant_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/parser_errors.rs b/huff_core/tests/parser_errors.rs index 0c7022ba..cabece8c 100644 --- a/huff_core/tests/parser_errors.rs +++ b/huff_core/tests/parser_errors.rs @@ -25,10 +25,10 @@ fn test_invalid_macro_statement() { "#; let const_start = source.find("FREE_STORAGE_POINTER()").unwrap_or(0); - let const_end = const_start + "FREE_STORAGE_POINTER()".len(); + let const_end = const_start + "FREE_STORAGE_POINTER()".len() - 1; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -53,7 +53,7 @@ fn test_unexpected_type() { let source = "#define function func() internal returns ()"; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -69,7 +69,7 @@ fn test_unexpected_type() { ), spans: AstSpan(vec![Span { start: source.find("internal").unwrap_or(0), - end: source.find("internal").unwrap_or(0) + "internal".len(), + end: source.find("internal").unwrap_or(0) + "internal".len() - 1, file: None }]), } @@ -83,7 +83,7 @@ fn test_invalid_definition() { let source = "#define invalid func() returns ()"; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -100,7 +100,7 @@ fn test_invalid_definition() { ), spans: AstSpan(vec![Span { start: source.find("invalid").unwrap_or(0), - end: source.find("invalid").unwrap_or(0) + "invalid".len(), + end: source.find("invalid").unwrap_or(0) + "invalid".len() - 1, file: None }]), } @@ -127,7 +127,7 @@ fn test_invalid_constant_value() { let source = &format!("#define constant CONSTANT = {value}"); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -144,7 +144,7 @@ fn test_invalid_constant_value() { ), spans: AstSpan(vec![Span { start: source.find(value).unwrap_or(0), - end: source.find(value).unwrap_or(0) + value.len(), + end: source.find(value).unwrap_or(0) + value.len() - 1, file: None }]), } @@ -174,7 +174,7 @@ fn test_invalid_token_in_macro_body() { ); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -188,7 +188,7 @@ fn test_invalid_token_in_macro_body() { hint: None, spans: AstSpan(vec![Span { start: source.rfind(value).unwrap_or(0), - end: source.rfind(value).unwrap_or(0) + value.len(), + end: source.rfind(value).unwrap_or(0) + value.len() - 1, file: None }]), } @@ -219,7 +219,7 @@ fn test_invalid_token_in_label_definition() { ); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -233,7 +233,7 @@ fn test_invalid_token_in_label_definition() { hint: None, spans: AstSpan(vec![Span { start: source.rfind(value).unwrap_or(0), - end: source.rfind(value).unwrap_or(0) + value.len(), + end: source.rfind(value).unwrap_or(0) + value.len() - 1, file: None }]), } @@ -256,7 +256,7 @@ fn test_invalid_single_arg() { let source = &format!("#define macro CONSTANT() = takes ({random_char}) returns (0) {{}}"); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer .into_iter() .map(|x| match x { @@ -278,7 +278,7 @@ fn test_invalid_single_arg() { "{random_char}" ))), hint: Some("Expected number representing stack item count.".to_string()), - spans: AstSpan(vec![Span { start: 34, end: 35, file: None }]), + spans: AstSpan(vec![Span { start: 34, end: 34, file: None }]), } ) } diff --git a/huff_core/tests/push_overrides.rs b/huff_core/tests/push_overrides.rs index b91976cd..fc7845ee 100644 --- a/huff_core/tests/push_overrides.rs +++ b/huff_core/tests/push_overrides.rs @@ -15,7 +15,7 @@ fn test_gracefully_pads_push_override() { // Lex and Parse the source code let flattened_source = FullFileSource { source: OVERRIDEN_PUSH, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -52,7 +52,7 @@ fn test_constructs_exact_push_override() { // Lex and Parse the source code let flattened_source = FullFileSource { source: OVERRIDEN_PUSH, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -85,7 +85,7 @@ fn test_fails_on_push_underflow() { "#; let flattened_source = FullFileSource { source: OVERRIDEN_PUSH, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); diff --git a/huff_core/tests/recurse_bytecode.rs b/huff_core/tests/recurse_bytecode.rs index 757e8337..46a26e16 100644 --- a/huff_core/tests/recurse_bytecode.rs +++ b/huff_core/tests/recurse_bytecode.rs @@ -1,5 +1,5 @@ use huff_codegen::Codegen; -use huff_lexer::Lexer; +use huff_lexer::*; use huff_parser::Parser; use huff_utils::prelude::*; @@ -46,7 +46,7 @@ fn recurse_macro_bytecode() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/test_circular_constructor.rs b/huff_core/tests/test_circular_constructor.rs index 6a7bf630..88ff2601 100644 --- a/huff_core/tests/test_circular_constructor.rs +++ b/huff_core/tests/test_circular_constructor.rs @@ -37,7 +37,7 @@ fn test_circular_large_constructors() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -85,7 +85,7 @@ fn test_circular_constructor_at_word_boundry() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -118,7 +118,7 @@ fn test_double_circular_constructor_multiple_macro_invocations() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -155,7 +155,7 @@ fn test_double_circular_constructor_nested_macro_invocations() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/tests.rs b/huff_core/tests/tests.rs index b7658467..f8adc0e4 100644 --- a/huff_core/tests/tests.rs +++ b/huff_core/tests/tests.rs @@ -1,5 +1,5 @@ use huff_codegen::Codegen; -use huff_lexer::Lexer; +use huff_lexer::*; use huff_parser::Parser; use huff_utils::{ error::CodegenErrorKind, @@ -24,7 +24,7 @@ fn test_invocation_should_fail() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = lexer::LexerNew::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/verbatim.rs b/huff_core/tests/verbatim.rs index 793c472c..98645cf4 100644 --- a/huff_core/tests/verbatim.rs +++ b/huff_core/tests/verbatim.rs @@ -12,7 +12,7 @@ fn test_verbatim() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -34,7 +34,7 @@ fn test_verbatim_invalid_hex() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(full_source); + let lexer = lexer::LexerNew::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); From 012789c7e3c9e9323bd902861b1fd05b4e6974aa Mon Sep 17 00:00:00 2001 From: jimboj Date: Fri, 10 Mar 2023 17:40:10 -0700 Subject: [PATCH 33/68] new lexer baby --- huff_core/README.md | 4 +- huff_core/benches/huff_benchmark.rs | 42 +- huff_core/src/lib.rs | 4 +- .../tests/alternative_constructor_macro.rs | 2 +- huff_core/tests/alternative_main_macro.rs | 2 +- huff_core/tests/breaking_jumptable.rs | 2 +- huff_core/tests/builtins.rs | 22 +- huff_core/tests/codegen_errors.rs | 14 +- huff_core/tests/compiling.rs | 4 +- huff_core/tests/erc20.rs | 2 +- huff_core/tests/erc721.rs | 2 +- huff_core/tests/exports_events.rs | 10 +- huff_core/tests/free_storage_pointer.rs | 2 +- huff_core/tests/functions.rs | 4 +- huff_core/tests/macro_invoc_args.rs | 14 +- huff_core/tests/parser_errors.rs | 14 +- huff_core/tests/push_overrides.rs | 6 +- huff_core/tests/recurse_bytecode.rs | 2 +- huff_core/tests/test_circular_constructor.rs | 8 +- huff_core/tests/tests.rs | 2 +- huff_core/tests/verbatim.rs | 4 +- huff_lexer/README.md | 25 +- huff_lexer/src/lexer.rs | 703 -------------- huff_lexer/src/lib.rs | 877 +++++++++--------- huff_lexer/tests/arg_calls.rs | 2 +- huff_lexer/tests/builtins.rs | 6 +- huff_lexer/tests/comments.rs | 6 +- huff_lexer/tests/context.rs | 6 +- huff_lexer/tests/decorators.rs | 4 +- huff_lexer/tests/eof.rs | 2 +- huff_lexer/tests/evm_types.rs | 8 +- huff_lexer/tests/fsp.rs | 2 +- huff_lexer/tests/function_type.rs | 2 +- huff_lexer/tests/hex.rs | 8 +- huff_lexer/tests/imports.rs | 22 +- huff_lexer/tests/keywords.rs | 32 +- huff_lexer/tests/labels.rs | 4 +- huff_lexer/tests/numbers.rs | 4 +- huff_lexer/tests/opcodes.rs | 2 +- huff_lexer/tests/symbols.rs | 12 +- huff_lexer/tests/tables.rs | 6 +- huff_parser/README.md | 4 +- huff_parser/tests/abi.rs | 2 +- .../tests/breaking_param_invocation.rs | 4 +- huff_parser/tests/constant.rs | 4 +- huff_parser/tests/error.rs | 4 +- huff_parser/tests/event.rs | 4 +- huff_parser/tests/function.rs | 10 +- huff_parser/tests/imports.rs | 4 +- huff_parser/tests/labels.rs | 4 +- huff_parser/tests/macro.rs | 60 +- huff_parser/tests/opcodes.rs | 67 +- .../tests/storage_pointer_derivation.rs | 2 +- huff_parser/tests/table.rs | 6 +- 54 files changed, 640 insertions(+), 1434 deletions(-) delete mode 100644 huff_lexer/src/lexer.rs diff --git a/huff_core/README.md b/huff_core/README.md index 2f6c2c6e..edc2f902 100644 --- a/huff_core/README.md +++ b/huff_core/README.md @@ -9,7 +9,7 @@ Compiling source code with the [Compiler](struct.Compiler.html) is very straight Once you instantiate a [Compiler](struct.Compiler.html) (WLOG, `compiler`) with the file source, you can generate the compiled artifacts by simply running: ```rust,ignore -let artifacts: Result, CompilerError<'_>> = compiler.execute(); +let artifacts: Result, CompilerError> = compiler.execute(); ``` Below we demonstrate taking a source file `../huff-examples/erc20/contracts/ERC20.huff`, and generating the copmiled artifacts. @@ -26,7 +26,7 @@ use std::rc::Rc; let mut compiler = Compiler::new(Arc::new(vec!["../huff-examples/erc20/contracts/ERC20.huff".to_string()]), None, None, None, None, None, false, false); // Execute the compiler -let res: Result>, Arc>> = compiler.execute(); +let res: Result>, Arc> = compiler.execute(); assert!(res.is_ok()); ``` diff --git a/huff_core/benches/huff_benchmark.rs b/huff_core/benches/huff_benchmark.rs index 861c3689..a67a5c0a 100644 --- a/huff_core/benches/huff_benchmark.rs +++ b/huff_core/benches/huff_benchmark.rs @@ -31,38 +31,7 @@ fn lex_erc20_from_source_benchmark(c: &mut Criterion) { // Isolate lexing to benchmark c.bench_function("Lexer: ERC-20", |b| { b.iter(|| { - let lexer = Lexer::new(full_source.clone()); - let _ = lexer.into_iter().map(|x| x.unwrap()).collect::>(); - }) - }); -} - -fn lex_erc20_from_source_benchmark_new(c: &mut Criterion) { - let file_provider = Arc::new(FileSystemFileProvider::new()); - let file_sources: Vec> = Compiler::fetch_sources( - vec![PathBuf::from("../huff-examples/erc20/contracts/ERC20.huff".to_string())], - file_provider.clone(), - ) - .into_iter() - .map(|p| p.unwrap()) - .collect(); - - // Recurse file deps + generate flattened source - let file_source = file_sources.get(0).unwrap(); - let recursed_file_source = - Compiler::recurse_deps(Arc::clone(file_source), &files::Remapper::new("./"), file_provider) - .unwrap(); - let flattened = FileSource::fully_flatten(Arc::clone(&recursed_file_source)); - let full_source = FullFileSource { - source: &flattened.0, - file: Some(Arc::clone(file_source)), - spans: flattened.1, - }; - - // Isolate lexing to benchmark - c.bench_function("Lexer_New: ERC-20", |b| { - b.iter(|| { - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let _ = lexer.into_iter().map(|x| x.unwrap()).collect::>(); }) }); @@ -90,7 +59,7 @@ fn parse_erc20_benchmark(c: &mut Criterion) { spans: flattened.1, }; - let lexer = Lexer::new(full_source); + let lexer = Lexer::new(full_source.source); let tokens = Box::new(lexer.into_iter().map(|x| x.unwrap()).collect::>()); // Isolate parsing to benchmark @@ -126,7 +95,7 @@ fn codegen_erc20_benchmark(c: &mut Criterion) { spans: flattened.1, }; - let lexer = Lexer::new(full_source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("../huff-examples/erc20/contracts".to_string())); @@ -174,7 +143,7 @@ fn erc20_compilation_benchmark(c: &mut Criterion) { file: Some(Arc::clone(file_source)), spans: flattened.1, }; - let lexer = Lexer::new(full_source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("../huff-examples/erc20/contracts".to_string())); let mut contract = parser.parse().unwrap(); @@ -219,7 +188,7 @@ fn erc721_compilation_benchmark(c: &mut Criterion) { file: Some(Arc::clone(file_source)), spans: flattened.1, }; - let lexer = Lexer::new(full_source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("../huff-examples/erc20/contracts".to_string())); let mut contract = parser.parse().unwrap(); @@ -244,7 +213,6 @@ fn erc721_compilation_benchmark(c: &mut Criterion) { criterion_group!( benches, lex_erc20_from_source_benchmark, - lex_erc20_from_source_benchmark_new, parse_erc20_benchmark, codegen_erc20_benchmark, erc20_compilation_benchmark, diff --git a/huff_core/src/lib.rs b/huff_core/src/lib.rs index 7dd7944c..84013553 100644 --- a/huff_core/src/lib.rs +++ b/huff_core/src/lib.rs @@ -342,7 +342,7 @@ impl<'a> Compiler<'a> { // Perform Lexical Analysis // Create a new lexer from the FileSource, flattening dependencies - let lexer: Lexer = Lexer::new(full_source); + let lexer = Lexer::new(full_source.source); // Grab the tokens from the lexer let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); @@ -380,7 +380,7 @@ impl<'a> Compiler<'a> { // Perform Lexical Analysis // Create a new lexer from the FileSource, flattening dependencies - let lexer: Lexer = Lexer::new(full_source); + let lexer = Lexer::new(full_source.source); // Grab the tokens from the lexer let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); diff --git a/huff_core/tests/alternative_constructor_macro.rs b/huff_core/tests/alternative_constructor_macro.rs index 74f842ee..a3880637 100644 --- a/huff_core/tests/alternative_constructor_macro.rs +++ b/huff_core/tests/alternative_constructor_macro.rs @@ -18,7 +18,7 @@ fn test_alternative_constructor_macro_provided() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/alternative_main_macro.rs b/huff_core/tests/alternative_main_macro.rs index b7d43643..265bc783 100644 --- a/huff_core/tests/alternative_main_macro.rs +++ b/huff_core/tests/alternative_main_macro.rs @@ -18,7 +18,7 @@ fn test_alternative_main_macro_provided() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/breaking_jumptable.rs b/huff_core/tests/breaking_jumptable.rs index bd7035f2..5d37e489 100644 --- a/huff_core/tests/breaking_jumptable.rs +++ b/huff_core/tests/breaking_jumptable.rs @@ -133,7 +133,7 @@ fn test_breaking_jump_table() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index bc2b8ce9..78349bc0 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -24,7 +24,7 @@ fn test_codesize_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -60,7 +60,7 @@ fn test_dyn_constructor_arg_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -149,7 +149,7 @@ fn test_tablesize_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -213,7 +213,7 @@ fn test_tablestart_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -278,7 +278,7 @@ fn test_jump_table_exhaustive_usage() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -338,7 +338,7 @@ fn test_jump_table_packed_exhaustive_usage() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -405,7 +405,7 @@ fn test_label_clashing() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -449,7 +449,7 @@ fn test_func_sig_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -494,7 +494,7 @@ fn test_event_hash_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -569,7 +569,7 @@ fn test_error_selector_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -612,7 +612,7 @@ fn test_rightpad_builtin() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/codegen_errors.rs b/huff_core/tests/codegen_errors.rs index 74eb0d96..a4d5754a 100644 --- a/huff_core/tests/codegen_errors.rs +++ b/huff_core/tests/codegen_errors.rs @@ -33,7 +33,7 @@ fn test_storage_pointers_not_derived() { // let const_end = const_start + "UNKNOWN_CONSTANT_DEFINITION".len(); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let contract = parser.parse().unwrap(); @@ -92,7 +92,7 @@ fn test_invalid_constant_definition() { let const_end = const_start + "UNKNOWN_CONSTANT_DEFINITION".len() - 1; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -135,7 +135,7 @@ fn test_missing_constructor() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -168,7 +168,7 @@ fn test_missing_main() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -201,7 +201,7 @@ fn test_missing_when_alternative_main_provided() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -244,7 +244,7 @@ fn test_unknown_macro_definition() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -291,7 +291,7 @@ fn test_unmatched_jump_label() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/compiling.rs b/huff_core/tests/compiling.rs index 9eeda85a..a7217028 100644 --- a/huff_core/tests/compiling.rs +++ b/huff_core/tests/compiling.rs @@ -40,7 +40,7 @@ const SOURCE: &str = r#" fn compiles_constructor_bytecode() { // Lex and Parse the source code let flattened_source = FullFileSource { source: SOURCE, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -67,7 +67,7 @@ fn compiles_constructor_bytecode() { fn compiles_runtime_bytecode() { // Lex and Parse the source code let flattened_source = FullFileSource { source: SOURCE, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/erc20.rs b/huff_core/tests/erc20.rs index 96d83ca5..09f721f6 100644 --- a/huff_core/tests/erc20.rs +++ b/huff_core/tests/erc20.rs @@ -28,7 +28,7 @@ fn test_erc20_compile() { file: Some(Arc::clone(file_source)), spans: flattened.1, }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("../huff-examples/erc20/contracts".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/erc721.rs b/huff_core/tests/erc721.rs index ca70928c..a8ab17f7 100644 --- a/huff_core/tests/erc721.rs +++ b/huff_core/tests/erc721.rs @@ -28,7 +28,7 @@ fn test_erc721_compile() { file: Some(Arc::clone(file_source)), spans: flattened.1, }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("../huff-examples/erc20/contracts".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/exports_events.rs b/huff_core/tests/exports_events.rs index 32cab88e..71c834e3 100644 --- a/huff_core/tests/exports_events.rs +++ b/huff_core/tests/exports_events.rs @@ -16,7 +16,7 @@ fn test_abi_uint_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -84,7 +84,7 @@ fn test_abi_int_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -152,7 +152,7 @@ fn test_abi_simple_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -211,7 +211,7 @@ fn test_abi_tuple_array_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -270,7 +270,7 @@ fn test_abi_nested_tuple_array_events() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/free_storage_pointer.rs b/huff_core/tests/free_storage_pointer.rs index 66cdc72e..8dddebe0 100644 --- a/huff_core/tests/free_storage_pointer.rs +++ b/huff_core/tests/free_storage_pointer.rs @@ -21,7 +21,7 @@ fn test_set_free_storage_pointers() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/functions.rs b/huff_core/tests/functions.rs index ef620de5..9a873744 100644 --- a/huff_core/tests/functions.rs +++ b/huff_core/tests/functions.rs @@ -93,7 +93,7 @@ fn test_function() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -187,7 +187,7 @@ fn test_nested_function() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/macro_invoc_args.rs b/huff_core/tests/macro_invoc_args.rs index 4ac61630..977aa2d2 100644 --- a/huff_core/tests/macro_invoc_args.rs +++ b/huff_core/tests/macro_invoc_args.rs @@ -19,7 +19,7 @@ fn test_opcode_macro_args() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -55,7 +55,7 @@ fn test_all_opcodes_in_macro_args() { // Lex + Parse let flattened_source = FullFileSource { source: &source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -91,7 +91,7 @@ fn test_constant_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -129,7 +129,7 @@ fn test_bubbled_label_call_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -166,7 +166,7 @@ fn test_bubbled_literal_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -203,7 +203,7 @@ fn test_bubbled_opcode_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); @@ -242,7 +242,7 @@ fn test_bubbled_constant_macro_arg() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/parser_errors.rs b/huff_core/tests/parser_errors.rs index cabece8c..8fd64b3c 100644 --- a/huff_core/tests/parser_errors.rs +++ b/huff_core/tests/parser_errors.rs @@ -28,7 +28,7 @@ fn test_invalid_macro_statement() { let const_end = const_start + "FREE_STORAGE_POINTER()".len() - 1; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -53,7 +53,7 @@ fn test_unexpected_type() { let source = "#define function func() internal returns ()"; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -83,7 +83,7 @@ fn test_invalid_definition() { let source = "#define invalid func() returns ()"; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -127,7 +127,7 @@ fn test_invalid_constant_value() { let source = &format!("#define constant CONSTANT = {value}"); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -174,7 +174,7 @@ fn test_invalid_token_in_macro_body() { ); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -219,7 +219,7 @@ fn test_invalid_token_in_label_definition() { ); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); @@ -256,7 +256,7 @@ fn test_invalid_single_arg() { let source = &format!("#define macro CONSTANT() = takes ({random_char}) returns (0) {{}}"); let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer .into_iter() .map(|x| match x { diff --git a/huff_core/tests/push_overrides.rs b/huff_core/tests/push_overrides.rs index fc7845ee..bff3ccd1 100644 --- a/huff_core/tests/push_overrides.rs +++ b/huff_core/tests/push_overrides.rs @@ -15,7 +15,7 @@ fn test_gracefully_pads_push_override() { // Lex and Parse the source code let flattened_source = FullFileSource { source: OVERRIDEN_PUSH, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -52,7 +52,7 @@ fn test_constructs_exact_push_override() { // Lex and Parse the source code let flattened_source = FullFileSource { source: OVERRIDEN_PUSH, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -85,7 +85,7 @@ fn test_fails_on_push_underflow() { "#; let flattened_source = FullFileSource { source: OVERRIDEN_PUSH, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); diff --git a/huff_core/tests/recurse_bytecode.rs b/huff_core/tests/recurse_bytecode.rs index 46a26e16..3e6b1ffd 100644 --- a/huff_core/tests/recurse_bytecode.rs +++ b/huff_core/tests/recurse_bytecode.rs @@ -46,7 +46,7 @@ fn recurse_macro_bytecode() { // Lex + Parse let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/test_circular_constructor.rs b/huff_core/tests/test_circular_constructor.rs index 88ff2601..d5eb3f51 100644 --- a/huff_core/tests/test_circular_constructor.rs +++ b/huff_core/tests/test_circular_constructor.rs @@ -37,7 +37,7 @@ fn test_circular_large_constructors() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -85,7 +85,7 @@ fn test_circular_constructor_at_word_boundry() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -118,7 +118,7 @@ fn test_double_circular_constructor_multiple_macro_invocations() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -155,7 +155,7 @@ fn test_double_circular_constructor_nested_macro_invocations() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_core/tests/tests.rs b/huff_core/tests/tests.rs index f8adc0e4..4c181a8a 100644 --- a/huff_core/tests/tests.rs +++ b/huff_core/tests/tests.rs @@ -24,7 +24,7 @@ fn test_invocation_should_fail() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_core/tests/verbatim.rs b/huff_core/tests/verbatim.rs index 98645cf4..b345f1c0 100644 --- a/huff_core/tests/verbatim.rs +++ b/huff_core/tests/verbatim.rs @@ -12,7 +12,7 @@ fn test_verbatim() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); @@ -34,7 +34,7 @@ fn test_verbatim_invalid_hex() { "#; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let mut contract = parser.parse().unwrap(); diff --git a/huff_lexer/README.md b/huff_lexer/README.md index eb13af53..d3ce1146 100644 --- a/huff_lexer/README.md +++ b/huff_lexer/README.md @@ -24,44 +24,37 @@ use std::ops::Deref; // Instantiate a new lexer let source = "#define macro HELLO_WORLD()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; -let mut lexer = Lexer::new(flattened_source); +let mut lexer = Lexer::new(flattened_source.sour); // This token should be a Define identifier let tok = lexer.next().unwrap().unwrap(); -assert_eq!(tok, Token::new(TokenKind::Define, Span::new(0..7, None))); -assert_eq!(lexer.current_span().deref(), &Span::new(0..7, None)); +assert_eq!(tok, Token::new(TokenKind::Define, Span::new(0..6, None))); // The next token should be the whitespace let tok = lexer.next().unwrap().unwrap(); -assert_eq!(tok, Token::new(TokenKind::Whitespace, Span::new(7..8, None))); -assert_eq!(lexer.current_span().deref(), &Span::new(7..8, None)); +assert_eq!(tok, Token::new(TokenKind::Whitespace, Span::new(7..7, None))); // Then we should parse the macro keyword let tok = lexer.next().unwrap().unwrap(); -assert_eq!(tok, Token::new(TokenKind::Macro, Span::new(8..13, None))); -assert_eq!(lexer.current_span().deref(), &Span::new(8..13, None)); +assert_eq!(tok, Token::new(TokenKind::Macro, Span::new(8..12, None))); // The next token should be another whitespace let tok = lexer.next().unwrap().unwrap(); -assert_eq!(tok, Token::new(TokenKind::Whitespace, Span::new(13..14, None))); -assert_eq!(lexer.current_span().deref(), &Span::new(13..14, None)); +assert_eq!(tok, Token::new(TokenKind::Whitespace, Span::new(13..13, None))); // Then we should get the function name let tok = lexer.next().unwrap().unwrap(); -assert_eq!(tok, Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), Span::new(14..25, None))); -assert_eq!(lexer.current_span().deref(), &Span::new(14..25, None)); +assert_eq!(tok, Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), Span::new(14..24, None))); // Then we should have an open paren let tok = lexer.next().unwrap().unwrap(); -assert_eq!(tok, Token::new(TokenKind::OpenParen, Span::new(25..26, None))); -assert_eq!(lexer.current_span().deref(), &Span::new(25..26, None)); +assert_eq!(tok, Token::new(TokenKind::OpenParen, Span::new(25..25, None))); // Lastly, we should have a closing parenthesis let tok = lexer.next().unwrap().unwrap(); -assert_eq!(tok, Token::new(TokenKind::CloseParen, Span::new(26..27, None))); -assert_eq!(lexer.current_span().deref(), &Span::new(26..27, None)); +assert_eq!(tok, Token::new(TokenKind::CloseParen, Span::new(26..26, None))); +lexer.next(); // We covered the whole source -assert_eq!(lexer.current_span().end, source.len()); assert!(lexer.eof); ``` diff --git a/huff_lexer/src/lexer.rs b/huff_lexer/src/lexer.rs deleted file mode 100644 index fa0cd239..00000000 --- a/huff_lexer/src/lexer.rs +++ /dev/null @@ -1,703 +0,0 @@ -use huff_utils::prelude::*; -use regex::Regex; -use std::{ - iter::{Peekable, Zip}, - str::Chars, - ops::RangeFrom, -}; -/* hiehgsebgoiesgoiseg */ -/// Defines a context in which the lexing happens. -/// Allows to differientate between EVM types and opcodes that can either -/// be identical or the latter being a substring of the former (example : bytes32 and byte) -#[derive(Debug, PartialEq, Eq)] -pub enum Context { - /// global context - Global, - /// Macro definition context - MacroDefinition, - /// Macro's body context - MacroBody, - /// Macro's argument context (definition or being called) - MacroArgs, - /// ABI context - Abi, - /// Lexing args of functions inputs/outputs and events - AbiArgs, - /// constant context - Constant, - /// Code table context - CodeTableBody, -} - -/// ## Lexer -/// -/// The lexer encapsulated in a struct. -pub struct LexerNew<'a> { - /// The source code as peekable chars. - /// WARN: SHOULD NEVER BE MODIFIED! - pub chars: Peekable, RangeFrom>>, - position: u32, - /// The previous lexed Token. - /// NOTE: Cannot be a whitespace. - pub lookback: Option, - /// Bool indicating if we have reached EOF - pub eof: bool, - /// Current context. - pub context: Context, -} - -pub type TokenResult = Result; - -impl<'a> LexerNew<'a> { - pub fn new(source: &'a str) -> Self { - LexerNew { - // We zip with the character index here to ensure the first char has index 0 - //chars: source.chars().peekable(), - chars: source.chars().zip(0..).peekable(), - position: 0, - lookback: None, - eof: false, - context: Context::Global, - } - } - - /// Consumes the next character - pub fn consume(&mut self) -> Option { - // self.chars.next().map(|x| { - // self.position += 1; - // x - // }) - - let (c, index) = self.chars.next()?; - self.position = index; - Some(c) - } - - /// Try to peek at the next character from the source - pub fn peek(&mut self) -> Option { - //self.chars.peek().copied() - self.chars.peek().map(|(c, _) | *c) - } - - /// Consume characters until a sequence matches - // pub fn seq_consume(&mut self, word: &str) { - // let mut current_pos = self.current_span().start; - // while self.peek().is_some() { - // let peeked = self.peek_n_chars_from(word.len(), current_pos); - // if word == peeked { - // break - // } - // self.consume(); - // current_pos += 1; - // } - // } - - /// Dynamically consumes characters based on filters - pub fn dyn_consume(&mut self, f: impl Fn(&char) -> bool + Copy) { - while self.peek().map(|x| f(&x)).unwrap_or(false) { - self.consume(); - } - } - - fn next_token(&mut self) -> TokenResult { - // let start = self.position; - if let Some(ch) = self.consume() { - let token = match ch { - '/' => { - let mut comment_string = String::new(); - let start = self.position; - comment_string.push(ch); - if let Some(ch2) = self.peek() { - match ch2 { - '/' => { - // Consume until newline - comment_string.push(ch2); - let (comment_string, start, end) = self.eat_while(Some(ch), |c| c != '\n'); - Ok(TokenKind::Comment(comment_string).into_span(start, end)) - } - '*' => { - // ref: https://github.com/rust-lang/rust/blob/900c3540378c8422b8087ffa3db60fa6c8abfcad/compiler/rustc_lexer/src/lib.rs#L474 - let c = self.consume(); - comment_string.push(c.unwrap()); - let mut depth = 1usize; - while let Some(c) = self.consume() { - match c { - '/' if self.peek() == Some('*') => { - comment_string.push(c); - let c2 = self.consume(); - comment_string.push(c2.unwrap()); - depth += 1; - } - '*' if self.peek() == Some('/') => { - comment_string.push(c); - let c2 = self.consume(); - comment_string.push(c2.unwrap()); - depth -= 1; - if depth == 0 { - // This block comment is closed, so for a construction like "/* */ */" - // there will be a successfully parsed block comment "/* */" - // and " */" will be processed separately. - - break; - } - } - _ => { - comment_string.push(c); - }, - - } - } - - Ok(TokenKind::Comment(comment_string).into_span(start, self.position)) - // TODO add string or just not store comments - // self.single_char_token(TokenKind::Comment("".to_owned())) - } - _ => self.single_char_token(TokenKind::Div) - } - } - else { - self.single_char_token(TokenKind::Div) - } - } - - // # keywords - '#' => { - let (word, start, end) = self.eat_while(Some(ch), |ch| { - ch.is_ascii_alphabetic() - }); - - let mut found_kind: Option = None; - - let keys = [TokenKind::Define, TokenKind::Include]; - for kind in keys.into_iter() { - let key = kind.to_string(); - let peeked = word.clone(); - if key == peeked { - found_kind = Some(kind); - break - } - } - - if let Some(kind) = &found_kind { - Ok(kind.clone().into_span(start, end)) - } else if self.context == Context::Global && self.peek().unwrap() == '[' { - Ok(TokenKind::Pound.into_single_span(self.position)) - } else { - // Otherwise we don't support # prefixed indentifiers - tracing::error!(target: "lexer", "INVALID '#' CHARACTER USAGE"); - return Err(LexicalError::new( - LexicalErrorKind::InvalidCharacter('#'), - Span { start: self.position as usize, end: self.position as usize, file: None }, - )) - } - } - // Alphabetical characters - ch if ch.is_alphabetic() || ch.eq(&'_') => { - let (word, start, mut end) = self.eat_while(Some(ch), |c| { - c.is_alphanumeric() || c == '_' - }); - - let mut found_kind: Option = None; - let keys = [ - TokenKind::Macro, - TokenKind::Fn, - TokenKind::Test, - TokenKind::Function, - TokenKind::Constant, - TokenKind::Error, - TokenKind::Takes, - TokenKind::Returns, - TokenKind::Event, - TokenKind::NonPayable, - TokenKind::Payable, - TokenKind::Indexed, - TokenKind::View, - TokenKind::Pure, - // First check for packed jump table - TokenKind::JumpTablePacked, - // Match with jump table if not - TokenKind::JumpTable, - TokenKind::CodeTable, - ]; - for kind in keys.into_iter() { - if self.context == Context::MacroBody { - break - } - let key = kind.to_string(); - let peeked = word.clone(); - - if key == peeked { - found_kind = Some(kind); - break - } - } - - // Check to see if the found kind is, in fact, a keyword and not the name of - // a function. If it is, set `found_kind` to `None` so that it is set to a - // `TokenKind::Ident` in the following control flow. - if !self.check_keyword_rules(&found_kind) { - found_kind = None; - } - - if let Some(kind) = &found_kind { - match kind { - TokenKind::Macro | TokenKind::Fn | TokenKind::Test => { - dbg!("found macro!"); - self.context = Context::MacroDefinition - } - TokenKind::Function | TokenKind::Event | TokenKind::Error => { - self.context = Context::Abi - } - TokenKind::Constant => self.context = Context::Constant, - TokenKind::CodeTable => self.context = Context::CodeTableBody, - _ => (), - } - } - - // Check for free storage pointer builtin - let fsp = "FREE_STORAGE_POINTER"; - if fsp == word { - // Consume the parenthesis following the FREE_STORAGE_POINTER - // Note: This will consume `FREE_STORAGE_POINTER)` or - // `FREE_STORAGE_POINTER(` as well - if let Some('(') = self.peek() { - self.consume(); - } - if let Some(')') = self.peek() { - self.consume(); - } - end = end + 2; - found_kind = Some(TokenKind::FreeStoragePointer); - } - - if let Some(':') = self.peek() { - found_kind = Some(TokenKind::Label(word.clone())); - } - - // Syntax sugar: true evaluates to 0x01, false evaluates to 0x00 - if matches!(word.as_str(), "true" | "false") { - found_kind = Some(TokenKind::Literal(str_to_bytes32( - if word.as_str() == "true" { "1" } else { "0" }, - ))); - self.eat_while(None, |c| { - c.is_alphanumeric() - }); - } - - if !(self.context != Context::MacroBody || found_kind.is_some()) { - if let Some(o) = OPCODES_MAP.get(&word.clone()) { - found_kind = Some(TokenKind::Opcode(o.to_owned())); - } - } - - if self.context == Context::AbiArgs { - let curr_char = self.peek().unwrap(); - dbg!(curr_char); - if !['(', ')'].contains(&curr_char) { - let (partial_raw_type, _, abi_args_end) = self - .eat_while(Some(ch), |c| { - c.is_alphanumeric() || c == '[' || c == ']' - }); - let raw_type = word.clone() + &partial_raw_type[1..]; - - if raw_type == TokenKind::Calldata.to_string() { - found_kind = Some(TokenKind::Calldata); - } else if raw_type == TokenKind::Memory.to_string() { - found_kind = Some(TokenKind::Memory); - } else if raw_type == TokenKind::Storage.to_string() { - found_kind = Some(TokenKind::Storage); - } else if EVM_TYPE_ARRAY_REGEX.is_match(&raw_type) { - // split to get array size and type - // TODO: support multi-dimensional arrays - let words: Vec = Regex::new(r"\[") - .unwrap() - .split(&raw_type) - .map(|x| x.replace(']', "")) - .collect(); - let mut size_vec: Vec = Vec::new(); - // go over all array sizes - let sizes = words.get(1..words.len()).unwrap(); - for size in sizes.iter() { - match size.is_empty() { - true => size_vec.push(0), - false => { - let arr_size: usize = size - .parse::() - .map_err(|_| { - let err = LexicalError { - kind: LexicalErrorKind::InvalidArraySize( - words[1].clone(), - ), - span: Span { start: start as usize, end: end as usize, file: None }, - }; - tracing::error!(target: "lexer", "{}", format!("{err:?}")); - err - }) - .unwrap(); - size_vec.push(arr_size); - } - } - } - let primitive = PrimitiveEVMType::try_from(words[0].clone()); - if let Ok(primitive) = primitive { - found_kind = Some(TokenKind::ArrayType(primitive, size_vec)); - } else { - let err = LexicalError { - kind: LexicalErrorKind::InvalidPrimitiveType( - words[0].clone(), - ), - span: Span { - start: start as usize, - end: end as usize, - file: None, - }, - }; - tracing::error!(target: "lexer", "{}", format!("{err:?}")); - } - } else { - // We don't want to consider any argument names or the "indexed" - // keyword here. - let primitive = PrimitiveEVMType::try_from(word.clone()); - if let Ok(primitive) = primitive { - found_kind = Some(TokenKind::PrimitiveType(primitive)); - } - } - end = abi_args_end; - } else { - // We don't want to consider any argument names or the "indexed" - // keyword here. - let primitive = PrimitiveEVMType::try_from(word.clone()); - if let Ok(primitive) = primitive { - found_kind = Some(TokenKind::PrimitiveType(primitive)); - } - } - } - - let kind = if let Some(kind) = &found_kind { - kind.clone() - } else { - let kind = if self.context == Context::MacroBody - && BuiltinFunctionKind::try_from(&word).is_ok() - { - TokenKind::BuiltinFunction(word) - } else { - TokenKind::Ident(word) - }; - - kind - }; - - Ok(kind.into_span(start, end)) - } - // If it's the start of a hex literal - ch if ch == '0' && self.peek().unwrap() == 'x' => { - self.eat_hex_digit(ch) - } - '=' => self.single_char_token(TokenKind::Assign), - '(' => { - match self.context { - Context::Abi => self.context = Context::AbiArgs, - Context::MacroBody => self.context = Context::MacroArgs, - _ => {} - } - self.single_char_token(TokenKind::OpenParen) - } - ')' => { - match self.context { - Context::AbiArgs => self.context = Context::Abi, - Context::MacroArgs => self.context = Context::MacroBody, - _ => {} - } - self.single_char_token(TokenKind::CloseParen) - } - '[' => self.single_char_token(TokenKind::OpenBracket), - ']' => self.single_char_token(TokenKind::CloseBracket), - '{' => { - if self.context == Context::MacroDefinition { - self.context = Context::MacroBody; - } - self.single_char_token(TokenKind::OpenBrace) - } - '}' => { - if matches!(self.context, Context::MacroBody | Context::CodeTableBody) { - self.context = Context::Global; - } - self.single_char_token(TokenKind::CloseBrace) - } - '+' => self.single_char_token(TokenKind::Add), - '-' => self.single_char_token(TokenKind::Sub), - '*' => self.single_char_token(TokenKind::Mul), - '<' => self.single_char_token(TokenKind::LeftAngle), - '>' => self.single_char_token(TokenKind::RightAngle), - // NOTE: TokenKind::Div is lexed further up since it overlaps with comment - ':' => self.single_char_token(TokenKind::Colon), - // identifiers - ',' => self.single_char_token(TokenKind::Comma), - '0'..='9' => self.eat_digit(ch), - // Lexes Spaces and Newlines as Whitespace - ch if ch.is_ascii_whitespace() => { - dbg!("Are we hitting this?"); - let (_, start, end) = self.eat_whitespace(); - Ok(TokenKind::Whitespace.into_span(start, end)) - } - // String literals. String literals can also be wrapped by single quotes - '"' | '\'' => { - Ok(self.eat_string_literal()) - } - ch => { - tracing::error!(target: "lexer", "UNSUPPORTED TOKEN '{}'", ch); - return Err(LexicalError::new( - LexicalErrorKind::InvalidCharacter(ch), - Span { start: self.position as usize, end: self.position as usize, file: None }, - )) - } - }?; - - if token.kind != TokenKind::Whitespace { - self.lookback = Some(token.clone()); - } - - return Ok(token) - } else { - self.eof = true; - Ok(Token { kind: TokenKind::Eof, span: Span { start: self.position as usize, end: self.position as usize, file: None } } ) - } - } - - fn single_char_token(&self, token_kind: TokenKind) -> TokenResult { - Ok(token_kind.into_single_span(self.position)) - } - - /// Keeps consuming tokens as long as the predicate is satisfied - fn eat_while bool>( - &mut self, - initial_char: Option, - predicate: F, - ) -> (String, u32, u32) { - let start = self.position; - - // This function is only called when we want to continue consuming a character of the same type. - // For example, we see a digit and we want to consume the whole integer - // Therefore, the current character which triggered this function will need to be appended - let mut word = String::new(); - if let Some(init_char) = initial_char { - word.push(init_char) - } - - // Keep checking that we are not at the EOF - while let Some(peek_char) = self.peek() { - // Then check for the predicate, if predicate matches append char and increment the cursor - // If not, return word. The next character will be analyzed on the next iteration of next_token, - // Which will increment the cursor - if !predicate(peek_char) { - return (word, start, self.position); - } - word.push(peek_char); - - // If we arrive at this point, then the char has been added to the word and we should increment the cursor - self.consume(); - } - - (word, start, self.position) - } - - - fn eat_digit(&mut self, initial_char: char) -> TokenResult { - let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { - ch.is_ascii_digit() - }); - - let integer = integer_str.parse().unwrap(); - - let integer_token = TokenKind::Num(integer); - let span = Span { start: start as usize, end: end as usize, file: None }; - Ok(Token { kind: integer_token, span }) - } - - fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult { - let (integer_str, mut start, end) = self.eat_while(Some(initial_char), |ch| { - ch.is_ascii_hexdigit() | (ch == 'x') - }); - // TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34 - - let kind = if self.context == Context::CodeTableBody { - // In codetables, the bytecode provided is of arbitrary length. We pass - // the code as an Ident, and it is appended to the end of the runtime - // bytecode in codegen. - if &integer_str[0..2] == "0x" { - TokenKind::Ident(integer_str[2..].to_owned()) - } else { - TokenKind::Ident(integer_str) - } - } else { - - TokenKind::Literal(str_to_bytes32(&integer_str[2..].as_ref())) - }; - - start = start + 2; - let span = Span { start: start as usize, end: end as usize, file: None }; - Ok(Token { kind, span }) - } - - /// Skips white space. They are not significant in the source language - fn eat_whitespace(&mut self) -> (String, u32, u32) { - self.eat_while(None, |ch| ch.is_whitespace()) - } - - fn eat_string_literal(&mut self) -> Token { - let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"' && ch != '\''); - let str_literal_token = TokenKind::Str(str_literal); - self.consume(); // Advance past the closing quote - str_literal_token.into_span(start_span, end_span + 1) - } - - // fn eat_alphabetic(&mut self, initial_char: char) -> (String, u32, u32) { - // let (word, start, end) = self.eat_while(Some(initial_char), |ch| { - // ch.is_ascii_alphabetic() - // }); - // (word, start, end) - // } - - /// Checks the previous token kind against the input. - pub fn checked_lookback(&self, kind: TokenKind) -> bool { - self.lookback.clone().and_then(|t| if t.kind == kind { Some(true) } else { None }).is_some() - } - - /// Check if a given keyword follows the keyword rules in the `source`. If not, it is a - /// `TokenKind::Ident`. - /// - /// Rules: - /// - The `macro`, `fn`, `test`, `function`, `constant`, `event`, `jumptable`, - /// `jumptable__packed`, and `table` keywords must be preceded by a `#define` keyword. - /// - The `takes` keyword must be preceded by an assignment operator: `=`. - /// - The `nonpayable`, `payable`, `view`, and `pure` keywords must be preceeded by one of these - /// keywords or a close paren. - /// - The `returns` keyword must be succeeded by an open parenthesis and must *not* be succeeded - /// by a colon or preceded by the keyword `function` - pub fn check_keyword_rules(&mut self, found_kind: &Option) -> bool { - match found_kind { - Some(TokenKind::Macro) | - Some(TokenKind::Fn) | - Some(TokenKind::Test) | - Some(TokenKind::Function) | - Some(TokenKind::Constant) | - Some(TokenKind::Error) | - Some(TokenKind::Event) | - Some(TokenKind::JumpTable) | - Some(TokenKind::JumpTablePacked) | - Some(TokenKind::CodeTable) => self.checked_lookback(TokenKind::Define), - Some(TokenKind::NonPayable) | - Some(TokenKind::Payable) | - Some(TokenKind::View) | - Some(TokenKind::Pure) => { - let keys = [ - TokenKind::NonPayable, - TokenKind::Payable, - TokenKind::View, - TokenKind::Pure, - TokenKind::CloseParen, - ]; - for key in keys { - if self.checked_lookback(key) { - return true - } - } - false - } - Some(TokenKind::Takes) => self.checked_lookback(TokenKind::Assign), - Some(TokenKind::Returns) => { - self.eat_whitespace(); - // Allow for loose and tight syntax (e.g. `returns (0)`, `returns(0)`, ...) - self.peek().unwrap_or(')') == '(' && - !self.checked_lookback(TokenKind::Function) - } - _ => true, - } - } - - /// Lex all imports - /// Example import: `// #include "./Utils.huff"` - pub fn lex_imports(source: &str) -> Vec { - let mut imports = vec![]; - let mut peekable_source = source.chars().peekable(); - let mut include_chars_iterator = "#include".chars().peekable(); - while peekable_source.peek().is_some() { - while let Some(nc) = peekable_source.next() { - if nc.eq(&'/') { - if let Some(nnc) = peekable_source.peek() { - if nnc.eq(&'/') { - // Iterate until newline - while let Some(lc) = &peekable_source.next() { - if lc.eq(&'\n') { - break - } - } - } else if nnc.eq(&'*') { - // Iterate until '*/' - while let Some(lc) = peekable_source.next() { - if lc.eq(&'*') { - if let Some(llc) = peekable_source.peek() { - if *llc == '/' { - break - } - } - } - } - } - } - } - if include_chars_iterator.peek().is_none() { - // Reset the include chars iterator - include_chars_iterator = "#include".chars().peekable(); - - // Skip over whitespace - while peekable_source.peek().is_some() { - if !peekable_source.peek().unwrap().is_whitespace() { - break - } else { - peekable_source.next(); - } - } - - // Then we should have an import path between quotes - if let Some(char) = peekable_source.peek() { - match char { - '"' | '\'' => { - peekable_source.next(); - let mut import = String::new(); - while peekable_source.peek().is_some() { - if let Some(c) = peekable_source.next() { - if matches!(c, '"' | '\'') { - imports.push(import); - break - } else { - import.push(c); - } - } - } - } - _ => { /* Ignore non-include tokens */ } - } - } - } else if nc.ne(&include_chars_iterator.next().unwrap()) { - include_chars_iterator = "#include".chars().peekable(); - break - } - } - } - imports - } - -} - -impl<'a> Iterator for LexerNew<'a> { - type Item = TokenResult; - - fn next(&mut self) -> Option { - if self.eof { - None - } else { - Some(self.next_token()) - } - } -} \ No newline at end of file diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index b6a05f88..f9815887 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -1,20 +1,11 @@ -#![doc = include_str!("../README.md")] -#![allow(dead_code)] -#![warn(missing_docs)] -#![warn(unused_extern_crates)] -#![forbid(unsafe_code)] -#![forbid(where_clauses_object_safety)] - use huff_utils::prelude::*; use regex::Regex; use std::{ - cell::{Ref, RefCell, RefMut}, - iter::Peekable, + iter::{Peekable, Zip}, str::Chars, + ops::RangeFrom, }; - -pub mod lexer; - +/* hiehgsebgoiesgoiseg */ /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either /// be identical or the latter being a substring of the former (example : bytes32 and byte) @@ -44,218 +35,63 @@ pub enum Context { pub struct Lexer<'a> { /// The source code as peekable chars. /// WARN: SHOULD NEVER BE MODIFIED! - pub reference_chars: Peekable>, - /// The source code as peekable chars. - pub chars: Peekable>, - /// The raw source code. - pub source: FullFileSource<'a>, - /// The current lexing span. - pub span: RefCell, + pub chars: Peekable, RangeFrom>>, + position: u32, /// The previous lexed Token. /// NOTE: Cannot be a whitespace. pub lookback: Option, - /// If the lexer has reached the end of file. + /// Bool indicating if we have reached EOF pub eof: bool, - /// EOF Token has been returned. - pub eof_returned: bool, /// Current context. pub context: Context, - - - pub position: u32, } +pub type TokenResult = Result; + impl<'a> Lexer<'a> { - /// Public associated function that instantiates a new lexer. - pub fn new(source: FullFileSource<'a>) -> Self { - Self { - reference_chars: source.source.chars().peekable(), - chars: source.source.chars().peekable(), - source, - span: RefCell::new(Span::default()), + pub fn new(source: &'a str) -> Self { + Lexer { + // We zip with the character index here to ensure the first char has index 0 + //chars: source.chars().peekable(), + chars: source.chars().zip(0..).peekable(), + position: 0, lookback: None, eof: false, - eof_returned: false, context: Context::Global, - position: 0, - } - } - - /// Lex all imports - /// Example import: `// #include "./Utils.huff"` - pub fn lex_imports(source: &str) -> Vec { - let mut imports = vec![]; - let mut peekable_source = source.chars().peekable(); - let mut include_chars_iterator = "#include".chars().peekable(); - while peekable_source.peek().is_some() { - while let Some(nc) = peekable_source.next() { - if nc.eq(&'/') { - if let Some(nnc) = peekable_source.peek() { - if nnc.eq(&'/') { - // Iterate until newline - while let Some(lc) = &peekable_source.next() { - if lc.eq(&'\n') { - break - } - } - } else if nnc.eq(&'*') { - // Iterate until '*/' - while let Some(lc) = peekable_source.next() { - if lc.eq(&'*') { - if let Some(llc) = peekable_source.peek() { - if *llc == '/' { - break - } - } - } - } - } - } - } - if include_chars_iterator.peek().is_none() { - // Reset the include chars iterator - include_chars_iterator = "#include".chars().peekable(); - - // Skip over whitespace - while peekable_source.peek().is_some() { - if !peekable_source.peek().unwrap().is_whitespace() { - break - } else { - peekable_source.next(); - } - } - - // Then we should have an import path between quotes - if let Some(char) = peekable_source.peek() { - match char { - '"' | '\'' => { - peekable_source.next(); - let mut import = String::new(); - while peekable_source.peek().is_some() { - if let Some(c) = peekable_source.next() { - if matches!(c, '"' | '\'') { - imports.push(import); - break - } else { - import.push(c); - } - } - } - } - _ => { /* Ignore non-include tokens */ } - } - } - } else if nc.ne(&include_chars_iterator.next().unwrap()) { - include_chars_iterator = "#include".chars().peekable(); - break - } - } - } - imports - } - - /// Public associated function that returns a shared reference to the current lexing span. - pub fn current_span(&self) -> Ref { - self.span.borrow() - } - - /// Public associated function that returns an exclusive reference to the current lexing span. - pub fn current_span_mut(&self) -> RefMut { - self.span.borrow_mut() - } - - /// Get the length of the previous lexing span. - pub fn lookback_len(&self) -> usize { - if let Some(lookback) = &self.lookback { - return lookback.span.end - lookback.span.start } - 0 } - /// Checks the previous token kind against the input. - pub fn checked_lookback(&self, kind: TokenKind) -> bool { - self.lookback.clone().and_then(|t| if t.kind == kind { Some(true) } else { None }).is_some() + /// Consumes the next character + pub fn consume(&mut self) -> Option { + // self.chars.next().map(|x| { + // self.position += 1; + // x + // }) + + let (c, index) = self.chars.next()?; + self.position = index; + Some(c) } /// Try to peek at the next character from the source pub fn peek(&mut self) -> Option { - self.chars.peek().copied() - } - - /// Dynamically peeks characters based on the filter - pub fn dyn_peek(&mut self, f: impl Fn(&char) -> bool + Copy) -> String { - let mut chars: Vec = Vec::new(); - let mut current_pos = self.current_span().start; - while self.nth_peek(current_pos).map(|x| f(&x)).unwrap_or(false) { - chars.push(self.nth_peek(current_pos).unwrap()); - current_pos += 1; - } - chars.iter().collect() - } - - /// Dynamically peeks until with last chec and checks - pub fn checked_lookforward(&mut self, ch: char) -> bool { - let mut current_pos = self.current_span().end; - while self.nth_peek(current_pos).map(|c| c.is_ascii_whitespace()).unwrap_or(false) { - current_pos += 1; - } - self.nth_peek(current_pos).map(|x| x == ch).unwrap_or(false) - } - - /// Try to peek at the nth character from the source - pub fn nth_peek(&mut self, n: usize) -> Option { - self.reference_chars.clone().nth(n) - } - - /// Try to peek at next n characters from the source - pub fn peek_n_chars(&mut self, n: usize) -> String { - let cur_span: Ref = self.current_span(); - // Break with an empty string if the bounds are exceeded - if cur_span.end + n > self.source.source.len() { - return String::default() - } - self.source.source[cur_span.start..cur_span.end + n].to_string() - } - - /// Peek n chars from a given start point in the source - pub fn peek_n_chars_from(&mut self, n: usize, from: usize) -> String { - self.source.source[Span::new(from..(from + n), None).range().unwrap()].to_string() - } - - /// Gets the current slice of the source code covered by span - pub fn slice(&self) -> String { - self.source.source[self.current_span().range().unwrap()].to_string() - } - - /// Consumes the characters - pub fn consume(&mut self) -> Option { - self.chars.next().map(|x| { - self.current_span_mut().end += 1; - self.position += 1; - x - }) - } - - /// Consumes n characters - pub fn nconsume(&mut self, count: usize) { - for _ in 0..count { - let _ = self.consume(); - } + //self.chars.peek().copied() + self.chars.peek().map(|(c, _) | *c) } /// Consume characters until a sequence matches - pub fn seq_consume(&mut self, word: &str) { - let mut current_pos = self.current_span().start; - while self.peek().is_some() { - let peeked = self.peek_n_chars_from(word.len(), current_pos); - if word == peeked { - break - } - self.consume(); - current_pos += 1; - } - } - + // pub fn seq_consume(&mut self, word: &str) { + // let mut current_pos = self.current_span().start; + // while self.peek().is_some() { + // let peeked = self.peek_n_chars_from(word.len(), current_pos); + // if word == peeked { + // break + // } + // self.consume(); + // current_pos += 1; + // } + // } + /// Dynamically consumes characters based on filters pub fn dyn_consume(&mut self, f: impl Fn(&char) -> bool + Copy) { while self.peek().map(|x| f(&x)).unwrap_or(false) { @@ -263,132 +99,105 @@ impl<'a> Lexer<'a> { } } - /// Resets the Lexer's span - /// - /// Only sets the previous span if the current token is not a whitespace. - pub fn reset(&mut self) { - let mut exclusive_span = self.current_span_mut(); - exclusive_span.start = exclusive_span.end; - } - - /// Check if a given keyword follows the keyword rules in the `source`. If not, it is a - /// `TokenKind::Ident`. - /// - /// Rules: - /// - The `macro`, `fn`, `test`, `function`, `constant`, `event`, `jumptable`, - /// `jumptable__packed`, and `table` keywords must be preceded by a `#define` keyword. - /// - The `takes` keyword must be preceded by an assignment operator: `=`. - /// - The `nonpayable`, `payable`, `view`, and `pure` keywords must be preceeded by one of these - /// keywords or a close paren. - /// - The `returns` keyword must be succeeded by an open parenthesis and must *not* be succeeded - /// by a colon or preceded by the keyword `function` - pub fn check_keyword_rules(&mut self, found_kind: &Option) -> bool { - match found_kind { - Some(TokenKind::Macro) | - Some(TokenKind::Fn) | - Some(TokenKind::Test) | - Some(TokenKind::Function) | - Some(TokenKind::Constant) | - Some(TokenKind::Error) | - Some(TokenKind::Event) | - Some(TokenKind::JumpTable) | - Some(TokenKind::JumpTablePacked) | - Some(TokenKind::CodeTable) => self.checked_lookback(TokenKind::Define), - Some(TokenKind::NonPayable) | - Some(TokenKind::Payable) | - Some(TokenKind::View) | - Some(TokenKind::Pure) => { - let keys = [ - TokenKind::NonPayable, - TokenKind::Payable, - TokenKind::View, - TokenKind::Pure, - TokenKind::CloseParen, - ]; - for key in keys { - if self.checked_lookback(key) { - return true - } - } - false - } - Some(TokenKind::Takes) => self.checked_lookback(TokenKind::Assign), - Some(TokenKind::Returns) => { - let cur_span_end = self.current_span().end; - // Allow for loose and tight syntax (e.g. `returns (0)`, `returns(0)`, ...) - self.checked_lookforward('(') && - !self.checked_lookback(TokenKind::Function) && - self.peek_n_chars_from(1, cur_span_end) != ":" - } - _ => true, - } - } -} - -impl<'a> Iterator for Lexer<'a> { - type Item = Result; - - /// Iterates over the source code - fn next(&mut self) -> Option { - self.reset(); + fn next_token(&mut self) -> TokenResult { + // let start = self.position; if let Some(ch) = self.consume() { - let kind = match ch { - // Comments + let token = match ch { '/' => { + let mut comment_string = String::new(); + let start = self.position; + comment_string.push(ch); if let Some(ch2) = self.peek() { match ch2 { '/' => { - self.consume(); // Consume until newline - self.dyn_consume(|c| *c != '\n'); - TokenKind::Comment(self.slice()) + comment_string.push(ch2); + let (comment_string, start, end) = self.eat_while(Some(ch), |c| c != '\n'); + Ok(TokenKind::Comment(comment_string).into_span(start, end)) } '*' => { - self.consume(); - // Consume until next '*/' occurance - self.seq_consume("*/"); - TokenKind::Comment(self.slice()) + // ref: https://github.com/rust-lang/rust/blob/900c3540378c8422b8087ffa3db60fa6c8abfcad/compiler/rustc_lexer/src/lib.rs#L474 + let c = self.consume(); + comment_string.push(c.unwrap()); + let mut depth = 1usize; + while let Some(c) = self.consume() { + match c { + '/' if self.peek() == Some('*') => { + comment_string.push(c); + let c2 = self.consume(); + comment_string.push(c2.unwrap()); + depth += 1; + } + '*' if self.peek() == Some('/') => { + comment_string.push(c); + let c2 = self.consume(); + comment_string.push(c2.unwrap()); + depth -= 1; + if depth == 0 { + // This block comment is closed, so for a construction like "/* */ */" + // there will be a successfully parsed block comment "/* */" + // and " */" will be processed separately. + + break; + } + } + _ => { + comment_string.push(c); + }, + + } + } + + Ok(TokenKind::Comment(comment_string).into_span(start, self.position)) + // TODO add string or just not store comments + // self.single_char_token(TokenKind::Comment("".to_owned())) } - _ => TokenKind::Div, + _ => self.single_char_token(TokenKind::Div) } - } else { - TokenKind::Div + } + else { + self.single_char_token(TokenKind::Div) } } + // # keywords '#' => { + let (word, start, end) = self.eat_while(Some(ch), |ch| { + ch.is_ascii_alphabetic() + }); + let mut found_kind: Option = None; let keys = [TokenKind::Define, TokenKind::Include]; for kind in keys.into_iter() { let key = kind.to_string(); - let token_length = key.len() - 1; - let peeked = self.peek_n_chars(token_length); - + let peeked = word.clone(); if key == peeked { - self.nconsume(token_length); found_kind = Some(kind); break } } if let Some(kind) = &found_kind { - kind.clone() - } else if self.context == Context::Global && &self.peek_n_chars(1) == "#[" { - TokenKind::Pound + Ok(kind.clone().into_span(start, end)) + } else if self.context == Context::Global && self.peek().unwrap() == '[' { + Ok(TokenKind::Pound.into_single_span(self.position)) } else { // Otherwise we don't support # prefixed indentifiers tracing::error!(target: "lexer", "INVALID '#' CHARACTER USAGE"); - return Some(Err(LexicalError::new( + return Err(LexicalError::new( LexicalErrorKind::InvalidCharacter('#'), - self.current_span().clone(), - ))) + Span { start: self.position as usize, end: self.position as usize, file: None }, + )) } } // Alphabetical characters ch if ch.is_alphabetic() || ch.eq(&'_') => { - let mut found_kind: Option = None; + let (word, start, mut end) = self.eat_while(Some(ch), |c| { + c.is_alphanumeric() || c == '_' + }); + let mut found_kind: Option = None; let keys = [ TokenKind::Macro, TokenKind::Fn, @@ -415,11 +224,9 @@ impl<'a> Iterator for Lexer<'a> { break } let key = kind.to_string(); - let token_length = key.len() - 1; - let peeked = self.peek_n_chars(token_length); + let peeked = word.clone(); if key == peeked { - self.nconsume(token_length); found_kind = Some(kind); break } @@ -448,10 +255,7 @@ impl<'a> Iterator for Lexer<'a> { // Check for free storage pointer builtin let fsp = "FREE_STORAGE_POINTER"; - let token_length = fsp.len() - 1; - let peeked = self.peek_n_chars(token_length); - if fsp == peeked { - self.nconsume(token_length); + if fsp == word { // Consume the parenthesis following the FREE_STORAGE_POINTER // Note: This will consume `FREE_STORAGE_POINTER)` or // `FREE_STORAGE_POINTER(` as well @@ -461,57 +265,39 @@ impl<'a> Iterator for Lexer<'a> { if let Some(')') = self.peek() { self.consume(); } + end = end + 2; found_kind = Some(TokenKind::FreeStoragePointer); } - let potential_label: String = - self.dyn_peek(|c| c.is_alphanumeric() || c == &'_' || c == &':'); - if let true = potential_label.ends_with(':') { - self.dyn_consume(|c| c.is_alphanumeric() || c == &'_'); - let label = self.slice(); - if let Some(l) = label.get(0..label.len()) { - found_kind = Some(TokenKind::Label(l.to_string())); - } else { - tracing::error!(target: "lexer", "[huff_lexer] Fatal Label Colon Truncation!"); - } + if let Some(':') = self.peek() { + found_kind = Some(TokenKind::Label(word.clone())); } - let pot_op = self.dyn_peek(|c| c.is_alphanumeric() || c == &'_'); - // Syntax sugar: true evaluates to 0x01, false evaluates to 0x00 - if matches!(pot_op.as_str(), "true" | "false") { + if matches!(word.as_str(), "true" | "false") { found_kind = Some(TokenKind::Literal(str_to_bytes32( - if pot_op.as_str() == "true" { "1" } else { "0" }, + if word.as_str() == "true" { "1" } else { "0" }, ))); - self.dyn_consume(|c| c.is_alphabetic()); + self.eat_while(None, |c| { + c.is_alphanumeric() + }); } - // goes over all opcodes - for opcode in OPCODES { - if self.context != Context::MacroBody || found_kind.is_some() { - break - } - if opcode == pot_op { - self.dyn_consume(|c| c.is_alphanumeric()); - if let Some(o) = OPCODES_MAP.get(opcode) { - found_kind = Some(TokenKind::Opcode(o.to_owned())); - } else { - tracing::error!(target: "lexer", "[huff_lexer] Fatal Opcode Mapping!"); - } - break + if !(self.context != Context::MacroBody || found_kind.is_some()) { + if let Some(o) = OPCODES_MAP.get(&word.clone()) { + found_kind = Some(TokenKind::Opcode(o.to_owned())); } } - - // Last case ; we are in ABI context and - // we are parsing an EVM type + if self.context == Context::AbiArgs { - let curr_char = self.peek()?; + let curr_char = self.peek().unwrap(); if !['(', ')'].contains(&curr_char) { - self.dyn_consume(|c| c.is_alphanumeric() || *c == '[' || *c == ']'); - // got a type at this point, we have to know which - let raw_type: String = self.slice(); + let (partial_raw_type, _, abi_args_end) = self + .eat_while(Some(ch), |c| { + c.is_alphanumeric() || c == '[' || c == ']' + }); + let raw_type = word.clone() + &partial_raw_type[1..]; - // Check if calldata, memory, or storage if raw_type == TokenKind::Calldata.to_string() { found_kind = Some(TokenKind::Calldata); } else if raw_type == TokenKind::Memory.to_string() { @@ -540,7 +326,7 @@ impl<'a> Iterator for Lexer<'a> { kind: LexicalErrorKind::InvalidArraySize( words[1].clone(), ), - span: self.current_span().clone(), + span: Span { start: start as usize, end: end as usize, file: None }, }; tracing::error!(target: "lexer", "{}", format!("{err:?}")); err @@ -555,66 +341,64 @@ impl<'a> Iterator for Lexer<'a> { found_kind = Some(TokenKind::ArrayType(primitive, size_vec)); } else { let err = LexicalError { - kind: LexicalErrorKind::InvalidPrimitiveType(words[0].clone()), - span: self.current_span().clone(), + kind: LexicalErrorKind::InvalidPrimitiveType( + words[0].clone(), + ), + span: Span { + start: start as usize, + end: end as usize, + file: None, + }, }; tracing::error!(target: "lexer", "{}", format!("{err:?}")); } } else { // We don't want to consider any argument names or the "indexed" // keyword here. - let primitive = PrimitiveEVMType::try_from(raw_type); + let primitive = PrimitiveEVMType::try_from(word.clone()); if let Ok(primitive) = primitive { found_kind = Some(TokenKind::PrimitiveType(primitive)); } } + end = abi_args_end; + } else { + // We don't want to consider any argument names or the "indexed" + // keyword here. + let primitive = PrimitiveEVMType::try_from(word.clone()); + if let Ok(primitive) = primitive { + found_kind = Some(TokenKind::PrimitiveType(primitive)); + } } } - if let Some(kind) = &found_kind { + let kind = if let Some(kind) = &found_kind { kind.clone() } else { - self.dyn_consume(|c| c.is_alphanumeric() || c.eq(&'_')); - - let slice = self.slice(); - // Check for built-in function calls - if self.context == Context::MacroBody && - BuiltinFunctionKind::try_from(&slice).is_ok() + let kind = if self.context == Context::MacroBody + && BuiltinFunctionKind::try_from(&word).is_ok() { - TokenKind::BuiltinFunction(slice) + TokenKind::BuiltinFunction(word) } else { - TokenKind::Ident(slice) - } - } + TokenKind::Ident(word) + }; + + kind + }; + + Ok(kind.into_span(start, end)) } // If it's the start of a hex literal ch if ch == '0' && self.peek().unwrap() == 'x' => { - self.consume(); // Consume the 'x' after '0' (separated from the `dyn_consume` so we don't have - // to match `x` in the actual hex) - self.dyn_consume(|c| { - c.is_numeric() || - // Match a-f & A-F - matches!(c, '\u{0041}'..='\u{0046}' | '\u{0061}'..='\u{0066}') - }); - self.current_span_mut().start += 2; // Ignore the "0x" - - if self.context == Context::CodeTableBody { - // In codetables, the bytecode provided is of arbitrary length. We pass - // the code as an Ident, and it is appended to the end of the runtime - // bytecode in codegen. - TokenKind::Ident(self.slice()) - } else { - TokenKind::Literal(str_to_bytes32(self.slice().as_ref())) - } + self.eat_hex_digit(ch) } - '=' => TokenKind::Assign, + '=' => self.single_char_token(TokenKind::Assign), '(' => { match self.context { Context::Abi => self.context = Context::AbiArgs, Context::MacroBody => self.context = Context::MacroArgs, _ => {} } - TokenKind::OpenParen + self.single_char_token(TokenKind::OpenParen) } ')' => { match self.context { @@ -622,130 +406,295 @@ impl<'a> Iterator for Lexer<'a> { Context::MacroArgs => self.context = Context::MacroBody, _ => {} } - TokenKind::CloseParen + self.single_char_token(TokenKind::CloseParen) } - '[' => TokenKind::OpenBracket, - ']' => TokenKind::CloseBracket, + '[' => self.single_char_token(TokenKind::OpenBracket), + ']' => self.single_char_token(TokenKind::CloseBracket), '{' => { if self.context == Context::MacroDefinition { self.context = Context::MacroBody; } - TokenKind::OpenBrace + self.single_char_token(TokenKind::OpenBrace) } '}' => { if matches!(self.context, Context::MacroBody | Context::CodeTableBody) { self.context = Context::Global; } - TokenKind::CloseBrace + self.single_char_token(TokenKind::CloseBrace) } - '+' => TokenKind::Add, - '-' => TokenKind::Sub, - '*' => TokenKind::Mul, - '<' => TokenKind::LeftAngle, - '>' => TokenKind::RightAngle, + '+' => self.single_char_token(TokenKind::Add), + '-' => self.single_char_token(TokenKind::Sub), + '*' => self.single_char_token(TokenKind::Mul), + '<' => self.single_char_token(TokenKind::LeftAngle), + '>' => self.single_char_token(TokenKind::RightAngle), // NOTE: TokenKind::Div is lexed further up since it overlaps with comment - ':' => TokenKind::Colon, + ':' => self.single_char_token(TokenKind::Colon), // identifiers - ',' => TokenKind::Comma, - '0'..='9' => { - self.dyn_consume(char::is_ascii_digit); - TokenKind::Num(self.slice().parse().unwrap()) - } + ',' => self.single_char_token(TokenKind::Comma), + '0'..='9' => self.eat_digit(ch), // Lexes Spaces and Newlines as Whitespace ch if ch.is_ascii_whitespace() => { - self.dyn_consume(char::is_ascii_whitespace); - TokenKind::Whitespace + let (_, start, end) = self.eat_whitespace(); + Ok(TokenKind::Whitespace.into_span(start, end)) + } + // String literals. String literals can also be wrapped by single quotes + '"' | '\'' => { + Ok(self.eat_string_literal()) } - // String literals - '"' => loop { - match self.peek() { - Some('"') => { - self.consume(); - let str = self.slice(); - break TokenKind::Str((str[1..str.len() - 1]).to_string()) - } - Some('\\') if matches!(self.nth_peek(1), Some('\\') | Some('"')) => { - self.consume(); - } - Some(_) => {} - None => { - self.eof = true; - tracing::error!(target: "lexer", "UNEXPECTED EOF SPAN"); - return Some(Err(LexicalError::new( - LexicalErrorKind::UnexpectedEof, - self.current_span().clone(), - ))) - } - } - self.consume(); - }, - // Allow string literals to be wrapped by single quotes - '\'' => loop { - match self.peek() { - Some('\'') => { - self.consume(); - let str = self.slice(); - break TokenKind::Str((str[1..str.len() - 1]).to_string()) - } - Some('\\') if matches!(self.nth_peek(1), Some('\\') | Some('\'')) => { - self.consume(); - } - Some(_) => {} - None => { - self.eof = true; - tracing::error!(target: "lexer", "UNEXPECTED EOF SPAN"); - return Some(Err(LexicalError::new( - LexicalErrorKind::UnexpectedEof, - self.current_span().clone(), - ))) - } - } - self.consume(); - }, - // At this point, the source code has an invalid or unsupported token ch => { tracing::error!(target: "lexer", "UNSUPPORTED TOKEN '{}'", ch); - return Some(Err(LexicalError::new( + return Err(LexicalError::new( LexicalErrorKind::InvalidCharacter(ch), - self.current_span().clone(), - ))) + Span { start: self.position as usize, end: self.position as usize, file: None }, + )) } - }; - - if self.peek().is_none() { - self.eof = true; - } + }?; - // Produce a relative span - let new_span = match self.source.relative_span(self.current_span()) { - Some(s) => s, - None => { - tracing::warn!(target: "lexer", "UNABLE TO RELATIVIZE SPAN FOR \"{}\"", kind); - tracing::warn!(target: "lexer", "Current Span: {:?}", self.current_span()); - self.current_span().clone() - } - }; - let token = Token { kind, span: new_span }; if token.kind != TokenKind::Whitespace { self.lookback = Some(token.clone()); } - return Some(Ok(token)) + return Ok(token) + } else { + self.eof = true; + Ok(Token { kind: TokenKind::Eof, span: Span { start: self.position as usize, end: self.position as usize, file: None } } ) } + } - // Mark EOF - self.eof = true; + fn single_char_token(&self, token_kind: TokenKind) -> TokenResult { + Ok(token_kind.into_single_span(self.position)) + } + + /// Keeps consuming tokens as long as the predicate is satisfied + fn eat_while bool>( + &mut self, + initial_char: Option, + predicate: F, + ) -> (String, u32, u32) { + let start = self.position; + + // This function is only called when we want to continue consuming a character of the same type. + // For example, we see a digit and we want to consume the whole integer + // Therefore, the current character which triggered this function will need to be appended + let mut word = String::new(); + if let Some(init_char) = initial_char { + word.push(init_char) + } - // If we haven't returned an eof token, return one - if !self.eof_returned { - self.eof_returned = true; - let token = Token { kind: TokenKind::Eof, span: self.current_span().clone() }; - if token.kind != TokenKind::Whitespace { - self.lookback = Some(token.clone()); + // Keep checking that we are not at the EOF + while let Some(peek_char) = self.peek() { + // Then check for the predicate, if predicate matches append char and increment the cursor + // If not, return word. The next character will be analyzed on the next iteration of next_token, + // Which will increment the cursor + if !predicate(peek_char) { + return (word, start, self.position); } - return Some(Ok(token)) + word.push(peek_char); + + // If we arrive at this point, then the char has been added to the word and we should increment the cursor + self.consume(); } - None + (word, start, self.position) + } + + + fn eat_digit(&mut self, initial_char: char) -> TokenResult { + let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { + ch.is_ascii_digit() + }); + + let integer = integer_str.parse().unwrap(); + + let integer_token = TokenKind::Num(integer); + let span = Span { start: start as usize, end: end as usize, file: None }; + Ok(Token { kind: integer_token, span }) + } + + fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult { + let (integer_str, mut start, end) = self.eat_while(Some(initial_char), |ch| { + ch.is_ascii_hexdigit() | (ch == 'x') + }); + // TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34 + + let kind = if self.context == Context::CodeTableBody { + // In codetables, the bytecode provided is of arbitrary length. We pass + // the code as an Ident, and it is appended to the end of the runtime + // bytecode in codegen. + if &integer_str[0..2] == "0x" { + TokenKind::Ident(integer_str[2..].to_owned()) + } else { + TokenKind::Ident(integer_str) + } + } else { + + TokenKind::Literal(str_to_bytes32(&integer_str[2..].as_ref())) + }; + + start = start + 2; + let span = Span { start: start as usize, end: end as usize, file: None }; + Ok(Token { kind, span }) + } + + /// Skips white space. They are not significant in the source language + fn eat_whitespace(&mut self) -> (String, u32, u32) { + self.eat_while(None, |ch| ch.is_whitespace()) + } + + fn eat_string_literal(&mut self) -> Token { + let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"' && ch != '\''); + let str_literal_token = TokenKind::Str(str_literal); + self.consume(); // Advance past the closing quote + str_literal_token.into_span(start_span, end_span + 1) + } + + // fn eat_alphabetic(&mut self, initial_char: char) -> (String, u32, u32) { + // let (word, start, end) = self.eat_while(Some(initial_char), |ch| { + // ch.is_ascii_alphabetic() + // }); + // (word, start, end) + // } + + /// Checks the previous token kind against the input. + pub fn checked_lookback(&self, kind: TokenKind) -> bool { + self.lookback.clone().and_then(|t| if t.kind == kind { Some(true) } else { None }).is_some() } + + /// Check if a given keyword follows the keyword rules in the `source`. If not, it is a + /// `TokenKind::Ident`. + /// + /// Rules: + /// - The `macro`, `fn`, `test`, `function`, `constant`, `event`, `jumptable`, + /// `jumptable__packed`, and `table` keywords must be preceded by a `#define` keyword. + /// - The `takes` keyword must be preceded by an assignment operator: `=`. + /// - The `nonpayable`, `payable`, `view`, and `pure` keywords must be preceeded by one of these + /// keywords or a close paren. + /// - The `returns` keyword must be succeeded by an open parenthesis and must *not* be succeeded + /// by a colon or preceded by the keyword `function` + pub fn check_keyword_rules(&mut self, found_kind: &Option) -> bool { + match found_kind { + Some(TokenKind::Macro) | + Some(TokenKind::Fn) | + Some(TokenKind::Test) | + Some(TokenKind::Function) | + Some(TokenKind::Constant) | + Some(TokenKind::Error) | + Some(TokenKind::Event) | + Some(TokenKind::JumpTable) | + Some(TokenKind::JumpTablePacked) | + Some(TokenKind::CodeTable) => self.checked_lookback(TokenKind::Define), + Some(TokenKind::NonPayable) | + Some(TokenKind::Payable) | + Some(TokenKind::View) | + Some(TokenKind::Pure) => { + let keys = [ + TokenKind::NonPayable, + TokenKind::Payable, + TokenKind::View, + TokenKind::Pure, + TokenKind::CloseParen, + ]; + for key in keys { + if self.checked_lookback(key) { + return true + } + } + false + } + Some(TokenKind::Takes) => self.checked_lookback(TokenKind::Assign), + Some(TokenKind::Returns) => { + self.eat_whitespace(); + // Allow for loose and tight syntax (e.g. `returns (0)`, `returns(0)`, ...) + self.peek().unwrap_or(')') == '(' && + !self.checked_lookback(TokenKind::Function) + } + _ => true, + } + } + + /// Lex all imports + /// Example import: `// #include "./Utils.huff"` + pub fn lex_imports(source: &str) -> Vec { + let mut imports = vec![]; + let mut peekable_source = source.chars().peekable(); + let mut include_chars_iterator = "#include".chars().peekable(); + while peekable_source.peek().is_some() { + while let Some(nc) = peekable_source.next() { + if nc.eq(&'/') { + if let Some(nnc) = peekable_source.peek() { + if nnc.eq(&'/') { + // Iterate until newline + while let Some(lc) = &peekable_source.next() { + if lc.eq(&'\n') { + break + } + } + } else if nnc.eq(&'*') { + // Iterate until '*/' + while let Some(lc) = peekable_source.next() { + if lc.eq(&'*') { + if let Some(llc) = peekable_source.peek() { + if *llc == '/' { + break + } + } + } + } + } + } + } + if include_chars_iterator.peek().is_none() { + // Reset the include chars iterator + include_chars_iterator = "#include".chars().peekable(); + + // Skip over whitespace + while peekable_source.peek().is_some() { + if !peekable_source.peek().unwrap().is_whitespace() { + break + } else { + peekable_source.next(); + } + } + + // Then we should have an import path between quotes + if let Some(char) = peekable_source.peek() { + match char { + '"' | '\'' => { + peekable_source.next(); + let mut import = String::new(); + while peekable_source.peek().is_some() { + if let Some(c) = peekable_source.next() { + if matches!(c, '"' | '\'') { + imports.push(import); + break + } else { + import.push(c); + } + } + } + } + _ => { /* Ignore non-include tokens */ } + } + } + } else if nc.ne(&include_chars_iterator.next().unwrap()) { + include_chars_iterator = "#include".chars().peekable(); + break + } + } + } + imports + } + } + +impl<'a> Iterator for Lexer<'a> { + type Item = TokenResult; + + fn next(&mut self) -> Option { + if self.eof { + None + } else { + Some(self.next_token()) + } + } +} \ No newline at end of file diff --git a/huff_lexer/tests/arg_calls.rs b/huff_lexer/tests/arg_calls.rs index 91cf0eae..b880b511 100644 --- a/huff_lexer/tests/arg_calls.rs +++ b/huff_lexer/tests/arg_calls.rs @@ -17,7 +17,7 @@ fn lexes_arg_calls() { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; // Parse tokens - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Eat Tokens let _ = lexer.next(); // Whitespace diff --git a/huff_lexer/tests/builtins.rs b/huff_lexer/tests/builtins.rs index 33906b04..3cff23d2 100644 --- a/huff_lexer/tests/builtins.rs +++ b/huff_lexer/tests/builtins.rs @@ -25,7 +25,7 @@ fn parses_builtin_function_in_macro_body() { "{", "}", ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); let _ = lexer.next(); // whitespace let _ = lexer.next(); // #define @@ -90,7 +90,7 @@ fn fails_to_parse_builtin_outside_macro_body() { for builtin in builtin_funcs { let source = &format!("{builtin}(MAIN)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); @@ -124,7 +124,7 @@ fn fails_to_parse_invalid_builtin() { "{", "}", ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); let _ = lexer.next(); // whitespace let _ = lexer.next(); // #define diff --git a/huff_lexer/tests/comments.rs b/huff_lexer/tests/comments.rs index 64b0367b..94ccb5ca 100644 --- a/huff_lexer/tests/comments.rs +++ b/huff_lexer/tests/comments.rs @@ -15,7 +15,7 @@ use std::ops::Deref; fn instantiates() { let source = "#define macro HELLO_WORLD()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); assert!(!lexer.eof); } @@ -23,7 +23,7 @@ fn instantiates() { fn single_line_comments() { let source = "// comment contents \n#define macro HELLO_WORLD()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); // The first token should be a single line comment let tok = lexer.next(); @@ -98,7 +98,7 @@ fn single_line_comments() { fn multi_line_comments() { let source = "/* comment contents*/#define macro HELLO_WORLD()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); // The first token should be a single line comment let tok = lexer.next(); diff --git a/huff_lexer/tests/context.rs b/huff_lexer/tests/context.rs index e72f3fa1..28874359 100644 --- a/huff_lexer/tests/context.rs +++ b/huff_lexer/tests/context.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn function_context() { let source = "#define function test(bytes32) {} returns (address)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -26,7 +26,7 @@ fn function_context() { fn event_context() { let source = "#define event Transfer(bytes32,address)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -44,7 +44,7 @@ fn event_context() { fn macro_context() { let source = "#define macro TEST() = takes (0) returns (0) {byte}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_lexer/tests/decorators.rs b/huff_lexer/tests/decorators.rs index e2b8c94d..1bc1d7e5 100644 --- a/huff_lexer/tests/decorators.rs +++ b/huff_lexer/tests/decorators.rs @@ -18,7 +18,7 @@ fn parses_decorator() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); let _ = lexer.next(); // whitespace @@ -126,7 +126,7 @@ fn fails_to_parse_decorator_in_body() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); for token in lexer.by_ref() { if let Err(e) = token { diff --git a/huff_lexer/tests/eof.rs b/huff_lexer/tests/eof.rs index 17826ea6..db76f82e 100644 --- a/huff_lexer/tests/eof.rs +++ b/huff_lexer/tests/eof.rs @@ -6,7 +6,7 @@ use std::ops::Deref; fn end_of_file() { let source = " "; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); // Eats the whitespace let _ = lexer.next(); diff --git a/huff_lexer/tests/evm_types.rs b/huff_lexer/tests/evm_types.rs index fcab1998..0e11054a 100644 --- a/huff_lexer/tests/evm_types.rs +++ b/huff_lexer/tests/evm_types.rs @@ -16,7 +16,7 @@ fn primitive_type_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -42,7 +42,7 @@ fn bounded_array_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -68,7 +68,7 @@ fn unbounded_array_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -93,7 +93,7 @@ fn multidim_array_parsing() { for (evm_type, evm_type_enum) in evm_types { let source = &format!("#define function test({evm_type}) view returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_lexer/tests/fsp.rs b/huff_lexer/tests/fsp.rs index 3506e46b..97a1dc2b 100644 --- a/huff_lexer/tests/fsp.rs +++ b/huff_lexer/tests/fsp.rs @@ -7,7 +7,7 @@ use std::ops::Deref; fn free_storage_pointer() { let source = "FREE_STORAGE_POINTER() "; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); // The first token should be the fsp let tok = lexer.next().unwrap().unwrap(); diff --git a/huff_lexer/tests/function_type.rs b/huff_lexer/tests/function_type.rs index 6e49c017..c012aa7d 100644 --- a/huff_lexer/tests/function_type.rs +++ b/huff_lexer/tests/function_type.rs @@ -14,7 +14,7 @@ fn parses_function_type() { for (fn_type, fn_type_kind) in fn_types { let source = &format!("#define function test() {fn_type} returns (uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace diff --git a/huff_lexer/tests/hex.rs b/huff_lexer/tests/hex.rs index ba072a5f..c6212896 100644 --- a/huff_lexer/tests/hex.rs +++ b/huff_lexer/tests/hex.rs @@ -1,5 +1,5 @@ use huff_lexer::*; -use huff_lexer::lexer::LexerNew; +use huff_lexer::Lexer; use huff_utils::prelude::*; use std::ops::Deref; @@ -7,7 +7,7 @@ use std::ops::Deref; fn parses_single_hex() { let source = "0xa57B"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); // The first and only token should be lexed as Literal(0xa57B) let tok = lexer.next().unwrap().unwrap(); @@ -22,7 +22,7 @@ fn parses_single_hex() { fn parses_bool() { let source = "false true"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); // The first token should be lexed as a Literal representing 0x00 let tok = lexer.next().unwrap().unwrap(); @@ -43,7 +43,7 @@ fn parses_bool() { fn parses_odd_len_hex() { let source = "0x1"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let mut lexer = Lexer::new(flattened_source.source.clone()); // The first and only token should be lexed as Literal(0x1) let tok = lexer.next().unwrap().unwrap(); diff --git a/huff_lexer/tests/imports.rs b/huff_lexer/tests/imports.rs index bf6082bf..a0a51b99 100644 --- a/huff_lexer/tests/imports.rs +++ b/huff_lexer/tests/imports.rs @@ -1,4 +1,4 @@ -use huff_lexer::lexer::LexerNew; +use huff_lexer::Lexer; use huff_utils::prelude::*; use std::ops::Deref; @@ -6,7 +6,7 @@ use std::ops::Deref; fn single_lex_imports() { let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = format!("#include \"{import_str}\""); - let lexed_imports = LexerNew::lex_imports(&source); + let lexed_imports = Lexer::lex_imports(&source); assert_eq!(lexed_imports.len(), 1); assert_eq!(lexed_imports[0], import_str); } @@ -24,7 +24,7 @@ fn commented_lex_imports() { "# ); - let lexed_imports = LexerNew::lex_imports(&source); + let lexed_imports = Lexer::lex_imports(&source); assert_eq!(lexed_imports.len(), 1); assert_eq!(lexed_imports[0], import_str); } @@ -42,7 +42,7 @@ fn multiple_lex_imports() { "# ); - let lexed_imports = LexerNew::lex_imports(&source); + let lexed_imports = Lexer::lex_imports(&source); assert_eq!(lexed_imports.len(), 3); for i in lexed_imports { assert_eq!(i, import_str); @@ -59,7 +59,7 @@ fn multiple_lex_imports_single_quotes() { "# ); - let lexed_imports = LexerNew::lex_imports(&source); + let lexed_imports = Lexer::lex_imports(&source); assert_eq!(lexed_imports.len(), 2); for i in lexed_imports { assert_eq!(i, import_str); @@ -70,7 +70,7 @@ fn multiple_lex_imports_single_quotes() { fn lex_imports_no_ending_quote() { let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = format!("#include '{import_str}"); - let lexed_imports = LexerNew::lex_imports(&source); + let lexed_imports = Lexer::lex_imports(&source); assert_eq!(lexed_imports.len(), 0); } @@ -78,7 +78,7 @@ fn lex_imports_no_ending_quote() { fn lex_imports_no_starting_quote() { let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = format!("#include {import_str}'"); - let lexed_imports = LexerNew::lex_imports(&source); + let lexed_imports = Lexer::lex_imports(&source); assert_eq!(lexed_imports.len(), 0); } @@ -86,7 +86,7 @@ fn lex_imports_no_starting_quote() { fn lex_imports_empty_quotes() { // let import_str = "../huff-examples/erc20/contracts/utils/Ownable.huff"; let source = "#include ''"; - let lexed_imports = LexerNew::lex_imports(source); + let lexed_imports = Lexer::lex_imports(source); assert_eq!(lexed_imports.len(), 1); assert_eq!(lexed_imports[0], ""); } @@ -95,7 +95,7 @@ fn lex_imports_empty_quotes() { fn include_no_quotes() { let source = "#include"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // The first token should be a single line comment let tok = lexer.next(); @@ -109,7 +109,7 @@ fn include_no_quotes() { fn include_with_string() { let source = "#include \"../huff-examples/erc20/contracts/utils/Ownable.huff\""; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // The first token should be a single line comment let tok = lexer.next(); @@ -144,7 +144,7 @@ fn include_with_string() { fn include_with_string_single_quote() { let source = "#include '../huff-examples/erc20/contracts/utils/Ownable.huff'"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // The first token should be a single line comment let tok = lexer.next(); diff --git a/huff_lexer/tests/keywords.rs b/huff_lexer/tests/keywords.rs index 90c9fabd..20db20a1 100644 --- a/huff_lexer/tests/keywords.rs +++ b/huff_lexer/tests/keywords.rs @@ -6,7 +6,7 @@ use std::ops::Deref; fn parses_macro_keyword() { let source = "#define macro"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); @@ -36,7 +36,7 @@ fn parses_macro_keyword() { fn parses_fn_keyword() { let source = "#define fn"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); @@ -66,7 +66,7 @@ fn parses_fn_keyword() { fn parses_test_keyword() { let source = "#define test"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); @@ -96,7 +96,7 @@ fn parses_test_keyword() { fn parses_function_keyword() { let source = "#define function"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); @@ -127,7 +127,7 @@ fn parses_function_keyword() { fn parses_event_keyword() { let source = "#define event TestEvent(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); @@ -163,7 +163,7 @@ fn parses_event_keyword() { fn parses_constant_keyword() { let source = "#define constant"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); @@ -193,7 +193,7 @@ fn parses_constant_keyword() { fn parses_takes_and_returns_keywords() { let source = "#define macro TEST() = takes (0) returns (0)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -240,7 +240,7 @@ fn parses_takes_and_returns_keywords() { fn parses_takes_and_returns_keywords_tight_syntax() { let source = "#define macro TEST() = takes(0) returns(0)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -285,7 +285,7 @@ fn parses_takes_and_returns_keywords_tight_syntax() { fn parses_function_type_keywords() { let source = "#define function test() view returns (uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace @@ -339,7 +339,7 @@ fn parses_function_definition_with_keyword_name() { for s in key_words { let source = &format!("#define function {s}(uint256) view returns(uint256)"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let end_span_s = 17 + s.len(); @@ -411,14 +411,14 @@ fn parses_label_with_keyword_name() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let fn_name_span = Span::new(0..s.len()-1, None); assert_eq!(unwrapped, Token::new(TokenKind::Label(s.to_string()), fn_name_span.clone())); - // let _ = lexer.next(); // colon + let _ = lexer.next(); // colon let _ = lexer.next(); // whitespace let tok = lexer.next(); @@ -461,7 +461,7 @@ fn parses_function_with_keyword_name() { let source = &format!("dup1 0x7c09063f eq {s} jumpi"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let _ = lexer.next(); // dup1 let _ = lexer.next(); // whitespace @@ -518,7 +518,7 @@ fn parses_function_with_keyword_name_in_macro() { ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let _ = lexer.next(); // whitespace let _ = lexer.next(); // #define @@ -598,7 +598,7 @@ fn parses_keyword_arbitrary_whitespace() { let source = &format!("#define {key}"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Define Identifier first let tok = lexer.next(); @@ -629,7 +629,7 @@ fn parses_keyword_arbitrary_whitespace() { fn parses_takes_keyword_arbitrary_whitespace() { let source = "#define macro TEST() = takes (0) returns (0)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let _ = lexer.next(); // #define let _ = lexer.next(); // whitespace diff --git a/huff_lexer/tests/labels.rs b/huff_lexer/tests/labels.rs index 1c7b33d2..07dc8cf8 100644 --- a/huff_lexer/tests/labels.rs +++ b/huff_lexer/tests/labels.rs @@ -6,7 +6,7 @@ fn parse_label() { let source = "#define macro HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add cool_label:\n0x01\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -25,7 +25,7 @@ fn parse_label_with_opcode_name() { let source = "#define macro HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add cool_label_return_swap1_mload:\n0x01\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_lexer/tests/numbers.rs b/huff_lexer/tests/numbers.rs index 202bda40..bf75e5fd 100644 --- a/huff_lexer/tests/numbers.rs +++ b/huff_lexer/tests/numbers.rs @@ -6,7 +6,7 @@ use std::ops::Deref; fn lexes_zero_prefixed_numbers() { let source = "00"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // The first and only token should be lexed as 0 let tok = lexer.next().unwrap().unwrap(); @@ -22,7 +22,7 @@ fn lexes_zero_prefixed_numbers() { fn lexes_large_numbers() { let source = &format!("{}", usize::MAX); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // The first and only token should be lexed let tok = lexer.next().unwrap().unwrap(); diff --git a/huff_lexer/tests/opcodes.rs b/huff_lexer/tests/opcodes.rs index f6836498..ff245a15 100644 --- a/huff_lexer/tests/opcodes.rs +++ b/huff_lexer/tests/opcodes.rs @@ -18,7 +18,7 @@ fn opcodes() { "{", "}", ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() diff --git a/huff_lexer/tests/symbols.rs b/huff_lexer/tests/symbols.rs index 9a207ff0..902756ff 100644 --- a/huff_lexer/tests/symbols.rs +++ b/huff_lexer/tests/symbols.rs @@ -6,7 +6,7 @@ use std::ops::Deref; fn lexes_assign_op() { let source = "#define constant TRANSFER_EVENT_SIGNATURE ="; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // This token should be a Define identifier let tok = lexer.next(); @@ -62,7 +62,7 @@ fn lexes_assign_op() { fn lexes_brackets() { let source = "[TOTAL_SUPPLY_LOCATION] sload"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // This token should be the open bracket let tok = lexer.next(); @@ -105,7 +105,7 @@ fn lexes_braces() { "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Eat the non-brace tokens let _ = lexer.next(); // whitespace @@ -164,7 +164,7 @@ fn lexes_math_ops() { // MATHS let source = r#"100 + 10 - 20 * 5 / 4"#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Eat the number and whitespace let _ = lexer.next(); @@ -222,7 +222,7 @@ fn lexes_math_ops() { fn lexes_commas() { let source = "test,test"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); // Eat alphanumerics let _ = lexer.next(); @@ -244,7 +244,7 @@ fn lexes_commas() { fn lexes_comma_sparse() { let source = "test , test"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let mut lexer = lexer::LexerNew::new(flattened_source.source); + let mut lexer = Lexer::new(flattened_source.source); let _ = lexer.next(); // alphanumerics let _ = lexer.next(); // whitespace diff --git a/huff_lexer/tests/tables.rs b/huff_lexer/tests/tables.rs index 2bcaf38a..feabae28 100644 --- a/huff_lexer/tests/tables.rs +++ b/huff_lexer/tests/tables.rs @@ -5,7 +5,7 @@ use huff_utils::prelude::*; fn parses_jump_table() { let source = "#define jumptable JUMP_TABLE()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -23,7 +23,7 @@ fn parses_jump_table() { fn parses_packed_jump_table() { let source = "#define jumptable__packed JUMP_TABLE_PACKED()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -41,7 +41,7 @@ fn parses_packed_jump_table() { fn parses_code_table() { let source = "#define table CODE_TABLE()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_parser/README.md b/huff_parser/README.md index 0aef91ad..9d8e488a 100644 --- a/huff_parser/README.md +++ b/huff_parser/README.md @@ -24,7 +24,7 @@ use std::sync::{Arc, Mutex}; // Create a Lexer from the source code let source = "#define macro HELLO_WORLD() = takes(0) returns(0) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; -let mut lexer = Lexer::new(flattened_source); +let mut lexer = Lexer::new(flattened_source.source); // Grab the tokens from the lexer let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); @@ -46,7 +46,7 @@ let expected_contract = Contract { statements: vec![], takes: 0, returns: 0, - span: AstSpan(vec![Span { start: 0, end: 7, file: None }, Span { start: 8, end: 13, file: None }, Span { start: 14, end: 25, file: None }, Span { start: 25, end: 26, file: None }, Span { start: 26, end: 27, file: None }, Span { start: 28, end: 29, file: None }, Span { start: 30, end: 35, file: None }, Span { start: 35, end: 36, file: None }, Span { start: 36, end: 37, file: None }, Span { start: 37, end: 38, file: None }, Span { start: 39, end: 46, file: None }, Span { start: 46, end: 47, file: None }, Span { start: 47, end: 48, file: None }, Span { start: 48, end: 49, file: None }, Span { start: 50, end: 51, file: None }, Span { start: 51, end: 52, file: None }]), + span: AstSpan(vec![Span { start: 0, end: 6, file: None }, Span { start: 8, end: 12, file: None }, Span { start: 14, end: 24, file: None }, Span { start: 25, end: 25, file: None }, Span { start: 26, end: 26, file: None }, Span { start: 28, end: 28, file: None }, Span { start: 30, end: 34, file: None }, Span { start: 35, end: 35, file: None }, Span { start: 36, end: 36, file: None }, Span { start: 37, end: 37, file: None }, Span { start: 39, end: 45, file: None }, Span { start: 46, end: 46, file: None }, Span { start: 47, end: 47, file: None }, Span { start: 48, end: 48, file: None }, Span { start: 50, end: 50, file: None }, Span { start: 51, end: 51, file: None }]), outlined: false, test: false, } diff --git a/huff_parser/tests/abi.rs b/huff_parser/tests/abi.rs index 00fff606..d054ce6e 100644 --- a/huff_parser/tests/abi.rs +++ b/huff_parser/tests/abi.rs @@ -7,7 +7,7 @@ fn build_abi_from_ast() { let source = "#define function test(uint256[2][],string) view returns(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source.clone()); + let lexer = Lexer::new(flattened_source.source.clone()); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_parser/tests/breaking_param_invocation.rs b/huff_parser/tests/breaking_param_invocation.rs index e1d429bd..5c2a5179 100644 --- a/huff_parser/tests/breaking_param_invocation.rs +++ b/huff_parser/tests/breaking_param_invocation.rs @@ -19,7 +19,7 @@ fn test_breaking_param_invocation() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -44,7 +44,7 @@ fn test_breaking_param_commas() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_parser/tests/constant.rs b/huff_parser/tests/constant.rs index 81cfd642..e1cb8b75 100644 --- a/huff_parser/tests/constant.rs +++ b/huff_parser/tests/constant.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn test_parses_free_storage_pointer_constant() { let source = "#define constant FSP_LOCATION = FREE_STORAGE_POINTER()"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); @@ -33,7 +33,7 @@ fn test_parses_free_storage_pointer_constant() { fn test_parses_literal_constant() { let source = "#define constant LITERAL = 0x8C5BE1E5EBEC7D5BD14F71427D1E84F3DD0314C0F7B2291E5B200AC8C7C3B925"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); diff --git a/huff_parser/tests/error.rs b/huff_parser/tests/error.rs index dd1ed3b9..e2afa324 100644 --- a/huff_parser/tests/error.rs +++ b/huff_parser/tests/error.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn test_parses_custom_error() { let source = "#define error TestError(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); @@ -42,7 +42,7 @@ fn test_error_sel_no_param() { let source = "#define error NotOwner()"; let full_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(full_source.source); + let lexer = Lexer::new(full_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, Some("".to_string())); let contract = parser.parse().unwrap(); diff --git a/huff_parser/tests/event.rs b/huff_parser/tests/event.rs index ab586bac..72ec5c6f 100644 --- a/huff_parser/tests/event.rs +++ b/huff_parser/tests/event.rs @@ -6,7 +6,7 @@ use huff_utils::{ast::Event, prelude::*}; fn test_prefix_event_arg_names_with_reserved_keywords() { let source: &str = "#define event TestEvent(bytes4 indexed interfaceId, uint256 uintTest, bool stringMe, string boolean)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let expected_tokens: Vec = vec![ Token { kind: TokenKind::Define, span: Span { start: 0, end: 6, file: None } }, @@ -247,7 +247,7 @@ fn test_parse_event() { for (source, expected) in sources { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) diff --git a/huff_parser/tests/function.rs b/huff_parser/tests/function.rs index a3855af9..a5db363f 100644 --- a/huff_parser/tests/function.rs +++ b/huff_parser/tests/function.rs @@ -197,7 +197,7 @@ fn parses_valid_function_definition() { for (index, source) in sources.into_iter().enumerate() { let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() .map(|x| x.unwrap()) @@ -217,7 +217,7 @@ fn parses_valid_function_definition() { fn cannot_parse_invalid_function_definition() { let source = "#define function test(uint256) returns(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); @@ -229,7 +229,7 @@ fn test_functions_with_keyword_arg_names_errors() { // The function parameter's name is a reserved keyword; this should throw an error let source: &str = "#define function myFunc(uint256 uint256) pure returns(uint256)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); @@ -239,7 +239,7 @@ fn test_functions_with_keyword_arg_names_errors() { fn test_functions_with_argument_locations() { let source: &str = "#define function myFunc(string calldata test, uint256[] storage) pure returns(bytes memory)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); @@ -249,7 +249,7 @@ fn test_functions_with_argument_locations() { fn test_can_prefix_function_arg_names_with_reserved_keywords() { let source: &str = "#define function supportsInterface(bytes4 interfaceId) view returns (bool)"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let expected_tokens: Vec = vec![ Token { kind: TokenKind::Define, span: Span { start: 0, end: 6, file: None } }, diff --git a/huff_parser/tests/imports.rs b/huff_parser/tests/imports.rs index 273797df..f6417c0e 100644 --- a/huff_parser/tests/imports.rs +++ b/huff_parser/tests/imports.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::*; fn parses_import() { let source = " /* .,*./. */ #include \"../huff-examples/erc20/contracts/ERC20.huff\""; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); @@ -25,7 +25,7 @@ fn parses_deep_imports() { #include "../huff-examples/erc20/contracts/utils/Ownable.huff" "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let contract = parser.parse().unwrap(); diff --git a/huff_parser/tests/labels.rs b/huff_parser/tests/labels.rs index 5fb57ae5..0ddbe05e 100644 --- a/huff_parser/tests/labels.rs +++ b/huff_parser/tests/labels.rs @@ -14,7 +14,7 @@ fn multiline_labels() { } "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -204,7 +204,7 @@ pub fn builtins_under_labels() { } "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_parser/tests/macro.rs b/huff_parser/tests/macro.rs index 8cc46f22..eb08e74c 100644 --- a/huff_parser/tests/macro.rs +++ b/huff_parser/tests/macro.rs @@ -1,4 +1,4 @@ -use huff_lexer::{*, lexer::LexerNew}; +use huff_lexer::{*, Lexer}; use huff_parser::*; use huff_utils::{evm::Opcode, prelude::*}; use tracing::debug; @@ -7,7 +7,7 @@ use tracing::debug; fn empty_macro() { let source = "#define macro HELLO_WORLD() = takes(0) returns(4) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -49,7 +49,7 @@ fn empty_macro() { fn empty_macro_without_takes_returns() { let source = "#define macro HELLO_WORLD() = {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -83,7 +83,7 @@ fn empty_macro_without_takes_returns() { fn empty_macro_only_takes() { let source = "#define macro HELLO_WORLD() = takes(3) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -97,18 +97,18 @@ fn empty_macro_only_takes() { takes: 3, returns: 0, span: AstSpan(vec![ - Span { start: 0, end: 7, file: None }, - Span { start: 8, end: 13, file: None }, - Span { start: 14, end: 25, file: None }, - Span { start: 25, end: 26, file: None }, - Span { start: 26, end: 27, file: None }, - Span { start: 28, end: 29, file: None }, - Span { start: 30, end: 35, file: None }, - Span { start: 35, end: 36, file: None }, - Span { start: 36, end: 37, file: None }, - Span { start: 37, end: 38, file: None }, - Span { start: 39, end: 40, file: None }, - Span { start: 40, end: 41, file: None }, + Span { start: 0, end: 6, file: None }, + Span { start: 8, end: 12, file: None }, + Span { start: 14, end: 24, file: None }, + Span { start: 25, end: 25, file: None }, + Span { start: 26, end: 26, file: None }, + Span { start: 28, end: 28, file: None }, + Span { start: 30, end: 34, file: None }, + Span { start: 35, end: 35, file: None }, + Span { start: 36, end: 36, file: None }, + Span { start: 37, end: 37, file: None }, + Span { start: 39, end: 39, file: None }, + Span { start: 40, end: 40, file: None }, ]), outlined: false, test: false, @@ -121,7 +121,7 @@ fn empty_macro_only_takes() { fn empty_macro_only_returns() { let source = "#define macro HELLO_WORLD() = returns(10) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -160,7 +160,7 @@ fn macro_with_simple_body() { let source = "#define macro HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -250,7 +250,7 @@ fn macro_with_arg_calls() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -421,8 +421,8 @@ fn macro_labels() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - // let lexer = Lexer::new(flattened_source); - let lexer = lexer::LexerNew::new(flattened_source.source); + // let lexer = Lexer::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -597,7 +597,7 @@ fn macro_invocation_with_arg_call() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -739,7 +739,7 @@ fn test_macro_opcode_arguments() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -809,7 +809,7 @@ fn macro_with_builtin_fn_call() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -877,7 +877,7 @@ fn macro_with_builtin_fn_call() { fn empty_outlined_macro() { let source = "#define fn HELLO_WORLD() = takes(0) returns(4) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -920,7 +920,7 @@ fn empty_outlined_macro() { fn outlined_macro_with_simple_body() { let source = "#define fn HELLO_WORLD() = takes(3) returns(0) {\n0x00 mstore\n 0x01 0x02 add\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -988,7 +988,7 @@ fn outlined_macro_with_simple_body() { fn empty_test() { let source = "#define test HELLO_WORLD() = takes(0) returns(4) {}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -1031,7 +1031,7 @@ fn test_with_simple_body() { let source = "#define test HELLO_WORLD() = takes(3) returns(0) {\n0x00 0x00 mstore\n 0x01 0x02 add\n}"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -1119,7 +1119,7 @@ fn empty_test_with_decorator() { #define test MY_TEST() = takes(0) returns(0) {} "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -1176,7 +1176,7 @@ fn empty_test_with_multi_flag_decorator() { #define test MY_TEST() = takes(0) returns(0) {} "#; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); diff --git a/huff_parser/tests/opcodes.rs b/huff_parser/tests/opcodes.rs index a54d355a..ebe87566 100644 --- a/huff_parser/tests/opcodes.rs +++ b/huff_parser/tests/opcodes.rs @@ -17,7 +17,7 @@ fn not_mistaken_as_opcode() { "# ); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer .into_iter() @@ -51,7 +51,7 @@ fn test_invalid_push_non_literal() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -71,77 +71,76 @@ fn test_push_literals() { // Parse tokens let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); - // let lexer = Lexer::new(flattened_source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let expected_tokens = vec![ - Token { kind: TokenKind::Whitespace, span: Span { start: 0, end: 9, file: None } }, - Token { kind: TokenKind::Define, span: Span { start: 9, end: 16, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 16, end: 17, file: None } }, - Token { kind: TokenKind::Macro, span: Span { start: 17, end: 22, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 22, end: 23, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 0, end: 8, file: None } }, + Token { kind: TokenKind::Define, span: Span { start: 9, end: 15, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 16, end: 16, file: None } }, + Token { kind: TokenKind::Macro, span: Span { start: 17, end: 21, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 22, end: 22, file: None } }, Token { kind: TokenKind::Ident("MAIN".to_string()), - span: Span { start: 23, end: 27, file: None }, + span: Span { start: 23, end: 26, file: None }, }, - Token { kind: TokenKind::OpenParen, span: Span { start: 27, end: 28, file: None } }, - Token { kind: TokenKind::CloseParen, span: Span { start: 28, end: 29, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 29, end: 30, file: None } }, - Token { kind: TokenKind::Assign, span: Span { start: 30, end: 31, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 31, end: 32, file: None } }, - Token { kind: TokenKind::OpenBrace, span: Span { start: 32, end: 33, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 33, end: 46, file: None } }, + Token { kind: TokenKind::OpenParen, span: Span { start: 27, end: 27, file: None } }, + Token { kind: TokenKind::CloseParen, span: Span { start: 28, end: 28, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 29, end: 29, file: None } }, + Token { kind: TokenKind::Assign, span: Span { start: 30, end: 30, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 31, end: 31, file: None } }, + Token { kind: TokenKind::OpenBrace, span: Span { start: 32, end: 32, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 33, end: 45, file: None } }, Token { kind: TokenKind::Opcode(Opcode::Push1), - span: Span { start: 46, end: 51, file: None }, + span: Span { start: 46, end: 50, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 51, end: 52, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 51, end: 51, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, ]), - span: Span { start: 54, end: 56, file: None }, + span: Span { start: 54, end: 55, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 56, end: 69, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 56, end: 68, file: None } }, Token { kind: TokenKind::Opcode(Opcode::Push32), - span: Span { start: 69, end: 75, file: None }, + span: Span { start: 69, end: 74, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 75, end: 76, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 75, end: 75, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, ]), - span: Span { start: 78, end: 81, file: None }, + span: Span { start: 78, end: 80, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 81, end: 94, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 81, end: 93, file: None } }, Token { kind: TokenKind::Opcode(Opcode::Push1), - span: Span { start: 94, end: 99, file: None }, + span: Span { start: 94, end: 98, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 99, end: 100, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 99, end: 99, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, ]), - span: Span { start: 102, end: 104, file: None }, + span: Span { start: 102, end: 103, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 104, end: 105, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 104, end: 104, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, ]), - span: Span { start: 107, end: 109, file: None }, + span: Span { start: 107, end: 108, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 109, end: 118, file: None } }, - Token { kind: TokenKind::CloseBrace, span: Span { start: 118, end: 119, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 119, end: 124, file: None } }, - Token { kind: TokenKind::Eof, span: Span { start: 124, end: 124, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 109, end: 117, file: None } }, + Token { kind: TokenKind::CloseBrace, span: Span { start: 118, end: 118, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 119, end: 123, file: None } }, + Token { kind: TokenKind::Eof, span: Span { start: 123, end: 123, file: None } }, ]; assert_eq!(expected_tokens, tokens); diff --git a/huff_parser/tests/storage_pointer_derivation.rs b/huff_parser/tests/storage_pointer_derivation.rs index c8f1e2d1..3b4a60f9 100644 --- a/huff_parser/tests/storage_pointer_derivation.rs +++ b/huff_parser/tests/storage_pointer_derivation.rs @@ -8,7 +8,7 @@ fn derives_storage_pointers() { "#define constant FSP_LOCATION = FREE_STORAGE_POINTER()\n#define constant FSP_LOCATION_2 = FREE_STORAGE_POINTER()\n#define constant NUM = 0xa57B"; let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); let mut contract = parser.parse().unwrap(); diff --git a/huff_parser/tests/table.rs b/huff_parser/tests/table.rs index ad41a993..fd0b58bd 100644 --- a/huff_parser/tests/table.rs +++ b/huff_parser/tests/table.rs @@ -9,7 +9,7 @@ fn table_with_no_body() { for kind in table_kinds { let source = &format!("#define {kind} TEST_TABLE() = {}{}", "{", "}"); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = lexer::LexerNew::new(flattened_source.source); + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); @@ -54,8 +54,8 @@ fn table_with_body() { let lb2_start = source.find("label_call_2").unwrap_or(0); let lb3_start = source.find("label_call_3").unwrap_or(0); let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - // let lexer = Lexer::new(flattened_source); - let lexer = lexer::LexerNew::new(flattened_source.source); + + let lexer = Lexer::new(flattened_source.source); let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); From 6e79fb25f261b094451a2de4ba87a6552471058e Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 17:49:35 -0700 Subject: [PATCH 34/68] cargo clippy --- huff_lexer/src/lib.rs | 23 +++++++++-------------- huff_tests/src/errors.rs | 2 +- huff_utils/src/error.rs | 8 ++++---- huff_utils/src/token.rs | 3 +++ 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index f9815887..c7183f23 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -265,7 +265,7 @@ impl<'a> Lexer<'a> { if let Some(')') = self.peek() { self.consume(); } - end = end + 2; + end += 2; found_kind = Some(TokenKind::FreeStoragePointer); } @@ -284,7 +284,7 @@ impl<'a> Lexer<'a> { } if !(self.context != Context::MacroBody || found_kind.is_some()) { - if let Some(o) = OPCODES_MAP.get(&word.clone()) { + if let Some(o) = OPCODES_MAP.get(&word) { found_kind = Some(TokenKind::Opcode(o.to_owned())); } } @@ -373,16 +373,11 @@ impl<'a> Lexer<'a> { let kind = if let Some(kind) = &found_kind { kind.clone() + } else if self.context == Context::MacroBody + && BuiltinFunctionKind::try_from(&word).is_ok() { + TokenKind::BuiltinFunction(word) } else { - let kind = if self.context == Context::MacroBody - && BuiltinFunctionKind::try_from(&word).is_ok() - { - TokenKind::BuiltinFunction(word) - } else { - TokenKind::Ident(word) - }; - - kind + TokenKind::Ident(word) }; Ok(kind.into_span(start, end)) @@ -454,7 +449,7 @@ impl<'a> Lexer<'a> { self.lookback = Some(token.clone()); } - return Ok(token) + Ok(token) } else { self.eof = true; Ok(Token { kind: TokenKind::Eof, span: Span { start: self.position as usize, end: self.position as usize, file: None } } ) @@ -528,10 +523,10 @@ impl<'a> Lexer<'a> { } } else { - TokenKind::Literal(str_to_bytes32(&integer_str[2..].as_ref())) + TokenKind::Literal(str_to_bytes32(integer_str[2..].as_ref())) }; - start = start + 2; + start += 2; let span = Span { start: start as usize, end: end as usize, file: None }; Ok(Token { kind, span }) } diff --git a/huff_tests/src/errors.rs b/huff_tests/src/errors.rs index 6491044d..92cb61dc 100644 --- a/huff_tests/src/errors.rs +++ b/huff_tests/src/errors.rs @@ -24,6 +24,6 @@ impl From for RunnerError { /// Convert a `EVMError` to a `RunnerError` impl From> for RunnerError { fn from(e: EVMError) -> Self { - RunnerError(format!("{:?}", e)) + RunnerError(format!("{e:?}")) } } diff --git a/huff_utils/src/error.rs b/huff_utils/src/error.rs index 68f5c397..9ecb2631 100644 --- a/huff_utils/src/error.rs +++ b/huff_utils/src/error.rs @@ -74,7 +74,7 @@ pub struct LexicalError { pub span: Span, } -impl<'a> LexicalError { +impl LexicalError { /// Public associated function to instatiate a new LexicalError. pub fn new(kind: LexicalErrorKind, span: Span) -> Self { Self { kind, span } @@ -95,13 +95,13 @@ pub enum LexicalErrorKind { InvalidPrimitiveType(String), } -impl<'a> Spanned for LexicalError { +impl Spanned for LexicalError { fn span(&self) -> Span { self.span.clone() } } -impl<'a, W: Write> Report for LexicalError { +impl Report for LexicalError { fn report(&self, f: &mut Reporter<'_, W>) -> std::io::Result<()> { match &self.kind { LexicalErrorKind::InvalidCharacter(ch) => write!(f.out, "Invalid character '{ch}'"), @@ -264,7 +264,7 @@ pub enum CompilerError { FailedCompiles(Vec), } -impl<'a> fmt::Display for CompilerError { +impl fmt::Display for CompilerError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { CompilerError::LexicalError(le) => match &le.kind { diff --git a/huff_utils/src/token.rs b/huff_utils/src/token.rs index 5f43e26a..c82fae17 100644 --- a/huff_utils/src/token.rs +++ b/huff_utils/src/token.rs @@ -132,10 +132,13 @@ pub enum TokenKind { } impl TokenKind { + + /// Transform a single char TokenKind into a Token given a single position pub fn into_single_span(self, position: u32) -> Token { self.into_span(position, position) } + /// Transform a TokenKind into a Token given a start and end position pub fn into_span(self, start: u32, end: u32) -> Token { Token { kind: self, span: Span { start: start as usize, end: end as usize, file: None } } } From a2ee3a2a5cc3c9e99907f686824265166c1c5638 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 17:50:09 -0700 Subject: [PATCH 35/68] cargo fmt --- huff_core/src/lib.rs | 15 ++-- huff_lexer/src/lib.rs | 131 ++++++++++++++++-------------- huff_lexer/tests/arg_calls.rs | 6 +- huff_lexer/tests/builtins.rs | 8 +- huff_lexer/tests/comments.rs | 4 +- huff_lexer/tests/decorators.rs | 1 - huff_lexer/tests/function_type.rs | 2 +- huff_lexer/tests/hex.rs | 3 +- huff_lexer/tests/keywords.rs | 12 ++- huff_lexer/tests/numbers.rs | 2 +- huff_parser/tests/macro.rs | 2 +- huff_utils/src/token.rs | 1 - 12 files changed, 96 insertions(+), 91 deletions(-) diff --git a/huff_core/src/lib.rs b/huff_core/src/lib.rs index 84013553..5aeb5eb3 100644 --- a/huff_core/src/lib.rs +++ b/huff_core/src/lib.rs @@ -214,13 +214,12 @@ impl<'a> Compiler<'a> { None => { tracing::debug!(target: "core", "FINISHED RECURSING DEPENDENCIES!"); // Parallel Dependency Resolution - let recursed_file_sources: Vec, Arc>> = - files - .into_par_iter() - .map(|v| { - Self::recurse_deps(v, &Remapper::new("./"), self.file_provider.clone()) - }) - .collect(); + let recursed_file_sources: Vec, Arc>> = files + .into_par_iter() + .map(|v| { + Self::recurse_deps(v, &Remapper::new("./"), self.file_provider.clone()) + }) + .collect(); // Collect Recurse Deps errors and try to resolve to the first one let mut errors = recursed_file_sources @@ -380,7 +379,7 @@ impl<'a> Compiler<'a> { // Perform Lexical Analysis // Create a new lexer from the FileSource, flattening dependencies - let lexer = Lexer::new(full_source.source); + let lexer = Lexer::new(full_source.source); // Grab the tokens from the lexer let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index c7183f23..1edafd5e 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -2,8 +2,8 @@ use huff_utils::prelude::*; use regex::Regex; use std::{ iter::{Peekable, Zip}, - str::Chars, ops::RangeFrom, + str::Chars, }; /* hiehgsebgoiesgoiseg */ /// Defines a context in which the lexing happens. @@ -76,7 +76,7 @@ impl<'a> Lexer<'a> { /// Try to peek at the next character from the source pub fn peek(&mut self) -> Option { //self.chars.peek().copied() - self.chars.peek().map(|(c, _) | *c) + self.chars.peek().map(|(c, _)| *c) } /// Consume characters until a sequence matches @@ -91,7 +91,7 @@ impl<'a> Lexer<'a> { // current_pos += 1; // } // } - + /// Dynamically consumes characters based on filters pub fn dyn_consume(&mut self, f: impl Fn(&char) -> bool + Copy) { while self.peek().map(|x| f(&x)).unwrap_or(false) { @@ -112,7 +112,8 @@ impl<'a> Lexer<'a> { '/' => { // Consume until newline comment_string.push(ch2); - let (comment_string, start, end) = self.eat_while(Some(ch), |c| c != '\n'); + let (comment_string, start, end) = + self.eat_while(Some(ch), |c| c != '\n'); Ok(TokenKind::Comment(comment_string).into_span(start, end)) } '*' => { @@ -134,37 +135,37 @@ impl<'a> Lexer<'a> { comment_string.push(c2.unwrap()); depth -= 1; if depth == 0 { - // This block comment is closed, so for a construction like "/* */ */" - // there will be a successfully parsed block comment "/* */" + // This block comment is closed, so for a + // construction like "/* */ */" + // there will be a successfully parsed block comment + // "/* */" // and " */" will be processed separately. - - break; + + break } } _ => { comment_string.push(c); - }, - + } } } - - Ok(TokenKind::Comment(comment_string).into_span(start, self.position)) + + Ok(TokenKind::Comment(comment_string) + .into_span(start, self.position)) // TODO add string or just not store comments - // self.single_char_token(TokenKind::Comment("".to_owned())) + // self.single_char_token(TokenKind::Comment("".to_owned())) } - _ => self.single_char_token(TokenKind::Div) + _ => self.single_char_token(TokenKind::Div), } - } - else { + } else { self.single_char_token(TokenKind::Div) } } // # keywords '#' => { - let (word, start, end) = self.eat_while(Some(ch), |ch| { - ch.is_ascii_alphabetic() - }); + let (word, start, end) = + self.eat_while(Some(ch), |ch| ch.is_ascii_alphabetic()); let mut found_kind: Option = None; @@ -187,15 +188,18 @@ impl<'a> Lexer<'a> { tracing::error!(target: "lexer", "INVALID '#' CHARACTER USAGE"); return Err(LexicalError::new( LexicalErrorKind::InvalidCharacter('#'), - Span { start: self.position as usize, end: self.position as usize, file: None }, + Span { + start: self.position as usize, + end: self.position as usize, + file: None, + }, )) } } // Alphabetical characters ch if ch.is_alphabetic() || ch.eq(&'_') => { - let (word, start, mut end) = self.eat_while(Some(ch), |c| { - c.is_alphanumeric() || c == '_' - }); + let (word, start, mut end) = + self.eat_while(Some(ch), |c| c.is_alphanumeric() || c == '_'); let mut found_kind: Option = None; let keys = [ @@ -275,12 +279,13 @@ impl<'a> Lexer<'a> { // Syntax sugar: true evaluates to 0x01, false evaluates to 0x00 if matches!(word.as_str(), "true" | "false") { - found_kind = Some(TokenKind::Literal(str_to_bytes32( - if word.as_str() == "true" { "1" } else { "0" }, - ))); - self.eat_while(None, |c| { - c.is_alphanumeric() - }); + found_kind = + Some(TokenKind::Literal(str_to_bytes32(if word.as_str() == "true" { + "1" + } else { + "0" + }))); + self.eat_while(None, |c| c.is_alphanumeric()); } if !(self.context != Context::MacroBody || found_kind.is_some()) { @@ -288,7 +293,7 @@ impl<'a> Lexer<'a> { found_kind = Some(TokenKind::Opcode(o.to_owned())); } } - + if self.context == Context::AbiArgs { let curr_char = self.peek().unwrap(); if !['(', ')'].contains(&curr_char) { @@ -373,8 +378,9 @@ impl<'a> Lexer<'a> { let kind = if let Some(kind) = &found_kind { kind.clone() - } else if self.context == Context::MacroBody - && BuiltinFunctionKind::try_from(&word).is_ok() { + } else if self.context == Context::MacroBody && + BuiltinFunctionKind::try_from(&word).is_ok() + { TokenKind::BuiltinFunction(word) } else { TokenKind::Ident(word) @@ -383,9 +389,7 @@ impl<'a> Lexer<'a> { Ok(kind.into_span(start, end)) } // If it's the start of a hex literal - ch if ch == '0' && self.peek().unwrap() == 'x' => { - self.eat_hex_digit(ch) - } + ch if ch == '0' && self.peek().unwrap() == 'x' => self.eat_hex_digit(ch), '=' => self.single_char_token(TokenKind::Assign), '(' => { match self.context { @@ -433,14 +437,16 @@ impl<'a> Lexer<'a> { Ok(TokenKind::Whitespace.into_span(start, end)) } // String literals. String literals can also be wrapped by single quotes - '"' | '\'' => { - Ok(self.eat_string_literal()) - } + '"' | '\'' => Ok(self.eat_string_literal()), ch => { tracing::error!(target: "lexer", "UNSUPPORTED TOKEN '{}'", ch); return Err(LexicalError::new( LexicalErrorKind::InvalidCharacter(ch), - Span { start: self.position as usize, end: self.position as usize, file: None }, + Span { + start: self.position as usize, + end: self.position as usize, + file: None, + }, )) } }?; @@ -452,14 +458,21 @@ impl<'a> Lexer<'a> { Ok(token) } else { self.eof = true; - Ok(Token { kind: TokenKind::Eof, span: Span { start: self.position as usize, end: self.position as usize, file: None } } ) + Ok(Token { + kind: TokenKind::Eof, + span: Span { + start: self.position as usize, + end: self.position as usize, + file: None, + }, + }) } } fn single_char_token(&self, token_kind: TokenKind) -> TokenResult { Ok(token_kind.into_single_span(self.position)) } - + /// Keeps consuming tokens as long as the predicate is satisfied fn eat_while bool>( &mut self, @@ -468,8 +481,8 @@ impl<'a> Lexer<'a> { ) -> (String, u32, u32) { let start = self.position; - // This function is only called when we want to continue consuming a character of the same type. - // For example, we see a digit and we want to consume the whole integer + // This function is only called when we want to continue consuming a character of the same + // type. For example, we see a digit and we want to consume the whole integer // Therefore, the current character which triggered this function will need to be appended let mut word = String::new(); if let Some(init_char) = initial_char { @@ -478,26 +491,25 @@ impl<'a> Lexer<'a> { // Keep checking that we are not at the EOF while let Some(peek_char) = self.peek() { - // Then check for the predicate, if predicate matches append char and increment the cursor - // If not, return word. The next character will be analyzed on the next iteration of next_token, - // Which will increment the cursor + // Then check for the predicate, if predicate matches append char and increment the + // cursor If not, return word. The next character will be analyzed on the + // next iteration of next_token, Which will increment the cursor if !predicate(peek_char) { - return (word, start, self.position); + return (word, start, self.position) } word.push(peek_char); - // If we arrive at this point, then the char has been added to the word and we should increment the cursor + // If we arrive at this point, then the char has been added to the word and we should + // increment the cursor self.consume(); } (word, start, self.position) } - fn eat_digit(&mut self, initial_char: char) -> TokenResult { - let (integer_str, start, end) = self.eat_while(Some(initial_char), |ch| { - ch.is_ascii_digit() - }); + let (integer_str, start, end) = + self.eat_while(Some(initial_char), |ch| ch.is_ascii_digit()); let integer = integer_str.parse().unwrap(); @@ -507,9 +519,8 @@ impl<'a> Lexer<'a> { } fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult { - let (integer_str, mut start, end) = self.eat_while(Some(initial_char), |ch| { - ch.is_ascii_hexdigit() | (ch == 'x') - }); + let (integer_str, mut start, end) = + self.eat_while(Some(initial_char), |ch| ch.is_ascii_hexdigit() | (ch == 'x')); // TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34 let kind = if self.context == Context::CodeTableBody { @@ -522,7 +533,6 @@ impl<'a> Lexer<'a> { TokenKind::Ident(integer_str) } } else { - TokenKind::Literal(str_to_bytes32(integer_str[2..].as_ref())) }; @@ -537,7 +547,8 @@ impl<'a> Lexer<'a> { } fn eat_string_literal(&mut self) -> Token { - let (str_literal, start_span, end_span) = self.eat_while(None, |ch| ch != '"' && ch != '\''); + let (str_literal, start_span, end_span) = + self.eat_while(None, |ch| ch != '"' && ch != '\''); let str_literal_token = TokenKind::Str(str_literal); self.consume(); // Advance past the closing quote str_literal_token.into_span(start_span, end_span + 1) @@ -600,8 +611,7 @@ impl<'a> Lexer<'a> { Some(TokenKind::Returns) => { self.eat_whitespace(); // Allow for loose and tight syntax (e.g. `returns (0)`, `returns(0)`, ...) - self.peek().unwrap_or(')') == '(' && - !self.checked_lookback(TokenKind::Function) + self.peek().unwrap_or(')') == '(' && !self.checked_lookback(TokenKind::Function) } _ => true, } @@ -679,7 +689,6 @@ impl<'a> Lexer<'a> { } imports } - } impl<'a> Iterator for Lexer<'a> { @@ -692,4 +701,4 @@ impl<'a> Iterator for Lexer<'a> { Some(self.next_token()) } } -} \ No newline at end of file +} diff --git a/huff_lexer/tests/arg_calls.rs b/huff_lexer/tests/arg_calls.rs index b880b511..11e5cad9 100644 --- a/huff_lexer/tests/arg_calls.rs +++ b/huff_lexer/tests/arg_calls.rs @@ -66,7 +66,6 @@ fn lexes_arg_calls() { let tok = lexer.next().unwrap().unwrap(); assert_eq!(tok, Token::new(TokenKind::LeftAngle, Span::new(184..184, None))); - // The we should have an Ident let tok = lexer.next().unwrap().unwrap(); assert_eq!(tok, Token::new(TokenKind::Ident("error".to_string()), Span::new(185..189, None))); @@ -88,7 +87,10 @@ fn lexes_arg_calls() { // Get an EOF token let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Eof, Span::new(source.len()-1..source.len()-1, None))); + assert_eq!( + tok, + Token::new(TokenKind::Eof, Span::new(source.len() - 1..source.len() - 1, None)) + ); // We should have reached EOF now assert!(lexer.eof); diff --git a/huff_lexer/tests/builtins.rs b/huff_lexer/tests/builtins.rs index 3cff23d2..d536d7be 100644 --- a/huff_lexer/tests/builtins.rs +++ b/huff_lexer/tests/builtins.rs @@ -54,7 +54,7 @@ fn parses_builtin_function_in_macro_body() { // The builtin fn should be parsed as a `TokenKind::BuiltinFunction` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let builtin_span = Span::new(74..74 + builtin.len()-1, None); + let builtin_span = Span::new(74..74 + builtin.len() - 1, None); assert_eq!( unwrapped, Token::new(TokenKind::BuiltinFunction(builtin.to_string()), builtin_span.clone()) @@ -67,7 +67,7 @@ fn parses_builtin_function_in_macro_body() { let _ = lexer.next(); // } let _ = lexer.next(); // whitespace let _ = lexer.next(); // eof - + // We covered the whole source assert!(lexer.eof); } @@ -94,7 +94,7 @@ fn fails_to_parse_builtin_outside_macro_body() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(0..builtin.len()-1, None); + let fn_name_span = Span::new(0..builtin.len() - 1, None); assert_eq!( unwrapped, Token::new(TokenKind::BuiltinFunction(builtin.to_string()), fn_name_span.clone()) @@ -153,7 +153,7 @@ fn fails_to_parse_invalid_builtin() { // The builtin fn should be parsed as a `TokenKind::BuiltinFunction` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let builtin_span = Span::new(74..74 + builtin.len()-1, None); + let builtin_span = Span::new(74..74 + builtin.len() - 1, None); assert_eq!( unwrapped, Token::new(TokenKind::BuiltinFunction(builtin.to_string()), builtin_span.clone()) diff --git a/huff_lexer/tests/comments.rs b/huff_lexer/tests/comments.rs index 94ccb5ca..cbcf421d 100644 --- a/huff_lexer/tests/comments.rs +++ b/huff_lexer/tests/comments.rs @@ -91,7 +91,7 @@ fn single_line_comments() { // We covered the whole source assert!(lexer.eof); - assert_eq!(source.len()-1, 47); + assert_eq!(source.len() - 1, 47); } #[test] @@ -160,5 +160,5 @@ fn multi_line_comments() { // We covered the whole source assert!(lexer.eof); - assert_eq!(source.len()-1, 47); + assert_eq!(source.len() - 1, 47); } diff --git a/huff_lexer/tests/decorators.rs b/huff_lexer/tests/decorators.rs index 1bc1d7e5..5d6242c6 100644 --- a/huff_lexer/tests/decorators.rs +++ b/huff_lexer/tests/decorators.rs @@ -49,7 +49,6 @@ fn parses_decorator() { let returns_span = Span::new(23..23, None); assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, returns_span.clone())); - // 0x01 let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); diff --git a/huff_lexer/tests/function_type.rs b/huff_lexer/tests/function_type.rs index c012aa7d..1675fb3d 100644 --- a/huff_lexer/tests/function_type.rs +++ b/huff_lexer/tests/function_type.rs @@ -27,7 +27,7 @@ fn parses_function_type() { // Lex view first let tok = lexer.next().unwrap().unwrap(); - let type_span = Span::new(24..24 + fn_type.len()-1, None); + let type_span = Span::new(24..24 + fn_type.len() - 1, None); assert_eq!(tok, Token::new(fn_type_kind, type_span.clone())); let _ = lexer.next(); // whitespace diff --git a/huff_lexer/tests/hex.rs b/huff_lexer/tests/hex.rs index c6212896..57d88112 100644 --- a/huff_lexer/tests/hex.rs +++ b/huff_lexer/tests/hex.rs @@ -1,5 +1,4 @@ -use huff_lexer::*; -use huff_lexer::Lexer; +use huff_lexer::{Lexer, *}; use huff_utils::prelude::*; use std::ops::Deref; diff --git a/huff_lexer/tests/keywords.rs b/huff_lexer/tests/keywords.rs index 20db20a1..bae15ab2 100644 --- a/huff_lexer/tests/keywords.rs +++ b/huff_lexer/tests/keywords.rs @@ -118,7 +118,6 @@ fn parses_function_keyword() { lexer.next(); - // We covered the whole source assert!(lexer.eof); } @@ -154,7 +153,6 @@ fn parses_event_keyword() { let _ = lexer.next(); // close parenthesis let _ = lexer.next(); // eof - // We covered the whole source assert!(lexer.eof); } @@ -351,7 +349,7 @@ fn parses_function_definition_with_keyword_name() { // Keyword as a function name (s) let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let ident_span = Span::new(17..end_span_s-1, None); + let ident_span = Span::new(17..end_span_s - 1, None); assert_eq!(unwrapped, Token::new(TokenKind::Ident(s.to_string()), ident_span.clone())); let _ = lexer.next(); // open parenthesis @@ -415,7 +413,7 @@ fn parses_label_with_keyword_name() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(0..s.len()-1, None); + let fn_name_span = Span::new(0..s.len() - 1, None); assert_eq!(unwrapped, Token::new(TokenKind::Label(s.to_string()), fn_name_span.clone())); let _ = lexer.next(); // colon @@ -473,7 +471,7 @@ fn parses_function_with_keyword_name() { // The keyword should be parsed as a `TokenKind::Ident` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(19..19 + s.len()-1, None); + let fn_name_span = Span::new(19..19 + s.len() - 1, None); assert_eq!(unwrapped, Token::new(TokenKind::Ident(s.to_string()), fn_name_span.clone())); let _ = lexer.next(); // whitespace @@ -569,7 +567,7 @@ fn parses_function_with_keyword_name_in_macro() { // The keyword should be parsed as a `TokenKind::Ident` here. let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let fn_name_span = Span::new(84..84 + s.len()-1, None); + let fn_name_span = Span::new(84..84 + s.len() - 1, None); assert_eq!(unwrapped, Token::new(TokenKind::Ident(s.to_string()), fn_name_span.clone())); let _ = lexer.next(); // whitespace @@ -615,7 +613,7 @@ fn parses_keyword_arbitrary_whitespace() { // Lastly we should parse the constant keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); - let constant_span = Span::new(12..12 + key.len()-1, None); + let constant_span = Span::new(12..12 + key.len() - 1, None); assert_eq!(unwrapped, Token::new(kind, constant_span.clone())); lexer.next(); diff --git a/huff_lexer/tests/numbers.rs b/huff_lexer/tests/numbers.rs index bf75e5fd..7844c4d1 100644 --- a/huff_lexer/tests/numbers.rs +++ b/huff_lexer/tests/numbers.rs @@ -26,7 +26,7 @@ fn lexes_large_numbers() { // The first and only token should be lexed let tok = lexer.next().unwrap().unwrap(); - assert_eq!(tok, Token::new(TokenKind::Num(usize::MAX), Span::new(0..source.len()-1, None))); + assert_eq!(tok, Token::new(TokenKind::Num(usize::MAX), Span::new(0..source.len() - 1, None))); lexer.next(); diff --git a/huff_parser/tests/macro.rs b/huff_parser/tests/macro.rs index eb08e74c..92fcf58b 100644 --- a/huff_parser/tests/macro.rs +++ b/huff_parser/tests/macro.rs @@ -1,4 +1,4 @@ -use huff_lexer::{*, Lexer}; +use huff_lexer::{Lexer, *}; use huff_parser::*; use huff_utils::{evm::Opcode, prelude::*}; use tracing::debug; diff --git a/huff_utils/src/token.rs b/huff_utils/src/token.rs index c82fae17..547fbe82 100644 --- a/huff_utils/src/token.rs +++ b/huff_utils/src/token.rs @@ -132,7 +132,6 @@ pub enum TokenKind { } impl TokenKind { - /// Transform a single char TokenKind into a Token given a single position pub fn into_single_span(self, position: u32) -> Token { self.into_span(position, position) From 1d6a29a42affbfcf052821c185005815c21c909f Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 17:55:42 -0700 Subject: [PATCH 36/68] comments cleanup --- huff_lexer/src/lib.rs | 41 ++--------------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index 1edafd5e..c15c2f02 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -5,7 +5,7 @@ use std::{ ops::RangeFrom, str::Chars, }; -/* hiehgsebgoiesgoiseg */ + /// Defines a context in which the lexing happens. /// Allows to differientate between EVM types and opcodes that can either /// be identical or the latter being a substring of the former (example : bytes32 and byte) @@ -52,7 +52,6 @@ impl<'a> Lexer<'a> { pub fn new(source: &'a str) -> Self { Lexer { // We zip with the character index here to ensure the first char has index 0 - //chars: source.chars().peekable(), chars: source.chars().zip(0..).peekable(), position: 0, lookback: None, @@ -63,11 +62,6 @@ impl<'a> Lexer<'a> { /// Consumes the next character pub fn consume(&mut self) -> Option { - // self.chars.next().map(|x| { - // self.position += 1; - // x - // }) - let (c, index) = self.chars.next()?; self.position = index; Some(c) @@ -79,28 +73,7 @@ impl<'a> Lexer<'a> { self.chars.peek().map(|(c, _)| *c) } - /// Consume characters until a sequence matches - // pub fn seq_consume(&mut self, word: &str) { - // let mut current_pos = self.current_span().start; - // while self.peek().is_some() { - // let peeked = self.peek_n_chars_from(word.len(), current_pos); - // if word == peeked { - // break - // } - // self.consume(); - // current_pos += 1; - // } - // } - - /// Dynamically consumes characters based on filters - pub fn dyn_consume(&mut self, f: impl Fn(&char) -> bool + Copy) { - while self.peek().map(|x| f(&x)).unwrap_or(false) { - self.consume(); - } - } - fn next_token(&mut self) -> TokenResult { - // let start = self.position; if let Some(ch) = self.consume() { let token = match ch { '/' => { @@ -140,7 +113,6 @@ impl<'a> Lexer<'a> { // there will be a successfully parsed block comment // "/* */" // and " */" will be processed separately. - break } } @@ -152,8 +124,6 @@ impl<'a> Lexer<'a> { Ok(TokenKind::Comment(comment_string) .into_span(start, self.position)) - // TODO add string or just not store comments - // self.single_char_token(TokenKind::Comment("".to_owned())) } _ => self.single_char_token(TokenKind::Div), } @@ -521,8 +491,8 @@ impl<'a> Lexer<'a> { fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult { let (integer_str, mut start, end) = self.eat_while(Some(initial_char), |ch| ch.is_ascii_hexdigit() | (ch == 'x')); + // TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34 - let kind = if self.context == Context::CodeTableBody { // In codetables, the bytecode provided is of arbitrary length. We pass // the code as an Ident, and it is appended to the end of the runtime @@ -554,13 +524,6 @@ impl<'a> Lexer<'a> { str_literal_token.into_span(start_span, end_span + 1) } - // fn eat_alphabetic(&mut self, initial_char: char) -> (String, u32, u32) { - // let (word, start, end) = self.eat_while(Some(initial_char), |ch| { - // ch.is_ascii_alphabetic() - // }); - // (word, start, end) - // } - /// Checks the previous token kind against the input. pub fn checked_lookback(&self, kind: TokenKind) -> bool { self.lookback.clone().and_then(|t| if t.kind == kind { Some(true) } else { None }).is_some() From a29b16fe85c7eee75888a9537b5da4ea85edcac7 Mon Sep 17 00:00:00 2001 From: vezenovm Date: Fri, 10 Mar 2023 17:55:56 -0700 Subject: [PATCH 37/68] cargo fmt --- huff_lexer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/huff_lexer/src/lib.rs b/huff_lexer/src/lib.rs index c15c2f02..7ce3f241 100644 --- a/huff_lexer/src/lib.rs +++ b/huff_lexer/src/lib.rs @@ -491,7 +491,7 @@ impl<'a> Lexer<'a> { fn eat_hex_digit(&mut self, initial_char: char) -> TokenResult { let (integer_str, mut start, end) = self.eat_while(Some(initial_char), |ch| ch.is_ascii_hexdigit() | (ch == 'x')); - + // TODO: check for sure that we have a correct hex string, eg. 0x56 and not 0x56x34 let kind = if self.context == Context::CodeTableBody { // In codetables, the bytecode provided is of arbitrary length. We pass From dca4f367b39beb21a519fc8ebf63e59d2e72eeaa Mon Sep 17 00:00:00 2001 From: d1ll0n Date: Thu, 30 Mar 2023 03:43:04 -0500 Subject: [PATCH 38/68] Add test for bubbled macro args with different names --- huff_core/tests/macro_invoc_args.rs | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/huff_core/tests/macro_invoc_args.rs b/huff_core/tests/macro_invoc_args.rs index 0b498432..6d695934 100644 --- a/huff_core/tests/macro_invoc_args.rs +++ b/huff_core/tests/macro_invoc_args.rs @@ -260,3 +260,37 @@ fn test_bubbled_constant_macro_arg() { // Check the bytecode assert_eq!(bytecode.to_lowercase(), expected_bytecode.to_lowercase()); } + + +#[test] +fn test_bubbled_arg_with_different_name() { + let source = r#" + #define macro MACRO_A(arg_a) = takes(0) returns(0) { + + } + #define macro MACRO_B(arg_b) =takes(0) returns(0) { + MACRO_A() + } + #define macro MAIN() = takes(0) returns(0){ + MACRO_B(0x01) + } + "#; + + // Lex + Parse + let flattened_source = FullFileSource { source, file: None, spans: vec![] }; + let lexer = Lexer::new(flattened_source); + let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); + let mut parser = Parser::new(tokens, None); + let mut contract = parser.parse().unwrap(); + contract.derive_storage_pointers(); + + // Create main and constructor bytecode + let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + + // Full expected bytecode output (generated from huffc) (placed here as a reference) + let expected_bytecode = "6001"; + + // Check the bytecode + assert_eq!(main_bytecode, expected_bytecode); + +} \ No newline at end of file From a5e4768776a96ad4023231119e35f0091e109e44 Mon Sep 17 00:00:00 2001 From: d1ll0n Date: Thu, 30 Mar 2023 03:45:21 -0500 Subject: [PATCH 39/68] use argcall for bubbled resolution instead of original name --- huff_codegen/src/irgen/arg_calls.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/huff_codegen/src/irgen/arg_calls.rs b/huff_codegen/src/irgen/arg_calls.rs index 58ccbe51..47e98899 100644 --- a/huff_codegen/src/irgen/arg_calls.rs +++ b/huff_codegen/src/irgen/arg_calls.rs @@ -67,7 +67,7 @@ pub fn bubble_arg_call( }; return if last_mi.1.macro_name.eq(¯o_def.name) { bubble_arg_call( - arg_name, + ac, bytes, &bubbled_macro_invocation, contract, @@ -78,7 +78,7 @@ pub fn bubble_arg_call( ) } else { bubble_arg_call( - arg_name, + &ac.to_string(), bytes, &bubbled_macro_invocation, contract, From b4cfa314b3626dbf577a713c0c0fb2d8225f830c Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+cheethas@users.noreply.github.com> Date: Sat, 1 Apr 2023 15:24:08 -0700 Subject: [PATCH 40/68] chore(clippy): resolve ambiguous exports (#261) * chore(clippy): appease * chore(fmt): fix * fix(clippy): ambiguous module exports * fix: ast doc test --------- Co-authored-by: cheethas --- huff_lexer/tests/arg_calls.rs | 1 - huff_lexer/tests/builtins.rs | 1 - huff_lexer/tests/comments.rs | 41 +++++++++++-------------- huff_lexer/tests/decorators.rs | 1 - huff_lexer/tests/eof.rs | 1 - huff_lexer/tests/fsp.rs | 2 -- huff_lexer/tests/function_type.rs | 1 - huff_lexer/tests/hex.rs | 3 +- huff_lexer/tests/imports.rs | 9 +++--- huff_lexer/tests/keywords.rs | 51 +++++++++++++++---------------- huff_lexer/tests/numbers.rs | 1 - huff_lexer/tests/symbols.rs | 37 +++++++++++----------- huff_parser/src/lib.rs | 8 ++--- huff_parser/tests/event.rs | 8 ++--- huff_parser/tests/function.rs | 12 ++++---- huff_parser/tests/macro.rs | 3 +- huff_utils/src/abi.rs | 6 ++-- huff_utils/src/ast.rs | 8 ++--- 18 files changed, 87 insertions(+), 107 deletions(-) diff --git a/huff_lexer/tests/arg_calls.rs b/huff_lexer/tests/arg_calls.rs index 11e5cad9..2cbdb4f1 100644 --- a/huff_lexer/tests/arg_calls.rs +++ b/huff_lexer/tests/arg_calls.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::{evm::Opcode, prelude::*}; -use std::ops::Deref; #[test] fn lexes_arg_calls() { diff --git a/huff_lexer/tests/builtins.rs b/huff_lexer/tests/builtins.rs index d536d7be..64cc6fc7 100644 --- a/huff_lexer/tests/builtins.rs +++ b/huff_lexer/tests/builtins.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::{FullFileSource, Span, Token, TokenKind}; -use std::ops::Deref; #[test] fn parses_builtin_function_in_macro_body() { diff --git a/huff_lexer/tests/comments.rs b/huff_lexer/tests/comments.rs index cbcf421d..898a6921 100644 --- a/huff_lexer/tests/comments.rs +++ b/huff_lexer/tests/comments.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::*; -use std::ops::Deref; // use proptest::prelude::*; @@ -37,57 +36,54 @@ fn single_line_comments() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(20..20, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span)); // This token should be a Define identifier let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(21..27, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(28..28, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span)); // Then we should parse the macro keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let macro_span = Span::new(29..33, None); - assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span)); // The next token should be another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let ws_span = Span::new(34..34, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span)); // Then we should get the function name let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let function_span = Span::new(35..45, None); - assert_eq!( - unwrapped, - Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), function_span.clone()) - ); + assert_eq!(unwrapped, Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), function_span)); // Then we should have an open paren let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let open_paren_span = Span::new(46..46, None); - assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, open_paren_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, open_paren_span)); // Lastly, we should have a closing parenthesis let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let close_paren_span = Span::new(47..47, None); - assert_eq!(unwrapped, Token::new(TokenKind::CloseParen, close_paren_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::CloseParen, close_paren_span)); let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let eof_span = Span::new(47..47, None); - assert_eq!(unwrapped, Token::new(TokenKind::Eof, eof_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Eof, eof_span)); // We covered the whole source assert!(lexer.eof); @@ -112,51 +108,48 @@ fn multi_line_comments() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(21..27, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(28..28, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span)); // Then we should parse the macro keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let macro_span = Span::new(29..33, None); - assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span)); // The next token should be another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let ws_span = Span::new(34..34, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span)); // Then we should get the function name let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let function_span = Span::new(35..45, None); - assert_eq!( - unwrapped, - Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), function_span.clone()) - ); + assert_eq!(unwrapped, Token::new(TokenKind::Ident("HELLO_WORLD".to_string()), function_span)); // Then we should have an open paren let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let open_paren_span = Span::new(46..46, None); - assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, open_paren_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::OpenParen, open_paren_span)); // Lastly, we should have a closing parenthesis let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let close_paren_span = Span::new(47..47, None); - assert_eq!(unwrapped, Token::new(TokenKind::CloseParen, close_paren_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::CloseParen, close_paren_span)); let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let eof_span = Span::new(47..47, None); - assert_eq!(unwrapped, Token::new(TokenKind::Eof, eof_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Eof, eof_span)); // We covered the whole source assert!(lexer.eof); diff --git a/huff_lexer/tests/decorators.rs b/huff_lexer/tests/decorators.rs index 5d6242c6..4cf3fbf2 100644 --- a/huff_lexer/tests/decorators.rs +++ b/huff_lexer/tests/decorators.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::{str_to_bytes32, FullFileSource, Span, Token, TokenKind}; -use std::ops::Deref; #[test] fn parses_decorator() { diff --git a/huff_lexer/tests/eof.rs b/huff_lexer/tests/eof.rs index db76f82e..c363c723 100644 --- a/huff_lexer/tests/eof.rs +++ b/huff_lexer/tests/eof.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::*; -use std::ops::Deref; #[test] fn end_of_file() { diff --git a/huff_lexer/tests/fsp.rs b/huff_lexer/tests/fsp.rs index 97a1dc2b..bc254c64 100644 --- a/huff_lexer/tests/fsp.rs +++ b/huff_lexer/tests/fsp.rs @@ -1,7 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::*; -/// Tests lexing the Free Storage Pointer Keyword -use std::ops::Deref; #[test] fn free_storage_pointer() { diff --git a/huff_lexer/tests/function_type.rs b/huff_lexer/tests/function_type.rs index 1675fb3d..10729edf 100644 --- a/huff_lexer/tests/function_type.rs +++ b/huff_lexer/tests/function_type.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::*; -use std::ops::Deref; #[test] fn parses_function_type() { diff --git a/huff_lexer/tests/hex.rs b/huff_lexer/tests/hex.rs index 57d88112..0d5b1ffc 100644 --- a/huff_lexer/tests/hex.rs +++ b/huff_lexer/tests/hex.rs @@ -1,6 +1,5 @@ -use huff_lexer::{Lexer, *}; +use huff_lexer::Lexer; use huff_utils::prelude::*; -use std::ops::Deref; #[test] fn parses_single_hex() { diff --git a/huff_lexer/tests/imports.rs b/huff_lexer/tests/imports.rs index a0a51b99..ebb95263 100644 --- a/huff_lexer/tests/imports.rs +++ b/huff_lexer/tests/imports.rs @@ -1,6 +1,5 @@ use huff_lexer::Lexer; use huff_utils::prelude::*; -use std::ops::Deref; #[test] fn single_lex_imports() { @@ -120,7 +119,7 @@ fn include_with_string() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let literal_span = Span::new(8..8, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, literal_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, literal_span)); // Then we should parse the string literal let tok = lexer.next(); @@ -130,7 +129,7 @@ fn include_with_string() { unwrapped, Token::new( TokenKind::Str("../huff-examples/erc20/contracts/utils/Ownable.huff".to_string()), - literal_span.clone() + literal_span ) ); @@ -155,7 +154,7 @@ fn include_with_string_single_quote() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let literal_span = Span::new(8..8, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, literal_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, literal_span)); // Then we should parse the string literal let tok = lexer.next(); @@ -165,7 +164,7 @@ fn include_with_string_single_quote() { unwrapped, Token::new( TokenKind::Str("../huff-examples/erc20/contracts/utils/Ownable.huff".to_string()), - literal_span.clone() + literal_span ) ); diff --git a/huff_lexer/tests/keywords.rs b/huff_lexer/tests/keywords.rs index bae15ab2..81c92f06 100644 --- a/huff_lexer/tests/keywords.rs +++ b/huff_lexer/tests/keywords.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::*; -use std::ops::Deref; #[test] fn parses_macro_keyword() { @@ -12,19 +11,19 @@ fn parses_macro_keyword() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(0..6, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let whitespace_span = Span::new(7..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span)); // Lastly we should parse the macro keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let macro_span = Span::new(8..12, None); - assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Macro, macro_span)); lexer.next(); @@ -42,19 +41,19 @@ fn parses_fn_keyword() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(0..6, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let whitespace_span = Span::new(7..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span)); // Lastly we should parse the fn keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let fn_span = Span::new(8..9, None); - assert_eq!(unwrapped, Token::new(TokenKind::Fn, fn_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Fn, fn_span)); lexer.next(); @@ -72,19 +71,19 @@ fn parses_test_keyword() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(0..6, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let whitespace_span = Span::new(7..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span)); // Lastly we should parse the fn keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let test_span = Span::new(8..11, None); - assert_eq!(unwrapped, Token::new(TokenKind::Test, test_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Test, test_span)); lexer.next(); @@ -102,19 +101,19 @@ fn parses_function_keyword() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(0..6, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let whitespace_span = Span::new(7..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span)); // Lastly we should parse the function keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let function_span = Span::new(8..15, None); - assert_eq!(unwrapped, Token::new(TokenKind::Function, function_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Function, function_span)); lexer.next(); @@ -132,19 +131,19 @@ fn parses_event_keyword() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(0..6, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let whitespace_span = Span::new(7..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span)); // Lastly we should parse the event keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let event_span = Span::new(8..12, None); - assert_eq!(unwrapped, Token::new(TokenKind::Event, event_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Event, event_span)); let _ = lexer.next(); // whitespace let _ = lexer.next(); // event name @@ -167,19 +166,19 @@ fn parses_constant_keyword() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(0..6, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let whitespace_span = Span::new(7..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span)); // Lastly we should parse the constant keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let constant_span = Span::new(8..15, None); - assert_eq!(unwrapped, Token::new(TokenKind::Constant, constant_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Constant, constant_span)); lexer.next(); @@ -208,7 +207,7 @@ fn parses_takes_and_returns_keywords() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let takes_span = Span::new(23..27, None); - assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span)); // Lex the middle 5 chars let _ = lexer.next(); // whitespace @@ -221,7 +220,7 @@ fn parses_takes_and_returns_keywords() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let returns_span = Span::new(37..43, None); - assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span)); // Lex the last 4 chars let _ = lexer.next(); // whitespace @@ -255,7 +254,7 @@ fn parses_takes_and_returns_keywords_tight_syntax() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let takes_span = Span::new(23..27, None); - assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span)); // Lex the next 4 chars let _ = lexer.next(); // open parenthesis @@ -267,7 +266,7 @@ fn parses_takes_and_returns_keywords_tight_syntax() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let returns_span = Span::new(32..38, None); - assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span)); // Lex the last 3 chars let _ = lexer.next(); // open parenthesis @@ -297,7 +296,7 @@ fn parses_function_type_keywords() { // Lex view first let tok = lexer.next().unwrap().unwrap(); let view_span = Span::new(24..27, None); - assert_eq!(tok, Token::new(TokenKind::View, view_span.clone())); + assert_eq!(tok, Token::new(TokenKind::View, view_span)); // Lex the next 4 chars let _ = lexer.next(); // whitespace @@ -644,7 +643,7 @@ fn parses_takes_keyword_arbitrary_whitespace() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let takes_span = Span::new(28..32, None); - assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Takes, takes_span)); // Lex the middle 5 chars let _ = lexer.next(); // whitespace @@ -657,7 +656,7 @@ fn parses_takes_keyword_arbitrary_whitespace() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let returns_span = Span::new(38..44, None); - assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Returns, returns_span)); // Lex the last 4 chars let _ = lexer.next(); // whitespace diff --git a/huff_lexer/tests/numbers.rs b/huff_lexer/tests/numbers.rs index 7844c4d1..e07695cf 100644 --- a/huff_lexer/tests/numbers.rs +++ b/huff_lexer/tests/numbers.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::*; -use std::ops::Deref; #[test] fn lexes_zero_prefixed_numbers() { diff --git a/huff_lexer/tests/symbols.rs b/huff_lexer/tests/symbols.rs index 902756ff..b4d48984 100644 --- a/huff_lexer/tests/symbols.rs +++ b/huff_lexer/tests/symbols.rs @@ -1,6 +1,5 @@ use huff_lexer::*; use huff_utils::prelude::*; -use std::ops::Deref; #[test] fn lexes_assign_op() { @@ -12,25 +11,25 @@ fn lexes_assign_op() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(0..6, None); - assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Define, define_span)); // The next token should be the whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let define_span = Span::new(7..7, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, define_span)); // Then we should parse the constant keyword let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let constant_span = Span::new(8..15, None); - assert_eq!(unwrapped, Token::new(TokenKind::Constant, constant_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Constant, constant_span)); // The next token should be another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let ws_span = Span::new(16..16, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, ws_span)); // Then we should get the function name let tok = lexer.next(); @@ -38,20 +37,20 @@ fn lexes_assign_op() { let function_span = Span::new(17..40, None); assert_eq!( unwrapped, - Token::new(TokenKind::Ident("TRANSFER_EVENT_SIGNATURE".to_string()), function_span.clone()) + Token::new(TokenKind::Ident("TRANSFER_EVENT_SIGNATURE".to_string()), function_span) ); // Then we should have another whitespace let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let whitespace_span = Span::new(41..41, None); - assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Whitespace, whitespace_span)); // Finally, we have our assign operator let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let assign_span = Span::new(42..42, None); - assert_eq!(unwrapped, Token::new(TokenKind::Assign, assign_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Assign, assign_span)); lexer.next(); // We covered the whole source @@ -68,7 +67,7 @@ fn lexes_brackets() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let bracket_span = Span::new(0..0, None); - assert_eq!(unwrapped, Token::new(TokenKind::OpenBracket, bracket_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::OpenBracket, bracket_span)); // The next token should be the location identifier let tok = lexer.next(); @@ -76,14 +75,14 @@ fn lexes_brackets() { let loc_span = Span::new(1..21, None); assert_eq!( unwrapped, - Token::new(TokenKind::Ident("TOTAL_SUPPLY_LOCATION".to_string()), loc_span.clone()) + Token::new(TokenKind::Ident("TOTAL_SUPPLY_LOCATION".to_string()), loc_span) ); // Then we should parse the closing bracket let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let bracket_span = Span::new(22..22, None); - assert_eq!(unwrapped, Token::new(TokenKind::CloseBracket, bracket_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::CloseBracket, bracket_span)); // Eat the last tokens let _ = lexer.next(); // whitespace @@ -134,7 +133,7 @@ fn lexes_braces() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let brace_span = Span::new(51..51, None); - assert_eq!(unwrapped, Token::new(TokenKind::OpenBrace, brace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::OpenBrace, brace_span)); // Eat the characters in between braces let _ = lexer.next(); // whitespace @@ -149,7 +148,7 @@ fn lexes_braces() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let brace_span = Span::new(131..131, None); - assert_eq!(unwrapped, Token::new(TokenKind::CloseBrace, brace_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::CloseBrace, brace_span)); // Eat the last whitespace let _ = lexer.next(); // whitespace @@ -174,7 +173,7 @@ fn lexes_math_ops() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let add_span = Span::new(4..4, None); - assert_eq!(unwrapped, Token::new(TokenKind::Add, add_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Add, add_span)); // Eat the number and whitespaces let _ = lexer.next(); @@ -185,7 +184,7 @@ fn lexes_math_ops() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let sub_span = Span::new(9..9, None); - assert_eq!(unwrapped, Token::new(TokenKind::Sub, sub_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Sub, sub_span)); // Eat the number and whitespaces let _ = lexer.next(); @@ -196,7 +195,7 @@ fn lexes_math_ops() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let mul_span = Span::new(14..14, None); - assert_eq!(unwrapped, Token::new(TokenKind::Mul, mul_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Mul, mul_span)); // Eat the number and whitespace let _ = lexer.next(); @@ -207,7 +206,7 @@ fn lexes_math_ops() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let div_span = Span::new(18..18, None); - assert_eq!(unwrapped, Token::new(TokenKind::Div, div_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Div, div_span)); // Eat the number and whitespace let _ = lexer.next(); @@ -230,7 +229,7 @@ fn lexes_commas() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let comma_span = Span::new(4..4, None); - assert_eq!(unwrapped, Token::new(TokenKind::Comma, comma_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Comma, comma_span)); // Eat alphanumerics let _ = lexer.next(); @@ -253,7 +252,7 @@ fn lexes_comma_sparse() { let tok = lexer.next(); let unwrapped = tok.unwrap().unwrap(); let comma_span = Span::new(5..5, None); - assert_eq!(unwrapped, Token::new(TokenKind::Comma, comma_span.clone())); + assert_eq!(unwrapped, Token::new(TokenKind::Comma, comma_span)); let _ = lexer.next(); // whitespace let _ = lexer.next(); // alphanumerics diff --git a/huff_parser/src/lib.rs b/huff_parser/src/lib.rs index 592484bb..fceed3ac 100644 --- a/huff_parser/src/lib.rs +++ b/huff_parser/src/lib.rs @@ -224,7 +224,7 @@ impl Parser { /// Parses a function. /// Adheres to - pub fn parse_function(&mut self) -> Result { + pub fn parse_function(&mut self) -> Result { // the first token should be of `TokenKind::Function` self.match_kind(TokenKind::Function)?; // function name should be next @@ -273,7 +273,7 @@ impl Parser { inputs.iter().map(|i| i.arg_type.as_ref().unwrap().clone()).collect::>(); hash_bytes(&mut signature, &format!("{name}({})", input_types.join(","))); - Ok(Function { + Ok(FunctionDefinition { name, signature, inputs, @@ -284,7 +284,7 @@ impl Parser { } /// Parse an event. - pub fn parse_event(&mut self) -> Result { + pub fn parse_event(&mut self) -> Result { // The event should start with `TokenKind::Event` self.match_kind(TokenKind::Event)?; @@ -312,7 +312,7 @@ impl Parser { parameters.iter().map(|i| i.arg_type.as_ref().unwrap().clone()).collect::>(); hash_bytes(&mut hash, &format!("{name}({})", input_types.join(","))); - Ok(Event { name, parameters, span: AstSpan(self.spans.clone()), hash }) + Ok(EventDefinition { name, parameters, span: AstSpan(self.spans.clone()), hash }) } /// Parse a constant. diff --git a/huff_parser/tests/event.rs b/huff_parser/tests/event.rs index 72ec5c6f..7e8baa9b 100644 --- a/huff_parser/tests/event.rs +++ b/huff_parser/tests/event.rs @@ -1,6 +1,6 @@ use huff_lexer::*; use huff_parser::*; -use huff_utils::{ast::Event, prelude::*}; +use huff_utils::{ast::EventDefinition, prelude::*}; #[test] fn test_prefix_event_arg_names_with_reserved_keywords() { @@ -75,7 +75,7 @@ fn test_parse_event() { let sources = [ ( "#define event TestEvent(uint256 indexed a,uint8 indexed)", - Event { + EventDefinition { name: "TestEvent".to_string(), parameters: vec![ Argument { @@ -137,7 +137,7 @@ fn test_parse_event() { ), ( "#define event TestEvent(uint256,uint8 b)", - Event { + EventDefinition { name: "TestEvent".to_string(), parameters: vec![ Argument { @@ -191,7 +191,7 @@ fn test_parse_event() { ), ( "#define event TestEvent(uint256 indexed,uint8)", - Event { + EventDefinition { name: "TestEvent".to_string(), parameters: vec![ Argument { diff --git a/huff_parser/tests/function.rs b/huff_parser/tests/function.rs index a5db363f..1654280a 100644 --- a/huff_parser/tests/function.rs +++ b/huff_parser/tests/function.rs @@ -1,7 +1,7 @@ use huff_lexer::*; use huff_parser::*; use huff_utils::{ - ast::{Function, FunctionType}, + ast::{FunctionDefinition, FunctionType}, prelude::*, }; use std::collections::HashMap; @@ -17,7 +17,7 @@ fn parses_valid_function_definition() { let expected_fns = HashMap::from([ ( 0, - Function { + FunctionDefinition { name: "test".to_string(), inputs: vec![ Argument { @@ -67,7 +67,7 @@ fn parses_valid_function_definition() { ), ( 1, - Function { + FunctionDefinition { name: "test".to_string(), inputs: vec![Argument { name: None, @@ -102,7 +102,7 @@ fn parses_valid_function_definition() { ), ( 2, - Function { + FunctionDefinition { name: "test".to_string(), inputs: vec![Argument { name: None, @@ -137,7 +137,7 @@ fn parses_valid_function_definition() { ), ( 3, - Function { + FunctionDefinition { name: "test".to_string(), inputs: vec![Argument { name: None, @@ -172,7 +172,7 @@ fn parses_valid_function_definition() { ), ( 4, - Function { + FunctionDefinition { name: "test".to_string(), inputs: vec![Argument { name: None, diff --git a/huff_parser/tests/macro.rs b/huff_parser/tests/macro.rs index 92fcf58b..bc34e903 100644 --- a/huff_parser/tests/macro.rs +++ b/huff_parser/tests/macro.rs @@ -1,7 +1,6 @@ -use huff_lexer::{Lexer, *}; +use huff_lexer::Lexer; use huff_parser::*; use huff_utils::{evm::Opcode, prelude::*}; -use tracing::debug; #[test] fn empty_macro() { diff --git a/huff_utils/src/abi.rs b/huff_utils/src/abi.rs index 93a00c02..2f6cb67f 100644 --- a/huff_utils/src/abi.rs +++ b/huff_utils/src/abi.rs @@ -20,7 +20,7 @@ //! imports: vec![], //! constants: Arc::new(Mutex::new(vec![])), //! errors: vec![], -//! functions: vec![huff_utils::ast::Function { +//! functions: vec![huff_utils::ast::FunctionDefinition { //! name: "CONSTRUCTOR".to_string(), //! signature: [0u8, 0u8, 0u8, 0u8], //! inputs: vec![], @@ -77,7 +77,7 @@ impl From for Abi { .iter() .filter(|m| m.name.to_lowercase() == "constructor") .cloned() - .collect::>() + .collect::>() .get(0) .map(|func| Constructor { inputs: func @@ -122,7 +122,7 @@ impl From for Abi { contract .functions .iter() - .filter(|function: &&ast::Function| function.name != "CONSTRUCTOR") + .filter(|function: &&ast::FunctionDefinition| function.name != "CONSTRUCTOR") .map(|function| { ( function.name.to_string(), diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index 97ccdf13..5a65a80c 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -97,9 +97,9 @@ pub struct Contract { /// Custom Errors pub errors: Vec, /// Functions - pub functions: Vec, + pub functions: Vec, /// Events - pub events: Vec, + pub events: Vec, /// Tables pub tables: Vec, } @@ -419,7 +419,7 @@ pub struct Argument { /// A Function Signature #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Function { +pub struct FunctionDefinition { /// The name of the function pub name: String, /// The function signature @@ -461,7 +461,7 @@ impl FunctionType { /// An Event Signature #[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct Event { +pub struct EventDefinition { /// The name of the event pub name: String, /// The parameters of the event From 8898a6afb280faf16625e6acf5b756b7e3025c50 Mon Sep 17 00:00:00 2001 From: eric tu Date: Mon, 3 Apr 2023 16:12:11 -0400 Subject: [PATCH 41/68] remove unnecessary allocations in codegen --- huff_codegen/src/irgen/constants.rs | 4 ++-- huff_codegen/src/irgen/statements.rs | 6 +++--- huff_codegen/src/lib.rs | 26 +++++++++++++------------- huff_utils/src/ast.rs | 28 ++++++++++++++-------------- huff_utils/src/bytecode.rs | 6 +++--- 5 files changed, 35 insertions(+), 35 deletions(-) diff --git a/huff_codegen/src/irgen/constants.rs b/huff_codegen/src/irgen/constants.rs index f9c3750c..2e1b0fcc 100644 --- a/huff_codegen/src/irgen/constants.rs +++ b/huff_codegen/src/irgen/constants.rs @@ -6,7 +6,7 @@ use huff_utils::prelude::{ pub fn constant_gen( name: &str, contract: &Contract, - ir_byte_span: AstSpan, + ir_byte_span: &AstSpan, ) -> Result { // Get the first `ConstantDefinition` that matches the constant's name let constants = contract @@ -20,7 +20,7 @@ pub fn constant_gen( return Err(CodegenError { kind: CodegenErrorKind::MissingConstantDefinition(name.to_string()), - span: ir_byte_span, + span: ir_byte_span.clone(), token: None, }) }; diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index b2b05107..50a2a17c 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -47,7 +47,7 @@ pub fn statement_gen( tracing::error!(target: "codegen", "Tests may not be invoked: {}", ir_macro.name); return Err(CodegenError { kind: CodegenErrorKind::TestInvocation(ir_macro.name.clone()), - span: ir_macro.span, + span: ir_macro.span.clone(), token: None, }) } @@ -97,7 +97,7 @@ pub fn statement_gen( mis.push((*offset, mi.clone())); let mut res: BytecodeRes = match Codegen::macro_to_bytecode( - ir_macro.clone(), + ir_macro, contract, scope, *offset, @@ -205,7 +205,7 @@ pub fn statement_gen( } else { // We will still need to recurse to get accurate values let res: BytecodeRes = match Codegen::macro_to_bytecode( - ir_macro.clone(), + ir_macro, contract, scope, *offset, diff --git a/huff_codegen/src/lib.rs b/huff_codegen/src/lib.rs index 3c77f813..1291e2ef 100644 --- a/huff_codegen/src/lib.rs +++ b/huff_codegen/src/lib.rs @@ -67,9 +67,9 @@ impl Codegen { // For each MacroInvocation Statement, recurse into bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( - m_macro.clone(), + m_macro, contract, - &mut vec![m_macro], + &mut vec![m_macro.clone()], 0, &mut Vec::default(), false, @@ -96,9 +96,9 @@ impl Codegen { // For each MacroInvocation Statement, recurse into bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( - c_macro.clone(), + c_macro, contract, - &mut vec![c_macro], + &mut vec![c_macro.clone()], 0, &mut Vec::default(), false, @@ -116,10 +116,10 @@ impl Codegen { } /// Helper function to find a macro or generate a CodegenError - pub(crate) fn get_macro_by_name( + pub(crate) fn get_macro_by_name<'a>( name: &str, - contract: &Contract, - ) -> Result { + contract: &'a Contract, + ) -> Result<&'a MacroDefinition, CodegenError> { if let Some(m) = contract.find_macro_by_name(name) { Ok(m) } else { @@ -273,7 +273,7 @@ impl Codegen { /// * `offset` - Current bytecode offset /// * `mis` - Vector of tuples containing parent macro invocations as well as their offsets. pub fn macro_to_bytecode( - macro_def: MacroDefinition, + macro_def: &MacroDefinition, contract: &Contract, scope: &mut Vec, mut offset: usize, @@ -294,15 +294,15 @@ impl Codegen { let circular_codesize_invocations = circular_codesize_invocations.unwrap_or(&mut ccsi); // Loop through all intermediate bytecode representations generated from the AST - for (_ir_bytes_index, ir_byte) in ir_bytes.into_iter().enumerate() { + for (_ir_bytes_index, ir_byte) in ir_bytes.iter().enumerate() { let starting_offset = offset; - match ir_byte.ty { + match &ir_byte.ty { IRByteType::Bytes(b) => { offset += b.0.len() / 2; - bytes.push((starting_offset, b)); + bytes.push((starting_offset, b.to_owned())); } IRByteType::Constant(name) => { - let push_bytes = constant_gen(&name, contract, ir_byte.span)?; + let push_bytes = constant_gen(&name, contract, &ir_byte.span)?; offset += push_bytes.len() / 2; tracing::debug!(target: "codegen", "OFFSET: {}, PUSH BYTES: {:?}", offset, push_bytes); bytes.push((starting_offset, Bytes(push_bytes))); @@ -550,7 +550,7 @@ impl Codegen { // Add 1 to starting offset to account for the JUMPDEST opcode let mut res = Codegen::macro_to_bytecode( - macro_def.clone(), + macro_def, contract, scope, *offset + 1, diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index 5a65a80c..17a2f744 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -106,9 +106,9 @@ pub struct Contract { impl Contract { /// Returns the first macro that matches the provided name - pub fn find_macro_by_name(&self, name: &str) -> Option { + pub fn find_macro_by_name(&self, name: &str) -> Option<&MacroDefinition> { if let Some(m) = self.macros.iter().find(|m| m.name == name) { - Some(m.clone()) + Some(m) } else { tracing::warn!("Failed to find macro \"{}\" in contract", name); None @@ -133,7 +133,7 @@ impl Contract { // Derive Constructor Storage Pointers match self.find_macro_by_name("CONSTRUCTOR") { Some(m) => self.recurse_ast_constants( - &m, + m, &mut storage_pointers, &mut last_assigned_free_pointer, false, @@ -147,7 +147,7 @@ impl Contract { // Derive Main Storage Pointers match self.find_macro_by_name("MAIN") { Some(m) => self.recurse_ast_constants( - &m, + m, &mut storage_pointers, &mut last_assigned_free_pointer, false, @@ -592,14 +592,14 @@ impl MacroDefinition { let push_bytes = format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2); inner_irbytes.push(IRBytes { ty: IRByteType::Bytes(Bytes(push_bytes)), - span: statement.span.clone(), + span: &statement.span, }); } StatementType::Opcode(o) => { let opcode_str = o.string(); inner_irbytes.push(IRBytes { ty: IRByteType::Bytes(Bytes(opcode_str)), - span: statement.span.clone(), + span: &statement.span, }); // If the opcode is a push, we need to consume the next statement, which must be // a literal as checked in the parser @@ -610,7 +610,7 @@ impl MacroDefinition { let prefixed_hex_literal = o.prefix_push_literal(&hex_literal); inner_irbytes.push(IRBytes { ty: IRByteType::Bytes(Bytes(prefixed_hex_literal)), - span: statement.span.clone(), + span: &statement.span, }); } _ => { @@ -624,7 +624,7 @@ impl MacroDefinition { StatementType::Code(c) => { inner_irbytes.push(IRBytes { ty: IRByteType::Bytes(Bytes(c.to_owned())), - span: statement.span.clone(), + span: &statement.span, }); } StatementType::MacroInvocation(mi) => { @@ -633,21 +633,21 @@ impl MacroDefinition { ty: StatementType::MacroInvocation(mi.clone()), span: statement.span.clone(), }), - span: statement.span.clone(), + span: &statement.span, }); } StatementType::Constant(name) => { // Constant needs to be evaluated at the top-level inner_irbytes.push(IRBytes { ty: IRByteType::Constant(name.to_owned()), - span: statement.span.clone(), + span: &statement.span, }); } StatementType::ArgCall(arg_name) => { // Arg call needs to use a destination defined in the calling macro context inner_irbytes.push(IRBytes { ty: IRByteType::ArgCall(arg_name.to_owned()), - span: statement.span.clone(), + span: &statement.span, }); } StatementType::LabelCall(jump_to) => { @@ -657,7 +657,7 @@ impl MacroDefinition { ty: StatementType::LabelCall(jump_to.to_string()), span: statement.span.clone(), }), - span: statement.span.clone(), + span: &statement.span, }); } StatementType::Label(l) => { @@ -667,7 +667,7 @@ impl MacroDefinition { ty: StatementType::Label(l.clone()), span: statement.span.clone(), }), - span: statement.span.clone(), + span: &statement.span, }); // Recurse label statements to IRBytes Bytes @@ -679,7 +679,7 @@ impl MacroDefinition { ty: StatementType::BuiltinFunctionCall(builtin.clone()), span: statement.span.clone(), }), - span: statement.span.clone(), + span: &statement.span, }); } } diff --git a/huff_utils/src/bytecode.rs b/huff_utils/src/bytecode.rs index bd520a2b..ffdb79e1 100644 --- a/huff_utils/src/bytecode.rs +++ b/huff_utils/src/bytecode.rs @@ -14,11 +14,11 @@ pub struct Bytes(pub String); /// Intermediate Bytecode Representation #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct IRBytes { +pub struct IRBytes<'a> { /// The type of IRByte pub ty: IRByteType, /// The Span of the IRBytes - pub span: AstSpan, + pub span: &'a AstSpan, } /// IRBytes Type @@ -36,7 +36,7 @@ pub enum IRByteType { /// Full Intermediate Bytecode Representation #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct IRBytecode(pub Vec); +pub struct IRBytecode<'a>(pub Vec>); /// ToIRBytecode /// From dbfe4d6319079ebdbd001bb7236c740a15ab4985 Mon Sep 17 00:00:00 2001 From: eric tu Date: Mon, 3 Apr 2023 16:45:23 -0400 Subject: [PATCH 42/68] reduce even more allocations --- huff_codegen/src/irgen/arg_calls.rs | 20 +++++++++++--------- huff_codegen/src/lib.rs | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/huff_codegen/src/irgen/arg_calls.rs b/huff_codegen/src/irgen/arg_calls.rs index 58ccbe51..eade4db6 100644 --- a/huff_codegen/src/irgen/arg_calls.rs +++ b/huff_codegen/src/irgen/arg_calls.rs @@ -11,12 +11,12 @@ use std::str::FromStr; pub fn bubble_arg_call( arg_name: &str, bytes: &mut Vec<(usize, Bytes)>, - macro_def: &MacroDefinition, + macro_def: MacroDefinition, contract: &Contract, - scope: &mut Vec, + scope: &mut [MacroDefinition], offset: &mut usize, // mis: Parent macro invocations and their indices - mis: &mut Vec<(usize, MacroInvocation)>, + mis: &mut [(usize, MacroInvocation)], jump_table: &mut JumpTable, ) -> Result<(), CodegenError> { let starting_offset = *offset; @@ -46,9 +46,10 @@ pub fn bubble_arg_call( MacroArg::ArgCall(ac) => { tracing::info!(target: "codegen", "GOT ARG CALL \"{}\" ARG FROM MACRO INVOCATION", ac); tracing::debug!(target: "codegen", "~~~ BUBBLING UP ARG CALL"); - let mut new_scope = Vec::from(&scope[..scope.len().saturating_sub(1)]); + let scope_len = scope.len(); + let mut new_scope = &mut scope[..scope_len.saturating_sub(1)]; let bubbled_macro_invocation = new_scope.last().unwrap().clone(); - tracing::debug!(target: "codegen", "BUBBLING UP WITH MACRO DEF: {}", bubbled_macro_invocation.name); + tracing::debug!(target: "codegen", "BUBBLING UP WITH MACRO DEF: {}", &bubbled_macro_invocation.name); tracing::debug!(target: "codegen", "CURRENT MACRO DEF: {}", macro_def.name); // Only remove an invocation if not at bottom level, otherwise we'll @@ -60,27 +61,28 @@ pub fn bubble_arg_call( kind: CodegenErrorKind::MissingMacroInvocation( macro_def.name.clone(), ), - span: bubbled_macro_invocation.span, + span: bubbled_macro_invocation.span.clone(), token: None, }) } }; + let mis_len = mis.len(); return if last_mi.1.macro_name.eq(¯o_def.name) { bubble_arg_call( arg_name, bytes, - &bubbled_macro_invocation, + bubbled_macro_invocation, contract, &mut new_scope, offset, - &mut Vec::from(&mis[..mis.len().saturating_sub(1)]), + &mut mis[..mis_len.saturating_sub(1)], jump_table, ) } else { bubble_arg_call( arg_name, bytes, - &bubbled_macro_invocation, + bubbled_macro_invocation, contract, &mut new_scope, offset, diff --git a/huff_codegen/src/lib.rs b/huff_codegen/src/lib.rs index 1291e2ef..4af99b3d 100644 --- a/huff_codegen/src/lib.rs +++ b/huff_codegen/src/lib.rs @@ -335,7 +335,7 @@ impl Codegen { bubble_arg_call( &arg_name, &mut bytes, - ¯o_def, + macro_def.clone(), contract, scope, &mut offset, From a760ef429d5b1b178bc1ea406fdbd02ce8ddc4a8 Mon Sep 17 00:00:00 2001 From: eric tu Date: Mon, 3 Apr 2023 18:13:15 -0400 Subject: [PATCH 43/68] lifetimes, baby --- huff_codegen/src/irgen/arg_calls.rs | 4 ++-- huff_codegen/src/irgen/statements.rs | 8 ++++---- huff_codegen/src/lib.rs | 24 ++++++++++++------------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/huff_codegen/src/irgen/arg_calls.rs b/huff_codegen/src/irgen/arg_calls.rs index eade4db6..6e13e22b 100644 --- a/huff_codegen/src/irgen/arg_calls.rs +++ b/huff_codegen/src/irgen/arg_calls.rs @@ -11,9 +11,9 @@ use std::str::FromStr; pub fn bubble_arg_call( arg_name: &str, bytes: &mut Vec<(usize, Bytes)>, - macro_def: MacroDefinition, + macro_def: &MacroDefinition, contract: &Contract, - scope: &mut [MacroDefinition], + scope: &mut [&MacroDefinition], offset: &mut usize, // mis: Parent macro invocations and their indices mis: &mut [(usize, MacroInvocation)], diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index 50a2a17c..a21918ea 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -4,11 +4,11 @@ use crate::Codegen; /// Generates the respective Bytecode for a given Statement #[allow(clippy::too_many_arguments)] -pub fn statement_gen( +pub fn statement_gen<'a>( s: &Statement, - contract: &Contract, + contract: &'a Contract, macro_def: &MacroDefinition, - scope: &mut Vec, + scope: &mut Vec<&'a MacroDefinition>, offset: &mut usize, mis: &mut Vec<(usize, MacroInvocation)>, jump_table: &mut JumpTable, @@ -93,7 +93,7 @@ pub fn statement_gen( *offset += stack_swaps.len() + 8; } else { // Recurse into macro invocation - scope.push(ir_macro.clone()); + scope.push(ir_macro); mis.push((*offset, mi.clone())); let mut res: BytecodeRes = match Codegen::macro_to_bytecode( diff --git a/huff_codegen/src/lib.rs b/huff_codegen/src/lib.rs index 4af99b3d..002160f3 100644 --- a/huff_codegen/src/lib.rs +++ b/huff_codegen/src/lib.rs @@ -69,7 +69,7 @@ impl Codegen { let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( m_macro, contract, - &mut vec![m_macro.clone()], + &mut vec![m_macro], 0, &mut Vec::default(), false, @@ -98,7 +98,7 @@ impl Codegen { let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( c_macro, contract, - &mut vec![c_macro.clone()], + &mut vec![c_macro], 0, &mut Vec::default(), false, @@ -272,10 +272,10 @@ impl Codegen { /// * `scope` - Current scope of the recursion. Contains all macro definitions recursed so far. /// * `offset` - Current bytecode offset /// * `mis` - Vector of tuples containing parent macro invocations as well as their offsets. - pub fn macro_to_bytecode( - macro_def: &MacroDefinition, - contract: &Contract, - scope: &mut Vec, + pub fn macro_to_bytecode<'a>( + macro_def: &'a MacroDefinition, + contract: &'a Contract, + scope: &mut Vec<&'a MacroDefinition>, mut offset: usize, mis: &mut Vec<(usize, MacroInvocation)>, recursing_constructor: bool, @@ -316,7 +316,7 @@ impl Codegen { let mut push_bytes = statement_gen( &s, contract, - ¯o_def, + macro_def, scope, &mut offset, mis, @@ -335,7 +335,7 @@ impl Codegen { bubble_arg_call( &arg_name, &mut bytes, - macro_def.clone(), + macro_def, contract, scope, &mut offset, @@ -534,9 +534,9 @@ impl Codegen { /// On success, passes ownership of `bytes` back to the caller. /// On failure, returns a CodegenError. #[allow(clippy::too_many_arguments)] - pub fn append_functions( - contract: &Contract, - scope: &mut Vec, + pub fn append_functions<'a>( + contract: &'a Contract, + scope: &mut Vec<&'a MacroDefinition>, offset: &mut usize, mis: &mut Vec<(usize, MacroInvocation)>, jump_table: &mut JumpTable, @@ -546,7 +546,7 @@ impl Codegen { ) -> Result, CodegenError> { for macro_def in contract.macros.iter().filter(|m| m.outlined) { // Push the function to the scope - scope.push(macro_def.clone()); + scope.push(macro_def); // Add 1 to starting offset to account for the JUMPDEST opcode let mut res = Codegen::macro_to_bytecode( From 5cd01eaa7fc45568880c1e87826014a59828ef7b Mon Sep 17 00:00:00 2001 From: eric tu Date: Mon, 3 Apr 2023 18:32:18 -0400 Subject: [PATCH 44/68] fixed test --- huff_tests/src/runner.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/huff_tests/src/runner.rs b/huff_tests/src/runner.rs index 1660f702..4d93d527 100644 --- a/huff_tests/src/runner.rs +++ b/huff_tests/src/runner.rs @@ -174,9 +174,9 @@ impl TestRunner { // Compile the passed test macro match Codegen::macro_to_bytecode( - m.to_owned(), + m, contract, - &mut vec![m.to_owned()], + &mut vec![m], 0, &mut Vec::default(), false, From 418a385fb9e20ef6ed8cb3f0b072bb099958baab Mon Sep 17 00:00:00 2001 From: eric tu Date: Mon, 3 Apr 2023 18:42:20 -0400 Subject: [PATCH 45/68] clippy --- huff_codegen/src/irgen/arg_calls.rs | 8 ++++---- huff_codegen/src/lib.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/huff_codegen/src/irgen/arg_calls.rs b/huff_codegen/src/irgen/arg_calls.rs index 6e13e22b..91bf6cde 100644 --- a/huff_codegen/src/irgen/arg_calls.rs +++ b/huff_codegen/src/irgen/arg_calls.rs @@ -47,8 +47,8 @@ pub fn bubble_arg_call( tracing::info!(target: "codegen", "GOT ARG CALL \"{}\" ARG FROM MACRO INVOCATION", ac); tracing::debug!(target: "codegen", "~~~ BUBBLING UP ARG CALL"); let scope_len = scope.len(); - let mut new_scope = &mut scope[..scope_len.saturating_sub(1)]; - let bubbled_macro_invocation = new_scope.last().unwrap().clone(); + let new_scope = &mut scope[..scope_len.saturating_sub(1)]; + let bubbled_macro_invocation = new_scope.last().unwrap(); tracing::debug!(target: "codegen", "BUBBLING UP WITH MACRO DEF: {}", &bubbled_macro_invocation.name); tracing::debug!(target: "codegen", "CURRENT MACRO DEF: {}", macro_def.name); @@ -73,7 +73,7 @@ pub fn bubble_arg_call( bytes, bubbled_macro_invocation, contract, - &mut new_scope, + new_scope, offset, &mut mis[..mis_len.saturating_sub(1)], jump_table, @@ -84,7 +84,7 @@ pub fn bubble_arg_call( bytes, bubbled_macro_invocation, contract, - &mut new_scope, + new_scope, offset, mis, jump_table, diff --git a/huff_codegen/src/lib.rs b/huff_codegen/src/lib.rs index 002160f3..cefbfc2b 100644 --- a/huff_codegen/src/lib.rs +++ b/huff_codegen/src/lib.rs @@ -302,7 +302,7 @@ impl Codegen { bytes.push((starting_offset, b.to_owned())); } IRByteType::Constant(name) => { - let push_bytes = constant_gen(&name, contract, &ir_byte.span)?; + let push_bytes = constant_gen(name, contract, ir_byte.span)?; offset += push_bytes.len() / 2; tracing::debug!(target: "codegen", "OFFSET: {}, PUSH BYTES: {:?}", offset, push_bytes); bytes.push((starting_offset, Bytes(push_bytes))); @@ -314,7 +314,7 @@ impl Codegen { continue } let mut push_bytes = statement_gen( - &s, + s, contract, macro_def, scope, @@ -333,7 +333,7 @@ impl Codegen { // Bubble up arg call by looking through the previous scopes. // Once the arg value is found, add it to `bytes` bubble_arg_call( - &arg_name, + arg_name, &mut bytes, macro_def, contract, From b31a3f726bdb79aaa434a9b888a0f108f84bb17a Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+cheethas@users.noreply.github.com> Date: Tue, 4 Apr 2023 14:59:59 -0700 Subject: [PATCH 46/68] fix(cg): fix merge issue (#270) * fix(cg): fix minor merge issue * chore(fmt) * fix(test): merge test fix --------- Co-authored-by: cheethas --- huff_codegen/src/irgen/arg_calls.rs | 5 +++-- huff_core/tests/macro_invoc_args.rs | 32 ++++++++++++++--------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/huff_codegen/src/irgen/arg_calls.rs b/huff_codegen/src/irgen/arg_calls.rs index 61758f4b..09e81621 100644 --- a/huff_codegen/src/irgen/arg_calls.rs +++ b/huff_codegen/src/irgen/arg_calls.rs @@ -67,9 +67,10 @@ pub fn bubble_arg_call( } }; let mis_len = mis.len(); + let ac_ = &ac.to_string(); return if last_mi.1.macro_name.eq(¯o_def.name) { bubble_arg_call( - ac, + ac_, bytes, bubbled_macro_invocation, contract, @@ -80,7 +81,7 @@ pub fn bubble_arg_call( ) } else { bubble_arg_call( - &ac.to_string(), + ac_, bytes, bubbled_macro_invocation, contract, diff --git a/huff_core/tests/macro_invoc_args.rs b/huff_core/tests/macro_invoc_args.rs index 5384d567..ab11f559 100644 --- a/huff_core/tests/macro_invoc_args.rs +++ b/huff_core/tests/macro_invoc_args.rs @@ -261,10 +261,9 @@ fn test_bubbled_constant_macro_arg() { assert_eq!(bytecode.to_lowercase(), expected_bytecode.to_lowercase()); } - #[test] fn test_bubbled_arg_with_different_name() { - let source = r#" + let source = r#" #define macro MACRO_A(arg_a) = takes(0) returns(0) { } @@ -276,21 +275,20 @@ fn test_bubbled_arg_with_different_name() { } "#; - // Lex + Parse - let flattened_source = FullFileSource { source, file: None, spans: vec![] }; - let lexer = Lexer::new(flattened_source); - let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); - let mut parser = Parser::new(tokens, None); - let mut contract = parser.parse().unwrap(); - contract.derive_storage_pointers(); - - // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + // Lex + Parse + let flattened_source = FullFileSource { source, file: None, spans: vec![] }; + let lexer = Lexer::new(flattened_source.source); + let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); + let mut parser = Parser::new(tokens, None); + let mut contract = parser.parse().unwrap(); + contract.derive_storage_pointers(); - // Full expected bytecode output (generated from huffc) (placed here as a reference) - let expected_bytecode = "6001"; + // Create main and constructor bytecode + let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - // Check the bytecode - assert_eq!(main_bytecode, expected_bytecode); + // Full expected bytecode output (generated from huffc) (placed here as a reference) + let expected_bytecode = "6001"; -} \ No newline at end of file + // Check the bytecode + assert_eq!(main_bytecode, expected_bytecode); +} From e1f10aa581130d720786005302f09eceec4ce990 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 12 Apr 2023 16:24:39 -0700 Subject: [PATCH 47/68] support push0 --- huff_core/tests/push_overrides.rs | 34 +++++++++++ huff_parser/src/lib.rs | 4 +- huff_parser/tests/opcodes.rs | 96 +++++++++++++++++++++++++++++++ huff_utils/src/ast.rs | 4 +- huff_utils/src/evm.rs | 83 +++++++++++++------------- 5 files changed, 178 insertions(+), 43 deletions(-) diff --git a/huff_core/tests/push_overrides.rs b/huff_core/tests/push_overrides.rs index bff3ccd1..17d5b8fd 100644 --- a/huff_core/tests/push_overrides.rs +++ b/huff_core/tests/push_overrides.rs @@ -74,6 +74,40 @@ fn test_constructs_exact_push_override() { assert!(!has_custom_bootstrap); } +#[test] +fn test_no_push0_override() { + // Create the raw source + const OVERRIDEN_PUSH: &str = r#" + #define macro CONSTRUCTOR() = { + push0 + } + #define macro MAIN() = {} + "#; + + // Lex and Parse the source code + let flattened_source = FullFileSource { source: OVERRIDEN_PUSH, file: None, spans: vec![] }; + let lexer = Lexer::new(flattened_source.source); + let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); + let mut parser = Parser::new(tokens, None); + + // Grab the first macro + let mut contract = parser.parse().unwrap(); + // Derive storage pointers + contract.derive_storage_pointers(); + + // Instantiate Codegen + let cg = Codegen::new(); + + // The codegen instance should have no artifact + assert!(cg.artifact.is_none()); + + // Have the Codegen create the constructor bytecode + let (cbytes, has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + assert_eq!(cbytes, String::from("5F")); + assert!(!has_custom_bootstrap); +} + #[test] #[should_panic] fn test_fails_on_push_underflow() { diff --git a/huff_parser/src/lib.rs b/huff_parser/src/lib.rs index fceed3ac..255df8f9 100644 --- a/huff_parser/src/lib.rs +++ b/huff_parser/src/lib.rs @@ -560,8 +560,8 @@ impl Parser { ty: StatementType::Opcode(o), span: AstSpan(curr_spans), }); - // If the opcode is a push, we need to parse the next literal - if o.is_push() { + // If the opcode is a push that takes a literal value, we need to parse the next literal + if o.is_value_push() { match self.current_token.kind.clone() { TokenKind::Literal(val) => { let curr_spans = vec![self.current_token.span.clone()]; diff --git a/huff_parser/tests/opcodes.rs b/huff_parser/tests/opcodes.rs index ebe87566..664fec2b 100644 --- a/huff_parser/tests/opcodes.rs +++ b/huff_parser/tests/opcodes.rs @@ -148,3 +148,99 @@ fn test_push_literals() { let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); } + +#[test] +fn test_push0() { + let source: &str = r#" + #define macro MAIN() = { + push1 0x10 + push32 0x108 + push1 0x10 0x10 + push0 + } + "#; + + // Parse tokens + let flattened_source = FullFileSource { source, file: None, spans: vec![] }; + let lexer = Lexer::new(flattened_source.source); + let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); + + let expected_tokens = vec![ + Token { kind: TokenKind::Whitespace, span: Span { start: 0, end: 9, file: None } }, + Token { kind: TokenKind::Define, span: Span { start: 9, end: 16, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 16, end: 17, file: None } }, + Token { kind: TokenKind::Macro, span: Span { start: 17, end: 22, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 22, end: 23, file: None } }, + Token { + kind: TokenKind::Ident("MAIN".to_string()), + span: Span { start: 23, end: 27, file: None }, + }, + Token { kind: TokenKind::OpenParen, span: Span { start: 27, end: 28, file: None } }, + Token { kind: TokenKind::CloseParen, span: Span { start: 28, end: 29, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 29, end: 30, file: None } }, + Token { kind: TokenKind::Assign, span: Span { start: 30, end: 31, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 31, end: 32, file: None } }, + Token { kind: TokenKind::OpenBrace, span: Span { start: 32, end: 33, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 33, end: 46, file: None } }, + Token { + kind: TokenKind::Opcode(Opcode::Push1), + span: Span { start: 46, end: 51, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 51, end: 52, file: None } }, + Token { + kind: TokenKind::Literal([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, + ]), + span: Span { start: 54, end: 56, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 56, end: 69, file: None } }, + Token { + kind: TokenKind::Opcode(Opcode::Push32), + span: Span { start: 69, end: 75, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 75, end: 76, file: None } }, + Token { + kind: TokenKind::Literal([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 8, + ]), + span: Span { start: 78, end: 81, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 81, end: 94, file: None } }, + Token { + kind: TokenKind::Opcode(Opcode::Push1), + span: Span { start: 94, end: 99, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 99, end: 100, file: None } }, + Token { + kind: TokenKind::Literal([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, + ]), + span: Span { start: 102, end: 104, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 104, end: 105, file: None } }, + Token { + kind: TokenKind::Literal([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, + ]), + span: Span { start: 107, end: 109, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 109, end: 122, file: None } }, + Token { + kind: TokenKind::Opcode(Opcode::Push0), + span: Span { start: 122, end: 127, file: None }, + }, + Token { kind: TokenKind::Whitespace, span: Span { start: 127, end: 136, file: None } }, + Token { kind: TokenKind::CloseBrace, span: Span { start: 136, end: 137, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 137, end: 142, file: None } }, + Token { kind: TokenKind::Eof, span: Span { start: 142, end: 142, file: None } }, + ]; + assert_eq!(expected_tokens, tokens); + + // This should parse correctly + let mut parser = Parser::new(tokens, None); + parser.parse().unwrap(); +} diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index 17a2f744..2d2a494f 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -601,9 +601,9 @@ impl MacroDefinition { ty: IRByteType::Bytes(Bytes(opcode_str)), span: &statement.span, }); - // If the opcode is a push, we need to consume the next statement, which must be + // If the opcode is a push that takes a literal value, we need to consume the next statement, which must be // a literal as checked in the parser - if o.is_push() { + if o.is_value_push() { match statement_iter.next() { Some(Statement { ty: StatementType::Literal(l), span: _ }) => { let hex_literal: String = bytes32_to_string(l, false); diff --git a/huff_utils/src/evm.rs b/huff_utils/src/evm.rs index d843187c..84e7d513 100644 --- a/huff_utils/src/evm.rs +++ b/huff_utils/src/evm.rs @@ -6,7 +6,7 @@ use strum_macros::EnumString; /// They are arranged in a particular order such that all the opcodes that have common /// prefixes are ordered by decreasing length to avoid mismatch when lexing. /// Example : [origin, or] or [push32, ..., push3] -pub const OPCODES: [&str; 146] = [ +pub const OPCODES: [&str; 147] = [ "lt", "gt", "slt", @@ -121,6 +121,7 @@ pub const OPCODES: [&str; 146] = [ "push3", "push2", "push1", + "push0", "swap16", "swap15", "swap14", @@ -198,6 +199,7 @@ pub static OPCODES_MAP: phf::Map<&'static str, Opcode> = phf_map! { "jumpi" => Opcode::Jumpi, "pc" => Opcode::Pc, "msize" => Opcode::Msize, + "push0" => Opcode::Push0, "push1" => Opcode::Push1, "push2" => Opcode::Push2, "push3" => Opcode::Push3, @@ -438,6 +440,8 @@ pub enum Opcode { Gas, /// Marks a valid destination for jumps Jumpdest, + /// Places a 0-byte on the top of the stack; TODO: put at end? + Push0, /// Places 1 byte item on top of the stack Push1, /// Places 2 byte item on top of the stack @@ -674,6 +678,7 @@ impl Opcode { Opcode::Msize => "59", Opcode::Gas => "5a", Opcode::Jumpdest => "5b", + Opcode::Push0 => "5F", Opcode::Push1 => "60", Opcode::Push2 => "61", Opcode::Push3 => "62", @@ -759,48 +764,48 @@ impl Opcode { opcode_str.to_string() } - /// Returns if the current opcode is a push opcode - pub fn is_push(&self) -> bool { + /// Returns if the current opcode is a push opcode that takes a literal value + pub fn is_value_push(&self) -> bool { matches!( self, - Opcode::Push1 | - Opcode::Push2 | - Opcode::Push3 | - Opcode::Push4 | - Opcode::Push5 | - Opcode::Push6 | - Opcode::Push7 | - Opcode::Push8 | - Opcode::Push9 | - Opcode::Push10 | - Opcode::Push11 | - Opcode::Push12 | - Opcode::Push13 | - Opcode::Push14 | - Opcode::Push15 | - Opcode::Push16 | - Opcode::Push17 | - Opcode::Push18 | - Opcode::Push19 | - Opcode::Push20 | - Opcode::Push21 | - Opcode::Push22 | - Opcode::Push23 | - Opcode::Push24 | - Opcode::Push25 | - Opcode::Push26 | - Opcode::Push27 | - Opcode::Push28 | - Opcode::Push29 | - Opcode::Push30 | - Opcode::Push31 | - Opcode::Push32 + Opcode::Push1 + | Opcode::Push2 + | Opcode::Push3 + | Opcode::Push4 + | Opcode::Push5 + | Opcode::Push6 + | Opcode::Push7 + | Opcode::Push8 + | Opcode::Push9 + | Opcode::Push10 + | Opcode::Push11 + | Opcode::Push12 + | Opcode::Push13 + | Opcode::Push14 + | Opcode::Push15 + | Opcode::Push16 + | Opcode::Push17 + | Opcode::Push18 + | Opcode::Push19 + | Opcode::Push20 + | Opcode::Push21 + | Opcode::Push22 + | Opcode::Push23 + | Opcode::Push24 + | Opcode::Push25 + | Opcode::Push26 + | Opcode::Push27 + | Opcode::Push28 + | Opcode::Push29 + | Opcode::Push30 + | Opcode::Push31 + | Opcode::Push32 ) } /// Prefixes the literal if necessary pub fn prefix_push_literal(&self, literal: &str) -> String { - if self.is_push() { + if self.is_value_push() { if let Ok(len) = u8::from_str_radix(&self.to_string(), 16) { if len >= 96 { let size = (len - 96 + 1) * 2; @@ -809,7 +814,7 @@ impl Opcode { let zeros_needed = size - literal.len() as u8; let zero_prefix = (0..zeros_needed).map(|_| "0").collect::>().join(""); - return format!("{zero_prefix}{literal}") + return format!("{zero_prefix}{literal}"); } } } @@ -820,11 +825,11 @@ impl Opcode { /// Checks if the value overflows the given push opcode pub fn push_overflows(&self, literal: &str) -> bool { - if self.is_push() { + if self.is_value_push() { if let Ok(len) = u8::from_str_radix(&self.to_string(), 16) { if len >= 96 { let size = (len - 96 + 1) * 2; - return literal.len() > size as usize + return literal.len() > size as usize; } } } From 9a2e82a370538d6f4222a3658de90b7ce0028cb5 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 12 Apr 2023 19:28:00 -0400 Subject: [PATCH 48/68] Add `PUSH0` --- huff_utils/src/evm.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/huff_utils/src/evm.rs b/huff_utils/src/evm.rs index d843187c..f29636d2 100644 --- a/huff_utils/src/evm.rs +++ b/huff_utils/src/evm.rs @@ -6,7 +6,7 @@ use strum_macros::EnumString; /// They are arranged in a particular order such that all the opcodes that have common /// prefixes are ordered by decreasing length to avoid mismatch when lexing. /// Example : [origin, or] or [push32, ..., push3] -pub const OPCODES: [&str; 146] = [ +pub const OPCODES: [&str; 147] = [ "lt", "gt", "slt", @@ -121,6 +121,7 @@ pub const OPCODES: [&str; 146] = [ "push3", "push2", "push1", + "push0", "swap16", "swap15", "swap14", @@ -198,6 +199,7 @@ pub static OPCODES_MAP: phf::Map<&'static str, Opcode> = phf_map! { "jumpi" => Opcode::Jumpi, "pc" => Opcode::Pc, "msize" => Opcode::Msize, + "push0" => Opcode::Push0, "push1" => Opcode::Push1, "push2" => Opcode::Push2, "push3" => Opcode::Push3, @@ -438,6 +440,8 @@ pub enum Opcode { Gas, /// Marks a valid destination for jumps Jumpdest, + /// Places a zero on top of the stack + Push0, /// Places 1 byte item on top of the stack Push1, /// Places 2 byte item on top of the stack @@ -674,6 +678,7 @@ impl Opcode { Opcode::Msize => "59", Opcode::Gas => "5a", Opcode::Jumpdest => "5b", + Opcode::Push0 => "5f", Opcode::Push1 => "60", Opcode::Push2 => "61", Opcode::Push3 => "62", @@ -760,6 +765,8 @@ impl Opcode { } /// Returns if the current opcode is a push opcode + /// Note: This function excludes `PUSH0`, as it behaves differently than the other push + /// opcodes. pub fn is_push(&self) -> bool { matches!( self, From 7e4e0000c89578a26919ca3a437dc702b0e3b386 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 12 Apr 2023 16:32:42 -0700 Subject: [PATCH 49/68] update test --- huff_parser/tests/opcodes.rs | 64 ++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/huff_parser/tests/opcodes.rs b/huff_parser/tests/opcodes.rs index 664fec2b..667f2121 100644 --- a/huff_parser/tests/opcodes.rs +++ b/huff_parser/tests/opcodes.rs @@ -166,77 +166,77 @@ fn test_push0() { let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let expected_tokens = vec![ - Token { kind: TokenKind::Whitespace, span: Span { start: 0, end: 9, file: None } }, - Token { kind: TokenKind::Define, span: Span { start: 9, end: 16, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 16, end: 17, file: None } }, - Token { kind: TokenKind::Macro, span: Span { start: 17, end: 22, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 22, end: 23, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 0, end: 8, file: None } }, + Token { kind: TokenKind::Define, span: Span { start: 9, end: 15, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 16, end: 16, file: None } }, + Token { kind: TokenKind::Macro, span: Span { start: 17, end: 21, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 22, end: 22, file: None } }, Token { kind: TokenKind::Ident("MAIN".to_string()), - span: Span { start: 23, end: 27, file: None }, + span: Span { start: 23, end: 26, file: None }, }, - Token { kind: TokenKind::OpenParen, span: Span { start: 27, end: 28, file: None } }, - Token { kind: TokenKind::CloseParen, span: Span { start: 28, end: 29, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 29, end: 30, file: None } }, - Token { kind: TokenKind::Assign, span: Span { start: 30, end: 31, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 31, end: 32, file: None } }, - Token { kind: TokenKind::OpenBrace, span: Span { start: 32, end: 33, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 33, end: 46, file: None } }, + Token { kind: TokenKind::OpenParen, span: Span { start: 27, end: 27, file: None } }, + Token { kind: TokenKind::CloseParen, span: Span { start: 28, end: 28, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 29, end: 29, file: None } }, + Token { kind: TokenKind::Assign, span: Span { start: 30, end: 30, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 31, end: 31, file: None } }, + Token { kind: TokenKind::OpenBrace, span: Span { start: 32, end: 32, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 33, end: 45, file: None } }, Token { kind: TokenKind::Opcode(Opcode::Push1), - span: Span { start: 46, end: 51, file: None }, + span: Span { start: 46, end: 50, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 51, end: 52, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 51, end: 51, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, ]), - span: Span { start: 54, end: 56, file: None }, + span: Span { start: 54, end: 55, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 56, end: 69, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 56, end: 68, file: None } }, Token { kind: TokenKind::Opcode(Opcode::Push32), - span: Span { start: 69, end: 75, file: None }, + span: Span { start: 69, end: 74, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 75, end: 76, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 75, end: 75, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, ]), - span: Span { start: 78, end: 81, file: None }, + span: Span { start: 78, end: 80, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 81, end: 94, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 81, end: 93, file: None } }, Token { kind: TokenKind::Opcode(Opcode::Push1), - span: Span { start: 94, end: 99, file: None }, + span: Span { start: 94, end: 98, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 99, end: 100, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 99, end: 99, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, ]), - span: Span { start: 102, end: 104, file: None }, + span: Span { start: 102, end: 103, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 104, end: 105, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 104, end: 104, file: None } }, Token { kind: TokenKind::Literal([ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, ]), - span: Span { start: 107, end: 109, file: None }, + span: Span { start: 107, end: 108, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 109, end: 122, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 109, end: 121, file: None } }, Token { kind: TokenKind::Opcode(Opcode::Push0), - span: Span { start: 122, end: 127, file: None }, + span: Span { start: 122, end: 126, file: None }, }, - Token { kind: TokenKind::Whitespace, span: Span { start: 127, end: 136, file: None } }, - Token { kind: TokenKind::CloseBrace, span: Span { start: 136, end: 137, file: None } }, - Token { kind: TokenKind::Whitespace, span: Span { start: 137, end: 142, file: None } }, - Token { kind: TokenKind::Eof, span: Span { start: 142, end: 142, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 127, end: 135, file: None } }, + Token { kind: TokenKind::CloseBrace, span: Span { start: 136, end: 136, file: None } }, + Token { kind: TokenKind::Whitespace, span: Span { start: 137, end: 141, file: None } }, + Token { kind: TokenKind::Eof, span: Span { start: 141, end: 141, file: None } }, ]; assert_eq!(expected_tokens, tokens); From 29a60fd1bc705ecb21fa7914b1176463314182ed Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 12 Apr 2023 16:39:22 -0700 Subject: [PATCH 50/68] tweak to match clabby/push0 --- huff_utils/src/evm.rs | 70 +++++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/huff_utils/src/evm.rs b/huff_utils/src/evm.rs index 84e7d513..308d1243 100644 --- a/huff_utils/src/evm.rs +++ b/huff_utils/src/evm.rs @@ -440,7 +440,7 @@ pub enum Opcode { Gas, /// Marks a valid destination for jumps Jumpdest, - /// Places a 0-byte on the top of the stack; TODO: put at end? + /// Place a zero on top of the stack Push0, /// Places 1 byte item on top of the stack Push1, @@ -768,38 +768,38 @@ impl Opcode { pub fn is_value_push(&self) -> bool { matches!( self, - Opcode::Push1 - | Opcode::Push2 - | Opcode::Push3 - | Opcode::Push4 - | Opcode::Push5 - | Opcode::Push6 - | Opcode::Push7 - | Opcode::Push8 - | Opcode::Push9 - | Opcode::Push10 - | Opcode::Push11 - | Opcode::Push12 - | Opcode::Push13 - | Opcode::Push14 - | Opcode::Push15 - | Opcode::Push16 - | Opcode::Push17 - | Opcode::Push18 - | Opcode::Push19 - | Opcode::Push20 - | Opcode::Push21 - | Opcode::Push22 - | Opcode::Push23 - | Opcode::Push24 - | Opcode::Push25 - | Opcode::Push26 - | Opcode::Push27 - | Opcode::Push28 - | Opcode::Push29 - | Opcode::Push30 - | Opcode::Push31 - | Opcode::Push32 + Opcode::Push1 | + Opcode::Push2 | + Opcode::Push3 | + Opcode::Push4 | + Opcode::Push5 | + Opcode::Push6 | + Opcode::Push7 | + Opcode::Push8 | + Opcode::Push9 | + Opcode::Push10 | + Opcode::Push11 | + Opcode::Push12 | + Opcode::Push13 | + Opcode::Push14 | + Opcode::Push15 | + Opcode::Push16 | + Opcode::Push17 | + Opcode::Push18 | + Opcode::Push19 | + Opcode::Push20 | + Opcode::Push21 | + Opcode::Push22 | + Opcode::Push23 | + Opcode::Push24 | + Opcode::Push25 | + Opcode::Push26 | + Opcode::Push27 | + Opcode::Push28 | + Opcode::Push29 | + Opcode::Push30 | + Opcode::Push31 | + Opcode::Push32 ) } @@ -814,7 +814,7 @@ impl Opcode { let zeros_needed = size - literal.len() as u8; let zero_prefix = (0..zeros_needed).map(|_| "0").collect::>().join(""); - return format!("{zero_prefix}{literal}"); + return format!("{zero_prefix}{literal}") } } } @@ -829,7 +829,7 @@ impl Opcode { if let Ok(len) = u8::from_str_radix(&self.to_string(), 16) { if len >= 96 { let size = (len - 96 + 1) * 2; - return literal.len() > size as usize; + return literal.len() > size as usize } } } From 7f8e3fbb1d496a29aae200ecbbad87e5ad533f08 Mon Sep 17 00:00:00 2001 From: James Wenzel Date: Wed, 12 Apr 2023 16:41:18 -0700 Subject: [PATCH 51/68] further tweaks --- huff_utils/src/evm.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/huff_utils/src/evm.rs b/huff_utils/src/evm.rs index 308d1243..6aa53795 100644 --- a/huff_utils/src/evm.rs +++ b/huff_utils/src/evm.rs @@ -440,7 +440,7 @@ pub enum Opcode { Gas, /// Marks a valid destination for jumps Jumpdest, - /// Place a zero on top of the stack + /// Places a zero on top of the stack Push0, /// Places 1 byte item on top of the stack Push1, @@ -678,7 +678,7 @@ impl Opcode { Opcode::Msize => "59", Opcode::Gas => "5a", Opcode::Jumpdest => "5b", - Opcode::Push0 => "5F", + Opcode::Push0 => "5f", Opcode::Push1 => "60", Opcode::Push2 => "61", Opcode::Push3 => "62", From 7518324fa119bfe9220e94f183058e5bf12c0ef5 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 12 Apr 2023 19:51:47 -0400 Subject: [PATCH 52/68] Lint --- huff_parser/src/lib.rs | 3 ++- huff_utils/src/ast.rs | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/huff_parser/src/lib.rs b/huff_parser/src/lib.rs index 255df8f9..5eba06ab 100644 --- a/huff_parser/src/lib.rs +++ b/huff_parser/src/lib.rs @@ -560,7 +560,8 @@ impl Parser { ty: StatementType::Opcode(o), span: AstSpan(curr_spans), }); - // If the opcode is a push that takes a literal value, we need to parse the next literal + // If the opcode is a push that takes a literal value, we need to parse the next + // literal if o.is_value_push() { match self.current_token.kind.clone() { TokenKind::Literal(val) => { diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index 2d2a494f..6f767918 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -601,8 +601,9 @@ impl MacroDefinition { ty: IRByteType::Bytes(Bytes(opcode_str)), span: &statement.span, }); - // If the opcode is a push that takes a literal value, we need to consume the next statement, which must be - // a literal as checked in the parser + // If the opcode is a push that takes a literal value, we need to consume the + // next statement, which must be a literal as checked in the + // parser if o.is_value_push() { match statement_iter.next() { Some(Statement { ty: StatementType::Literal(l), span: _ }) => { From 7f3b07d088f55496ec2a92cb3141af808aed0ae3 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 12 Apr 2023 19:55:04 -0400 Subject: [PATCH 53/68] Update huff_utils/src/evm.rs Co-authored-by: Alex Beregszaszi --- huff_utils/src/evm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/huff_utils/src/evm.rs b/huff_utils/src/evm.rs index 6aa53795..8ad61a40 100644 --- a/huff_utils/src/evm.rs +++ b/huff_utils/src/evm.rs @@ -764,7 +764,7 @@ impl Opcode { opcode_str.to_string() } - /// Returns if the current opcode is a push opcode that takes a literal value + /// Returns true if the current opcode is a push opcode that takes a literal value pub fn is_value_push(&self) -> bool { matches!( self, From d42ff50c41d69154539f2f67a3173802ab3eeb07 Mon Sep 17 00:00:00 2001 From: clabby Date: Wed, 12 Apr 2023 19:55:35 -0400 Subject: [PATCH 54/68] Fix emo's test --- huff_core/tests/push_overrides.rs | 2 +- huff_utils/src/ast.rs | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/huff_core/tests/push_overrides.rs b/huff_core/tests/push_overrides.rs index 17d5b8fd..e69a3a06 100644 --- a/huff_core/tests/push_overrides.rs +++ b/huff_core/tests/push_overrides.rs @@ -104,7 +104,7 @@ fn test_no_push0_override() { // Have the Codegen create the constructor bytecode let (cbytes, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); - assert_eq!(cbytes, String::from("5F")); + assert_eq!(cbytes, String::from("5f")); assert!(!has_custom_bootstrap); } diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index 6f767918..af114ddb 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -602,8 +602,7 @@ impl MacroDefinition { span: &statement.span, }); // If the opcode is a push that takes a literal value, we need to consume the - // next statement, which must be a literal as checked in the - // parser + // next statement, which must be a literal as checked in the parser if o.is_value_push() { match statement_iter.next() { Some(Statement { ty: StatementType::Literal(l), span: _ }) => { From 43c642c0f316b15a28dd1f6ea6fbf897b0647214 Mon Sep 17 00:00:00 2001 From: Sabnock01 <24715302+Sabnock01@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:25:25 -0500 Subject: [PATCH 55/68] fix: make __ERROR accept string literal and right-pad --- huff_codegen/src/irgen/statements.rs | 11 +++++++++-- huff_core/tests/builtins.rs | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index b2b05107..9c1bcba7 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -425,12 +425,19 @@ pub fn statement_gen( .iter() .find(|e| bf.args[0].name.as_ref().unwrap().eq(&e.name)) { - // Add 28 bytes to left-pad the 4 byte selector + // Add 28 bytes to right-pad the 4 byte selector let selector = - format!("{}{}", hex::encode(error.selector), "00".repeat(28)); + format!("{}{}", "00".repeat(28), hex::encode(error.selector)); let push_bytes = format!("{}{selector}", Opcode::Push32); *offset += push_bytes.len() / 2; bytes.push((starting_offset, Bytes(push_bytes))); + } else if let Some(s) = &bf.args[0].name { + let mut signature = [0u8; 4]; // Only keep first 4 bytes + hash_bytes(&mut signature, s); + + let push_bytes = format!("{}{}{}", Opcode::Push32, "00".repeat(28), hex::encode(signature)); + *offset += push_bytes.len() / 2; + bytes.push((starting_offset, Bytes(push_bytes))); } else { tracing::error!( target: "codegen", diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index 18450060..63b9b0b9 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -548,7 +548,7 @@ fn test_error_selector_builtin() { // Input stack: [condition, message_length, message] continue jumpi // [message] - __ERROR(Error) // [error_selector, message_length, message] + __ERROR("Error(string)") // [error_selector, message_length, message] 0x00 mstore // [message_length, message] 0x20 0x04 mstore // [message_length, message] 0x24 mstore // [message] @@ -587,15 +587,15 @@ fn test_error_selector_builtin() { // Have Codegen create the runtime bytecode let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); - assert_eq!(&r_bytes[2..66], "be20788c00000000000000000000000000000000000000000000000000000000"); + assert_eq!(&r_bytes[2..66], "00000000000000000000000000000000000000000000000000000000be20788c"); assert_eq!( &r_bytes[98..162], - "08c379a000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000008c379a0" ); assert_eq!( r_bytes, String::from( - "7fbe20788c0000000000000000000000000000000000000000000000000000000060005260045260246000fd610064577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260245260445260646000fd5b50" + "7f00000000000000000000000000000000000000000000000000000000be20788c60005260045260246000fd610064577f0000000000000000000000000000000000000000000000000000000008c379a0600052602060045260245260445260646000fd5b50" ) ); } From 519c6caf629000fdf4096ddc2441c8e69648761d Mon Sep 17 00:00:00 2001 From: Sabnock01 <24715302+Sabnock01@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:33:10 -0500 Subject: [PATCH 56/68] cargo fmt --- huff_codegen/src/irgen/statements.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index 9c1bcba7..55fffbb2 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -435,7 +435,12 @@ pub fn statement_gen( let mut signature = [0u8; 4]; // Only keep first 4 bytes hash_bytes(&mut signature, s); - let push_bytes = format!("{}{}{}", Opcode::Push32, "00".repeat(28), hex::encode(signature)); + let push_bytes = format!( + "{}{}{}", + Opcode::Push32, + "00".repeat(28), + hex::encode(signature) + ); *offset += push_bytes.len() / 2; bytes.push((starting_offset, Bytes(push_bytes))); } else { From 6a322c177c1656ffe9774a1f487871995506a80c Mon Sep 17 00:00:00 2001 From: Sabnock01 <24715302+Sabnock01@users.noreply.github.com> Date: Tue, 18 Apr 2023 08:35:24 -0500 Subject: [PATCH 57/68] cargo fmt again --- huff_codegen/src/irgen/statements.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index 55fffbb2..502899bb 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -436,9 +436,9 @@ pub fn statement_gen( hash_bytes(&mut signature, s); let push_bytes = format!( - "{}{}{}", - Opcode::Push32, - "00".repeat(28), + "{}{}{}", + Opcode::Push32, + "00".repeat(28), hex::encode(signature) ); *offset += push_bytes.len() / 2; From 8cf48690f9934351f0db9052600b63cca2769292 Mon Sep 17 00:00:00 2001 From: Sabnock01 <24715302+Sabnock01@users.noreply.github.com> Date: Wed, 19 Apr 2023 01:45:57 -0500 Subject: [PATCH 58/68] remove padding changes --- huff_codegen/src/irgen/statements.rs | 4 ++-- huff_core/tests/builtins.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index 502899bb..446713a2 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -425,9 +425,9 @@ pub fn statement_gen( .iter() .find(|e| bf.args[0].name.as_ref().unwrap().eq(&e.name)) { - // Add 28 bytes to right-pad the 4 byte selector + // Add 28 bytes to left-pad the 4 byte selector let selector = - format!("{}{}", "00".repeat(28), hex::encode(error.selector)); + format!("{}{}", hex::encode(error.selector), "00".repeat(28)); let push_bytes = format!("{}{selector}", Opcode::Push32); *offset += push_bytes.len() / 2; bytes.push((starting_offset, Bytes(push_bytes))); diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index 63b9b0b9..de274a92 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -587,10 +587,10 @@ fn test_error_selector_builtin() { // Have Codegen create the runtime bytecode let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); - assert_eq!(&r_bytes[2..66], "00000000000000000000000000000000000000000000000000000000be20788c"); + assert_eq!(&r_bytes[2..66], "be20788c00000000000000000000000000000000000000000000000000000000"); assert_eq!( &r_bytes[98..162], - "0000000000000000000000000000000000000000000000000000000008c379a0" + "08c379a000000000000000000000000000000000000000000000000000000000" ); assert_eq!( r_bytes, From 8a7750c1a21207a7a8f619fd4845d0c9272480ae Mon Sep 17 00:00:00 2001 From: Sabnock01 <24715302+Sabnock01@users.noreply.github.com> Date: Wed, 19 Apr 2023 01:47:27 -0500 Subject: [PATCH 59/68] again --- huff_core/tests/builtins.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index de274a92..0fe35930 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -595,7 +595,7 @@ fn test_error_selector_builtin() { assert_eq!( r_bytes, String::from( - "7f00000000000000000000000000000000000000000000000000000000be20788c60005260045260246000fd610064577f0000000000000000000000000000000000000000000000000000000008c379a0600052602060045260245260445260646000fd5b50" + "7fbe20788c0000000000000000000000000000000000000000000000000000000060005260045260246000fd610064577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260245260445260646000fd5b50" ) ); } From 4b0642aafe71c14674d45aabbf84c231f221e5b7 Mon Sep 17 00:00:00 2001 From: Sabnock <24715302+Sabnock01@users.noreply.github.com> Date: Mon, 24 Apr 2023 08:40:24 -0500 Subject: [PATCH 60/68] Update huff_codegen/src/irgen/statements.rs Co-authored-by: clabby --- huff_codegen/src/irgen/statements.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index 446713a2..ec55d0ef 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -436,9 +436,8 @@ pub fn statement_gen( hash_bytes(&mut signature, s); let push_bytes = format!( - "{}{}{}", - Opcode::Push32, - "00".repeat(28), + "{}{}", + Opcode::Push4, hex::encode(signature) ); *offset += push_bytes.len() / 2; From 894ed88f5b0c351f2dbd287cc09013e28557f836 Mon Sep 17 00:00:00 2001 From: nicolas <48695862+merklefruit@users.noreply.github.com> Date: Tue, 25 Apr 2023 23:13:46 +0200 Subject: [PATCH 61/68] Feat/cli label indices (#274) * feat: added huff_cli flag to print jump label indices * chore: hex formatting * chore: fmt * feat: better formatting * chore: removed unnecessary format * chore: adapted code to review --- Cargo.lock | 1 + huff_cli/Cargo.toml | 1 + huff_cli/src/huffc.rs | 93 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 423f7cb0..2273cb0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -699,6 +699,7 @@ name = "huff_cli" version = "0.3.1" dependencies = [ "clap 3.2.23", + "comfy-table", "ethers-core", "huff_codegen", "huff_core", diff --git a/huff_cli/Cargo.toml b/huff_cli/Cargo.toml index d45d7659..b5ac3aa0 100644 --- a/huff_cli/Cargo.toml +++ b/huff_cli/Cargo.toml @@ -17,6 +17,7 @@ huff_core = { path = "../huff_core", version = "0.x.x" } huff_codegen = { path = "../huff_codegen", version = "0.x.x" } huff_utils = { path = "../huff_utils", version = "0.x.x" } huff_tests = { path = "../huff_tests", version = "0.x.x" } +comfy-table = "6.0.0" tracing = "0.1.34" ethers-core = "1.0.2" yansi = "0.5.1" diff --git a/huff_cli/src/huffc.rs b/huff_cli/src/huffc.rs index c8fc8b76..93bc0299 100644 --- a/huff_cli/src/huffc.rs +++ b/huff_cli/src/huffc.rs @@ -8,6 +8,7 @@ #![allow(deprecated)] use clap::{App, CommandFactory, Parser as ClapParser, Subcommand}; +use comfy_table::{modifiers::UTF8_ROUND_CORNERS, presets::UTF8_FULL, Cell, Color, Row, Table}; use ethers_core::utils::hex; use huff_codegen::Codegen; use huff_core::Compiler; @@ -18,8 +19,8 @@ use huff_tests::{ use huff_utils::{ file_provider::FileSystemFileProvider, prelude::{ - export_interfaces, gen_sol_interfaces, str_to_bytes32, unpack_files, AstSpan, CodegenError, - CodegenErrorKind, CompilerError, FileSource, Literal, OutputLocation, Span, + export_interfaces, gen_sol_interfaces, str_to_bytes32, unpack_files, AstSpan, BytecodeRes, + CodegenError, CodegenErrorKind, CompilerError, FileSource, Literal, OutputLocation, Span, }, }; use isatty::stdout_isatty; @@ -82,6 +83,10 @@ struct Huff { #[clap(short = 'v', long = "verbose")] verbose: bool, + /// Prints out the jump label PC indices for the specified contract. + #[clap(short = 'l', long = "label-indices")] + label_indices: bool, + /// Override / set constants for the compilation environment. #[clap(short = 'c', long = "constants", multiple_values = true)] constants: Option>, @@ -91,7 +96,7 @@ struct Huff { alternative_main: Option, /// Compile a specific constructor macro - #[clap(short = 'l', long = "alt-constructor")] + #[clap(short = 't', long = "alt-constructor")] alternative_constructor: Option, /// Test subcommand @@ -194,7 +199,7 @@ fn main() { let compiler: Compiler = Compiler { sources: Arc::clone(&sources), output, - alternative_main: cli.alternative_main, + alternative_main: cli.alternative_main.clone(), alternative_constructor: cli.alternative_constructor, construct_args: cli.inputs, constant_overrides: constants, @@ -204,6 +209,86 @@ fn main() { file_provider: Arc::new(FileSystemFileProvider {}), }; + if cli.label_indices { + match compiler.grab_contracts() { + Ok(contracts) => { + if contracts.len() > 1 { + eprintln!( + "{}", + Paint::red("Multiple contracts found. Please specify a single contract and try again.") + ); + std::process::exit(1); + } + + if let Some(contract) = contracts.first() { + let macro_def = contract + .find_macro_by_name( + &cli.alternative_main.unwrap_or_else(|| "MAIN".to_string()), + ) + .unwrap_or_else(|| { + eprintln!( + "{}", + Paint::red( + "Macro not found. Please specify a valid macro and try again." + ) + ); + std::process::exit(1); + }); + + // Recurse through the macro and generate bytecode + let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( + macro_def.clone(), + contract, + &mut vec![macro_def.clone()], + 0, + &mut Vec::default(), + false, + None, + ) + .unwrap(); + + if !bytecode_res.label_indices.is_empty() { + // Format the label indices nicely in a table + let mut table = Table::new(); + table.load_preset(UTF8_FULL).apply_modifier(UTF8_ROUND_CORNERS); + table + .set_header(vec![ + Cell::new("Jump Label").fg(Color::Cyan), + Cell::new("Program counter offset (in hex)").fg(Color::Cyan), + ]) + .add_rows(bytecode_res.label_indices.iter().map(|(label, index)| { + Row::from(vec![ + Cell::new(label), + Cell::new(&format!("{:#04x}", index)), + ]) + })); + println!("{table}"); + } else { + eprintln!( + "{}", + Paint::red( + "No jump labels found. Please try again.\nHint: you can run this command on a specific macro by adding the `-m ` flag.\n" + ) + ); + std::process::exit(1); + } + } else { + eprintln!( + "{}", + Paint::red("No contract found. Please specify a contract and try again.") + ); + std::process::exit(1); + } + } + Err(e) => { + tracing::error!(target: "cli", "PARSER ERRORED!"); + eprintln!("{}", Paint::red(e)); + std::process::exit(1); + } + } + return + } + if let Some(TestCommands::Test { format, match_ }) = cli.test { match compiler.grab_contracts() { Ok(contracts) => { From 80fed022048d498bd3ff5dddad5f910b44a54744 Mon Sep 17 00:00:00 2001 From: cheethas Date: Mon, 1 May 2023 15:33:55 +0000 Subject: [PATCH 62/68] fix: fmt --- huff_codegen/src/irgen/statements.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index 0ac88037..da67a7a7 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -435,11 +435,7 @@ pub fn statement_gen<'a>( let mut signature = [0u8; 4]; // Only keep first 4 bytes hash_bytes(&mut signature, s); - let push_bytes = format!( - "{}{}", - Opcode::Push4, - hex::encode(signature) - ); + let push_bytes = format!("{}{}", Opcode::Push4, hex::encode(signature)); *offset += push_bytes.len() / 2; bytes.push((starting_offset, Bytes(push_bytes))); } else { From cb7fc2642ba30fc6e9656df503a2f2bd8f7c673d Mon Sep 17 00:00:00 2001 From: cheethas Date: Mon, 1 May 2023 15:37:01 +0000 Subject: [PATCH 63/68] fix: clippy fix: clippy --- huff_cli/src/huffc.rs | 6 +++--- huff_codegen/src/lib.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/huff_cli/src/huffc.rs b/huff_cli/src/huffc.rs index 93bc0299..d7f0194a 100644 --- a/huff_cli/src/huffc.rs +++ b/huff_cli/src/huffc.rs @@ -237,9 +237,9 @@ fn main() { // Recurse through the macro and generate bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( - macro_def.clone(), + macro_def, contract, - &mut vec![macro_def.clone()], + &mut vec![macro_def], 0, &mut Vec::default(), false, @@ -259,7 +259,7 @@ fn main() { .add_rows(bytecode_res.label_indices.iter().map(|(label, index)| { Row::from(vec![ Cell::new(label), - Cell::new(&format!("{:#04x}", index)), + Cell::new(format!("{:#04x}", index)), ]) })); println!("{table}"); diff --git a/huff_codegen/src/lib.rs b/huff_codegen/src/lib.rs index cefbfc2b..640147c1 100644 --- a/huff_codegen/src/lib.rs +++ b/huff_codegen/src/lib.rs @@ -610,7 +610,7 @@ impl Codegen { constructor_bytecode: &str, has_custom_bootstrap: bool, ) -> Result { - let mut artifact: &mut Artifact = if let Some(art) = &mut self.artifact { + let artifact: &mut Artifact = if let Some(art) = &mut self.artifact { art } else { self.artifact = Some(Artifact::default()); From 07c3d9962931e785427239c462546418bbf2dbd7 Mon Sep 17 00:00:00 2001 From: cheethas Date: Mon, 1 May 2023 15:49:02 +0000 Subject: [PATCH 64/68] fix: update error test --- huff_core/tests/builtins.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index 21ebb2d2..e6923b3f 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -588,14 +588,11 @@ fn test_error_selector_builtin() { // Have Codegen create the runtime bytecode let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); assert_eq!(&r_bytes[2..66], "be20788c00000000000000000000000000000000000000000000000000000000"); - assert_eq!( - &r_bytes[98..162], - "08c379a000000000000000000000000000000000000000000000000000000000" - ); + assert_eq!(&r_bytes[98..106], "08c379a0"); assert_eq!( r_bytes, String::from( - "7fbe20788c0000000000000000000000000000000000000000000000000000000060005260045260246000fd610064577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260245260445260646000fd5b50" + "7fbe20788c0000000000000000000000000000000000000000000000000000000060005260045260246000fd610048576308c379a0600052602060045260245260445260646000fd5b50" ) ); } From 453cab27697932efe873a31a09ccf44a97f8595b Mon Sep 17 00:00:00 2001 From: Maddiaa0 <47148561+Maddiaa0@users.noreply.github.com> Date: Fri, 26 May 2023 00:28:24 +0000 Subject: [PATCH 65/68] chore(deps): bump all --- Cargo.lock | 557 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 351 insertions(+), 206 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2273cb0a..6e9dbe60 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,9 +15,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -41,14 +41,14 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a8c1df849285fbacd587de7818cc7d13be6cd2cbcd47a04fb1801b0e2706e33" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -63,6 +63,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64ct" version = "1.6.0" @@ -89,18 +95,18 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "byte-slice-cast" @@ -149,9 +155,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "num-integer", "num-traits", @@ -170,9 +176,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.23" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags", @@ -187,15 +193,15 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.2.18" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -238,9 +244,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "convert_case" @@ -250,9 +256,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -295,9 +301,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -305,9 +311,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", @@ -316,9 +322,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if 1.0.0", @@ -329,9 +335,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if 1.0.0", ] @@ -379,6 +385,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -391,9 +409,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af91f40b7355f82b0a891f50e70399475945bb0b0da4f1700ce60761c9d3e359" +checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad" dependencies = [ "csv-core", "itoa", @@ -420,6 +438,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -430,16 +458,17 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.109", ] [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -450,10 +479,23 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +dependencies = [ + "der 0.7.6", + "digest", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", + "signature 2.1.0", ] [[package]] @@ -468,28 +510,46 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", "digest", - "ff", + "ff 0.12.1", "generic-array", - "group", + "group 0.12.1", "rand_core", - "sec1", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.2", + "digest", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "rand_core", + "sec1 0.7.2", "subtle", "zeroize", ] [[package]] name = "enumn" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e88bcb3a067a6555d577aba299e75eff9942da276e6506fc6274327daa026132" +checksum = "48016319042fb7c87b78d2993084a831793a897a5cd1a2a67cab9d1eeb4b7d76" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.17", ] [[package]] @@ -549,11 +609,11 @@ dependencies = [ "arrayvec", "bytes", "chrono", - "elliptic-curve", + "elliptic-curve 0.12.3", "ethabi", "generic-array", "hex", - "k256", + "k256 0.11.6", "open-fastrlp", "rand", "rlp", @@ -576,6 +636,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "fixed-hash" version = "0.8.0" @@ -596,19 +666,20 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -623,7 +694,18 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff", + "ff 0.12.1", + "rand_core", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", "rand_core", "subtle", ] @@ -681,9 +763,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-literal" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] name = "hmac" @@ -698,7 +780,7 @@ dependencies = [ name = "huff_cli" version = "0.3.1" dependencies = [ - "clap 3.2.23", + "clap 3.2.25", "comfy-table", "ethers-core", "huff_codegen", @@ -857,14 +939,14 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", @@ -893,15 +975,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" dependencies = [ "wasm-bindgen", ] @@ -913,17 +995,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if 1.0.0", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2", "sha3", ] +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa 0.16.7", + "elliptic-curve 0.13.5", + "sha2", +] + [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -939,9 +1033,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.139" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "lock_api" @@ -985,9 +1079,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -1004,15 +1098,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "nom8" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" -dependencies = [ - "memchr", -] - [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1143,14 +1228,14 @@ dependencies = [ "bytes", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "os_str_bytes" -version = "6.4.1" +version = "6.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" [[package]] name = "overload" @@ -1160,9 +1245,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parity-scale-codec" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" +checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" dependencies = [ "arrayvec", "bitvec", @@ -1181,7 +1266,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1265,7 +1350,7 @@ dependencies = [ "proc-macro-hack", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1278,7 +1363,7 @@ dependencies = [ "phf_shared 0.11.1", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1311,7 +1396,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", + "der 0.6.1", "spki", ] @@ -1365,9 +1450,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", "toml_edit", @@ -1382,7 +1467,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1405,18 +1490,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -1459,9 +1544,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ "either", "rayon-core", @@ -1469,9 +1554,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -1496,13 +1581,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.2", ] [[package]] @@ -1511,20 +1596,26 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "revm" -version = "3.0.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284747ad0324ed0e805dcf8f412e2beccb7a547fbd84f0607865001b8719c515" +checksum = "f293f351c4c203d321744e54ed7eed3d2b6eef4c140228910dde3ac9a5ea8031" dependencies = [ "auto_impl", "revm-interpreter", @@ -1533,9 +1624,9 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "1.0.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db1b86f1d21d1852b40ec8ac9b6d31ac8a7c000875155809d41ce68f6369dc56" +checksum = "a53980a26f9b5a66d13511c35074d4b53631e157850a1d7cf1af4efc2c2b72c9" dependencies = [ "derive_more", "enumn", @@ -1545,11 +1636,11 @@ dependencies = [ [[package]] name = "revm-precompile" -version = "2.0.0" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66837781605c6dcb7f07ad87604eeab3119dae9149d69d8839073dd6f188673d" +checksum = "41320af3bd6a65153d38eb1d3638ba89104cc9513c7feedb2d8510e8307dab29" dependencies = [ - "k256", + "k256 0.13.1", "num", "once_cell", "revm-primitives", @@ -1562,11 +1653,12 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "1.0.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad165d3f69e4d14405d82c6625864ee48c162dcebdf170322e6dd80398226a9e" +checksum = "304d998f466ffef72d76c7f20b05bf08a96801736a6fb1fdef47d49a292618df" dependencies = [ "auto_impl", + "bitvec", "bytes", "derive_more", "enumn", @@ -1574,6 +1666,7 @@ dependencies = [ "hashbrown 0.13.2", "hex", "hex-literal", + "primitive-types", "rlp", "ruint", "sha3", @@ -1585,11 +1678,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ripemd" version = "0.1.3" @@ -1617,14 +1720,14 @@ checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "ruint" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad3a104dc8c3867f653b0fec89c65e00b0ceb752718ad282177a7e0f33257ac" +checksum = "9d470e29e933dac4101180fd6574971892315c414cf2961a192729089687cc9b" dependencies = [ "derive_more", "primitive-types", @@ -1657,15 +1760,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "same-file" @@ -1678,9 +1781,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.3.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "001cf62ece89779fd16105b5f515ad0e5cedcd5440d3dd806bb067978e7c3608" +checksum = "b569c32c806ec3abdf3b5869fb8bf1e0d275a7c1c9b0b05603d9464632649edf" dependencies = [ "cfg-if 1.0.0", "derive_more", @@ -1690,14 +1793,14 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.3.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "303959cf613a6f6efd19ed4b4ad5bf79966a13352716299ad532cfb115f4205c" +checksum = "53012eae69e5aa5c14671942a5dd47de59d4cdcff8532a6dd0e081faf1119482" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1712,43 +1815,56 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", "generic-array", "pkcs8", "subtle", "zeroize", ] +[[package]] +name = "sec1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.6", + "generic-array", + "subtle", + "zeroize", +] + [[package]] name = "secp256k1" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" dependencies = [ "secp256k1-sys", ] [[package]] name = "secp256k1-sys" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642a62736682fdd8c71da0eb273e453c8ac74e33b9fb310e22ba5b03ec7651ff" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" dependencies = [ "cc", ] [[package]] name = "semver" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.152" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -1776,20 +1892,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.152" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.17", ] [[package]] name = "serde_json" -version = "1.0.93" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -1809,9 +1925,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest", "keccak", @@ -1866,6 +1982,16 @@ dependencies = [ "rand_core", ] +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "siphasher" version = "0.3.10" @@ -1902,7 +2028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", ] [[package]] @@ -1936,7 +2062,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", ] [[package]] @@ -1954,9 +2080,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "syn" @@ -1969,6 +2095,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45b6ddbb36c5b969c182aec3c4a0bce7df3fbad4b77114706a49aacc80567388" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "tap" version = "1.0.1" @@ -2001,22 +2138,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.17", ] [[package]] @@ -2059,19 +2196,19 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" +checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" [[package]] name = "toml_edit" -version = "0.18.1" +version = "0.19.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" +checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" dependencies = [ "indexmap", - "nom8", "toml_datetime", + "winnow", ] [[package]] @@ -2088,20 +2225,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.17", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -2120,9 +2257,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", @@ -2156,7 +2293,7 @@ checksum = "258bc1c4f8e2e73a977812ab339d503e6feeb92700f6d07a6de4d321522d5c08" dependencies = [ "lazy_static", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2179,9 +2316,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" [[package]] name = "unicode-width" @@ -2197,9 +2334,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uuid" -version = "1.3.0" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" +checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" dependencies = [ "getrandom", ] @@ -2218,12 +2355,11 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -2235,9 +2371,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -2245,24 +2381,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.17", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2270,28 +2406,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.17", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" dependencies = [ "js-sys", "wasm-bindgen", @@ -2339,9 +2475,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -2354,45 +2490,54 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "winnow" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +dependencies = [ + "memchr", +] [[package]] name = "wyz" @@ -2411,6 +2556,6 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" From 25f04d9e09462f96eb8921c0e3061bf62a560417 Mon Sep 17 00:00:00 2001 From: Sabnock <24715302+Sabnock01@users.noreply.github.com> Date: Fri, 16 Jun 2023 01:53:17 -0500 Subject: [PATCH 66/68] chore: print help when no arguments provided (#284) --- huff_cli/src/huffc.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/huff_cli/src/huffc.rs b/huff_cli/src/huffc.rs index d7f0194a..cac7ce1b 100644 --- a/huff_cli/src/huffc.rs +++ b/huff_cli/src/huffc.rs @@ -132,7 +132,7 @@ pub(crate) fn get_input(prompt: &str) -> String { fn main() { // Into App - let app: App = Huff::into_app(); + let mut app: App = Huff::into_app(); // Parse the command line arguments let mut cli = Huff::parse(); @@ -142,6 +142,13 @@ fn main() { Compiler::init_tracing_subscriber(Some(vec![tracing::Level::DEBUG.into()])); } + // Check if no argument is provided + if cli.path.is_none() { + // Print help and exit + app.print_help().unwrap(); + return + } + // Create compiler from the Huff Args let sources: Arc> = match cli.get_inputs() { Ok(s) => Arc::new(s), From 10aa9d09b10f4a21d8d2e7be4d542c224ac69bd4 Mon Sep 17 00:00:00 2001 From: Philippe Dumonet Date: Sat, 8 Jul 2023 09:10:04 -0500 Subject: [PATCH 67/68] Compile 0 literals to the `PUSH0` opcode (#280) * feat: make literal gen reusable and default to push0 * feat: update tests to reflect push0 codegen change * fix: make `literal_gen` more idiomatic --- huff_codegen/src/irgen/constants.rs | 7 +--- .../tests/alternative_constructor_macro.rs | 2 +- huff_core/tests/alternative_main_macro.rs | 2 +- huff_core/tests/breaking_jumptable.rs | 2 +- huff_core/tests/builtins.rs | 26 ++++++------- huff_core/tests/compiling.rs | 4 +- huff_core/tests/functions.rs | 4 +- huff_core/tests/gen_artifact.rs | 3 +- huff_core/tests/in_memory.rs | 2 +- huff_core/tests/push_overrides.rs | 37 +++++++++++++++++++ huff_core/tests/recurse_bytecode.rs | 2 +- huff_utils/src/ast.rs | 3 +- huff_utils/src/bytes_util.rs | 11 +++++- 13 files changed, 73 insertions(+), 32 deletions(-) diff --git a/huff_codegen/src/irgen/constants.rs b/huff_codegen/src/irgen/constants.rs index 2e1b0fcc..e1696501 100644 --- a/huff_codegen/src/irgen/constants.rs +++ b/huff_codegen/src/irgen/constants.rs @@ -1,5 +1,5 @@ use huff_utils::prelude::{ - bytes32_to_string, AstSpan, CodegenError, CodegenErrorKind, ConstVal, Contract, + literal_gen, AstSpan, CodegenError, CodegenErrorKind, ConstVal, Contract, }; /// Transforms a constant definition into it's respective bytecode @@ -30,10 +30,7 @@ pub fn constant_gen( // prior to generating the IR bytes. tracing::info!(target: "codegen", "FOUND CONSTANT DEFINITION: {}", constant.name); let push_bytes = match &constant.value { - ConstVal::Literal(l) => { - let hex_literal: String = bytes32_to_string(l, false); - format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2) - } + ConstVal::Literal(l) => literal_gen(l), ConstVal::FreeStoragePointer(fsp) => { // If this is reached in codegen stage, the `derive_storage_pointers` // method was not called on the AST. diff --git a/huff_core/tests/alternative_constructor_macro.rs b/huff_core/tests/alternative_constructor_macro.rs index a3880637..4d9b36a9 100644 --- a/huff_core/tests/alternative_constructor_macro.rs +++ b/huff_core/tests/alternative_constructor_macro.rs @@ -28,7 +28,7 @@ fn test_alternative_constructor_macro_provided() { // Create constructor bytecode match Codegen::generate_constructor_bytecode(&contract, alternative_constructor_label) { - Ok((mb, _)) => assert_eq!(mb, "6004356000602435".to_string()), + Ok((mb, _)) => assert_eq!(mb, "6004355f602435".to_string()), Err(_) => panic!("moose"), } } diff --git a/huff_core/tests/alternative_main_macro.rs b/huff_core/tests/alternative_main_macro.rs index 265bc783..2c9bea0a 100644 --- a/huff_core/tests/alternative_main_macro.rs +++ b/huff_core/tests/alternative_main_macro.rs @@ -28,7 +28,7 @@ fn test_alternative_main_macro_provided() { // Createconstructor bytecode match Codegen::generate_main_bytecode(&contract, alternative_main) { - Ok(mb) => assert_eq!(mb, "6004356000602435".to_string()), + Ok(mb) => assert_eq!(mb, "6004355f602435".to_string()), Err(_) => panic!("moose"), } } diff --git a/huff_core/tests/breaking_jumptable.rs b/huff_core/tests/breaking_jumptable.rs index 5d37e489..7d8ee40f 100644 --- a/huff_core/tests/breaking_jumptable.rs +++ b/huff_core/tests/breaking_jumptable.rs @@ -151,5 +151,5 @@ fn test_breaking_jump_table() { // Have the Codegen create the main macro bytecode let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); - assert_eq!(mbytes, String::from("60fe6100cc600039600080fd5b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b80000c000e00100012001400160018001a001c001e00200022002400260028002a002c002e00300032003400360038003a003c003e00400042004400460048004a004c004e00500052005400560058005a005c005e00600062006400660068006a006c006e00700072007400760078007a007c007e00800082008400860088008a008c008e00900092009400960098009a009c009e00a000a200a400a600a800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800ca00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800ca00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c8")); + assert_eq!(mbytes, String::from("60fe6100ca5f395f80fd5b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b80000a000c000e00100012001400160018001a001c001e00200022002400260028002a002c002e00300032003400360038003a003c003e00400042004400460048004a004c004e00500052005400560058005a005c005e00600062006400660068006a006c006e00700072007400760078007a007c007e00800082008400860088008a008c008e00900092009400960098009a009c009e00a000a200a400a600a800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c6")); } diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index e6923b3f..2751d216 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -43,7 +43,7 @@ fn test_codesize_builtin() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); - assert_eq!(cbytes, String::from("6004")); + assert_eq!(cbytes, String::from("6003")); assert!(!custom_bootstrap); } @@ -167,7 +167,7 @@ fn test_tablesize_builtin() { // Have the Codegen create the constructor bytecode let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); - assert_eq!(mbytes, String::from("6008608061002c60003960205b60006000f35b60006000f35b60006000f35b60006000f3000c00120018001e000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001eDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF")); + assert_eq!(mbytes, String::from("600860806100235f3960205b5f5ff35b5f5ff35b5f5ff35b5f5ff3000b000f00130017000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000017DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF")); } #[test] @@ -232,7 +232,7 @@ fn test_tablestart_builtin() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); - assert_eq!(cbytes, String::from("61001e6100265b60006000f35b60006000f35b60006000f35b60006000f30006000c001200180000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018")); + assert_eq!(cbytes, String::from("61001661001e5b5f5ff35b5f5ff35b5f5ff35b5f5ff30006000a000e00120000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012")); assert!(custom_bootstrap); } @@ -296,7 +296,7 @@ fn test_jump_table_exhaustive_usage() { // Have the Codegen create the constructor bytecode let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); - assert_eq!(mbytes, String::from("608061004060003960003560e01c8063a9059cbb14610019575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002e0000000000000000000000000000000000000000000000000000000000000034000000000000000000000000000000000000000000000000000000000000003a")); + assert_eq!(mbytes, String::from("608061003e5f395f3560e01c8063a9059cbb14610017575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000038")); } #[test] @@ -356,7 +356,7 @@ fn test_jump_table_packed_exhaustive_usage() { // Have the Codegen create the main macro bytecode let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); - assert_eq!(mbytes, String::from("600861004060003960003560e01c8063a9059cbb14610019575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010028002e0034003a")); + assert_eq!(mbytes, String::from("600861003e5f395f3560e01c8063a9059cbb14610017575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010026002c00320038")); } #[test] @@ -423,7 +423,7 @@ fn test_label_clashing() { // Have the Codegen create the main macro bytecode let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); - assert_eq!(mbytes, String::from("6008610048600039608061005060003960003560e01c8063a9059cbb14610021575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b602060200100300036003c004200000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003c0000000000000000000000000000000000000000000000000000000000000042")); + assert_eq!(mbytes, String::from("60086100455f39608061004d5f395f3560e01c8063a9059cbb1461001e575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b6020602001002d00330039003f000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003f")); } #[test] @@ -468,13 +468,13 @@ fn test_func_sig_builtin() { // Have the Codegen create the constructor bytecode let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); // `transfer(address,uint256) signature = 0xa9059cbb - assert_eq!(&cbytes[16..24], "a9059cbb"); - assert_eq!(&cbytes[38..46], "a9059cbb"); - assert_eq!(&cbytes[60..68], "a9059cbb"); + assert_eq!(&cbytes[14..22], "a9059cbb"); + assert_eq!(&cbytes[36..44], "a9059cbb"); + assert_eq!(&cbytes[58..66], "a9059cbb"); assert_eq!( cbytes, String::from( - "60003560e01c8063a9059cbb14610027578063a9059cbb14610027578063a9059cbb14610027575b" + "5f3560e01c8063a9059cbb14610026578063a9059cbb14610026578063a9059cbb14610026575b" ) ); } @@ -525,7 +525,7 @@ fn test_event_hash_builtin() { ); assert_eq!( cbytes, - String::from("7fbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a87fbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a87fbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a8600055") + String::from("7fbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a87fbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a87fbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a85f55") ); } @@ -588,11 +588,11 @@ fn test_error_selector_builtin() { // Have Codegen create the runtime bytecode let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); assert_eq!(&r_bytes[2..66], "be20788c00000000000000000000000000000000000000000000000000000000"); - assert_eq!(&r_bytes[98..106], "08c379a0"); + assert_eq!(&r_bytes[94..102], "08c379a0"); assert_eq!( r_bytes, String::from( - "7fbe20788c0000000000000000000000000000000000000000000000000000000060005260045260246000fd610048576308c379a0600052602060045260245260445260646000fd5b50" + "7fbe20788c000000000000000000000000000000000000000000000000000000005f5260045260245ffd610044576308c379a05f52602060045260245260445260645ffd5b50" ) ); } diff --git a/huff_core/tests/compiling.rs b/huff_core/tests/compiling.rs index a7217028..3688d371 100644 --- a/huff_core/tests/compiling.rs +++ b/huff_core/tests/compiling.rs @@ -59,7 +59,7 @@ fn compiles_constructor_bytecode() { let (cbytes, custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); println!("Constructor Bytecode Result: {cbytes:?}"); - assert_eq!(cbytes, String::from("33600055")); + assert_eq!(cbytes, String::from("335f55")); assert!(!custom_bootstrap); } @@ -84,7 +84,7 @@ fn compiles_runtime_bytecode() { // Have the Codegen create the constructor bytecode let (cbytes, cbootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); - assert_eq!(cbytes, String::from("33600055")); + assert_eq!(cbytes, String::from("335f55")); assert!(!cbootstrap); let inputs: Vec = vec![]; diff --git a/huff_core/tests/functions.rs b/huff_core/tests/functions.rs index 9a873744..652f19c1 100644 --- a/huff_core/tests/functions.rs +++ b/huff_core/tests/functions.rs @@ -115,7 +115,7 @@ fn test_function() { let mut cg = Codegen::new(); let artifact = cg.churn(Arc::clone(&Arc::new(FileSource::default())), vec![], &rbytes, "", false).unwrap(); - assert_eq!(artifact.bytecode, String::from("60ad8060093d393df360003560e01c8063075900201461002757806319715c0d1461004457806327902d6914610061575b60443560243560043561003b92919061007e565b60005260206000f35b60443560243560043561005892919061007e565b60005260206000f35b60443560243560043561007592919061007e565b60005260206000f35b828282026000521515908015906000510483141716156100a457506000510460016100aa575b60006000fd5b9056")); + assert_eq!(artifact.bytecode, String::from("60a18060093d393df35f3560e01c8063075900201461002657806319715c0d1461004157806327902d691461005c575b60443560243560043561003a929190610077565b5f5260205ff35b604435602435600435610055929190610077565b5f5260205ff35b604435602435600435610070929190610077565b5f5260205ff35b828282025f521515908015905f5104831417161561009a57505f5104600161009e575b5f5ffd5b9056")); } #[test] @@ -209,5 +209,5 @@ fn test_nested_function() { let mut cg = Codegen::new(); let artifact = cg.churn(Arc::clone(&Arc::new(FileSource::default())), vec![], &rbytes, "", false).unwrap(); - assert_eq!(artifact.bytecode, String::from("606b8060093d393df360003560e01c80630759002014610011575b60443560243560043561002592919061005d565b60005260206000f35b82828202600052151590801590600051048314171615610054575060005104600161005a575b60006000fd5b90565b61006892919061002e565b9056")); + assert_eq!(artifact.bytecode, String::from("60638060093d393df35f3560e01c80630759002014610010575b604435602435600435610024929190610055565b5f5260205ff35b828282025f521515908015905f5104831417161561004e57505f51046001610052575b5f5ffd5b90565b61006092919061002b565b9056")); } diff --git a/huff_core/tests/gen_artifact.rs b/huff_core/tests/gen_artifact.rs index e9798b33..25ebe90d 100644 --- a/huff_core/tests/gen_artifact.rs +++ b/huff_core/tests/gen_artifact.rs @@ -40,8 +40,7 @@ fn test_missing_constructor() { assert_eq!(artifact.file, arc_source); assert_eq!( artifact.bytecode, - "601a8060093d393df360003560e01c806340c10f1914610011575b6004356000602435" - .to_string() + "60188060093d393df35f3560e01c806340c10f1914610010575b6004355f602435".to_string() ); } _ => panic!("moose"), diff --git a/huff_core/tests/in_memory.rs b/huff_core/tests/in_memory.rs index 60aaea55..069860f8 100644 --- a/huff_core/tests/in_memory.rs +++ b/huff_core/tests/in_memory.rs @@ -49,6 +49,6 @@ fn test_in_memory_compiler() { assert_eq!( artifact.bytecode, - "601a8060093d393df360003560e01c806340c10f1914610011575b6004356000602435".to_string() + "60188060093d393df35f3560e01c806340c10f1914610010575b6004355f602435".to_string() ); } diff --git a/huff_core/tests/push_overrides.rs b/huff_core/tests/push_overrides.rs index e69a3a06..73e54ac0 100644 --- a/huff_core/tests/push_overrides.rs +++ b/huff_core/tests/push_overrides.rs @@ -124,3 +124,40 @@ fn test_fails_on_push_underflow() { let mut parser = Parser::new(tokens, None); parser.parse().unwrap(); } + +#[test] +fn test_literal_to_push0() { + const LITERAL_PUSH: &str = r#" + #define constant ALICE = 0x0000 + #define constant BOB = 0x0001 + + #define macro MAIN() = { + push0 + 0x00 + 0x000000 + push1 0x00 + [ALICE] + [BOB] + } + "#; + + let flattened_source = FullFileSource { source: LITERAL_PUSH, file: None, spans: vec![] }; + let lexer = Lexer::new(flattened_source.source); + let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); + let mut parser = Parser::new(tokens, None); + + // Grab the first macro + let mut contract = parser.parse().unwrap(); + // Derive storage pointers + contract.derive_storage_pointers(); + + // Instantiate Codegen + let cg = Codegen::new(); + + // The codegen instance should have no artifact + assert!(cg.artifact.is_none()); + + // Have the Codegen create the constructor bytecode + let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + assert_eq!(cbytes, String::from("5f5f5f60005f6001")); +} diff --git a/huff_core/tests/recurse_bytecode.rs b/huff_core/tests/recurse_bytecode.rs index 3e6b1ffd..045cf21d 100644 --- a/huff_core/tests/recurse_bytecode.rs +++ b/huff_core/tests/recurse_bytecode.rs @@ -59,7 +59,7 @@ fn recurse_macro_bytecode() { assert!(!has_custom_bootstrap); // Full expected bytecode output (generated from huffc) (placed here as a reference) - let expected_bytecode = "61003f8061000d6000396000f360003560E01c8063a9059cbb1461001c57806340c10f191461002e575b60043533602435600160005260206000f35b60043560006024358060005401600055"; + let expected_bytecode = "6100398061000d6000396000f35f3560e01c8063a9059cbb1461001b57806340c10f191461002b575b6004353360243560015f5260205ff35b6004355f602435805f54015f55"; // Construct the expected output let mut artifact = Artifact::default(); diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index af114ddb..8ffb8e5d 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -588,8 +588,7 @@ impl MacroDefinition { while let Some(statement) = statement_iter.next() { match &statement.ty { StatementType::Literal(l) => { - let hex_literal: String = bytes32_to_string(l, false); - let push_bytes = format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2); + let push_bytes = literal_gen(l); inner_irbytes.push(IRBytes { ty: IRByteType::Bytes(Bytes(push_bytes)), span: &statement.span, diff --git a/huff_utils/src/bytes_util.rs b/huff_utils/src/bytes_util.rs index 685a5237..583c71a3 100644 --- a/huff_utils/src/bytes_util.rs +++ b/huff_utils/src/bytes_util.rs @@ -1,5 +1,5 @@ +use crate::evm::Opcode; use std::num::ParseIntError; - use tiny_keccak::{Hasher, Keccak}; /// Convert a string slice to a `[u8; 32]` @@ -68,3 +68,12 @@ pub fn hash_bytes(dest: &mut [u8], to_hash: &String) { hasher.update(to_hash.as_bytes()); hasher.finalize(dest); } + +/// Converts a value literal to its smallest equivalent `PUSHX` bytecode +pub fn literal_gen(l: &[u8; 32]) -> String { + let hex_literal: String = bytes32_to_string(l, false); + match hex_literal.as_str() { + "00" => Opcode::Push0.to_string(), + _ => format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2), + } +} From a7403c97e85611ca26022fe48ee6ef8e97725cc7 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Sat, 8 Jul 2023 09:33:16 -0600 Subject: [PATCH 68/68] feat(huffc): enable specifying evm version (#281) * feat: make literal gen reusable and default to push0 * feat: update tests to reflect push0 codegen change * feat: make changes, cleanup doc tests * feat: evm version scaffold * feat: user can specify whether to implement push0 * chore(huffc): bump packages version * fix: update tests to use evm_version * feat: add paris codegen tests * fix: clippy * fix: update benchmarks clean * fix: rename is_shanghai to has_push0 * revert: accidental removal of help * chore: update lock * chore(lint): clippy + fmt --------- Co-authored-by: Philogy Co-authored-by: Maddiaa0 --- Cargo.lock | 400 ++++++++++-------- README.md | 45 +- huff_cli/Cargo.toml | 2 +- huff_cli/README.md | 90 +++- huff_cli/src/huffc.rs | 12 +- huff_codegen/Cargo.toml | 2 +- huff_codegen/README.md | 14 +- huff_codegen/src/irgen/constants.rs | 5 +- huff_codegen/src/irgen/statements.rs | 3 + huff_codegen/src/lib.rs | 16 +- huff_codegen/tests/constructor_args.rs | 10 +- huff_core/Cargo.toml | 2 +- huff_core/README.md | 6 +- huff_core/benches/huff_benchmark.rs | 18 +- huff_core/src/lib.rs | 15 +- .../tests/alternative_constructor_macro.rs | 6 +- huff_core/tests/alternative_main_macro.rs | 4 +- huff_core/tests/breaking_jumptable.rs | 2 +- huff_core/tests/builtins.rs | 28 +- huff_core/tests/codegen_errors.rs | 14 +- huff_core/tests/compiling.rs | 11 +- huff_core/tests/erc20.rs | 47 +- huff_core/tests/erc721.rs | 48 ++- huff_core/tests/file_resolution.rs | 7 +- huff_core/tests/free_storage_pointer.rs | 7 +- huff_core/tests/functions.rs | 6 +- huff_core/tests/gen_artifact.rs | 8 +- huff_core/tests/in_memory.rs | 3 + huff_core/tests/macro_invoc_args.rs | 32 +- huff_core/tests/push_overrides.rs | 8 +- huff_core/tests/recurse_bytecode.rs | 6 +- huff_core/tests/test_circular_constructor.rs | 8 +- huff_core/tests/tests.rs | 4 +- huff_core/tests/verbatim.rs | 4 +- huff_js/Cargo.toml | 2 +- huff_js/src/lib.rs | 6 +- huff_lexer/Cargo.toml | 2 +- huff_parser/Cargo.toml | 2 +- huff_tests/src/runner.rs | 6 +- huff_utils/src/ast.rs | 15 +- huff_utils/src/bytecode.rs | 7 +- huff_utils/src/bytes_util.rs | 21 +- huff_utils/src/evm_version.rs | 58 +++ huff_utils/src/lib.rs | 7 +- 44 files changed, 661 insertions(+), 358 deletions(-) create mode 100644 huff_utils/src/evm_version.rs diff --git a/Cargo.lock b/Cargo.lock index 6e9dbe60..d42d6fef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,18 +15,24 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "atty" @@ -155,11 +161,11 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ - "num-integer", + "android-tzdata", "num-traits", ] @@ -184,7 +190,7 @@ dependencies = [ "bitflags", "clap_derive", "clap_lex", - "indexmap", + "indexmap 1.9.3", "once_cell", "strsim", "termcolor", @@ -232,9 +238,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "6.1.4" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7b787b0dc42e8111badfdbe4c3059158ccb2db8780352fa1b01e8ccf45cc4d" +checksum = "7e959d788268e3bf9d35ace83e81b124190378e4c91c9067524675e33394b8ba" dependencies = [ "crossterm", "strum", @@ -244,9 +250,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" [[package]] name = "convert_case" @@ -256,9 +262,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -322,9 +328,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if 1.0.0", @@ -335,18 +341,18 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "crossterm" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" dependencies = [ "bitflags", "crossterm_winapi", @@ -360,9 +366,9 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ "winapi", ] @@ -409,9 +415,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad" +checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" dependencies = [ "csv-core", "itoa", @@ -440,9 +446,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" dependencies = [ "const-oid", "zeroize", @@ -491,7 +497,7 @@ version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ - "der 0.7.6", + "der 0.7.7", "digest", "elliptic-curve 0.13.5", "rfc6979 0.4.0", @@ -543,15 +549,21 @@ dependencies = [ [[package]] name = "enumn" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48016319042fb7c87b78d2993084a831793a897a5cd1a2a67cab9d1eeb4b7d76" +checksum = "c9838a970f5de399d3070ae1739e131986b2f5dcc223c7423ca0927e3a878522" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "ethabi" version = "18.0.0" @@ -677,9 +689,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -731,6 +743,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -748,12 +766,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -778,7 +793,7 @@ dependencies = [ [[package]] name = "huff_cli" -version = "0.3.1" +version = "0.3.2" dependencies = [ "clap 3.2.25", "comfy-table", @@ -796,7 +811,7 @@ dependencies = [ [[package]] name = "huff_codegen" -version = "0.3.1" +version = "0.3.2" dependencies = [ "ethers-core", "hex", @@ -809,7 +824,7 @@ dependencies = [ [[package]] name = "huff_core" -version = "0.3.1" +version = "0.3.2" dependencies = [ "cfg-if 1.0.0", "criterion", @@ -831,7 +846,7 @@ dependencies = [ [[package]] name = "huff_lexer" -version = "0.3.1" +version = "0.3.2" dependencies = [ "huff_utils", "regex", @@ -840,7 +855,7 @@ dependencies = [ [[package]] name = "huff_parser" -version = "0.3.1" +version = "0.3.2" dependencies = [ "hex", "huff_lexer", @@ -861,7 +876,7 @@ dependencies = [ "huff_parser", "huff_utils", "lazy_static", - "phf 0.11.1", + "phf 0.11.2", "revm", "serde", "serde_json", @@ -894,7 +909,7 @@ dependencies = [ [[package]] name = "huffc-js" -version = "0.3.1" +version = "0.3.2" dependencies = [ "huff_core", "huff_utils", @@ -952,6 +967,16 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "isatty" version = "0.1.9" @@ -975,15 +1000,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -1033,15 +1058,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -1049,12 +1074,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "maplit" @@ -1068,7 +1090,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -1079,18 +1101,18 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", @@ -1186,19 +1208,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.2", "libc", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "oorandom" @@ -1233,9 +1255,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.0" +version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" [[package]] name = "overload" @@ -1245,9 +1267,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parity-scale-codec" -version = "3.5.0" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" +checksum = "756d439303e94fae44f288ba881ad29670c65b0c4b0e05674ca81061bb65f2c5" dependencies = [ "arrayvec", "bitvec", @@ -1259,9 +1281,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.4" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" +checksum = "9d884d78fcf214d70b1e239fcd1c6e5e95aa3be1881918da2e488cc946c7a476" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1281,15 +1303,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "smallvec", - "windows-sys", + "windows-targets", ] [[package]] @@ -1311,12 +1333,12 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.1", - "phf_shared 0.11.1", + "phf_macros 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -1331,11 +1353,11 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "phf_shared 0.11.1", + "phf_shared 0.11.2", "rand", ] @@ -1355,15 +1377,15 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ - "phf_generator 0.11.1", - "phf_shared 0.11.1", + "phf_generator 0.11.2", + "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", ] [[package]] @@ -1377,18 +1399,18 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ "siphasher", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pkcs8" @@ -1402,9 +1424,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ "num-traits", "plotters-backend", @@ -1415,15 +1437,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" [[package]] name = "plotters-svg" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" dependencies = [ "plotters-backend", ] @@ -1490,18 +1512,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1572,22 +1594,23 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.8.3" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.3.2", + "regex-syntax 0.7.3", ] [[package]] @@ -1599,6 +1622,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.3", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -1607,9 +1641,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "revm" @@ -1760,15 +1794,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "same-file" @@ -1781,9 +1815,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b569c32c806ec3abdf3b5869fb8bf1e0d275a7c1c9b0b05603d9464632649edf" +checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" dependencies = [ "cfg-if 1.0.0", "derive_more", @@ -1793,9 +1827,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53012eae69e5aa5c14671942a5dd47de59d4cdcff8532a6dd0e081faf1119482" +checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1830,7 +1864,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" dependencies = [ "base16ct 0.2.0", - "der 0.7.6", + "der 0.7.7", "generic-array", "subtle", "zeroize", @@ -1862,9 +1896,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" dependencies = [ "serde_derive", ] @@ -1892,20 +1926,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -1914,9 +1948,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -2000,9 +2034,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "spin" @@ -2097,9 +2131,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.17" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b6ddbb36c5b969c182aec3c4a0bce7df3fbad4b77114706a49aacc80567388" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -2138,22 +2172,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] [[package]] @@ -2196,17 +2230,17 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" dependencies = [ - "indexmap", + "indexmap 2.0.0", "toml_datetime", "winnow", ] @@ -2225,13 +2259,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] [[package]] @@ -2316,9 +2350,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-width" @@ -2334,9 +2368,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uuid" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" dependencies = [ "getrandom", ] @@ -2371,9 +2405,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -2381,24 +2415,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2406,28 +2440,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -2466,18 +2500,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -2490,51 +2524,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" dependencies = [ "memchr", ] diff --git a/README.md b/README.md index 7487db04..39a3815b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ > `huff-rs` is a [Huff](https://github.com/huff-language) compiler built in rust. - ## What is a Huff? Huff is a low-level programming language designed for developing highly optimized smart contracts that run on the Ethereum Virtual Machine (EVM). Huff does not hide the inner workings of the EVM. Instead, Huff exposes its programming stack to the developer for manual manipulation. @@ -17,7 +16,6 @@ While EVM experts can use Huff to write highly-efficient smart contracts for use To dive deeper into [Huff](https://github.com/huff-language), visit the [Official Huff Docs](https://huff.sh)(also available on [github](https://github.com/huff-language/huff-docs)). - ## Installation _Something not working? Send a message in [discord](https://discord.huff.sh)._ @@ -33,14 +31,16 @@ To avoid redirecting the script directly into bash, download and run the [huffup To install the Huff compiler, simply run `huffup`. If you have the old [huffc (TypeScript version)](https://github.com/huff-language/huffc) npm package installed globally, you can remove it with: + ```bash sudo yarn global remove huffc ``` -To make sure you are running the rust version, you can run `huffc --version` and it should respond with `huff_cli `. If it responds with `2.0.0` that means you are running the Typescript version. +To make sure you are running the rust version, you can run `huffc --version` and it should respond with `huff_cli `. If it responds with `2.0.0` that means you are running the Typescript version. + ```bash $ huffc --version -huff_cli 0.3.1 +huff_cli 0.3.2 ``` **Alternatively** @@ -59,43 +59,41 @@ OR cargo install --git https://raw.githubusercontent.com/huff-language/huff-rs --locked huff_cli ``` - ## How Fast? **Compilation Benchmarks** | Compiler | Cold (No Cache) | Light Cache | Deep Cache | Full Cache | | -------------------------------- | --------------- | ----------- | ---------- | ---------- | -| [huff-language/huff-rs][huff-rs] | XXXms | XXXms | XXXms | XXXms | -| [huff-language/huffc][huffc] | XXXms | XXXms | XXXms | XXXms | +| [huff-language/huff-rs][huff-rs] | XXXms | XXXms | XXXms | XXXms | +| [huff-language/huffc][huffc] | XXXms | XXXms | XXXms | XXXms | _Note: Compilation benchmarks were performed on [huff-examples erc20](https://github.com/huff-language/huff-examples/tree/main/erc20/contracts/ERC20.huff)._ - ## Architecture ![Huff Compiler Architecture](./assets/huffc.png) - ## Modules -* [huff_core](./huff_core): The core module to huff-rs. Resolves source file paths, executes compilation, and exports artifacts. -* [huff_cli](./huff_cli): The command line interface for the Huff compiler. -* [huff_js](./huff_js): A wasm compatible interface to the Huff compiler for JavaScript bindings. -* [huff_lexer](./huff_lexer): Takes in the source of a `.huff` file and generates a vector of `Token`s. -* [huff_parser](./huff_parser): Crafts a `Contract` AST from the vector of `Token`s generated by [huff_lexer](./huff_lexer). -* [huff_codegen](./huff_codegen): EVM Bytecode generation module that accepts an AST generated by [huff_parser](./huff_parser). -* [huff_utils](./huff_utils): Various utilities and types used by all modules. -* [huffup](./huffup): Update or revert to a specific huff-rs branch with ease. (Forked from [foundry](https://github.com/foundry-rs/foundry)) +- [huff_core](./huff_core): The core module to huff-rs. Resolves source file paths, executes compilation, and exports artifacts. +- [huff_cli](./huff_cli): The command line interface for the Huff compiler. +- [huff_js](./huff_js): A wasm compatible interface to the Huff compiler for JavaScript bindings. +- [huff_lexer](./huff_lexer): Takes in the source of a `.huff` file and generates a vector of `Token`s. +- [huff_parser](./huff_parser): Crafts a `Contract` AST from the vector of `Token`s generated by [huff_lexer](./huff_lexer). +- [huff_codegen](./huff_codegen): EVM Bytecode generation module that accepts an AST generated by [huff_parser](./huff_parser). +- [huff_utils](./huff_utils): Various utilities and types used by all modules. +- [huffup](./huffup): Update or revert to a specific huff-rs branch with ease. (Forked from [foundry](https://github.com/foundry-rs/foundry)) ## Contributing All contributions are welcome! We want to make contributing to this project as easy and transparent as possible, whether it's: - - Reporting a bug - - Discussing the current state of the code - - Submitting a fix - - Proposing new features - - Becoming a maintainer + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Becoming a maintainer We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/huff-language/huff-rs/issues/new); it's that easy! @@ -141,7 +139,6 @@ When the PR checklist isn't complete, it is **highly** recommended to make it a For breaking changes: make sure to edit the [excalidraw asset](https://excalidraw.com/#json=9YvTZp-rY9NOQnX9TC8Dz,sVM8vpgvQqGiXNXrBNshTg) and export the file to [./assets/huffc.excalidraw](./assets/huffc.excalidraw) along with an image to [./assets/huffc.png](./assets/huffc.png). - ## Safety > **Warning** @@ -150,13 +147,13 @@ For breaking changes: make sure to edit the [excalidraw asset](https://excalidra > Expect rapid iteration and **use at your own risk**. > > This code is **not designed for safety**. +> > - There are untested invariants in the code that may break. > - **You can easily shoot yourself in the foot if you're not careful.** > - You should thoroughly read the documentation and examples. > > We **do not give any warranties** and **will not be liable for any loss** incurred through any use of this codebase. - ## Acknowledgements The original [Huff Language](https://github.com/huff-language) compiler: [`huffc`](https://github.com/huff-language/huffc). diff --git a/huff_cli/Cargo.toml b/huff_cli/Cargo.toml index b5ac3aa0..5e94d20e 100644 --- a/huff_cli/Cargo.toml +++ b/huff_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_cli" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_cli/README.md b/huff_cli/README.md index 18c0f264..3970afc5 100644 --- a/huff_cli/README.md +++ b/huff_cli/README.md @@ -5,43 +5,87 @@ The `huffc` CLI is written using [clap's](https://docs.rs/clap) [derive feature] ## huffc ``` -huffc 0.3.1 +huffc 0.3.2 Huff Language Compiler built in Pure Rust. USAGE: - huffc [OPTIONS] [--] [PATH] + huffc [OPTIONS] [PATH] [SUBCOMMAND] ARGS: The contract(s) to compile OPTIONS: - -a, --artifacts Whether to generate artifacts or not - -b, --bytecode Generate and log bytecode - -d, --output-directory The output directory [default: ./artifacts] - -g, --interface Generate solidity interface for a Huff artifact - -h, --help Print help information - -i, --inputs ... The input constructor arguments - -n, --interactive Interactively input the constructor args - -o, --output The output file path - -p, --print Prints out to the terminal - -r, --bin-runtime Generate and log runtime bytecode - -s, --source-path The contracts source path [default: ./contracts] - -v, --verbose Verbose output - -V, --version Print version information - -z, --optimize Optimize compilation [WIP] + -a, --artifacts + Whether to generate artifacts or not + + -b, --bytecode + Generate and log bytecode + + -c, --constants ... + Override / set constants for the compilation environment + + -d, --output-directory + The output directory [default: ./artifacts] + + -e, --evm-version + Set the EVM version + + -g, --interface [...] + Generate solidity interface for a Huff artifact + + -h, --help + Print help information + + -i, --inputs ... + The input constructor arguments + + -l, --label-indices + Prints out the jump label PC indices for the specified contract + + -m, --alt-main + Compile a specific macro + + -n, --interactive + Interactively input the constructor args + + -o, --output + The output file path + + -p, --print + Prints out to the terminal + + -r, --bin-runtime + Generate and log runtime bytecode + + -s, --source-path + The contracts source path [default: ./contracts] + + -t, --alt-constructor + Compile a specific constructor macro + + -v, --verbose + Verbose output + + -V, --version + Print version information + + -z, --optimize + Optimize compilation [WIP] + ``` _NOTE: To generate the above output, run: `huffc --help`_ - ## Usage To run `huffc` from the command line, you can simply run: + ```bash huffc --help ``` By default, huffc will attempt to compile all contracts in the `contracts` directory. If there is no `contracts` directory present, the following will spit out an error like so: + ```bash,color=red ~ huffc @@ -90,18 +134,19 @@ huffc -o ./artifact.json ./huff-examples/erc20/contracts/ERC20.huff ``` **NOTE**: The following will _not_ compile since multiple artifacts cannot be output to the same artifact json file. + ```bash huffc -o ./artifact.json ./contracts/ ``` - #### Entering Constructor Arguments `huffc` supports passing in constructor arguments to the contract. This is done by passing in the `--interactive` (shorthand: `-n`) flag or passing the `--inputs` (shorthand: `-i`) flag. - and passing in the arguments as a comma separated list. +and passing in the arguments as a comma separated list. For example, to compile a contract (let's call it `example.huff`) with the following constructor definition: + ```huff #define macro CONSTRUCTOR(uint256, address) = takes(0) returns (0) { 0x04 calldataload @@ -119,14 +164,14 @@ $ huffc -b -n ./contracts/example.huff [INTERACTIVE] Enter a uint256 for constructor param: 100 [INTERACTIVE] Enter a address for constructor param: 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef -33600.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef +335f.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef ``` Alternatively, you can enter the arguments as a comma separated list by using the `-i` or `--inputs` flag like so: ```bash $ huffc -b -i 100, 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef ./contracts/example.huff -33600.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef +335f0.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef ``` #### Other Options @@ -136,15 +181,16 @@ $ huffc -b -i 100, 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef ./contracts/exampl - `-z` or `--optimize`: Optimizes the contract compilation - a work in progress. - `-g` or `--interface`: Generates a solidity interface for the contract. - ## Building huffc from source To run `huffc` from the command line, you can use the following command: + ```bash cargo run --bin huffc ``` To pass arguments into the `huffc` binary, simply pass them in after a `--` flag. For example, to get the `huffc` version (a `-V` flag), you can run: + ```bash cargo run --bin huffc -- -V ``` diff --git a/huff_cli/src/huffc.rs b/huff_cli/src/huffc.rs index cac7ce1b..f0605bc0 100644 --- a/huff_cli/src/huffc.rs +++ b/huff_cli/src/huffc.rs @@ -20,7 +20,8 @@ use huff_utils::{ file_provider::FileSystemFileProvider, prelude::{ export_interfaces, gen_sol_interfaces, str_to_bytes32, unpack_files, AstSpan, BytecodeRes, - CodegenError, CodegenErrorKind, CompilerError, FileSource, Literal, OutputLocation, Span, + CodegenError, CodegenErrorKind, CompilerError, EVMVersion, FileSource, Literal, + OutputLocation, Span, }, }; use isatty::stdout_isatty; @@ -99,6 +100,10 @@ struct Huff { #[clap(short = 't', long = "alt-constructor")] alternative_constructor: Option, + /// Set the EVM version + #[clap(short = 'e', long = "evm-version")] + evm_version: Option, + /// Test subcommand #[clap(subcommand)] test: Option, @@ -185,6 +190,9 @@ fn main() { .collect() }); + // Parse the EVM version + let evm_version = EVMVersion::from(cli.evm_version); + let mut use_cache = true; if cli.interactive { // Don't accept configured inputs @@ -204,6 +212,7 @@ fn main() { }; let compiler: Compiler = Compiler { + evm_version: &evm_version, sources: Arc::clone(&sources), output, alternative_main: cli.alternative_main.clone(), @@ -244,6 +253,7 @@ fn main() { // Recurse through the macro and generate bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( + &evm_version, macro_def, contract, &mut vec![macro_def], diff --git a/huff_codegen/Cargo.toml b/huff_codegen/Cargo.toml index 247801e3..bc46ba22 100644 --- a/huff_codegen/Cargo.toml +++ b/huff_codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_codegen" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_codegen/README.md b/huff_codegen/README.md index 1cd5ba81..7c5d2b8c 100644 --- a/huff_codegen/README.md +++ b/huff_codegen/README.md @@ -36,13 +36,13 @@ assert!(cg.ast.is_none()); assert!(cg.artifact.is_none()); // ERC20 Bytecode -let main_bytecode = "60003560E01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; -let constructor_bytecode = "33600055"; +let main_bytecode = "5f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3"; +let constructor_bytecode = "335f55"; let inputs = vec![]; let churn_res = cg.churn(Arc::new(FileSource::default()), inputs, main_bytecode, constructor_bytecode, false); // Validate the output bytecode -assert_eq!(churn_res.unwrap().bytecode, "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3".to_lowercase()); +assert_eq!(churn_res.unwrap().bytecode, "335f5561019980600d3d393df35f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3".to_lowercase()); // Write the compile artifact out to a file // cg.export("./output.json"); @@ -97,10 +97,10 @@ let contract = Contract { }; // Generate the main bytecode -let main_bytecode: String = Codegen::generate_main_bytecode(&contract, None).unwrap(); +let main_bytecode: String = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Validate the output bytecode -assert_eq!(main_bytecode, "60003560e01c"); +assert_eq!(main_bytecode, "5f3560e01c"); ``` Similarly, once you have a [Contract](../huff_utils/ast/struct.Contract.html) instance with a simple **CONSTRUCTOR** macro definition. You can generate the constructor/creation bytecode using the [generate_constructor_bytecode](struct.Codegen.html#method.generate_constructor_bytecode) function. @@ -152,9 +152,9 @@ let contract = Contract { }; // Generate the constructor bytecode -let (constructor_bytecode, has_custom_bootstrap): (String, bool) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); +let (constructor_bytecode, has_custom_bootstrap): (String, bool) = Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Validate the output bytecode -assert_eq!(constructor_bytecode, "60003560e01c"); +assert_eq!(constructor_bytecode, "5f3560e01c"); assert_eq!(has_custom_bootstrap, false); ``` diff --git a/huff_codegen/src/irgen/constants.rs b/huff_codegen/src/irgen/constants.rs index e1696501..b9706bda 100644 --- a/huff_codegen/src/irgen/constants.rs +++ b/huff_codegen/src/irgen/constants.rs @@ -1,9 +1,10 @@ use huff_utils::prelude::{ - literal_gen, AstSpan, CodegenError, CodegenErrorKind, ConstVal, Contract, + literal_gen, AstSpan, CodegenError, CodegenErrorKind, ConstVal, Contract, EVMVersion, }; /// Transforms a constant definition into it's respective bytecode pub fn constant_gen( + evm_version: &EVMVersion, name: &str, contract: &Contract, ir_byte_span: &AstSpan, @@ -30,7 +31,7 @@ pub fn constant_gen( // prior to generating the IR bytes. tracing::info!(target: "codegen", "FOUND CONSTANT DEFINITION: {}", constant.name); let push_bytes = match &constant.value { - ConstVal::Literal(l) => literal_gen(l), + ConstVal::Literal(l) => literal_gen(evm_version, l), ConstVal::FreeStoragePointer(fsp) => { // If this is reached in codegen stage, the `derive_storage_pointers` // method was not called on the AST. diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index da67a7a7..96688202 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -5,6 +5,7 @@ use crate::Codegen; /// Generates the respective Bytecode for a given Statement #[allow(clippy::too_many_arguments)] pub fn statement_gen<'a>( + evm_version: &EVMVersion, s: &Statement, contract: &'a Contract, macro_def: &MacroDefinition, @@ -97,6 +98,7 @@ pub fn statement_gen<'a>( mis.push((*offset, mi.clone())); let mut res: BytecodeRes = match Codegen::macro_to_bytecode( + evm_version, ir_macro, contract, scope, @@ -205,6 +207,7 @@ pub fn statement_gen<'a>( } else { // We will still need to recurse to get accurate values let res: BytecodeRes = match Codegen::macro_to_bytecode( + evm_version, ir_macro, contract, scope, diff --git a/huff_codegen/src/lib.rs b/huff_codegen/src/lib.rs index 640147c1..aca743ab 100644 --- a/huff_codegen/src/lib.rs +++ b/huff_codegen/src/lib.rs @@ -12,7 +12,7 @@ use huff_utils::{ bytes_util, error::CodegenError, evm::Opcode, - prelude::{format_even_bytes, pad_n_bytes, CodegenErrorKind, FileSource, Span}, + prelude::{format_even_bytes, pad_n_bytes, CodegenErrorKind, EVMVersion, FileSource, Span}, types::EToken, }; use regex::Regex; @@ -56,6 +56,7 @@ impl Codegen { /// Generates main bytecode from a Contract AST pub fn generate_main_bytecode( + evm_version: &EVMVersion, contract: &Contract, alternative_main: Option, ) -> Result { @@ -67,6 +68,7 @@ impl Codegen { // For each MacroInvocation Statement, recurse into bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( + evm_version, m_macro, contract, &mut vec![m_macro], @@ -84,6 +86,7 @@ impl Codegen { /// Generates constructor bytecode from a Contract AST pub fn generate_constructor_bytecode( + evm_version: &EVMVersion, contract: &Contract, alternative_constructor: Option, ) -> Result<(String, bool), CodegenError> { @@ -96,6 +99,7 @@ impl Codegen { // For each MacroInvocation Statement, recurse into bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( + evm_version, c_macro, contract, &mut vec![c_macro], @@ -272,7 +276,9 @@ impl Codegen { /// * `scope` - Current scope of the recursion. Contains all macro definitions recursed so far. /// * `offset` - Current bytecode offset /// * `mis` - Vector of tuples containing parent macro invocations as well as their offsets. + #[allow(clippy::too_many_arguments)] pub fn macro_to_bytecode<'a>( + evm_version: &EVMVersion, macro_def: &'a MacroDefinition, contract: &'a Contract, scope: &mut Vec<&'a MacroDefinition>, @@ -283,7 +289,7 @@ impl Codegen { ) -> Result { // Get intermediate bytecode representation of the macro definition let mut bytes: Vec<(usize, Bytes)> = Vec::default(); - let ir_bytes = macro_def.to_irbytecode()?.0; + let ir_bytes = macro_def.to_irbytecode(evm_version)?.0; // Define outer loop variables let mut jump_table = JumpTable::new(); @@ -302,7 +308,7 @@ impl Codegen { bytes.push((starting_offset, b.to_owned())); } IRByteType::Constant(name) => { - let push_bytes = constant_gen(name, contract, ir_byte.span)?; + let push_bytes = constant_gen(evm_version, name, contract, ir_byte.span)?; offset += push_bytes.len() / 2; tracing::debug!(target: "codegen", "OFFSET: {}, PUSH BYTES: {:?}", offset, push_bytes); bytes.push((starting_offset, Bytes(push_bytes))); @@ -314,6 +320,7 @@ impl Codegen { continue } let mut push_bytes = statement_gen( + evm_version, s, contract, macro_def, @@ -355,6 +362,7 @@ impl Codegen { // (i.e., we're at the top level of recursion) if scope.len() == 1 { bytes = Codegen::append_functions( + evm_version, contract, scope, &mut offset, @@ -535,6 +543,7 @@ impl Codegen { /// On failure, returns a CodegenError. #[allow(clippy::too_many_arguments)] pub fn append_functions<'a>( + evm_version: &EVMVersion, contract: &'a Contract, scope: &mut Vec<&'a MacroDefinition>, offset: &mut usize, @@ -550,6 +559,7 @@ impl Codegen { // Add 1 to starting offset to account for the JUMPDEST opcode let mut res = Codegen::macro_to_bytecode( + evm_version, macro_def, contract, scope, diff --git a/huff_codegen/tests/constructor_args.rs b/huff_codegen/tests/constructor_args.rs index 065c175f..24287e66 100644 --- a/huff_codegen/tests/constructor_args.rs +++ b/huff_codegen/tests/constructor_args.rs @@ -13,7 +13,7 @@ fn encode_simple_constructor_args() { let expected_bytes32: Vec = str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap(); // Bogus constructors args - let args: Vec = vec![ + let args: Vec = [ "Hello", "10000", "false", @@ -44,7 +44,7 @@ fn encode_array_constructor_args() { let _expected_bytes32: Vec = str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap(); // Bogus constructors args - let args: Vec = vec![ + let args: Vec = [ "[100, 200, 300]", "[0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087, 0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087]", "[true, false, false]", @@ -95,14 +95,12 @@ fn encode_missing_brackets_array_constructor_args() { let _expected_bytes32: Vec = str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap(); // Bogus constructors args - let args: Vec = vec![ - " 100, 200, 300 ", + let args: Vec = [" 100, 200, 300 ", " 0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087, 0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087", "true, false, false", "Hello, World, Yes", " \"Hello\", \"World\", \"Yes\"", - "'Hello', 'World', 'Yes' ", - ] + "'Hello', 'World', 'Yes' "] .iter() .map(|s| s.to_string()) .collect(); diff --git a/huff_core/Cargo.toml b/huff_core/Cargo.toml index e6d8eb0e..9249a887 100644 --- a/huff_core/Cargo.toml +++ b/huff_core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_core" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_core/README.md b/huff_core/README.md index edc2f902..9d33f152 100644 --- a/huff_core/README.md +++ b/huff_core/README.md @@ -18,12 +18,14 @@ Below we demonstrate taking a source file `../huff-examples/erc20/contracts/ERC2 use huff_core::Compiler; use huff_utils::error::CompilerError; use huff_utils::artifact::Artifact; +use huff_utils::prelude::EVMVersion; use std::sync::Arc; use std::cell::RefCell; use std::rc::Rc; -// Instantiate the Compiler Instance -let mut compiler = Compiler::new(Arc::new(vec!["../huff-examples/erc20/contracts/ERC20.huff".to_string()]), None, None, None, None, None, false, false); +// Instantiate the Compiler Instance with a targeted evm version. +let evm_version = &EVMVersion::default(); +let mut compiler = Compiler::new(evm_version, Arc::new(vec!["../huff-examples/erc20/contracts/ERC20.huff".to_string()]), None, None, None, None, None, false, false); // Execute the compiler let res: Result>, Arc> = compiler.execute(); diff --git a/huff_core/benches/huff_benchmark.rs b/huff_core/benches/huff_benchmark.rs index a67a5c0a..e001cf71 100644 --- a/huff_core/benches/huff_benchmark.rs +++ b/huff_core/benches/huff_benchmark.rs @@ -102,11 +102,13 @@ fn codegen_erc20_benchmark(c: &mut Criterion) { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Isolate codegen to benchmark c.bench_function("Codegen: ERC-20", |b| b.iter(|| { // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version,&contract, None).unwrap(); + let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(evm_version,&contract, None).unwrap(); // Churn let mut cg = Codegen::new(); @@ -149,9 +151,11 @@ fn erc20_compilation_benchmark(c: &mut Criterion) { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version,&contract, None).unwrap(); + let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(evm_version, &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); @@ -194,9 +198,11 @@ fn erc721_compilation_benchmark(c: &mut Criterion) { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version, &contract, None).unwrap(); + let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(evm_version,&contract, None).unwrap(); // Churn let mut cg = Codegen::new(); diff --git a/huff_core/src/lib.rs b/huff_core/src/lib.rs index 5aeb5eb3..e40e0151 100644 --- a/huff_core/src/lib.rs +++ b/huff_core/src/lib.rs @@ -43,9 +43,11 @@ pub(crate) mod cache; /// /// ```rust /// use huff_core::Compiler; +/// use huff_utils::prelude::EVMVersion; /// use std::sync::Arc; /// /// let compiler = Compiler::new( +/// &EVMVersion::default(), /// Arc::new(vec!["../huff-examples/erc20/contracts/ERC20.huff".to_string()]), /// Some("./artifacts".to_string()), /// None, @@ -57,7 +59,9 @@ pub(crate) mod cache; /// ); /// ``` #[derive(Debug, Clone)] -pub struct Compiler<'a> { +pub struct Compiler<'a, 'l> { + /// The EVM version to compile for + pub evm_version: &'l EVMVersion, /// The location of the files to compile pub sources: Arc>, /// The output location @@ -80,10 +84,11 @@ pub struct Compiler<'a> { pub file_provider: Arc>, } -impl<'a> Compiler<'a> { +impl<'a, 'l> Compiler<'a, 'l> { /// Public associated function to instantiate a new compiler. #[allow(clippy::too_many_arguments)] pub fn new( + evm_version: &'l EVMVersion, sources: Arc>, output: Option, alternative_main: Option, @@ -97,6 +102,7 @@ impl<'a> Compiler<'a> { Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()])); } Self { + evm_version, sources, output, alternative_main, @@ -112,7 +118,9 @@ impl<'a> Compiler<'a> { /// Creates a new instance of a compiler with an in-memory FileReader from the supplied sources /// map. + #[allow(clippy::too_many_arguments)] pub fn new_in_memory( + evm_version: &'l EVMVersion, sources: Arc>, file_sources: HashMap, alternative_main: Option, @@ -125,6 +133,7 @@ impl<'a> Compiler<'a> { Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()])); } Self { + evm_version, sources, output: None, alternative_main, @@ -399,6 +408,7 @@ impl<'a> Compiler<'a> { // Primary Bytecode Generation let mut cg = Codegen::new(); let main_bytecode = match Codegen::generate_main_bytecode( + self.evm_version, &contract, self.alternative_main.clone(), ) { @@ -426,6 +436,7 @@ impl<'a> Compiler<'a> { let inputs = self.get_constructor_args(); let (constructor_bytecode, has_custom_bootstrap) = match Codegen::generate_constructor_bytecode( + self.evm_version, &contract, self.alternative_constructor.clone(), ) { diff --git a/huff_core/tests/alternative_constructor_macro.rs b/huff_core/tests/alternative_constructor_macro.rs index 4d9b36a9..256923f9 100644 --- a/huff_core/tests/alternative_constructor_macro.rs +++ b/huff_core/tests/alternative_constructor_macro.rs @@ -27,7 +27,11 @@ fn test_alternative_constructor_macro_provided() { let alternative_constructor_label = Some(String::from("ALT_CONSTRUCTOR")); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, alternative_constructor_label) { + match Codegen::generate_constructor_bytecode( + &EVMVersion::default(), + &contract, + alternative_constructor_label, + ) { Ok((mb, _)) => assert_eq!(mb, "6004355f602435".to_string()), Err(_) => panic!("moose"), } diff --git a/huff_core/tests/alternative_main_macro.rs b/huff_core/tests/alternative_main_macro.rs index 2c9bea0a..bbc2c5bc 100644 --- a/huff_core/tests/alternative_main_macro.rs +++ b/huff_core/tests/alternative_main_macro.rs @@ -26,8 +26,8 @@ fn test_alternative_main_macro_provided() { let alternative_main = Some(String::from("MINT")); - // Createconstructor bytecode - match Codegen::generate_main_bytecode(&contract, alternative_main) { + // Create main bytecode + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, alternative_main) { Ok(mb) => assert_eq!(mb, "6004355f602435".to_string()), Err(_) => panic!("moose"), } diff --git a/huff_core/tests/breaking_jumptable.rs b/huff_core/tests/breaking_jumptable.rs index 7d8ee40f..9866179a 100644 --- a/huff_core/tests/breaking_jumptable.rs +++ b/huff_core/tests/breaking_jumptable.rs @@ -150,6 +150,6 @@ fn test_breaking_jump_table() { assert!(cg.artifact.is_none()); // Have the Codegen create the main macro bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("60fe6100ca5f395f80fd5b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b80000a000c000e00100012001400160018001a001c001e00200022002400260028002a002c002e00300032003400360038003a003c003e00400042004400460048004a004c004e00500052005400560058005a005c005e00600062006400660068006a006c006e00700072007400760078007a007c007e00800082008400860088008a008c008e00900092009400960098009a009c009e00a000a200a400a600a800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c6")); } diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index 2751d216..d2188ebc 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -42,7 +42,7 @@ fn test_codesize_builtin() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("6003")); assert!(!custom_bootstrap); } @@ -76,10 +76,12 @@ fn test_dyn_constructor_arg_builtin() { // The codegen instance should have no artifact assert!(cg.artifact.is_none()); + let evm_version = &EVMVersion::default(); + // Have the Codegen create the constructor bytecode let (constructor_code, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); - let main_code = Codegen::generate_main_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(evm_version, &contract, None).unwrap(); + let main_code = Codegen::generate_main_bytecode(evm_version, &contract, None).unwrap(); let args = Codegen::encode_constructor_args(vec![String::from("testing")]); let final_bytecode = cg.churn( @@ -166,7 +168,7 @@ fn test_tablesize_builtin() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("600860806100235f3960205b5f5ff35b5f5ff35b5f5ff35b5f5ff3000b000f00130017000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000017DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF")); } @@ -231,7 +233,7 @@ fn test_tablestart_builtin() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("61001661001e5b5f5ff35b5f5ff35b5f5ff35b5f5ff30006000a000e00120000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012")); assert!(custom_bootstrap); } @@ -295,7 +297,7 @@ fn test_jump_table_exhaustive_usage() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("608061003e5f395f3560e01c8063a9059cbb14610017575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000038")); } @@ -355,7 +357,7 @@ fn test_jump_table_packed_exhaustive_usage() { assert!(cg.artifact.is_none()); // Have the Codegen create the main macro bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("600861003e5f395f3560e01c8063a9059cbb14610017575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010026002c00320038")); } @@ -422,7 +424,7 @@ fn test_label_clashing() { assert!(cg.artifact.is_none()); // Have the Codegen create the main macro bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("60086100455f39608061004d5f395f3560e01c8063a9059cbb1461001e575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b6020602001002d00330039003f000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003f")); } @@ -466,7 +468,7 @@ fn test_func_sig_builtin() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let cbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // `transfer(address,uint256) signature = 0xa9059cbb assert_eq!(&cbytes[14..22], "a9059cbb"); assert_eq!(&cbytes[36..44], "a9059cbb"); @@ -498,6 +500,8 @@ fn test_event_hash_builtin() { let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); + let evm_version = EVMVersion::default(); + // Parse the AST let mut contract = parser.parse().unwrap(); @@ -511,7 +515,7 @@ fn test_event_hash_builtin() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let cbytes = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // `transfer(address,address,uint256) signature = // 0xbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a8 assert_eq!(&cbytes[2..66], "beabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a8"); @@ -586,7 +590,7 @@ fn test_error_selector_builtin() { assert!(cg.artifact.is_none()); // Have Codegen create the runtime bytecode - let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let r_bytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(&r_bytes[2..66], "be20788c00000000000000000000000000000000000000000000000000000000"); assert_eq!(&r_bytes[94..102], "08c379a0"); assert_eq!( @@ -626,7 +630,7 @@ fn test_rightpad_builtin() { assert!(cg.artifact.is_none()); // Have Codegen create the runtime bytecode - let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let r_bytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(&r_bytes[2..66], "a57b000000000000000000000000000000000000000000000000000000000000"); assert_eq!( &r_bytes[68..132], diff --git a/huff_core/tests/codegen_errors.rs b/huff_core/tests/codegen_errors.rs index a4d5754a..57454f05 100644 --- a/huff_core/tests/codegen_errors.rs +++ b/huff_core/tests/codegen_errors.rs @@ -39,7 +39,7 @@ fn test_storage_pointers_not_derived() { let contract = parser.parse().unwrap(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -99,7 +99,7 @@ fn test_invalid_constant_definition() { contract.derive_storage_pointers(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -142,7 +142,7 @@ fn test_missing_constructor() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -175,7 +175,7 @@ fn test_missing_main() { contract.derive_storage_pointers(); // Createconstructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -210,7 +210,7 @@ fn test_missing_when_alternative_main_provided() { let alternative_main = Some(String::from("NAH")); // Createconstructor bytecode - match Codegen::generate_main_bytecode(&contract, alternative_main) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, alternative_main) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -251,7 +251,7 @@ fn test_unknown_macro_definition() { contract.derive_storage_pointers(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -298,7 +298,7 @@ fn test_unmatched_jump_label() { contract.derive_storage_pointers(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( diff --git a/huff_core/tests/compiling.rs b/huff_core/tests/compiling.rs index 3688d371..a84e71f9 100644 --- a/huff_core/tests/compiling.rs +++ b/huff_core/tests/compiling.rs @@ -57,7 +57,7 @@ fn compiles_constructor_bytecode() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); println!("Constructor Bytecode Result: {cbytes:?}"); assert_eq!(cbytes, String::from("335f55")); assert!(!custom_bootstrap); @@ -83,15 +83,16 @@ fn compiles_runtime_bytecode() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let (cbytes, cbootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let (cbytes, cbootstrap) = + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("335f55")); assert!(!cbootstrap); let inputs: Vec = vec![]; // ERC20 Bytecode let main_bytecode = - "60003560E01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; - let constructor_bytecode = "33600055"; + "5f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3"; + let constructor_bytecode = "335f55"; let churn_res = cg.churn( Arc::new(FileSource::default()), inputs, @@ -101,7 +102,7 @@ fn compiles_runtime_bytecode() { ); assert!(churn_res.is_ok()); assert_eq!(churn_res.unwrap().bytecode, - "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3".to_lowercase() + "335f5561019980600d3d393df35f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3".to_lowercase() ); // Validate the Codegen Artifact diff --git a/huff_core/tests/erc20.rs b/huff_core/tests/erc20.rs index 09f721f6..3c1144fe 100644 --- a/huff_core/tests/erc20.rs +++ b/huff_core/tests/erc20.rs @@ -34,25 +34,52 @@ fn test_erc20_compile() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); - // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + // Create main and constructor bytecode using the paris compatible evm version + let paris_evm = EVMVersion::new(SupportedEVMVersions::Paris); + + let paris_main_bytecode = Codegen::generate_main_bytecode(&paris_evm, &contract, None).unwrap(); + let (paris_constructor_bytecode, paris_has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&paris_evm, &contract, None).unwrap(); + + // Create main and constructor bytecode using the shanghai compatible evm version + let shanghai_evm = EVMVersion::new(SupportedEVMVersions::Shanghai); + + let shanghai_main_bytecode = + Codegen::generate_main_bytecode(&shanghai_evm, &contract, None).unwrap(); + let (shanghai_constructor_bytecode, has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&shanghai_evm, &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); - let artifact = cg + let paris_artifact = cg .churn( Arc::clone(file_source), vec![], - &main_bytecode, - &constructor_bytecode, - has_custom_bootstrap, + &paris_main_bytecode, + &paris_constructor_bytecode, + paris_has_custom_bootstrap, ) .unwrap(); // Full expected bytecode output (generated from huffc) - let expected_bytecode = "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; + let expected_paris_bytecode = "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; + + assert_eq!(paris_artifact.bytecode.to_lowercase(), expected_paris_bytecode.to_lowercase()); + + let shanghai_artifact = cg + .churn( + Arc::clone(file_source), + vec![], + &shanghai_main_bytecode, + &shanghai_constructor_bytecode, + has_custom_bootstrap, + ) + .unwrap(); + + let expected_shanghai_bytecode = "335f5561019980600d3d393df35f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3"; - assert_eq!(artifact.bytecode.to_lowercase(), expected_bytecode.to_lowercase()); + assert_eq!( + shanghai_artifact.bytecode.to_lowercase(), + expected_shanghai_bytecode.to_lowercase() + ); } diff --git a/huff_core/tests/erc721.rs b/huff_core/tests/erc721.rs index a8ab17f7..3460cec3 100644 --- a/huff_core/tests/erc721.rs +++ b/huff_core/tests/erc721.rs @@ -34,26 +34,52 @@ fn test_erc721_compile() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); - // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + // Create main and constructor bytecode using the paris compatible evm version + let paris_evm = EVMVersion::new(SupportedEVMVersions::Paris); + + let paris_main_bytecode = Codegen::generate_main_bytecode(&paris_evm, &contract, None).unwrap(); + let (paris_constructor_bytecode, paris_has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&paris_evm, &contract, None).unwrap(); + + // Create main and constructor bytecode using the shanghai compatible evm version + let shanghai_evm = EVMVersion::new(SupportedEVMVersions::Shanghai); + + let shanghai_main_bytecode = + Codegen::generate_main_bytecode(&shanghai_evm, &contract, None).unwrap(); + let (shanghai_constructor_bytecode, has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&shanghai_evm, &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); - let artifact = cg + let paris_artifact = cg + .churn( + Arc::clone(file_source), + vec![], + &paris_main_bytecode, + &paris_constructor_bytecode, + paris_has_custom_bootstrap, + ) + .unwrap(); + + // Full expected bytecode output (generated from huffc) + let expected_paris_bytecode = "336000556103b180600e3d393df360003560e01c8063a9059cbb146100a057806342842e0e146101a3578063b88d4fde146101a9578063095ea7b31461027b578063a22cb46514610310578063081812fc146102f357806340c10f19146101af57806370a082311461025e5780636352211e1461039457806306fdde031461035e57806395d89b4114610364578063c87b56dd1461036a57806301ffc9a714610370578063e985e9c514610376575b6044356024356004358083600160005260006020015260406000205491146100c75761019d565b8033146101005733816000526000602001526040600020546101005782600260005260006020015260406000205433146101005761019d565b6001816003600052600060200152604060002054038160036000526000602001526040600020558160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a4005b60006000fd5b60006000fd5b60006000fd5b60005433146101be5760006000fd5b6024356004356000826001600052600060200152604060002054156101e257610258565b8160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60006000a4005b60006000fd5b600435600360005260006020015260406000205460005260206000f35b6024358060016000526000602001526040600020548033143382600052600060200152604060002054176102ae576102ed565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560006000a4005b60006000fd5b600435600260005260006020015260406000205460005260206000f35b60243560043533600052600060200152604060002055600435336024356000527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160006000a4005b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60243560043560005260006020015260406000205460005260206000f35b600435600160005260006020015260406000205460005260206000f3"; + + assert_eq!(paris_artifact.bytecode.to_lowercase(), expected_paris_bytecode.to_lowercase()); + + let shanghai_artifact = cg .churn( Arc::clone(file_source), vec![], - &main_bytecode, - &constructor_bytecode, + &shanghai_main_bytecode, + &shanghai_constructor_bytecode, has_custom_bootstrap, ) .unwrap(); - // Full expected bytecode output (different from huffc since our storage pointer derivation is - // depth first) - let expected_bytecode = "336000556103b180600e3d393df360003560e01c8063a9059cbb146100a057806342842e0e146101a3578063b88d4fde146101a9578063095ea7b31461027b578063a22cb46514610310578063081812fc146102f357806340c10f19146101af57806370a082311461025e5780636352211e1461039457806306fdde031461035e57806395d89b4114610364578063c87b56dd1461036a57806301ffc9a714610370578063e985e9c514610376575b6044356024356004358083600160005260006020015260406000205491146100c75761019d565b8033146101005733816000526000602001526040600020546101005782600260005260006020015260406000205433146101005761019d565b6001816003600052600060200152604060002054038160036000526000602001526040600020558160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a4005b60006000fd5b60006000fd5b60006000fd5b60005433146101be5760006000fd5b6024356004356000826001600052600060200152604060002054156101e257610258565b8160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60006000a4005b60006000fd5b600435600360005260006020015260406000205460005260206000f35b6024358060016000526000602001526040600020548033143382600052600060200152604060002054176102ae576102ed565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560006000a4005b60006000fd5b600435600260005260006020015260406000205460005260206000f35b60243560043533600052600060200152604060002055600435336024356000527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160006000a4005b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60243560043560005260006020015260406000205460005260206000f35b600435600160005260006020015260406000205460005260206000f3"; + let expected_shanghai_bytecode = "335f5561038680600d3d393df35f3560e01c8063a9059cbb1461009f57806342842e0e1461019e578063b88d4fde146101a2578063095ea7b314610267578063a22cb465146102f6578063081812fc146102db57806340c10f19146101a657806370a082311461024c5780636352211e1461036b57806306fdde031461033f57806395d89b4114610343578063c87b56dd1461034757806301ffc9a71461034b578063e985e9c51461034f575b6044356024356004358083600160005260006020015260406000205491146100c65761019a565b8033146100ff5733816000526000602001526040600020546100ff5782600260005260006020015260406000205433146100ff5761019a565b600181600360005260006020015260406000205403816003600052600060200152604060002055816003600052600060200152604060002054600101826003600052600060200152604060002055818360016000526000602001526040600020555f8360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa4005b5f5ffd5b5f5ffd5b5f5ffd5b5f5433146101b2575f5ffd5b6024356004355f826001600052600060200152604060002054156101d557610248565b816003600052600060200152604060002054600101826003600052600060200152604060002055818360016000526000602001526040600020555f8360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f5fa4005b5f5ffd5b60043560036000526000602001526040600020545f5260205ff35b60243580600160005260006020015260406000205480331433826000526000602001526040600020541761029a576102d7565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f5fa4005b5f5ffd5b60043560026000526000602001526040600020545f5260205ff35b60243560043533600052600060200152604060002055600435336024355f527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c315f5fa4005b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b6024356004356000526000602001526040600020545f5260205ff35b60043560016000526000602001526040600020545f5260205ff3"; - assert_eq!(artifact.bytecode.to_lowercase(), expected_bytecode.to_lowercase()); + assert_eq!( + shanghai_artifact.bytecode.to_lowercase(), + expected_shanghai_bytecode.to_lowercase() + ); } diff --git a/huff_core/tests/file_resolution.rs b/huff_core/tests/file_resolution.rs index d3ec9385..ae09d7c3 100644 --- a/huff_core/tests/file_resolution.rs +++ b/huff_core/tests/file_resolution.rs @@ -3,20 +3,23 @@ use std::{path::PathBuf, sync::Arc}; use huff_core::Compiler; use huff_utils::{ file_provider::{FileProvider, FileSystemFileProvider}, - prelude::{CompilerError, OutputLocation, UnpackError}, + prelude::{CompilerError, EVMVersion, OutputLocation, UnpackError}, }; #[test] fn test_get_outputs_no_output() { + let evm_version = EVMVersion::default(); let compiler: Compiler = - Compiler::new(Arc::new(vec![]), None, None, None, None, None, false, false); + Compiler::new(&evm_version, Arc::new(vec![]), None, None, None, None, None, false, false); let ol: OutputLocation = compiler.get_outputs(); assert_eq!(ol, OutputLocation::default()); } #[test] fn test_get_outputs_with_output() { + let evm_version = EVMVersion::default(); let compiler: Compiler = Compiler::new( + &evm_version, Arc::new(vec![]), Some("./test_out/".to_string()), None, diff --git a/huff_core/tests/free_storage_pointer.rs b/huff_core/tests/free_storage_pointer.rs index 8dddebe0..888e99c8 100644 --- a/huff_core/tests/free_storage_pointer.rs +++ b/huff_core/tests/free_storage_pointer.rs @@ -1,7 +1,10 @@ use huff_codegen::Codegen; use huff_lexer::*; use huff_parser::Parser; -use huff_utils::{prelude::FullFileSource, token::Token}; +use huff_utils::{ + prelude::{EVMVersion, FullFileSource}, + token::Token, +}; /// Check that free storage pointers referenced outside of macro bodies /// are assigned correctly at compilation @@ -32,6 +35,6 @@ fn test_set_free_storage_pointers() { contract.derive_storage_pointers(); // Assert the Free storage pointer has been set to 0 - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert!(mbytes.starts_with("6000")); } diff --git a/huff_core/tests/functions.rs b/huff_core/tests/functions.rs index 652f19c1..50bca7f7 100644 --- a/huff_core/tests/functions.rs +++ b/huff_core/tests/functions.rs @@ -1,7 +1,7 @@ use huff_codegen::Codegen; use huff_lexer::*; use huff_parser::Parser; -use huff_utils::prelude::{FileSource, FullFileSource, Token}; +use huff_utils::prelude::{EVMVersion, FileSource, FullFileSource, Token}; use std::sync::Arc; #[test] @@ -110,7 +110,7 @@ fn test_function() { assert!(cg.artifact.is_none()); // Have the Codegen create the runtime bytecode - let rbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let rbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); let artifact = @@ -204,7 +204,7 @@ fn test_nested_function() { assert!(cg.artifact.is_none()); // Have the Codegen create the runtime bytecode - let rbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let rbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); let artifact = diff --git a/huff_core/tests/gen_artifact.rs b/huff_core/tests/gen_artifact.rs index 25ebe90d..a490991a 100644 --- a/huff_core/tests/gen_artifact.rs +++ b/huff_core/tests/gen_artifact.rs @@ -30,8 +30,11 @@ fn test_missing_constructor() { dependencies: None, }; + let evm_version = EVMVersion::default(); + // Instantiate a new compiler - let compiler = Compiler::new(Arc::new(vec![]), None, None, None, None, None, false, false); + let compiler = + Compiler::new(&evm_version, Arc::new(vec![]), None, None, None, None, None, false, false); // Generate the compile artifact let arc_source = Arc::new(full_source); @@ -74,8 +77,11 @@ fn test_missing_constructor_with_inputs() { dependencies: None, }; + let evm_version = EVMVersion::default(); + // Instantiate a new compiler let compiler = Compiler::new( + &evm_version, Arc::new(vec![]), None, None, diff --git a/huff_core/tests/in_memory.rs b/huff_core/tests/in_memory.rs index 069860f8..320cbb2c 100644 --- a/huff_core/tests/in_memory.rs +++ b/huff_core/tests/in_memory.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, sync::Arc}; use huff_core::Compiler; +use huff_utils::prelude::EVMVersion; #[test] fn test_in_memory_compiler() { @@ -31,7 +32,9 @@ fn test_in_memory_compiler() { file_sources.insert(String::from("lib/mint.huff"), String::from(source_mint)); // Instantiate a new compiler + let evm_version = EVMVersion::default(); let compiler = Compiler::new_in_memory( + &evm_version, Arc::new(vec![main_file_name.clone()]), file_sources, None, diff --git a/huff_core/tests/macro_invoc_args.rs b/huff_core/tests/macro_invoc_args.rs index ab11f559..1ddc850f 100644 --- a/huff_core/tests/macro_invoc_args.rs +++ b/huff_core/tests/macro_invoc_args.rs @@ -25,8 +25,10 @@ fn test_opcode_macro_args() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff3d5260203df3"; @@ -61,8 +63,10 @@ fn test_all_opcodes_in_macro_args() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = format!("60088060093d393df360ff{}", Opcode::from_str(o).unwrap()); @@ -97,8 +101,10 @@ fn test_constant_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff6002"; @@ -135,8 +141,10 @@ fn test_bubbled_label_call_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff5b610000"; @@ -172,8 +180,10 @@ fn test_bubbled_literal_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff610420"; @@ -209,8 +219,10 @@ fn test_bubbled_opcode_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff3d"; @@ -248,8 +260,10 @@ fn test_bubbled_constant_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff6002"; @@ -283,8 +297,10 @@ fn test_bubbled_arg_with_different_name() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "6001"; diff --git a/huff_core/tests/push_overrides.rs b/huff_core/tests/push_overrides.rs index 73e54ac0..b0678928 100644 --- a/huff_core/tests/push_overrides.rs +++ b/huff_core/tests/push_overrides.rs @@ -32,7 +32,7 @@ fn test_gracefully_pads_push_override() { // Have the Codegen create the constructor bytecode let (cbytes, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!( cbytes, String::from("7f0000000000000000000000000000000000000000000000000000000000000234") @@ -69,7 +69,7 @@ fn test_constructs_exact_push_override() { // Have the Codegen create the constructor bytecode let (cbytes, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("6034")); assert!(!has_custom_bootstrap); } @@ -103,7 +103,7 @@ fn test_no_push0_override() { // Have the Codegen create the constructor bytecode let (cbytes, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("5f")); assert!(!has_custom_bootstrap); } @@ -158,6 +158,6 @@ fn test_literal_to_push0() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let cbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("5f5f5f60005f6001")); } diff --git a/huff_core/tests/recurse_bytecode.rs b/huff_core/tests/recurse_bytecode.rs index 045cf21d..9cd040a4 100644 --- a/huff_core/tests/recurse_bytecode.rs +++ b/huff_core/tests/recurse_bytecode.rs @@ -52,10 +52,12 @@ fn recurse_macro_bytecode() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version, &contract, None).unwrap(); let (constructor_bytecode, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(evm_version, &contract, None).unwrap(); assert!(!has_custom_bootstrap); // Full expected bytecode output (generated from huffc) (placed here as a reference) diff --git a/huff_core/tests/test_circular_constructor.rs b/huff_core/tests/test_circular_constructor.rs index d5eb3f51..4d0acd20 100644 --- a/huff_core/tests/test_circular_constructor.rs +++ b/huff_core/tests/test_circular_constructor.rs @@ -44,7 +44,7 @@ fn test_circular_large_constructors() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(),&contract, None) { Ok((mb, _)) => assert_eq!("60ff58585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858".to_string(), mb), Err(_) => panic!("moose"), } @@ -92,7 +92,7 @@ fn test_circular_constructor_at_word_boundry() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(),&contract, None) { Ok((mb, _)) => assert_eq!("61010358585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858610103".to_string(), mb), Err(_) => panic!("moose"), } @@ -125,7 +125,7 @@ fn test_double_circular_constructor_multiple_macro_invocations() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None) { Ok((mb, _)) => assert_eq!("60075860076007".to_string(), mb), Err(_) => panic!("moose"), } @@ -162,7 +162,7 @@ fn test_double_circular_constructor_nested_macro_invocations() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None) { Ok((mb, _)) => assert_eq!("600a58600a586003600a".to_string(), mb), Err(_) => panic!("moose"), } diff --git a/huff_core/tests/tests.rs b/huff_core/tests/tests.rs index 4c181a8a..ba2b653e 100644 --- a/huff_core/tests/tests.rs +++ b/huff_core/tests/tests.rs @@ -3,7 +3,7 @@ use huff_lexer::*; use huff_parser::Parser; use huff_utils::{ error::CodegenErrorKind, - prelude::{FullFileSource, Token}, + prelude::{EVMVersion, FullFileSource, Token}, }; #[test] @@ -42,7 +42,7 @@ fn test_invocation_should_fail() { // Have the Codegen create the runtime bytecode. Should throw an error because test // invocation is not allowed. - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("Expected an error"), Err(e) => { assert_eq!( diff --git a/huff_core/tests/verbatim.rs b/huff_core/tests/verbatim.rs index b345f1c0..d5f6e595 100644 --- a/huff_core/tests/verbatim.rs +++ b/huff_core/tests/verbatim.rs @@ -19,7 +19,7 @@ fn test_verbatim() { contract.derive_storage_pointers(); // Get main bytecode with verbatim - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(mb) => assert_eq!(mb, "1234567890abcdef".to_string()), Err(_) => panic!("moose"), } @@ -41,5 +41,5 @@ fn test_verbatim_invalid_hex() { contract.derive_storage_pointers(); // Expect failure to generate bytecode with verbatim - assert!(Codegen::generate_main_bytecode(&contract, None).is_err()); + assert!(Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).is_err()); } diff --git a/huff_js/Cargo.toml b/huff_js/Cargo.toml index e1dbd813..9970e75e 100644 --- a/huff_js/Cargo.toml +++ b/huff_js/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huffc-js" -version = "0.3.1" +version = "0.3.2" authors = ["refcell", "clabby", "exp.table", "kanewallmann"] edition = "2021" readme = "README.md" diff --git a/huff_js/src/lib.rs b/huff_js/src/lib.rs index 406e092f..2d339028 100644 --- a/huff_js/src/lib.rs +++ b/huff_js/src/lib.rs @@ -9,7 +9,7 @@ use std::{collections::HashMap, sync::Arc}; use wasm_bindgen::prelude::*; use huff_core::Compiler; -use huff_utils::{abi::Abi, artifact::Artifact, error::CompilerError}; +use huff_utils::{abi::Abi, artifact::Artifact, error::CompilerError, prelude::EVMVersion}; use serde::{Deserialize, Serialize}; /// Converts a CompilerError into a returnable JsValue @@ -20,6 +20,7 @@ fn compiler_error_to_js_value(ce: Arc) -> JsValue { #[derive(Serialize, Deserialize)] struct CompilerInput { + evm_version: Option, sources: Vec, files: HashMap, construct_args: Option>, @@ -45,7 +46,10 @@ struct CompilerOutput { pub fn compile(input: JsValue) -> Result { let input: CompilerInput = serde_wasm_bindgen::from_value(input)?; + let evm_version = EVMVersion::from(input.evm_version); + let compiler = Compiler::new_in_memory( + &evm_version, Arc::new(input.sources), input.files, input.alternative_main, diff --git a/huff_lexer/Cargo.toml b/huff_lexer/Cargo.toml index 5a4594a0..dabed711 100644 --- a/huff_lexer/Cargo.toml +++ b/huff_lexer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_lexer" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_parser/Cargo.toml b/huff_parser/Cargo.toml index bf447f30..8c139e5e 100644 --- a/huff_parser/Cargo.toml +++ b/huff_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_parser" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_tests/src/runner.rs b/huff_tests/src/runner.rs index 4d93d527..912a31b0 100644 --- a/huff_tests/src/runner.rs +++ b/huff_tests/src/runner.rs @@ -7,7 +7,7 @@ use ethers_core::{ use huff_codegen::Codegen; use huff_utils::{ ast::{DecoratorFlag, MacroDefinition}, - prelude::{pad_n_bytes, CompilerError, Contract}, + prelude::{pad_n_bytes, CompilerError, Contract, EVMVersion}, }; use revm::{ db::DbAccount, @@ -170,10 +170,14 @@ impl TestRunner { m: &MacroDefinition, contract: &Contract, ) -> Result { + // TODO: set to non default + let evm_version = EVMVersion::default(); + let name = m.name.to_owned(); // Compile the passed test macro match Codegen::macro_to_bytecode( + &evm_version, m, contract, &mut vec![m], diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index 8ffb8e5d..72cf8fe6 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -6,6 +6,7 @@ use crate::{ bytes_util::*, error::CodegenError, evm::Opcode, + evm_version::EVMVersion, prelude::{MacroArg::Ident, Span, TokenKind}, }; use std::{ @@ -547,8 +548,9 @@ pub struct MacroDefinition { } impl ToIRBytecode for MacroDefinition { - fn to_irbytecode(&self) -> Result { - let inner_irbytes: Vec = MacroDefinition::to_irbytes(&self.statements); + fn to_irbytecode(&self, evm_version: &EVMVersion) -> Result { + let inner_irbytes: Vec = + MacroDefinition::to_irbytes(evm_version, &self.statements); Ok(IRBytecode(inner_irbytes)) } } @@ -581,14 +583,17 @@ impl MacroDefinition { } /// Translate statements into IRBytes - pub fn to_irbytes(statements: &[Statement]) -> Vec { + pub fn to_irbytes<'a>( + evm_version: &EVMVersion, + statements: &'a [Statement], + ) -> Vec> { let mut inner_irbytes: Vec = vec![]; let mut statement_iter = statements.iter(); while let Some(statement) = statement_iter.next() { match &statement.ty { StatementType::Literal(l) => { - let push_bytes = literal_gen(l); + let push_bytes = literal_gen(evm_version, l); inner_irbytes.push(IRBytes { ty: IRByteType::Bytes(Bytes(push_bytes)), span: &statement.span, @@ -670,7 +675,7 @@ impl MacroDefinition { }); // Recurse label statements to IRBytes Bytes - inner_irbytes.append(&mut MacroDefinition::to_irbytes(&l.inner)); + inner_irbytes.append(&mut MacroDefinition::to_irbytes(evm_version, &l.inner)); } StatementType::BuiltinFunctionCall(builtin) => { inner_irbytes.push(IRBytes { diff --git a/huff_utils/src/bytecode.rs b/huff_utils/src/bytecode.rs index ffdb79e1..5b67fe2f 100644 --- a/huff_utils/src/bytecode.rs +++ b/huff_utils/src/bytecode.rs @@ -2,7 +2,10 @@ //! //! Abstract translating state into bytecode. -use crate::prelude::{AstSpan, Statement, TableDefinition}; +use crate::{ + evm_version::EVMVersion, + prelude::{AstSpan, Statement, TableDefinition}, +}; use std::{ collections::{BTreeMap, BTreeSet}, fmt::{self, Display}, @@ -43,7 +46,7 @@ pub struct IRBytecode<'a>(pub Vec>); /// Converts a stateful object to intermediate bytecode pub trait ToIRBytecode { /// Translates `self` to intermediate bytecode representation - fn to_irbytecode(&self) -> Result; + fn to_irbytecode(&self, evm_version: &EVMVersion) -> Result; } /// Full Bytecode diff --git a/huff_utils/src/bytes_util.rs b/huff_utils/src/bytes_util.rs index 583c71a3..feb862e7 100644 --- a/huff_utils/src/bytes_util.rs +++ b/huff_utils/src/bytes_util.rs @@ -1,4 +1,4 @@ -use crate::evm::Opcode; +use crate::{evm::Opcode, evm_version::EVMVersion}; use std::num::ParseIntError; use tiny_keccak::{Hasher, Keccak}; @@ -70,10 +70,23 @@ pub fn hash_bytes(dest: &mut [u8], to_hash: &String) { } /// Converts a value literal to its smallest equivalent `PUSHX` bytecode -pub fn literal_gen(l: &[u8; 32]) -> String { +pub fn literal_gen(evm_version: &EVMVersion, l: &[u8; 32]) -> String { let hex_literal: String = bytes32_to_string(l, false); match hex_literal.as_str() { - "00" => Opcode::Push0.to_string(), - _ => format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2), + "00" => format_push0(evm_version, hex_literal), + _ => format_literal(hex_literal), } } + +fn format_push0(evm_version: &EVMVersion, hex_literal: String) -> String { + if evm_version.has_push0() { + Opcode::Push0.to_string() + } else { + format_literal(hex_literal) + } +} + +/// Converts a literal into its bytecode string representation +pub fn format_literal(hex_literal: String) -> String { + format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2) +} diff --git a/huff_utils/src/evm_version.rs b/huff_utils/src/evm_version.rs new file mode 100644 index 00000000..44e1a2af --- /dev/null +++ b/huff_utils/src/evm_version.rs @@ -0,0 +1,58 @@ +use std::cmp::PartialOrd; + +/// Evm Version +/// +/// Determines which features will be available when compiling. + +#[derive(Debug, PartialEq, PartialOrd)] +pub enum SupportedEVMVersions { + /// Introduced prevrandao, disallow difficulty opcode (does not affect codegen) + Paris, + /// Introduce Push0, compiler will use by default + Shanghai, +} + +#[derive(Debug)] +/// EVM Version +pub struct EVMVersion { + version: SupportedEVMVersions, +} + +impl EVMVersion { + /// Create a new EVM Version with the specified value + pub fn new(version: SupportedEVMVersions) -> Self { + Self { version } + } + + /// As PartialOrd is implemented in the struct, all versions after shanghai will support this + pub fn has_push0(&self) -> bool { + self.version >= SupportedEVMVersions::Shanghai + } +} + +impl Default for EVMVersion { + fn default() -> Self { + Self::new(SupportedEVMVersions::Shanghai) + } +} + +/// Convert from Option to EVMVersion +impl From> for EVMVersion { + fn from(version: Option) -> Self { + match version { + Some(version) => Self::from(version), + None => Self::default(), + } + } +} + +/// Convert from String to EVMVersion +impl From for EVMVersion { + fn from(version: String) -> Self { + match version.as_str() { + "shanghai" => Self::new(SupportedEVMVersions::Shanghai), + "paris" => Self::new(SupportedEVMVersions::Paris), + _ => Self::default(), + } + } +} diff --git a/huff_utils/src/lib.rs b/huff_utils/src/lib.rs index 21f3b236..3dd3fc87 100644 --- a/huff_utils/src/lib.rs +++ b/huff_utils/src/lib.rs @@ -54,10 +54,13 @@ pub mod time; /// Wasm Module pub mod wasm; +/// EVM Version Module +pub mod evm_version; + /// Prelude wraps common utilities. pub mod prelude { pub use crate::{ - abi::*, artifact::*, ast::*, bytecode::*, bytes_util::*, error::*, evm::*, files::*, io::*, - report::*, sol_interface::*, token::*, types::*, + abi::*, artifact::*, ast::*, bytecode::*, bytes_util::*, error::*, evm::*, evm_version::*, + files::*, io::*, report::*, sol_interface::*, token::*, types::*, }; }