mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-22 22:15:02 +00:00
add src and location to dbg
This commit is contained in:
parent
4587c4ebc5
commit
3966d63e2f
21 changed files with 385 additions and 119 deletions
|
@ -20,11 +20,11 @@ extern fn roc_realloc(c_ptr: *anyopaque, new_size: usize, old_size: usize, align
|
||||||
// This should never be passed a null pointer.
|
// This should never be passed a null pointer.
|
||||||
extern fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void;
|
extern fn roc_dealloc(c_ptr: *anyopaque, alignment: u32) callconv(.C) void;
|
||||||
|
|
||||||
extern fn roc_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void;
|
extern fn roc_dbg(loc: *anyopaque, src: *anyopaque, message: *anyopaque) callconv(.C) void;
|
||||||
|
|
||||||
// Since roc_dbg is never used by the builtins, we need at export a function that uses it to stop DCE.
|
// Since roc_dbg is never used by the builtins, we need at export a function that uses it to stop DCE.
|
||||||
pub fn test_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void {
|
pub fn test_dbg(loc: *anyopaque, src: *anyopaque, message: *anyopaque) callconv(.C) void {
|
||||||
roc_dbg(file_path, message);
|
roc_dbg(loc, src, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern fn kill(pid: c_int, sig: c_int) c_int;
|
extern fn kill(pid: c_int, sig: c_int) c_int;
|
||||||
|
@ -47,9 +47,10 @@ fn testing_roc_mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int
|
||||||
return mmap(addr, length, prot, flags, fd, offset);
|
return mmap(addr, length, prot, flags, fd, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testing_roc_dbg(file_path: *anyopaque, message: *anyopaque) callconv(.C) void {
|
fn testing_roc_dbg(loc: *anyopaque, src: *anyopaque, message: *anyopaque) callconv(.C) void {
|
||||||
_ = message;
|
_ = message;
|
||||||
_ = file_path;
|
_ = src;
|
||||||
|
_ = loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
comptime {
|
comptime {
|
||||||
|
|
|
@ -670,11 +670,15 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
|
||||||
},
|
},
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
loc_message,
|
loc_message,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable,
|
variable,
|
||||||
symbol,
|
symbol,
|
||||||
} => Dbg {
|
} => Dbg {
|
||||||
|
source_location: source_location.clone(),
|
||||||
|
source: source.clone(),
|
||||||
loc_message: Box::new(loc_message.map(|e| go_help!(e))),
|
loc_message: Box::new(loc_message.map(|e| go_help!(e))),
|
||||||
loc_continuation: Box::new(loc_continuation.map(|e| go_help!(e))),
|
loc_continuation: Box::new(loc_continuation.map(|e| go_help!(e))),
|
||||||
variable: sub!(*variable),
|
variable: sub!(*variable),
|
||||||
|
|
|
@ -269,6 +269,8 @@ pub enum Expr {
|
||||||
},
|
},
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location: Box<str>,
|
||||||
|
source: Box<str>,
|
||||||
loc_message: Box<Loc<Expr>>,
|
loc_message: Box<Loc<Expr>>,
|
||||||
loc_continuation: Box<Loc<Expr>>,
|
loc_continuation: Box<Loc<Expr>>,
|
||||||
variable: Variable,
|
variable: Variable,
|
||||||
|
@ -1249,7 +1251,7 @@ pub fn canonicalize_expr<'a>(
|
||||||
ast::Expr::Dbg(_, _) => {
|
ast::Expr::Dbg(_, _) => {
|
||||||
internal_error!("Dbg should have been desugared by now")
|
internal_error!("Dbg should have been desugared by now")
|
||||||
}
|
}
|
||||||
ast::Expr::LowLevelDbg(message, continuation) => {
|
ast::Expr::LowLevelDbg(source_location, source, message, continuation) => {
|
||||||
let mut output = Output::default();
|
let mut output = Output::default();
|
||||||
|
|
||||||
let (loc_message, output1) =
|
let (loc_message, output1) =
|
||||||
|
@ -1276,6 +1278,8 @@ pub fn canonicalize_expr<'a>(
|
||||||
|
|
||||||
(
|
(
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location: (*source_location).into(),
|
||||||
|
source: (*source).into(),
|
||||||
loc_message: Box::new(loc_message),
|
loc_message: Box::new(loc_message),
|
||||||
loc_continuation: Box::new(loc_continuation),
|
loc_continuation: Box::new(loc_continuation),
|
||||||
variable: var_store.fresh(),
|
variable: var_store.fresh(),
|
||||||
|
@ -2097,6 +2101,8 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
loc_message,
|
loc_message,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable,
|
variable,
|
||||||
|
@ -2113,6 +2119,8 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
||||||
};
|
};
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
loc_message: Box::new(loc_message),
|
loc_message: Box::new(loc_message),
|
||||||
loc_continuation: Box::new(loc_continuation),
|
loc_continuation: Box::new(loc_continuation),
|
||||||
variable,
|
variable,
|
||||||
|
@ -2398,7 +2406,7 @@ pub fn is_valid_interpolation(expr: &ast::Expr<'_>) -> bool {
|
||||||
| ast::Expr::MalformedClosure => true,
|
| ast::Expr::MalformedClosure => true,
|
||||||
// Newlines are disallowed inside interpolation, and these all require newlines
|
// Newlines are disallowed inside interpolation, and these all require newlines
|
||||||
ast::Expr::Dbg(_, _)
|
ast::Expr::Dbg(_, _)
|
||||||
| ast::Expr::LowLevelDbg(_, _)
|
| ast::Expr::LowLevelDbg(_, _, _, _)
|
||||||
| ast::Expr::Defs(_, _)
|
| ast::Expr::Defs(_, _)
|
||||||
| ast::Expr::Expect(_, _)
|
| ast::Expr::Expect(_, _)
|
||||||
| ast::Expr::When(_, _)
|
| ast::Expr::When(_, _)
|
||||||
|
|
|
@ -275,6 +275,8 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
loc_defs: &'a mut Defs<'a>,
|
loc_defs: &'a mut Defs<'a>,
|
||||||
header_type: &roc_parse::header::HeaderType,
|
header_type: &roc_parse::header::HeaderType,
|
||||||
home: ModuleId,
|
home: ModuleId,
|
||||||
|
module_path: &str,
|
||||||
|
src: &'a str,
|
||||||
module_ids: &'a ModuleIds,
|
module_ids: &'a ModuleIds,
|
||||||
exposed_ident_ids: IdentIds,
|
exposed_ident_ids: IdentIds,
|
||||||
dep_idents: &'a IdentIdsByModule,
|
dep_idents: &'a IdentIdsByModule,
|
||||||
|
@ -310,7 +312,7 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
||||||
// operators, and then again on *their* nested operators, ultimately applying the
|
// operators, and then again on *their* nested operators, ultimately applying the
|
||||||
// rules multiple times unnecessarily.
|
// rules multiple times unnecessarily.
|
||||||
crate::operator::desugar_defs(arena, loc_defs);
|
crate::operator::desugar_defs(arena, loc_defs, src, &mut None, module_path);
|
||||||
|
|
||||||
let mut rigid_variables = RigidVariables::default();
|
let mut rigid_variables = RigidVariables::default();
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use roc_parse::ast::{
|
||||||
AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, StrSegment, ValueDef,
|
AssignedField, Collection, Pattern, RecordBuilderField, StrLiteral, StrSegment, ValueDef,
|
||||||
WhenBranch,
|
WhenBranch,
|
||||||
};
|
};
|
||||||
use roc_region::all::{Loc, Region};
|
use roc_region::all::{LineInfo, Loc, Region};
|
||||||
|
|
||||||
// BinOp precedence logic adapted from Gluon by Markus Westerlind
|
// BinOp precedence logic adapted from Gluon by Markus Westerlind
|
||||||
// https://github.com/gluon-lang/gluon - license information can be found in
|
// https://github.com/gluon-lang/gluon - license information can be found in
|
||||||
|
@ -67,13 +67,19 @@ fn new_op_call_expr<'a>(
|
||||||
Loc { region, value }
|
Loc { region, value }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desugar_value_def<'a>(arena: &'a Bump, def: &'a ValueDef<'a>) -> ValueDef<'a> {
|
fn desugar_value_def<'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
def: &'a ValueDef<'a>,
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
|
) -> ValueDef<'a> {
|
||||||
use ValueDef::*;
|
use ValueDef::*;
|
||||||
|
|
||||||
match def {
|
match def {
|
||||||
Body(loc_pattern, loc_expr) => Body(
|
Body(loc_pattern, loc_expr) => Body(
|
||||||
desugar_loc_pattern(arena, loc_pattern),
|
desugar_loc_pattern(arena, loc_pattern, src, line_info, module_path),
|
||||||
desugar_expr(arena, loc_expr),
|
desugar_expr(arena, loc_expr, src, line_info, module_path),
|
||||||
),
|
),
|
||||||
ann @ Annotation(_, _) => *ann,
|
ann @ Annotation(_, _) => *ann,
|
||||||
AnnotatedBody {
|
AnnotatedBody {
|
||||||
|
@ -87,13 +93,14 @@ fn desugar_value_def<'a>(arena: &'a Bump, def: &'a ValueDef<'a>) -> ValueDef<'a>
|
||||||
ann_type,
|
ann_type,
|
||||||
comment: *comment,
|
comment: *comment,
|
||||||
body_pattern,
|
body_pattern,
|
||||||
body_expr: desugar_expr(arena, body_expr),
|
body_expr: desugar_expr(arena, body_expr, src, line_info, module_path),
|
||||||
},
|
},
|
||||||
Dbg {
|
Dbg {
|
||||||
condition,
|
condition,
|
||||||
preceding_comment,
|
preceding_comment,
|
||||||
} => {
|
} => {
|
||||||
let desugared_condition = &*arena.alloc(desugar_expr(arena, condition));
|
let desugared_condition =
|
||||||
|
&*arena.alloc(desugar_expr(arena, condition, src, line_info, module_path));
|
||||||
Dbg {
|
Dbg {
|
||||||
condition: desugared_condition,
|
condition: desugared_condition,
|
||||||
preceding_comment: *preceding_comment,
|
preceding_comment: *preceding_comment,
|
||||||
|
@ -103,7 +110,8 @@ fn desugar_value_def<'a>(arena: &'a Bump, def: &'a ValueDef<'a>) -> ValueDef<'a>
|
||||||
condition,
|
condition,
|
||||||
preceding_comment,
|
preceding_comment,
|
||||||
} => {
|
} => {
|
||||||
let desugared_condition = &*arena.alloc(desugar_expr(arena, condition));
|
let desugared_condition =
|
||||||
|
&*arena.alloc(desugar_expr(arena, condition, src, line_info, module_path));
|
||||||
Expect {
|
Expect {
|
||||||
condition: desugared_condition,
|
condition: desugared_condition,
|
||||||
preceding_comment: *preceding_comment,
|
preceding_comment: *preceding_comment,
|
||||||
|
@ -113,7 +121,8 @@ fn desugar_value_def<'a>(arena: &'a Bump, def: &'a ValueDef<'a>) -> ValueDef<'a>
|
||||||
condition,
|
condition,
|
||||||
preceding_comment,
|
preceding_comment,
|
||||||
} => {
|
} => {
|
||||||
let desugared_condition = &*arena.alloc(desugar_expr(arena, condition));
|
let desugared_condition =
|
||||||
|
&*arena.alloc(desugar_expr(arena, condition, src, line_info, module_path));
|
||||||
ExpectFx {
|
ExpectFx {
|
||||||
condition: desugared_condition,
|
condition: desugared_condition,
|
||||||
preceding_comment: *preceding_comment,
|
preceding_comment: *preceding_comment,
|
||||||
|
@ -122,15 +131,27 @@ fn desugar_value_def<'a>(arena: &'a Bump, def: &'a ValueDef<'a>) -> ValueDef<'a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn desugar_defs<'a>(arena: &'a Bump, defs: &mut roc_parse::ast::Defs<'a>) {
|
pub fn desugar_defs<'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
defs: &mut roc_parse::ast::Defs<'a>,
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
|
) {
|
||||||
for value_def in defs.value_defs.iter_mut() {
|
for value_def in defs.value_defs.iter_mut() {
|
||||||
*value_def = desugar_value_def(arena, arena.alloc(*value_def));
|
*value_def = desugar_value_def(arena, arena.alloc(*value_def), src, line_info, module_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reorder the expression tree based on operator precedence and associativity rules,
|
/// Reorder the expression tree based on operator precedence and associativity rules,
|
||||||
/// then replace the BinOp nodes with Apply nodes. Also drop SpaceBefore and SpaceAfter nodes.
|
/// then replace the BinOp nodes with Apply nodes. Also drop SpaceBefore and SpaceAfter nodes.
|
||||||
pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc<Expr<'a>> {
|
pub fn desugar_expr<'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
loc_expr: &'a Loc<Expr<'a>>,
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
|
) -> &'a Loc<Expr<'a>> {
|
||||||
match &loc_expr.value {
|
match &loc_expr.value {
|
||||||
Float(..)
|
Float(..)
|
||||||
| Num(..)
|
| Num(..)
|
||||||
|
@ -153,16 +174,22 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
StrLiteral::PlainLine(_) => loc_expr,
|
StrLiteral::PlainLine(_) => loc_expr,
|
||||||
StrLiteral::Line(segments) => {
|
StrLiteral::Line(segments) => {
|
||||||
let region = loc_expr.region;
|
let region = loc_expr.region;
|
||||||
let value = Str(StrLiteral::Line(desugar_str_segments(arena, segments)));
|
let value = Str(StrLiteral::Line(desugar_str_segments(
|
||||||
|
arena,
|
||||||
|
segments,
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
)));
|
||||||
|
|
||||||
arena.alloc(Loc { region, value })
|
arena.alloc(Loc { region, value })
|
||||||
}
|
}
|
||||||
StrLiteral::Block(lines) => {
|
StrLiteral::Block(lines) => {
|
||||||
let region = loc_expr.region;
|
let region = loc_expr.region;
|
||||||
let new_lines = Vec::from_iter_in(
|
let new_lines = Vec::from_iter_in(
|
||||||
lines
|
lines.iter().map(|segments| {
|
||||||
.iter()
|
desugar_str_segments(arena, segments, src, line_info, module_path)
|
||||||
.map(|segments| desugar_str_segments(arena, segments)),
|
}),
|
||||||
arena,
|
arena,
|
||||||
);
|
);
|
||||||
let value = Str(StrLiteral::Block(new_lines.into_bump_slice()));
|
let value = Str(StrLiteral::Block(new_lines.into_bump_slice()));
|
||||||
|
@ -177,7 +204,17 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
region,
|
region,
|
||||||
value: **sub_expr,
|
value: **sub_expr,
|
||||||
};
|
};
|
||||||
let value = TupleAccess(&desugar_expr(arena, arena.alloc(loc_sub_expr)).value, paths);
|
let value = TupleAccess(
|
||||||
|
&desugar_expr(
|
||||||
|
arena,
|
||||||
|
arena.alloc(loc_sub_expr),
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
)
|
||||||
|
.value,
|
||||||
|
paths,
|
||||||
|
);
|
||||||
|
|
||||||
arena.alloc(Loc { region, value })
|
arena.alloc(Loc { region, value })
|
||||||
}
|
}
|
||||||
|
@ -187,7 +224,17 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
region,
|
region,
|
||||||
value: **sub_expr,
|
value: **sub_expr,
|
||||||
};
|
};
|
||||||
let value = RecordAccess(&desugar_expr(arena, arena.alloc(loc_sub_expr)).value, paths);
|
let value = RecordAccess(
|
||||||
|
&desugar_expr(
|
||||||
|
arena,
|
||||||
|
arena.alloc(loc_sub_expr),
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
)
|
||||||
|
.value,
|
||||||
|
paths,
|
||||||
|
);
|
||||||
|
|
||||||
arena.alloc(Loc { region, value })
|
arena.alloc(Loc { region, value })
|
||||||
}
|
}
|
||||||
|
@ -195,7 +242,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
let mut new_items = Vec::with_capacity_in(items.len(), arena);
|
let mut new_items = Vec::with_capacity_in(items.len(), arena);
|
||||||
|
|
||||||
for item in items.iter() {
|
for item in items.iter() {
|
||||||
new_items.push(desugar_expr(arena, item));
|
new_items.push(desugar_expr(arena, item, src, line_info, module_path));
|
||||||
}
|
}
|
||||||
let new_items = new_items.into_bump_slice();
|
let new_items = new_items.into_bump_slice();
|
||||||
let value: Expr<'a> = List(items.replace_items(new_items));
|
let value: Expr<'a> = List(items.replace_items(new_items));
|
||||||
|
@ -205,32 +252,47 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
value,
|
value,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Record(fields) => arena.alloc(Loc {
|
Record(fields) => {
|
||||||
region: loc_expr.region,
|
let mut allocated = Vec::with_capacity_in(fields.len(), arena);
|
||||||
value: Record(fields.map_items(arena, |field| {
|
for field in fields.iter() {
|
||||||
let value = desugar_field(arena, &field.value);
|
let value = desugar_field(arena, &field.value, src, line_info, module_path);
|
||||||
Loc {
|
allocated.push(Loc {
|
||||||
value,
|
value,
|
||||||
region: field.region,
|
region: field.region,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})),
|
let fields = fields.replace_items(allocated.into_bump_slice());
|
||||||
}),
|
arena.alloc(Loc {
|
||||||
Tuple(fields) => arena.alloc(Loc {
|
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
value: Tuple(fields.map_items(arena, |field| desugar_expr(arena, field))),
|
value: Record(fields),
|
||||||
}),
|
})
|
||||||
|
}
|
||||||
|
Tuple(fields) => {
|
||||||
|
let mut allocated = Vec::with_capacity_in(fields.len(), arena);
|
||||||
|
for field in fields.iter() {
|
||||||
|
let expr = desugar_expr(arena, field, src, line_info, module_path);
|
||||||
|
allocated.push(expr);
|
||||||
|
}
|
||||||
|
let fields = fields.replace_items(allocated.into_bump_slice());
|
||||||
|
arena.alloc(Loc {
|
||||||
|
region: loc_expr.region,
|
||||||
|
value: Tuple(fields),
|
||||||
|
})
|
||||||
|
}
|
||||||
RecordUpdate { fields, update } => {
|
RecordUpdate { fields, update } => {
|
||||||
// NOTE the `update` field is always a `Var { .. }`, we only desugar it to get rid of
|
// NOTE the `update` field is always a `Var { .. }`, we only desugar it to get rid of
|
||||||
// any spaces before/after
|
// any spaces before/after
|
||||||
let new_update = desugar_expr(arena, update);
|
let new_update = desugar_expr(arena, update, src, line_info, module_path);
|
||||||
|
|
||||||
let new_fields = fields.map_items(arena, |field| {
|
let mut allocated = Vec::with_capacity_in(fields.len(), arena);
|
||||||
let value = desugar_field(arena, &field.value);
|
for field in fields.iter() {
|
||||||
Loc {
|
let value = desugar_field(arena, &field.value, src, line_info, module_path);
|
||||||
|
allocated.push(Loc {
|
||||||
value,
|
value,
|
||||||
region: field.region,
|
region: field.region,
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
let new_fields = fields.replace_items(allocated.into_bump_slice());
|
||||||
|
|
||||||
arena.alloc(Loc {
|
arena.alloc(Loc {
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
|
@ -243,8 +305,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
Closure(loc_patterns, loc_ret) => arena.alloc(Loc {
|
Closure(loc_patterns, loc_ret) => arena.alloc(Loc {
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
value: Closure(
|
value: Closure(
|
||||||
desugar_loc_patterns(arena, loc_patterns),
|
desugar_loc_patterns(arena, loc_patterns, src, line_info, module_path),
|
||||||
desugar_expr(arena, loc_ret),
|
desugar_expr(arena, loc_ret, src, line_info, module_path),
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
Backpassing(loc_patterns, loc_body, loc_ret) => {
|
Backpassing(loc_patterns, loc_body, loc_ret) => {
|
||||||
|
@ -253,10 +315,11 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
// loc_ret
|
// loc_ret
|
||||||
|
|
||||||
// first desugar the body, because it may contain |>
|
// first desugar the body, because it may contain |>
|
||||||
let desugared_body = desugar_expr(arena, loc_body);
|
let desugared_body = desugar_expr(arena, loc_body, src, line_info, module_path);
|
||||||
|
|
||||||
let desugared_ret = desugar_expr(arena, loc_ret);
|
let desugared_ret = desugar_expr(arena, loc_ret, src, line_info, module_path);
|
||||||
let desugared_loc_patterns = desugar_loc_patterns(arena, loc_patterns);
|
let desugared_loc_patterns =
|
||||||
|
desugar_loc_patterns(arena, loc_patterns, src, line_info, module_path);
|
||||||
let closure = Expr::Closure(desugared_loc_patterns, desugared_ret);
|
let closure = Expr::Closure(desugared_loc_patterns, desugared_ret);
|
||||||
let loc_closure = Loc::at(loc_expr.region, closure);
|
let loc_closure = Loc::at(loc_expr.region, closure);
|
||||||
|
|
||||||
|
@ -289,12 +352,20 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
value: UnappliedRecordBuilder(loc_expr),
|
value: UnappliedRecordBuilder(loc_expr),
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
}),
|
}),
|
||||||
BinOps(lefts, right) => desugar_bin_ops(arena, loc_expr.region, lefts, right),
|
BinOps(lefts, right) => desugar_bin_ops(
|
||||||
|
arena,
|
||||||
|
loc_expr.region,
|
||||||
|
lefts,
|
||||||
|
right,
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
),
|
||||||
Defs(defs, loc_ret) => {
|
Defs(defs, loc_ret) => {
|
||||||
let mut defs = (*defs).clone();
|
let mut defs = (*defs).clone();
|
||||||
desugar_defs(arena, &mut defs);
|
desugar_defs(arena, &mut defs, src, line_info, module_path);
|
||||||
|
|
||||||
let loc_ret = desugar_expr(arena, loc_ret);
|
let loc_ret = desugar_expr(arena, loc_ret, src, line_info, module_path);
|
||||||
|
|
||||||
arena.alloc(Loc::at(loc_expr.region, Defs(arena.alloc(defs), loc_ret)))
|
arena.alloc(Loc::at(loc_expr.region, Defs(arena.alloc(defs), loc_ret)))
|
||||||
}
|
}
|
||||||
|
@ -326,13 +397,17 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
desugared_args.push(desugar_expr(arena, arg));
|
desugared_args.push(desugar_expr(arena, arg, src, line_info, module_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
let desugared_args = desugared_args.into_bump_slice();
|
let desugared_args = desugared_args.into_bump_slice();
|
||||||
|
|
||||||
let mut apply: &Loc<Expr> = arena.alloc(Loc {
|
let mut apply: &Loc<Expr> = arena.alloc(Loc {
|
||||||
value: Apply(desugar_expr(arena, loc_fn), desugared_args, *called_via),
|
value: Apply(
|
||||||
|
desugar_expr(arena, loc_fn, src, line_info, module_path),
|
||||||
|
desugared_args,
|
||||||
|
*called_via,
|
||||||
|
),
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -341,7 +416,7 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
|
|
||||||
Some(apply_exprs) => {
|
Some(apply_exprs) => {
|
||||||
for expr in apply_exprs {
|
for expr in apply_exprs {
|
||||||
let desugared_expr = desugar_expr(arena, expr);
|
let desugared_expr = desugar_expr(arena, expr, src, line_info, module_path);
|
||||||
|
|
||||||
let args = std::slice::from_ref(arena.alloc(apply));
|
let args = std::slice::from_ref(arena.alloc(apply));
|
||||||
|
|
||||||
|
@ -356,15 +431,23 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
apply
|
apply
|
||||||
}
|
}
|
||||||
When(loc_cond_expr, branches) => {
|
When(loc_cond_expr, branches) => {
|
||||||
let loc_desugared_cond = &*arena.alloc(desugar_expr(arena, loc_cond_expr));
|
let loc_desugared_cond = &*arena.alloc(desugar_expr(
|
||||||
|
arena,
|
||||||
|
loc_cond_expr,
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
));
|
||||||
let mut desugared_branches = Vec::with_capacity_in(branches.len(), arena);
|
let mut desugared_branches = Vec::with_capacity_in(branches.len(), arena);
|
||||||
|
|
||||||
for branch in branches.iter() {
|
for branch in branches.iter() {
|
||||||
let desugared_expr = desugar_expr(arena, &branch.value);
|
let desugared_expr =
|
||||||
let desugared_patterns = desugar_loc_patterns(arena, branch.patterns);
|
desugar_expr(arena, &branch.value, src, line_info, module_path);
|
||||||
|
let desugared_patterns =
|
||||||
|
desugar_loc_patterns(arena, branch.patterns, src, line_info, module_path);
|
||||||
|
|
||||||
let desugared_guard = if let Some(guard) = &branch.guard {
|
let desugared_guard = if let Some(guard) = &branch.guard {
|
||||||
Some(*desugar_expr(arena, guard))
|
Some(*desugar_expr(arena, guard, src, line_info, module_path))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -402,7 +485,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let loc_fn_var = arena.alloc(Loc { region, value });
|
let loc_fn_var = arena.alloc(Loc { region, value });
|
||||||
let desugared_args = arena.alloc([desugar_expr(arena, loc_arg)]);
|
let desugared_args =
|
||||||
|
arena.alloc([desugar_expr(arena, loc_arg, src, line_info, module_path)]);
|
||||||
|
|
||||||
arena.alloc(Loc {
|
arena.alloc(Loc {
|
||||||
value: Apply(loc_fn_var, desugared_args, CalledVia::UnaryOp(op)),
|
value: Apply(loc_fn_var, desugared_args, CalledVia::UnaryOp(op)),
|
||||||
|
@ -418,6 +502,9 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
value: **expr,
|
value: **expr,
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
}),
|
}),
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ParensAround(expr) => {
|
ParensAround(expr) => {
|
||||||
|
@ -427,6 +514,9 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
value: **expr,
|
value: **expr,
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
}),
|
}),
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
);
|
);
|
||||||
|
|
||||||
arena.alloc(Loc {
|
arena.alloc(Loc {
|
||||||
|
@ -436,14 +526,20 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
}
|
}
|
||||||
If(if_thens, final_else_branch) => {
|
If(if_thens, final_else_branch) => {
|
||||||
// If does not get desugared into `when` so we can give more targeted error messages during type checking.
|
// If does not get desugared into `when` so we can give more targeted error messages during type checking.
|
||||||
let desugared_final_else = &*arena.alloc(desugar_expr(arena, final_else_branch));
|
let desugared_final_else = &*arena.alloc(desugar_expr(
|
||||||
|
arena,
|
||||||
|
final_else_branch,
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
));
|
||||||
|
|
||||||
let mut desugared_if_thens = Vec::with_capacity_in(if_thens.len(), arena);
|
let mut desugared_if_thens = Vec::with_capacity_in(if_thens.len(), arena);
|
||||||
|
|
||||||
for (condition, then_branch) in if_thens.iter() {
|
for (condition, then_branch) in if_thens.iter() {
|
||||||
desugared_if_thens.push((
|
desugared_if_thens.push((
|
||||||
*desugar_expr(arena, condition),
|
*desugar_expr(arena, condition, src, line_info, module_path),
|
||||||
*desugar_expr(arena, then_branch),
|
*desugar_expr(arena, then_branch, src, line_info, module_path),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,8 +549,15 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Expect(condition, continuation) => {
|
Expect(condition, continuation) => {
|
||||||
let desugared_condition = &*arena.alloc(desugar_expr(arena, condition));
|
let desugared_condition =
|
||||||
let desugared_continuation = &*arena.alloc(desugar_expr(arena, continuation));
|
&*arena.alloc(desugar_expr(arena, condition, src, line_info, module_path));
|
||||||
|
let desugared_continuation = &*arena.alloc(desugar_expr(
|
||||||
|
arena,
|
||||||
|
continuation,
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
));
|
||||||
arena.alloc(Loc {
|
arena.alloc(Loc {
|
||||||
value: Expect(desugared_condition, desugared_continuation),
|
value: Expect(desugared_condition, desugared_continuation),
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
|
@ -463,7 +566,13 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
Dbg(condition, continuation) => {
|
Dbg(condition, continuation) => {
|
||||||
// Desugars a `dbg x` statement into essentially
|
// Desugars a `dbg x` statement into essentially
|
||||||
// Inspect.toInspector x |> Inspect.apply (Inspect.init {}) |> Inspect.toDbgStr |> LowLevelDbg
|
// Inspect.toInspector x |> Inspect.apply (Inspect.init {}) |> Inspect.toDbgStr |> LowLevelDbg
|
||||||
let desugared_continuation = &*arena.alloc(desugar_expr(arena, continuation));
|
let desugared_continuation = &*arena.alloc(desugar_expr(
|
||||||
|
arena,
|
||||||
|
continuation,
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
|
));
|
||||||
|
|
||||||
let region = condition.region;
|
let region = condition.region;
|
||||||
// Inspect.toInspector x
|
// Inspect.toInspector x
|
||||||
|
@ -475,7 +584,8 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
value: to_inspector_fn,
|
value: to_inspector_fn,
|
||||||
region,
|
region,
|
||||||
});
|
});
|
||||||
let desugared_to_inspector_args = arena.alloc([desugar_expr(arena, condition)]);
|
let desugared_to_inspector_args =
|
||||||
|
arena.alloc([desugar_expr(arena, condition, src, line_info, module_path)]);
|
||||||
|
|
||||||
let inspector = arena.alloc(Loc {
|
let inspector = arena.alloc(Loc {
|
||||||
value: Apply(
|
value: Apply(
|
||||||
|
@ -533,19 +643,41 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
value: Apply(loc_to_dbg_str_fn_var, to_dbg_str_args, CalledVia::Space),
|
value: Apply(loc_to_dbg_str_fn_var, to_dbg_str_args, CalledVia::Space),
|
||||||
region,
|
region,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// line_info is an option so that we can lazily calculate it.
|
||||||
|
// That way it there are no `dbg` statements, we never pay the cast of scanning the source an extra time.
|
||||||
|
if matches!(line_info, None) {
|
||||||
|
*line_info = Some(LineInfo::new(src));
|
||||||
|
}
|
||||||
|
let line_col = line_info.as_ref().unwrap().convert_pos(region.start());
|
||||||
|
|
||||||
|
let dbg_src = src
|
||||||
|
.split_at(region.start().offset as usize)
|
||||||
|
.1
|
||||||
|
.split_at((region.end().offset - region.start().offset) as usize)
|
||||||
|
.0;
|
||||||
|
|
||||||
// |> LowLevelDbg
|
// |> LowLevelDbg
|
||||||
arena.alloc(Loc {
|
arena.alloc(Loc {
|
||||||
value: LowLevelDbg(dbg_str, desugared_continuation),
|
value: LowLevelDbg(
|
||||||
|
arena.alloc(format!("{}:{}", module_path, line_col.line)),
|
||||||
|
arena.alloc(dbg_src),
|
||||||
|
dbg_str,
|
||||||
|
desugared_continuation,
|
||||||
|
),
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
LowLevelDbg(_, _) => unreachable!("Only exists after desugaring"),
|
LowLevelDbg(_, _, _, _) => unreachable!("Only exists after desugaring"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desugar_str_segments<'a>(
|
fn desugar_str_segments<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
segments: &'a [StrSegment<'a>],
|
segments: &'a [StrSegment<'a>],
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
) -> &'a [StrSegment<'a>] {
|
) -> &'a [StrSegment<'a>] {
|
||||||
Vec::from_iter_in(
|
Vec::from_iter_in(
|
||||||
segments.iter().map(|segment| match segment {
|
segments.iter().map(|segment| match segment {
|
||||||
|
@ -559,6 +691,9 @@ fn desugar_str_segments<'a>(
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
value: *loc_expr.value,
|
value: *loc_expr.value,
|
||||||
}),
|
}),
|
||||||
|
src,
|
||||||
|
line_info,
|
||||||
|
module_path,
|
||||||
);
|
);
|
||||||
StrSegment::Interpolated(Loc {
|
StrSegment::Interpolated(Loc {
|
||||||
region: loc_desugared.region,
|
region: loc_desugared.region,
|
||||||
|
@ -574,6 +709,9 @@ fn desugar_str_segments<'a>(
|
||||||
fn desugar_field<'a>(
|
fn desugar_field<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
field: &'a AssignedField<'a, Expr<'a>>,
|
field: &'a AssignedField<'a, Expr<'a>>,
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
) -> AssignedField<'a, Expr<'a>> {
|
) -> AssignedField<'a, Expr<'a>> {
|
||||||
use roc_parse::ast::AssignedField::*;
|
use roc_parse::ast::AssignedField::*;
|
||||||
|
|
||||||
|
@ -584,7 +722,7 @@ fn desugar_field<'a>(
|
||||||
region: loc_str.region,
|
region: loc_str.region,
|
||||||
},
|
},
|
||||||
spaces,
|
spaces,
|
||||||
desugar_expr(arena, loc_expr),
|
desugar_expr(arena, loc_expr, src, line_info, module_path),
|
||||||
),
|
),
|
||||||
OptionalValue(loc_str, spaces, loc_expr) => OptionalValue(
|
OptionalValue(loc_str, spaces, loc_expr) => OptionalValue(
|
||||||
Loc {
|
Loc {
|
||||||
|
@ -592,7 +730,7 @@ fn desugar_field<'a>(
|
||||||
region: loc_str.region,
|
region: loc_str.region,
|
||||||
},
|
},
|
||||||
spaces,
|
spaces,
|
||||||
desugar_expr(arena, loc_expr),
|
desugar_expr(arena, loc_expr, src, line_info, module_path),
|
||||||
),
|
),
|
||||||
LabelOnly(loc_str) => {
|
LabelOnly(loc_str) => {
|
||||||
// Desugar { x } into { x: x }
|
// Desugar { x } into { x: x }
|
||||||
|
@ -610,11 +748,11 @@ fn desugar_field<'a>(
|
||||||
region: loc_str.region,
|
region: loc_str.region,
|
||||||
},
|
},
|
||||||
&[],
|
&[],
|
||||||
desugar_expr(arena, arena.alloc(loc_expr)),
|
desugar_expr(arena, arena.alloc(loc_expr), src, line_info, module_path),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
SpaceBefore(field, _spaces) => desugar_field(arena, field),
|
SpaceBefore(field, _spaces) => desugar_field(arena, field, src, line_info, module_path),
|
||||||
SpaceAfter(field, _spaces) => desugar_field(arena, field),
|
SpaceAfter(field, _spaces) => desugar_field(arena, field, src, line_info, module_path),
|
||||||
|
|
||||||
Malformed(string) => Malformed(string),
|
Malformed(string) => Malformed(string),
|
||||||
}
|
}
|
||||||
|
@ -623,11 +761,14 @@ fn desugar_field<'a>(
|
||||||
fn desugar_loc_patterns<'a>(
|
fn desugar_loc_patterns<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
loc_patterns: &'a [Loc<Pattern<'a>>],
|
loc_patterns: &'a [Loc<Pattern<'a>>],
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
) -> &'a [Loc<Pattern<'a>>] {
|
) -> &'a [Loc<Pattern<'a>>] {
|
||||||
Vec::from_iter_in(
|
Vec::from_iter_in(
|
||||||
loc_patterns.iter().map(|loc_pattern| Loc {
|
loc_patterns.iter().map(|loc_pattern| Loc {
|
||||||
region: loc_pattern.region,
|
region: loc_pattern.region,
|
||||||
value: desugar_pattern(arena, loc_pattern.value),
|
value: desugar_pattern(arena, loc_pattern.value, src, line_info, module_path),
|
||||||
}),
|
}),
|
||||||
arena,
|
arena,
|
||||||
)
|
)
|
||||||
|
@ -637,14 +778,23 @@ fn desugar_loc_patterns<'a>(
|
||||||
fn desugar_loc_pattern<'a>(
|
fn desugar_loc_pattern<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
loc_pattern: &'a Loc<Pattern<'a>>,
|
loc_pattern: &'a Loc<Pattern<'a>>,
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
) -> &'a Loc<Pattern<'a>> {
|
) -> &'a Loc<Pattern<'a>> {
|
||||||
arena.alloc(Loc {
|
arena.alloc(Loc {
|
||||||
region: loc_pattern.region,
|
region: loc_pattern.region,
|
||||||
value: desugar_pattern(arena, loc_pattern.value),
|
value: desugar_pattern(arena, loc_pattern.value, src, line_info, module_path),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desugar_pattern<'a>(arena: &'a Bump, pattern: Pattern<'a>) -> Pattern<'a> {
|
fn desugar_pattern<'a>(
|
||||||
|
arena: &'a Bump,
|
||||||
|
pattern: Pattern<'a>,
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
|
) -> Pattern<'a> {
|
||||||
use roc_parse::ast::Pattern::*;
|
use roc_parse::ast::Pattern::*;
|
||||||
|
|
||||||
match pattern {
|
match pattern {
|
||||||
|
@ -667,7 +817,7 @@ fn desugar_pattern<'a>(arena: &'a Bump, pattern: Pattern<'a>) -> Pattern<'a> {
|
||||||
let desugared_arg_patterns = Vec::from_iter_in(
|
let desugared_arg_patterns = Vec::from_iter_in(
|
||||||
arg_patterns.iter().map(|arg_pattern| Loc {
|
arg_patterns.iter().map(|arg_pattern| Loc {
|
||||||
region: arg_pattern.region,
|
region: arg_pattern.region,
|
||||||
value: desugar_pattern(arena, arg_pattern.value),
|
value: desugar_pattern(arena, arg_pattern.value, src, line_info, module_path),
|
||||||
}),
|
}),
|
||||||
arena,
|
arena,
|
||||||
)
|
)
|
||||||
|
@ -676,26 +826,62 @@ fn desugar_pattern<'a>(arena: &'a Bump, pattern: Pattern<'a>) -> Pattern<'a> {
|
||||||
Apply(tag, desugared_arg_patterns)
|
Apply(tag, desugared_arg_patterns)
|
||||||
}
|
}
|
||||||
RecordDestructure(field_patterns) => {
|
RecordDestructure(field_patterns) => {
|
||||||
RecordDestructure(field_patterns.map_items(arena, |field_pattern| Loc {
|
let mut allocated = Vec::with_capacity_in(field_patterns.len(), arena);
|
||||||
|
for field_pattern in field_patterns.iter() {
|
||||||
|
let value =
|
||||||
|
desugar_pattern(arena, field_pattern.value, src, line_info, module_path);
|
||||||
|
allocated.push(Loc {
|
||||||
|
value,
|
||||||
region: field_pattern.region,
|
region: field_pattern.region,
|
||||||
value: desugar_pattern(arena, field_pattern.value),
|
});
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
RequiredField(name, field_pattern) => {
|
let field_patterns = field_patterns.replace_items(allocated.into_bump_slice());
|
||||||
RequiredField(name, desugar_loc_pattern(arena, field_pattern))
|
|
||||||
|
RecordDestructure(field_patterns)
|
||||||
|
}
|
||||||
|
RequiredField(name, field_pattern) => RequiredField(
|
||||||
|
name,
|
||||||
|
desugar_loc_pattern(arena, field_pattern, src, line_info, module_path),
|
||||||
|
),
|
||||||
|
OptionalField(name, expr) => {
|
||||||
|
OptionalField(name, desugar_expr(arena, expr, src, line_info, module_path))
|
||||||
|
}
|
||||||
|
Tuple(patterns) => {
|
||||||
|
let mut allocated = Vec::with_capacity_in(patterns.len(), arena);
|
||||||
|
for pattern in patterns.iter() {
|
||||||
|
let value = desugar_pattern(arena, pattern.value, src, line_info, module_path);
|
||||||
|
allocated.push(Loc {
|
||||||
|
value,
|
||||||
|
region: pattern.region,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let patterns = patterns.replace_items(allocated.into_bump_slice());
|
||||||
|
|
||||||
|
Tuple(patterns)
|
||||||
|
}
|
||||||
|
List(patterns) => {
|
||||||
|
let mut allocated = Vec::with_capacity_in(patterns.len(), arena);
|
||||||
|
for pattern in patterns.iter() {
|
||||||
|
let value = desugar_pattern(arena, pattern.value, src, line_info, module_path);
|
||||||
|
allocated.push(Loc {
|
||||||
|
value,
|
||||||
|
region: pattern.region,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let patterns = patterns.replace_items(allocated.into_bump_slice());
|
||||||
|
|
||||||
|
List(patterns)
|
||||||
|
}
|
||||||
|
As(sub_pattern, symbol) => As(
|
||||||
|
desugar_loc_pattern(arena, sub_pattern, src, line_info, module_path),
|
||||||
|
symbol,
|
||||||
|
),
|
||||||
|
SpaceBefore(sub_pattern, _spaces) => {
|
||||||
|
desugar_pattern(arena, *sub_pattern, src, line_info, module_path)
|
||||||
|
}
|
||||||
|
SpaceAfter(sub_pattern, _spaces) => {
|
||||||
|
desugar_pattern(arena, *sub_pattern, src, line_info, module_path)
|
||||||
}
|
}
|
||||||
OptionalField(name, expr) => OptionalField(name, desugar_expr(arena, expr)),
|
|
||||||
Tuple(patterns) => Tuple(patterns.map_items(arena, |elem_pattern| Loc {
|
|
||||||
region: elem_pattern.region,
|
|
||||||
value: desugar_pattern(arena, elem_pattern.value),
|
|
||||||
})),
|
|
||||||
List(patterns) => List(patterns.map_items(arena, |elem_pattern| Loc {
|
|
||||||
region: elem_pattern.region,
|
|
||||||
value: desugar_pattern(arena, elem_pattern.value),
|
|
||||||
})),
|
|
||||||
As(sub_pattern, symbol) => As(desugar_loc_pattern(arena, sub_pattern), symbol),
|
|
||||||
SpaceBefore(sub_pattern, _spaces) => desugar_pattern(arena, *sub_pattern),
|
|
||||||
SpaceAfter(sub_pattern, _spaces) => desugar_pattern(arena, *sub_pattern),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,19 +1010,22 @@ fn desugar_bin_ops<'a>(
|
||||||
whole_region: Region,
|
whole_region: Region,
|
||||||
lefts: &'a [(Loc<Expr<'_>>, Loc<BinOp>)],
|
lefts: &'a [(Loc<Expr<'_>>, Loc<BinOp>)],
|
||||||
right: &'a Loc<Expr<'_>>,
|
right: &'a Loc<Expr<'_>>,
|
||||||
|
src: &'a str,
|
||||||
|
line_info: &mut Option<LineInfo>,
|
||||||
|
module_path: &str,
|
||||||
) -> &'a Loc<Expr<'a>> {
|
) -> &'a Loc<Expr<'a>> {
|
||||||
let mut arg_stack: Vec<&'a Loc<Expr>> = Vec::with_capacity_in(lefts.len() + 1, arena);
|
let mut arg_stack: Vec<&'a Loc<Expr>> = Vec::with_capacity_in(lefts.len() + 1, arena);
|
||||||
let mut op_stack: Vec<Loc<BinOp>> = Vec::with_capacity_in(lefts.len(), arena);
|
let mut op_stack: Vec<Loc<BinOp>> = Vec::with_capacity_in(lefts.len(), arena);
|
||||||
|
|
||||||
for (loc_expr, loc_op) in lefts {
|
for (loc_expr, loc_op) in lefts {
|
||||||
arg_stack.push(desugar_expr(arena, loc_expr));
|
arg_stack.push(desugar_expr(arena, loc_expr, src, line_info, module_path));
|
||||||
match run_binop_step(arena, whole_region, &mut arg_stack, &mut op_stack, *loc_op) {
|
match run_binop_step(arena, whole_region, &mut arg_stack, &mut op_stack, *loc_op) {
|
||||||
Err(problem) => return problem,
|
Err(problem) => return problem,
|
||||||
Ok(()) => continue,
|
Ok(()) => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut expr = desugar_expr(arena, right);
|
let mut expr = desugar_expr(arena, right, src, line_info, module_path);
|
||||||
|
|
||||||
for (left, loc_op) in arg_stack.into_iter().zip(op_stack.into_iter()).rev() {
|
for (left, loc_op) in arg_stack.into_iter().zip(op_stack.into_iter()).rev() {
|
||||||
expr = arena.alloc(new_op_call_expr(arena, left, loc_op, expr));
|
expr = arena.alloc(new_op_call_expr(arena, left, loc_op, expr));
|
||||||
|
|
|
@ -387,6 +387,8 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
||||||
}
|
}
|
||||||
Expr::Dbg {
|
Expr::Dbg {
|
||||||
variable,
|
variable,
|
||||||
|
source: _,
|
||||||
|
source_location: _,
|
||||||
loc_message,
|
loc_message,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
symbol: _,
|
symbol: _,
|
||||||
|
|
|
@ -52,7 +52,13 @@ pub fn can_expr_with(arena: &Bump, home: ModuleId, expr_str: &str) -> CanExprOut
|
||||||
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
||||||
// operators, and then again on *their* nested operators, ultimately applying the
|
// operators, and then again on *their* nested operators, ultimately applying the
|
||||||
// rules multiple times unnecessarily.
|
// rules multiple times unnecessarily.
|
||||||
let loc_expr = operator::desugar_expr(arena, &loc_expr);
|
let loc_expr = operator::desugar_expr(
|
||||||
|
arena,
|
||||||
|
&loc_expr,
|
||||||
|
expr_str,
|
||||||
|
&mut None,
|
||||||
|
arena.alloc("TestPath"),
|
||||||
|
);
|
||||||
|
|
||||||
let mut scope = Scope::new(home, IdentIds::default(), Default::default());
|
let mut scope = Scope::new(home, IdentIds::default(), Default::default());
|
||||||
scope.add_alias(
|
scope.add_alias(
|
||||||
|
|
|
@ -741,6 +741,8 @@ pub fn constrain_expr(
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location: _,
|
||||||
|
source: _,
|
||||||
loc_message,
|
loc_message,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable,
|
variable,
|
||||||
|
|
|
@ -62,7 +62,7 @@ impl<'a> Formattable for Expr<'a> {
|
||||||
condition.is_multiline() || continuation.is_multiline()
|
condition.is_multiline() || continuation.is_multiline()
|
||||||
}
|
}
|
||||||
Dbg(condition, continuation) => condition.is_multiline() || continuation.is_multiline(),
|
Dbg(condition, continuation) => condition.is_multiline() || continuation.is_multiline(),
|
||||||
LowLevelDbg(_, _) => unreachable!(
|
LowLevelDbg(_, _, _, _) => unreachable!(
|
||||||
"LowLevelDbg should only exist after desugaring, not during formatting"
|
"LowLevelDbg should only exist after desugaring, not during formatting"
|
||||||
),
|
),
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ impl<'a> Formattable for Expr<'a> {
|
||||||
Dbg(condition, continuation) => {
|
Dbg(condition, continuation) => {
|
||||||
fmt_dbg(buf, condition, continuation, self.is_multiline(), indent);
|
fmt_dbg(buf, condition, continuation, self.is_multiline(), indent);
|
||||||
}
|
}
|
||||||
LowLevelDbg(_, _) => unreachable!(
|
LowLevelDbg(_, _, _, _) => unreachable!(
|
||||||
"LowLevelDbg should only exist after desugaring, not during formatting"
|
"LowLevelDbg should only exist after desugaring, not during formatting"
|
||||||
),
|
),
|
||||||
If(branches, final_else) => {
|
If(branches, final_else) => {
|
||||||
|
|
|
@ -726,7 +726,7 @@ impl<'a> RemoveSpaces<'a> for Expr<'a> {
|
||||||
arena.alloc(a.remove_spaces(arena)),
|
arena.alloc(a.remove_spaces(arena)),
|
||||||
arena.alloc(b.remove_spaces(arena)),
|
arena.alloc(b.remove_spaces(arena)),
|
||||||
),
|
),
|
||||||
Expr::LowLevelDbg(_, _) => unreachable!(
|
Expr::LowLevelDbg(_, _, _, _) => unreachable!(
|
||||||
"LowLevelDbg should only exist after desugaring, not during formatting"
|
"LowLevelDbg should only exist after desugaring, not during formatting"
|
||||||
),
|
),
|
||||||
Expr::Apply(a, b, c) => Expr::Apply(
|
Expr::Apply(a, b, c) => Expr::Apply(
|
||||||
|
|
|
@ -910,16 +910,18 @@ impl<'a, 'ctx, 'env> Env<'a, 'ctx, 'env> {
|
||||||
&self,
|
&self,
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
location: BasicValueEnum<'ctx>,
|
location: BasicValueEnum<'ctx>,
|
||||||
|
source: BasicValueEnum<'ctx>,
|
||||||
message: BasicValueEnum<'ctx>,
|
message: BasicValueEnum<'ctx>,
|
||||||
) {
|
) {
|
||||||
let function = self.module.get_function("roc_dbg").unwrap();
|
let function = self.module.get_function("roc_dbg").unwrap();
|
||||||
|
|
||||||
let loc = self.string_to_arg(env, location);
|
let loc = self.string_to_arg(env, location);
|
||||||
|
let src = self.string_to_arg(env, source);
|
||||||
let msg = self.string_to_arg(env, message);
|
let msg = self.string_to_arg(env, message);
|
||||||
|
|
||||||
let call = self
|
let call =
|
||||||
.builder
|
self.builder
|
||||||
.new_build_call(function, &[loc.into(), msg.into()], "roc_dbg");
|
.new_build_call(function, &[loc.into(), src.into(), msg.into()], "roc_dbg");
|
||||||
|
|
||||||
call.set_call_convention(C_CALL_CONV);
|
call.set_call_convention(C_CALL_CONV);
|
||||||
}
|
}
|
||||||
|
@ -3527,17 +3529,17 @@ pub(crate) fn build_exp_stmt<'a, 'ctx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol,
|
symbol,
|
||||||
variable: _,
|
variable: _,
|
||||||
remainder,
|
remainder,
|
||||||
} => {
|
} => {
|
||||||
if env.mode.runs_expects() {
|
if env.mode.runs_expects() {
|
||||||
// TODO: Change location to `filename:line_number`
|
let location = build_string_literal(env, parent, source_location);
|
||||||
// let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(*symbol) };
|
let source = build_string_literal(env, parent, source);
|
||||||
let location =
|
|
||||||
build_string_literal(env, parent, symbol.module_string(&env.interns));
|
|
||||||
let message = scope.load_symbol(symbol);
|
let message = scope.load_symbol(symbol);
|
||||||
env.call_dbg(env, location, message);
|
env.call_dbg(env, location, source, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
build_exp_stmt(
|
build_exp_stmt(
|
||||||
|
|
|
@ -166,7 +166,13 @@ pub fn can_expr_with<'a>(
|
||||||
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
// visited a BinOp node we'd recursively try to apply this to each of its nested
|
||||||
// operators, and then again on *their* nested operators, ultimately applying the
|
// operators, and then again on *their* nested operators, ultimately applying the
|
||||||
// rules multiple times unnecessarily.
|
// rules multiple times unnecessarily.
|
||||||
let loc_expr = operator::desugar_expr(arena, &loc_expr);
|
let loc_expr = operator::desugar_expr(
|
||||||
|
arena,
|
||||||
|
&loc_expr,
|
||||||
|
expr_str,
|
||||||
|
&mut None,
|
||||||
|
arena.alloc("TestPath"),
|
||||||
|
);
|
||||||
|
|
||||||
let mut scope = Scope::new(home, IdentIds::default(), Default::default());
|
let mut scope = Scope::new(home, IdentIds::default(), Default::default());
|
||||||
|
|
||||||
|
|
|
@ -5264,6 +5264,8 @@ fn canonicalize_and_constrain<'a>(
|
||||||
|
|
||||||
let ParsedModule {
|
let ParsedModule {
|
||||||
module_id,
|
module_id,
|
||||||
|
module_path,
|
||||||
|
src,
|
||||||
header_type,
|
header_type,
|
||||||
exposed_ident_ids,
|
exposed_ident_ids,
|
||||||
parsed_defs,
|
parsed_defs,
|
||||||
|
@ -5286,6 +5288,8 @@ fn canonicalize_and_constrain<'a>(
|
||||||
parsed_defs,
|
parsed_defs,
|
||||||
&header_type,
|
&header_type,
|
||||||
module_id,
|
module_id,
|
||||||
|
&*arena.alloc(module_path.to_string_lossy()),
|
||||||
|
src,
|
||||||
module_ids,
|
module_ids,
|
||||||
exposed_ident_ids,
|
exposed_ident_ids,
|
||||||
&dep_idents,
|
&dep_idents,
|
||||||
|
|
|
@ -631,10 +631,14 @@ fn specialize_drops_stmt<'a, 'i>(
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
Stmt::Dbg {
|
Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol,
|
symbol,
|
||||||
variable,
|
variable,
|
||||||
remainder,
|
remainder,
|
||||||
} => arena.alloc(Stmt::Dbg {
|
} => arena.alloc(Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol: *symbol,
|
symbol: *symbol,
|
||||||
variable: *variable,
|
variable: *variable,
|
||||||
remainder: specialize_drops_stmt(
|
remainder: specialize_drops_stmt(
|
||||||
|
|
|
@ -689,6 +689,8 @@ fn insert_refcount_operations_stmt<'v, 'a>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Stmt::Dbg {
|
Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol,
|
symbol,
|
||||||
variable,
|
variable,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -703,6 +705,8 @@ fn insert_refcount_operations_stmt<'v, 'a>(
|
||||||
);
|
);
|
||||||
|
|
||||||
arena.alloc(Stmt::Dbg {
|
arena.alloc(Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol: *symbol,
|
symbol: *symbol,
|
||||||
variable: *variable,
|
variable: *variable,
|
||||||
remainder: newer_remainder,
|
remainder: newer_remainder,
|
||||||
|
|
|
@ -1531,6 +1531,10 @@ pub enum Stmt<'a> {
|
||||||
remainder: &'a Stmt<'a>,
|
remainder: &'a Stmt<'a>,
|
||||||
},
|
},
|
||||||
Dbg {
|
Dbg {
|
||||||
|
/// The location this dbg is in source as a printable string.
|
||||||
|
source_location: &'a str,
|
||||||
|
/// The source code of the expression being debugged.
|
||||||
|
source: &'a str,
|
||||||
/// The expression we're displaying
|
/// The expression we're displaying
|
||||||
symbol: Symbol,
|
symbol: Symbol,
|
||||||
/// The specialized variable of the expression
|
/// The specialized variable of the expression
|
||||||
|
@ -4602,6 +4606,8 @@ pub fn with_hole<'a>(
|
||||||
Expect { .. } => unreachable!("I think this is unreachable"),
|
Expect { .. } => unreachable!("I think this is unreachable"),
|
||||||
ExpectFx { .. } => unreachable!("I think this is unreachable"),
|
ExpectFx { .. } => unreachable!("I think this is unreachable"),
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
loc_message,
|
loc_message,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable: cond_variable,
|
variable: cond_variable,
|
||||||
|
@ -4621,6 +4627,8 @@ pub fn with_hole<'a>(
|
||||||
env,
|
env,
|
||||||
procs,
|
procs,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
|
&*arena.alloc(source_location),
|
||||||
|
&*arena.alloc(source),
|
||||||
dbg_symbol,
|
dbg_symbol,
|
||||||
*loc_message,
|
*loc_message,
|
||||||
cond_variable,
|
cond_variable,
|
||||||
|
@ -5892,8 +5900,10 @@ fn compile_dbg<'a>(
|
||||||
env: &mut Env<'a, '_>,
|
env: &mut Env<'a, '_>,
|
||||||
procs: &mut Procs<'a>,
|
procs: &mut Procs<'a>,
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
|
source_location: &'a str,
|
||||||
|
source: &'a str,
|
||||||
dbg_symbol: Symbol,
|
dbg_symbol: Symbol,
|
||||||
loc_condition: Loc<roc_can::expr::Expr>,
|
loc_message: Loc<roc_can::expr::Expr>,
|
||||||
variable: Variable,
|
variable: Variable,
|
||||||
continuation: Stmt<'a>,
|
continuation: Stmt<'a>,
|
||||||
) -> Stmt<'a> {
|
) -> Stmt<'a> {
|
||||||
|
@ -5904,6 +5914,8 @@ fn compile_dbg<'a>(
|
||||||
.fresh_unnamed_flex_var();
|
.fresh_unnamed_flex_var();
|
||||||
|
|
||||||
let dbg_stmt = Stmt::Dbg {
|
let dbg_stmt = Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol: dbg_symbol,
|
symbol: dbg_symbol,
|
||||||
variable: spec_var,
|
variable: spec_var,
|
||||||
remainder: env.arena.alloc(continuation),
|
remainder: env.arena.alloc(continuation),
|
||||||
|
@ -5914,17 +5926,17 @@ fn compile_dbg<'a>(
|
||||||
store_specialized_expectation_lookups(env, [variable], &[spec_var]);
|
store_specialized_expectation_lookups(env, [variable], &[spec_var]);
|
||||||
|
|
||||||
let symbol_is_reused = matches!(
|
let symbol_is_reused = matches!(
|
||||||
can_reuse_symbol(env, layout_cache, procs, &loc_condition.value, variable),
|
can_reuse_symbol(env, layout_cache, procs, &loc_message.value, variable),
|
||||||
ReuseSymbol::Value(_)
|
ReuseSymbol::Value(_)
|
||||||
);
|
);
|
||||||
|
|
||||||
// skip evaluating the condition if it's just a symbol
|
// skip evaluating the message if it's just a symbol
|
||||||
if symbol_is_reused {
|
if symbol_is_reused {
|
||||||
dbg_stmt
|
dbg_stmt
|
||||||
} else {
|
} else {
|
||||||
with_hole(
|
with_hole(
|
||||||
env,
|
env,
|
||||||
loc_condition.value,
|
loc_message.value,
|
||||||
variable,
|
variable,
|
||||||
procs,
|
procs,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
|
@ -7137,6 +7149,8 @@ pub fn from_can<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
loc_message,
|
loc_message,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable: cond_variable,
|
variable: cond_variable,
|
||||||
|
@ -7148,6 +7162,8 @@ pub fn from_can<'a>(
|
||||||
env,
|
env,
|
||||||
procs,
|
procs,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
|
&*env.arena.alloc(source_location),
|
||||||
|
&*env.arena.alloc(source),
|
||||||
dbg_symbol,
|
dbg_symbol,
|
||||||
*loc_message,
|
*loc_message,
|
||||||
cond_variable,
|
cond_variable,
|
||||||
|
@ -7621,6 +7637,8 @@ fn substitute_in_stmt_help<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol,
|
symbol,
|
||||||
variable,
|
variable,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -7629,6 +7647,8 @@ fn substitute_in_stmt_help<'a>(
|
||||||
substitute_in_stmt_help(arena, remainder, subs).unwrap_or(remainder);
|
substitute_in_stmt_help(arena, remainder, subs).unwrap_or(remainder);
|
||||||
|
|
||||||
let expect = Dbg {
|
let expect = Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol: substitute(subs, *symbol).unwrap_or(*symbol),
|
symbol: substitute(subs, *symbol).unwrap_or(*symbol),
|
||||||
variable: *variable,
|
variable: *variable,
|
||||||
remainder: new_remainder,
|
remainder: new_remainder,
|
||||||
|
|
|
@ -651,6 +651,8 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Stmt::Dbg {
|
Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol,
|
symbol,
|
||||||
variable,
|
variable,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -666,6 +668,8 @@ fn insert_reset_reuse_operations_stmt<'a, 'i>(
|
||||||
);
|
);
|
||||||
|
|
||||||
arena.alloc(Stmt::Dbg {
|
arena.alloc(Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol: *symbol,
|
symbol: *symbol,
|
||||||
variable: *variable,
|
variable: *variable,
|
||||||
remainder: new_remainder,
|
remainder: new_remainder,
|
||||||
|
|
|
@ -330,6 +330,8 @@ fn insert_jumps<'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbg {
|
Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol,
|
symbol,
|
||||||
variable,
|
variable,
|
||||||
remainder,
|
remainder,
|
||||||
|
@ -342,6 +344,8 @@ fn insert_jumps<'a>(
|
||||||
needle_result,
|
needle_result,
|
||||||
) {
|
) {
|
||||||
Some(cont) => Some(arena.alloc(Dbg {
|
Some(cont) => Some(arena.alloc(Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol: *symbol,
|
symbol: *symbol,
|
||||||
variable: *variable,
|
variable: *variable,
|
||||||
remainder: cont,
|
remainder: cont,
|
||||||
|
@ -1020,10 +1024,14 @@ impl<'a> TrmcEnv<'a> {
|
||||||
remainder: arena.alloc(self.walk_stmt(env, remainder)),
|
remainder: arena.alloc(self.walk_stmt(env, remainder)),
|
||||||
},
|
},
|
||||||
Stmt::Dbg {
|
Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol,
|
symbol,
|
||||||
variable,
|
variable,
|
||||||
remainder,
|
remainder,
|
||||||
} => Stmt::Dbg {
|
} => Stmt::Dbg {
|
||||||
|
source_location,
|
||||||
|
source,
|
||||||
symbol: *symbol,
|
symbol: *symbol,
|
||||||
variable: *variable,
|
variable: *variable,
|
||||||
remainder: arena.alloc(self.walk_stmt(env, remainder)),
|
remainder: arena.alloc(self.walk_stmt(env, remainder)),
|
||||||
|
|
|
@ -302,7 +302,7 @@ pub enum Expr<'a> {
|
||||||
Expect(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
Expect(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
||||||
Dbg(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
Dbg(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
||||||
// This form of debug is a desugared call to roc_dbg
|
// This form of debug is a desugared call to roc_dbg
|
||||||
LowLevelDbg(&'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
LowLevelDbg(&'a str, &'a str, &'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
||||||
|
|
||||||
// Application
|
// Application
|
||||||
/// To apply by name, do Apply(Var(...), ...)
|
/// To apply by name, do Apply(Var(...), ...)
|
||||||
|
@ -1537,7 +1537,7 @@ impl<'a> Malformed for Expr<'a> {
|
||||||
Backpassing(args, call, body) => args.iter().any(|arg| arg.is_malformed()) || call.is_malformed() || body.is_malformed(),
|
Backpassing(args, call, body) => args.iter().any(|arg| arg.is_malformed()) || call.is_malformed() || body.is_malformed(),
|
||||||
Expect(condition, continuation) |
|
Expect(condition, continuation) |
|
||||||
Dbg(condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
|
Dbg(condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
|
||||||
LowLevelDbg(condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
|
LowLevelDbg(_, _, condition, continuation) => condition.is_malformed() || continuation.is_malformed(),
|
||||||
Apply(func, args, _) => func.is_malformed() || args.iter().any(|arg| arg.is_malformed()),
|
Apply(func, args, _) => func.is_malformed() || args.iter().any(|arg| arg.is_malformed()),
|
||||||
BinOps(firsts, last) => firsts.iter().any(|(expr, _)| expr.is_malformed()) || last.is_malformed(),
|
BinOps(firsts, last) => firsts.iter().any(|(expr, _)| expr.is_malformed()) || last.is_malformed(),
|
||||||
UnaryOp(expr, _) => expr.is_malformed(),
|
UnaryOp(expr, _) => expr.is_malformed(),
|
||||||
|
|
|
@ -1933,7 +1933,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
|
||||||
| Expr::When(_, _)
|
| Expr::When(_, _)
|
||||||
| Expr::Expect(_, _)
|
| Expr::Expect(_, _)
|
||||||
| Expr::Dbg(_, _)
|
| Expr::Dbg(_, _)
|
||||||
| Expr::LowLevelDbg(_, _)
|
| Expr::LowLevelDbg(_, _, _, _)
|
||||||
| Expr::MalformedClosure
|
| Expr::MalformedClosure
|
||||||
| Expr::PrecedenceConflict { .. }
|
| Expr::PrecedenceConflict { .. }
|
||||||
| Expr::MultipleRecordBuilders { .. }
|
| Expr::MultipleRecordBuilders { .. }
|
||||||
|
|
|
@ -673,7 +673,7 @@ impl IterTokens for Loc<Expr<'_>> {
|
||||||
Expr::Dbg(e1, e2) => (e1.iter_tokens(arena).into_iter())
|
Expr::Dbg(e1, e2) => (e1.iter_tokens(arena).into_iter())
|
||||||
.chain(e2.iter_tokens(arena))
|
.chain(e2.iter_tokens(arena))
|
||||||
.collect_in(arena),
|
.collect_in(arena),
|
||||||
Expr::LowLevelDbg(e1, e2) => (e1.iter_tokens(arena).into_iter())
|
Expr::LowLevelDbg(_, _, e1, e2) => (e1.iter_tokens(arena).into_iter())
|
||||||
.chain(e2.iter_tokens(arena))
|
.chain(e2.iter_tokens(arena))
|
||||||
.collect_in(arena),
|
.collect_in(arena),
|
||||||
Expr::Apply(e1, e2, _called_via) => (e1.iter_tokens(arena).into_iter())
|
Expr::Apply(e1, e2, _called_via) => (e1.iter_tokens(arena).into_iter())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue