Merge pull request #7245 from joshuawarner32/dbg-expr-only

Make dbg always be parsed as an expression
This commit is contained in:
Joshua Warner 2024-11-26 17:41:28 -08:00 committed by GitHub
commit 0295bb58da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 122 additions and 156 deletions

View file

@ -7,7 +7,7 @@ Defs {
EitherIndex(2147483648),
],
regions: [
@0-26,
@0-28,
],
space_before: [
Slice { start: 0, length: 0 },
@ -24,13 +24,13 @@ Defs {
@0-4 Identifier {
ident: "main",
},
@11-26 Defs(
@11-28 Defs(
Defs {
tags: [
EitherIndex(2147483648),
],
regions: [
@15-26,
@16-27,
],
space_before: [
Slice { start: 0, length: 0 },
@ -42,17 +42,17 @@ Defs {
type_defs: [],
value_defs: [
Body(
@15-26 Identifier {
@16-27 Identifier {
ident: "1",
},
@15-26 ParensAround(
@16-27 ParensAround(
Defs(
Defs {
tags: [
EitherIndex(2147483648),
],
regions: [
@20-25,
@21-26,
],
space_before: [
Slice { start: 0, length: 0 },
@ -64,48 +64,50 @@ Defs {
type_defs: [],
value_defs: [
Body(
@20-25 Identifier {
@21-26 Identifier {
ident: "0",
},
@20-25 Apply(
@22-23 Var {
module_name: "Num",
ident: "add",
},
[
@20-21 Num(
"1",
@21-26 ParensAround(
Apply(
@23-24 Var {
module_name: "Num",
ident: "add",
},
[
@21-22 Num(
"1",
),
@25-26 Num(
"1",
),
],
BinOp(
Plus,
),
@24-25 Num(
"1",
),
],
BinOp(
Plus,
),
),
),
],
},
@15-26 LowLevelDbg(
@16-27 LowLevelDbg(
(
"test.roc:3",
" ",
),
@20-25 Apply(
@20-25 Var {
@21-26 Apply(
@21-26 Var {
module_name: "Inspect",
ident: "toStr",
},
[
@20-25 Var {
@21-26 Var {
module_name: "",
ident: "0",
},
],
Space,
),
@20-25 Var {
@21-26 Var {
module_name: "",
ident: "0",
},
@ -115,25 +117,25 @@ Defs {
),
],
},
@11-26 LowLevelDbg(
@11-28 LowLevelDbg(
(
"test.roc:2",
"in =\n ",
"n =\n ",
),
@15-26 Apply(
@15-26 Var {
@16-27 Apply(
@16-27 Var {
module_name: "Inspect",
ident: "toStr",
},
[
@15-26 Var {
@16-27 Var {
module_name: "",
ident: "1",
},
],
Space,
),
@15-26 Var {
@16-27 Var {
module_name: "",
ident: "1",
},

View file

@ -464,7 +464,7 @@ mod suffixed_tests {
run_test!(
r#"
main =
dbg (dbg 1 + 1)
dbg (dbg (1 + 1))
"#
);
}

View file

@ -447,7 +447,7 @@ impl<'a> Formattable for Expr<'a> {
buf.push_str("dbg");
}
DbgStmt(condition, continuation) => {
fmt_dbg_stmt(buf, condition, continuation, self.is_multiline(), indent);
fmt_dbg_stmt(buf, condition, continuation, parens, indent);
}
LowLevelDbg(_, _, _) => unreachable!(
"LowLevelDbg should only exist after desugaring, not during formatting"
@ -1022,42 +1022,15 @@ fn fmt_dbg_stmt<'a>(
buf: &mut Buf,
condition: &'a Loc<Expr<'a>>,
continuation: &'a Loc<Expr<'a>>,
_: bool,
parens: Parens,
indent: u16,
) {
buf.ensure_ends_with_newline();
buf.indent(indent);
buf.push_str("dbg");
buf.spaces(1);
fn should_outdent(mut expr: &Expr) -> bool {
loop {
match expr {
Expr::ParensAround(_) | Expr::List(_) | Expr::Record(_) | Expr::Tuple(_) => {
return true
}
Expr::SpaceAfter(inner, _) => {
expr = inner;
}
_ => return false,
}
}
}
let inner_indent = if should_outdent(&condition.value) {
indent
} else {
indent + INDENT
};
let cond_value = condition.value.extract_spaces();
let is_defs = matches!(cond_value.item, Expr::Defs(_, _));
let newlines = if is_defs { Newlines::Yes } else { Newlines::No };
condition.format_with_options(buf, Parens::NotNeeded, newlines, inner_indent);
Expr::Apply(
&Loc::at_zero(Expr::Dbg),
&[condition],
called_via::CalledVia::Space,
)
.format_with_options(buf, parens, Newlines::Yes, indent);
// Always put a blank line after the `dbg` line(s)
buf.ensure_ends_with_blank_line();

View file

@ -545,10 +545,6 @@ fn stmt_start<'a>(
EExpr::Expect,
expect_help(options, preceding_comment)
)),
loc(specialize_err(
EExpr::Dbg,
dbg_stmt_help(options, preceding_comment)
)),
loc(specialize_err(EExpr::Return, return_help(options))),
loc(specialize_err(EExpr::Import, map(import(), Stmt::ValueDef))),
map(
@ -2668,34 +2664,6 @@ fn return_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Stmt<'a>, ERetu
.trace("return_help")
}
fn dbg_stmt_help<'a>(
options: ExprParseOptions,
preceding_comment: Region,
) -> impl Parser<'a, Stmt<'a>, EExpect<'a>> {
(move |arena: &'a Bump, state: State<'a>, min_indent| {
let (_, _, state) =
parser::keyword(keyword::DBG, EExpect::Dbg).parse(arena, state, min_indent)?;
let (_, condition, state) = parse_block(
options,
arena,
state,
true,
EExpect::IndentCondition,
EExpect::Condition,
)
.map_err(|(_, f)| (MadeProgress, f))?;
let stmt = Stmt::ValueDef(ValueDef::Dbg {
condition: arena.alloc(condition),
preceding_comment,
});
Ok((MadeProgress, stmt, state))
})
.trace("dbg_stmt_help")
}
fn dbg_kw<'a>() -> impl Parser<'a, Expr<'a>, EExpect<'a>> {
(move |arena: &'a Bump, state: State<'a>, min_indent: u32| {
let (_, _, next_state) =
@ -3110,12 +3078,43 @@ fn stmts_to_defs<'a>(
}
Stmt::Expr(e) => {
if i + 1 < stmts.len() {
defs.push_value_def(
ValueDef::Stmt(arena.alloc(Loc::at(sp_stmt.item.region, e))),
sp_stmt.item.region,
sp_stmt.before,
&[],
);
if let Expr::Apply(
Loc {
value: Expr::Dbg, ..
},
args,
_,
) = e
{
if args.len() != 1 {
// TODO: this should be done in can, not parsing!
return Err(EExpr::Dbg(
EExpect::DbgArity(sp_stmt.item.region.start()),
sp_stmt.item.region.start(),
));
}
let condition = &args[0];
let rest = stmts_to_expr(&stmts[i + 1..], arena)?;
let e = Expr::DbgStmt(condition, arena.alloc(rest));
let e = if sp_stmt.before.is_empty() {
e
} else {
arena.alloc(e).before(sp_stmt.before)
};
last_expr = Some(Loc::at(sp_stmt.item.region, e));
// don't re-process the rest of the statements; they got consumed by the dbg expr
break;
} else {
defs.push_value_def(
ValueDef::Stmt(arena.alloc(Loc::at(sp_stmt.item.region, e))),
sp_stmt.item.region,
sp_stmt.before,
&[],
);
}
} else {
let e = if sp_stmt.before.is_empty() {
e

View file

@ -1465,6 +1465,7 @@ impl<'a> Normalize<'a> for EExpect<'a> {
EExpect::Continuation(arena.alloc(inner_err.normalize(arena)), Position::zero())
}
EExpect::IndentCondition(_) => EExpect::IndentCondition(Position::zero()),
EExpect::DbgArity(_) => EExpect::DbgArity(Position::zero()),
}
}
}

View file

@ -513,6 +513,7 @@ pub enum EExpect<'a> {
Condition(&'a EExpr<'a>, Position),
Continuation(&'a EExpr<'a>, Position),
IndentCondition(Position),
DbgArity(Position),
}
#[derive(Debug, Clone, PartialEq, Eq)]

View file

@ -1,6 +1,6 @@
SpaceAfter(
Apply(
@0-5 Dbg,
@0-3 Dbg,
[
@4-5 Num(
"1",

View file

@ -1,3 +1,3 @@
dbg 1 == 1
dbg (1 == 1)
4

View file

@ -1,20 +1,22 @@
SpaceBefore(
SpaceAfter(
DbgStmt(
@5-11 BinOps(
[
(
@5-6 Num(
"1",
@6-12 ParensAround(
BinOps(
[
(
@6-7 Num(
"1",
),
@8-10 Equals,
),
@7-9 Equals,
],
@11-12 Num(
"1",
),
],
@10-11 Num(
"1",
),
),
@13-14 SpaceBefore(
@15-16 SpaceBefore(
Num(
"4",
),

View file

@ -1,4 +1,4 @@
dbg 1 == 1
dbg (1 == 1)
4

View file

@ -1,53 +1,38 @@
SpaceAfter(
DbgStmt(
@5-10 SpaceBefore(
Defs(
Defs {
tags: [
EitherIndex(2147483648),
],
regions: [
@5-6,
],
space_before: [
Slice { start: 0, length: 0 },
],
space_after: [
Slice { start: 0, length: 0 },
],
spaces: [],
type_defs: [],
value_defs: [
Stmt(
@5-6 Var {
module_name: "",
ident: "q",
},
),
],
},
@8-10 SpaceBefore(
Var {
@6-14 SpaceBefore(
ParensAround(
Apply(
@6-7 Var {
module_name: "",
ident: "qt",
ident: "q",
},
[
Newline,
@12-14 SpaceBefore(
Var {
module_name: "",
ident: "qt",
},
[
Newline,
],
),
],
Space,
),
),
[
Newline,
],
),
@11-16 SpaceBefore(
@16-21 SpaceBefore(
Apply(
@11-12 Var {
@16-17 Var {
module_name: "",
ident: "g",
},
[
@14-16 SpaceBefore(
@19-21 SpaceBefore(
Var {
module_name: "",
ident: "qt",

View file

@ -1,5 +1,5 @@
dbg
q
qt
(q
qt)
g
qt