Skip to content

Commit

Permalink
limit lines to 80 columns. refactor parser some more
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkRTA committed Jan 6, 2024
1 parent e7ef0c3 commit f443bbb
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 64 deletions.
1 change: 1 addition & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
imports_granularity = "item"
group_imports = "StdExternalCrate"
max_width=80
46 changes: 26 additions & 20 deletions crates/dtacheck/src/linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ pub trait Lint {
fn to_codespan(&self, id: usize) -> Diagnostic<usize>;
}

pub fn lint_file(ast: &[Node], tokens: &[Token], funcs: &Function) -> Vec<Box<dyn Lint>> {
pub fn lint_file(
ast: &[Node],
tokens: &[Token],
funcs: &Function,
) -> Vec<Box<dyn Lint>> {
let mut lints = Vec::new();
lint_node(&mut lints, ast, funcs);
lint_preprocs(&mut lints, tokens);
Expand All @@ -23,13 +27,14 @@ pub fn lint_file(ast: &[Node], tokens: &[Token], funcs: &Function) -> Vec<Box<dy
fn lint_node(lints: &mut Vec<Box<dyn Lint>>, ast: &[Node], funcs: &Function) {
for node in ast {
match &node.kind {
NodeKind::Array(array) | NodeKind::Prop(array) | NodeKind::Define(_, array) => {
lint_node(lints, array, funcs)
}
NodeKind::Array(array)
| NodeKind::Prop(array)
| NodeKind::Define(_, array) => lint_node(lints, array, funcs),
NodeKind::Stmt(array) => {
lint_node(lints, array, funcs);

let has_preprocessor_directive = array.iter().any(|tok| tok.is_preproc());
let has_preprocessor_directive =
array.iter().any(|tok| tok.is_preproc());

if !has_preprocessor_directive {
lint_fn_args(lints, array, node.span.clone(), funcs);
Expand All @@ -51,15 +56,17 @@ impl Lint for FunctionArgLint {
fn to_codespan(&self, id: usize) -> Diagnostic<usize> {
match self {
Self::TooManyArgs(name, range) => Diagnostic::error()
.with_message(format!("calling `{name}` with too many arguments"))
.with_labels(vec![
Label::primary(id, range.clone()).with_message("too many arguments")
]),
.with_message(format!(
"calling `{name}` with too many arguments"
))
.with_labels(vec![Label::primary(id, range.clone())
.with_message("too many arguments")]),
Self::NotEnoughArgs(name, range) => Diagnostic::error()
.with_message(format!("calling `{name}` with too few arguments"))
.with_labels(vec![
Label::primary(id, range.clone()).with_message("not enough arguments")
]),
.with_message(format!(
"calling `{name}` with too few arguments"
))
.with_labels(vec![Label::primary(id, range.clone())
.with_message("not enough arguments")]),
}
}
}
Expand Down Expand Up @@ -183,7 +190,9 @@ pub fn lint_preprocs(lints: &mut Vec<Box<dyn Lint>>, tokens: &[Token]) {
TokenKind::Else => {
if let Some(entry) = directive_stack.pop() {
if entry.1 {
lints.push(Box::new(PreProcLint::Extra(token.span.clone())))
lints.push(Box::new(PreProcLint::Extra(
token.span.clone(),
)))
}
directive_stack.push((token.span.clone(), true));
} else {
Expand All @@ -199,10 +208,7 @@ pub fn lint_preprocs(lints: &mut Vec<Box<dyn Lint>>, tokens: &[Token]) {
}
}

lints.append(
&mut directive_stack
.into_iter()
.map(|x| Box::new(PreProcLint::Unmatched(x.0)) as Box<dyn Lint>)
.collect::<Vec<_>>(),
);
for lint in directive_stack {
lints.push(Box::new(PreProcLint::Unmatched(lint.0)))
}
}
92 changes: 48 additions & 44 deletions crates/dtacheck/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ impl Lint for ParseLint {
Self::UnmatchedBrace(opening, closing) => Diagnostic::error()
.with_message("unmatched delimiter")
.with_labels(vec![
Label::primary(id, closing.clone()).with_message("unexpected token"),
Label::primary(id, opening.clone()).with_message("unmatched delimiter"),
Label::primary(id, closing.clone())
.with_message("unexpected token"),
Label::primary(id, opening.clone())
.with_message("unmatched delimiter"),
]),
Self::GenericError(span) => Diagnostic::error()
.with_message("unexpected token")
.with_labels(vec![
Label::primary(id, span.clone()).with_message("unexpected token")
]),
.with_labels(vec![Label::primary(id, span.clone())
.with_message("unexpected token")]),
}
}
}
Expand Down Expand Up @@ -74,7 +75,10 @@ impl<'a> Parser<'a> {
}
}

fn eat_open_brace(&mut self, f: fn(&TokenKind) -> bool) -> ParseResult<Token> {
fn eat_open_brace(
&mut self,
f: fn(&TokenKind) -> bool,
) -> ParseResult<Token> {
let token = self.lookahead(0);

if f(&token.kind) {
Expand Down Expand Up @@ -150,11 +154,14 @@ impl<'a> Parser<'a> {
let upper_span = self.previous().span;
Ok(Node::new_stmt(array, lower_span.start..upper_span.end))
} else if self.eat_if(TokenKind::is_define) {
let span = self.previous().span;
let lower_span = self.previous().span;
let sym = self.eat(TokenKind::is_sym)?;
self.eat_open_brace(TokenKind::is_l_paren)?;
let array = self.parse_list(TokenKind::is_r_paren)?;
Ok(Node::new_define(span, sym, array))
let upper_span = self.previous().span;
let lower = lower_span.start;
let upper = upper_span.end;
Ok(Node::new_define(lower..upper, sym, array))
} else if self.eat_if(TokenKind::is_include) {
let span = self.previous().span;
let sym = self.eat(TokenKind::is_sym)?;
Expand All @@ -178,7 +185,37 @@ impl<'a> Parser<'a> {
}
}

fn parse_list(&mut self, stop: fn(&TokenKind) -> bool) -> ParseResult<Vec<Node>> {
fn recover_mismatched_braces(&mut self) -> bool {
if !self.brace_stack.is_empty() {
let token = self.lookahead(0);
let unmatched = self.brace_stack.last().unwrap().span.clone();
let current = token.span.clone();
let diag = ParseLint::UnmatchedBrace(unmatched, current);

if token.kind.is_r_bracket()
|| token.kind.is_r_paren()
|| token.kind.is_r_brace()
{
self.diagnostics.push(diag);
self.bump(1);
self.brace_stack.pop().unwrap();
return true;
}

if token.kind.is_eof() {
self.diagnostics.push(diag);
self.brace_stack.pop().unwrap();
return true;
}
}

return false;
}

fn parse_list(
&mut self,
stop: fn(&TokenKind) -> bool,
) -> ParseResult<Vec<Node>> {
let mut nodes = Vec::new();
loop {
if self.eat_if(stop) {
Expand All @@ -190,29 +227,9 @@ impl<'a> Parser<'a> {
match self.parse_node() {
Ok(x) => nodes.push(x),
Err(e) => {
if !self.brace_stack.is_empty() {
let token = self.lookahead(0);
let unmatched = self.brace_stack.last().unwrap().span.clone();
let current = token.span.clone();
let diag = ParseLint::UnmatchedBrace(unmatched, current);

if token.kind.is_r_bracket()
|| token.kind.is_r_paren()
|| token.kind.is_r_brace()
{
self.diagnostics.push(diag);
self.bump(1);
self.brace_stack.pop().unwrap();
break;
}

if token.kind.is_eof() {
self.diagnostics.push(diag);
self.brace_stack.pop().unwrap();
break;
}
if self.recover_mismatched_braces() {
break;
}

return Err(e);
}
}
Expand Down Expand Up @@ -266,17 +283,6 @@ pub struct Node {
pub span: Range<usize>,
}

#[allow(clippy::reversed_empty_ranges)]
fn combine_node_spans(list: &[Node]) -> Range<usize> {
list.iter()
.map(|x| &x.span)
.fold(usize::MAX..0, |current, next| {
let start = current.start.min(next.start);
let end = current.end.max(next.end);
start..end
})
}

impl Node {
fn new_array(list: Vec<Node>, span: Range<usize>) -> Node {
Node {
Expand All @@ -300,8 +306,6 @@ impl Node {
}

fn new_define(span: Range<usize>, sym: Token, array: Vec<Node>) -> Node {
let vec_span = combine_node_spans(&array);
let span = span.start..vec_span.end.min(sym.span.end);
Node {
kind: NodeKind::Define(sym.kind.unwrap_sym(), array),
span,
Expand Down

0 comments on commit f443bbb

Please sign in to comment.