mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-11 23:01:02 +00:00
94ec34c4d5
Separate between compilation and linker phases to allow deploy time linking and back-porting era compiler changes to fix #91. Unlinked contract binaries (caused by missing libraries or missing factory dependencies in turn) are emitted as raw ELF object. Few drive by fixes: - #98 - A compiler panic on missing libraries definitions. - Fixes some incosistent type forwarding in JSON output (empty string vs. null object). - Remove the unused fallback for size optimization setting. - Remove the broken `--lvm-ir` mode. - CI workflow fixes. --------- Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com> Signed-off-by: xermicus <bigcyrill@hotmail.com> Signed-off-by: xermicus <cyrill@parity.io>
138 lines
4.1 KiB
Rust
138 lines
4.1 KiB
Rust
//! The compiler lexer.
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|
|
|
|
use self::error::Error;
|
|
use self::token::lexeme::comment::Comment;
|
|
use self::token::lexeme::identifier::Identifier;
|
|
use self::token::lexeme::literal::integer::Integer as IntegerLiteral;
|
|
use self::token::lexeme::literal::string::String as StringLiteral;
|
|
use self::token::lexeme::symbol::Symbol;
|
|
use self::token::lexeme::Lexeme;
|
|
use self::token::location::Location;
|
|
use self::token::Token;
|
|
|
|
pub mod error;
|
|
pub mod token;
|
|
|
|
/// The compiler lexer.
|
|
pub struct Lexer {
|
|
/// The input source code.
|
|
input: String,
|
|
/// The number of characters processed so far.
|
|
offset: u32,
|
|
/// The current location.
|
|
location: Location,
|
|
/// The peeked lexeme, waiting to be fetched.
|
|
peeked: Option<Token>,
|
|
}
|
|
|
|
impl Lexer {
|
|
/// A shortcut constructor.
|
|
pub fn new(mut input: String) -> Self {
|
|
input.push('\n');
|
|
|
|
Self {
|
|
input,
|
|
offset: 0,
|
|
location: Location::default(),
|
|
peeked: None,
|
|
}
|
|
}
|
|
|
|
/// Advances the lexer, returning the next lexeme.
|
|
#[allow(clippy::should_implement_trait)]
|
|
pub fn next(&mut self) -> Result<Token, Error> {
|
|
if let Some(peeked) = self.peeked.take() {
|
|
return Ok(peeked);
|
|
}
|
|
|
|
while self.offset
|
|
< self
|
|
.input
|
|
.len()
|
|
.try_into()
|
|
.map_err(|_| Error::InvalidLexeme {
|
|
location: self.location,
|
|
sequence: Default::default(),
|
|
})?
|
|
{
|
|
let input = &self.input[(self.offset as usize)..];
|
|
|
|
if input.starts_with(|character| char::is_ascii_whitespace(&character)) {
|
|
if input.starts_with('\n') {
|
|
self.location.line += 1;
|
|
self.location.column = 1;
|
|
} else if !input.starts_with('\r') {
|
|
self.location.column += 1;
|
|
}
|
|
self.offset += 1;
|
|
continue;
|
|
}
|
|
|
|
if let Some(token) = Comment::parse(input) {
|
|
self.offset += token.length;
|
|
self.location
|
|
.shift_down(token.location.line, token.location.column);
|
|
continue;
|
|
}
|
|
|
|
if let Some(mut token) = StringLiteral::parse(input) {
|
|
token.location = self.location;
|
|
|
|
self.offset += token.length;
|
|
self.location.shift_right(token.length);
|
|
return Ok(token);
|
|
}
|
|
|
|
if let Some(mut token) = IntegerLiteral::parse(input) {
|
|
token.location = self.location;
|
|
|
|
self.offset += token.length;
|
|
self.location.shift_right(token.length);
|
|
return Ok(token);
|
|
}
|
|
|
|
if let Some(mut token) = Identifier::parse(input) {
|
|
token.location = self.location;
|
|
|
|
self.offset += token.length;
|
|
self.location.shift_right(token.length);
|
|
return Ok(token);
|
|
}
|
|
|
|
if let Some(mut token) = Symbol::parse(input) {
|
|
token.location = self.location;
|
|
|
|
self.offset += token.length;
|
|
self.location.shift_right(token.length);
|
|
return Ok(token);
|
|
}
|
|
|
|
let end = self.input[(self.offset as usize)..]
|
|
.find(char::is_whitespace)
|
|
.unwrap_or(self.input.len());
|
|
return Err(Error::InvalidLexeme {
|
|
location: self.location,
|
|
sequence: self.input[(self.offset as usize)..(self.offset as usize) + end]
|
|
.to_owned(),
|
|
});
|
|
}
|
|
|
|
Ok(Token::new(self.location, Lexeme::EndOfFile, 0))
|
|
}
|
|
|
|
/// Peeks the next lexeme without advancing the iterator.
|
|
pub fn peek(&mut self) -> Result<Token, Error> {
|
|
match self.peeked {
|
|
Some(ref peeked) => Ok(peeked.clone()),
|
|
None => {
|
|
let peeked = self.next()?;
|
|
self.peeked = Some(peeked.clone());
|
|
Ok(peeked)
|
|
}
|
|
}
|
|
}
|
|
}
|