Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 35 additions & 19 deletions compiler/noirc_frontend/src/hir/comptime/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub(super) fn display_quoted(
writeln!(f, "quote {{")?;
let indent = indent + 1;
write!(f, "{}", " ".repeat(indent * 4))?;
display_tokens(tokens, interner, indent, f)?;
TokensPrettyPrinter { tokens, interner, indent }.fmt(f)?;
writeln!(f)?;
let indent = indent - 1;
write!(f, "{}", " ".repeat(indent * 4))?;
Expand All @@ -47,30 +47,26 @@ pub(super) fn display_quoted(
struct TokensPrettyPrinter<'tokens, 'interner> {
tokens: &'tokens [Token],
interner: &'interner NodeInterner,
indent: usize,
}

impl<'tokens, 'interner> Display for TokensPrettyPrinter<'tokens, 'interner> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
display_tokens(self.tokens, self.interner, 0, f)
}
}
let mut token_printer = TokenPrettyPrinter::new(self.interner, self.indent);
for token in self.tokens {
token_printer.print(token, f)?;
}

fn display_tokens(
tokens: &[Token],
interner: &NodeInterner,
indent: usize,
f: &mut std::fmt::Formatter<'_>,
) -> std::fmt::Result {
let mut token_printer = TokenPrettyPrinter::new(interner, indent);
for token in tokens {
token_printer.print(token, f)?;
// If the printer refrained from printing a token right away, this will make it do it
token_printer.print(&Token::EOF, f)?;

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

pub(super) fn tokens_to_string(tokens: Rc<Vec<Token>>, interner: &NodeInterner) -> String {
let tokens: Vec<Token> = tokens.iter().cloned().collect();
TokensPrettyPrinter { tokens: &tokens, interner }.to_string()
TokensPrettyPrinter { tokens: &tokens, interner, indent: 0 }.to_string()
}

/// Tries to print tokens in a way that it'll be easier for the user to understand a
Expand All @@ -95,6 +91,7 @@ struct TokenPrettyPrinter<'interner> {
last_was_alphanumeric: bool,
last_was_right_brace: bool,
last_was_semicolon: bool,
last_was_op: bool,
}

impl<'interner> TokenPrettyPrinter<'interner> {
Expand All @@ -105,13 +102,17 @@ impl<'interner> TokenPrettyPrinter<'interner> {
last_was_alphanumeric: false,
last_was_right_brace: false,
last_was_semicolon: false,
last_was_op: false,
}
}

fn print(&mut self, token: &Token, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let last_was_alphanumeric = self.last_was_alphanumeric;
self.last_was_alphanumeric = false;

let last_was_op = self.last_was_op;
self.last_was_op = false;

// After `}` we usually want a newline... but not always!
if self.last_was_right_brace {
self.last_was_right_brace = false;
Expand Down Expand Up @@ -163,6 +164,12 @@ impl<'interner> TokenPrettyPrinter<'interner> {
}
}

// If the last token was one of `+`, `-`, etc. and the current token is not `=`, we want a space
// (we avoid outputting a space if the token is `=` a bit below)
if last_was_op && !matches!(token, Token::Assign) {
write!(f, " ")?;
}

match token {
Token::QuotedType(id) => write!(f, "{}", self.interner.get_quoted_type(*id)),
Token::InternedExpr(id) => {
Expand Down Expand Up @@ -235,16 +242,25 @@ impl<'interner> TokenPrettyPrinter<'interner> {
| Token::GreaterEqual
| Token::Equal
| Token::NotEqual
| Token::Plus
| Token::Arrow => write!(f, " {token} "),
Token::Assign => {
if last_was_op {
write!(f, "{token} ")
} else {
write!(f, " {token} ")
}
}
Token::Plus
| Token::Minus
| Token::Star
| Token::Slash
| Token::Percent
| Token::Ampersand
| Token::ShiftLeft
| Token::ShiftRight
| Token::Assign
| Token::Arrow => write!(f, " {token} "),
| Token::ShiftRight => {
self.last_was_op = true;
write!(f, " {token}")
}
Token::LeftParen
| Token::RightParen
| Token::LeftBracket
Expand Down