mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-29 17:33:45 +00:00
print all the relevant info
This commit is contained in:
parent
e7f3c6f281
commit
e44a8a9eed
17 changed files with 308 additions and 12 deletions
|
@ -1000,7 +1000,15 @@ fn roc_dev_native(
|
||||||
SIGUSR2 => {
|
SIGUSR2 => {
|
||||||
// this is the signal we use for a dbg
|
// this is the signal we use for a dbg
|
||||||
|
|
||||||
println!("I need to dbg something");
|
roc_repl_expect::run::render_dbgs_in_memory(
|
||||||
|
&mut writer,
|
||||||
|
arena,
|
||||||
|
&mut expectations,
|
||||||
|
&interns,
|
||||||
|
&layout_interner,
|
||||||
|
&memory,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
_ => println!("received signal {}", sig),
|
_ => println!("received signal {}", sig),
|
||||||
}
|
}
|
||||||
|
|
|
@ -615,10 +615,12 @@ fn deep_copy_expr_help<C: CopyEnv>(env: &mut C, copied: &mut Vec<Variable>, expr
|
||||||
loc_condition,
|
loc_condition,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable,
|
variable,
|
||||||
|
symbol,
|
||||||
} => Dbg {
|
} => Dbg {
|
||||||
loc_condition: Box::new(loc_condition.map(|e| go_help!(e))),
|
loc_condition: Box::new(loc_condition.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),
|
||||||
|
symbol: *symbol,
|
||||||
},
|
},
|
||||||
|
|
||||||
TypedHole(v) => TypedHole(sub!(*v)),
|
TypedHole(v) => TypedHole(sub!(*v)),
|
||||||
|
|
|
@ -244,6 +244,7 @@ pub enum Expr {
|
||||||
loc_condition: Box<Loc<Expr>>,
|
loc_condition: Box<Loc<Expr>>,
|
||||||
loc_continuation: Box<Loc<Expr>>,
|
loc_continuation: Box<Loc<Expr>>,
|
||||||
variable: Variable,
|
variable: Variable,
|
||||||
|
symbol: Symbol,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Rendered as empty box in editor
|
/// Rendered as empty box in editor
|
||||||
|
@ -260,6 +261,14 @@ pub struct ExpectLookup {
|
||||||
pub ability_info: Option<SpecializationId>,
|
pub ability_info: Option<SpecializationId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug)]
|
||||||
|
pub struct DbgLookup {
|
||||||
|
pub symbol: Symbol,
|
||||||
|
pub var: Variable,
|
||||||
|
pub region: Region,
|
||||||
|
pub ability_info: Option<SpecializationId>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Expr {
|
impl Expr {
|
||||||
pub fn category(&self) -> Category {
|
pub fn category(&self) -> Category {
|
||||||
match self {
|
match self {
|
||||||
|
@ -1039,6 +1048,33 @@ pub fn canonicalize_expr<'a>(
|
||||||
output,
|
output,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
ast::Expr::Dbg(condition, continuation) => {
|
||||||
|
let mut output = Output::default();
|
||||||
|
|
||||||
|
let (loc_condition, output1) =
|
||||||
|
canonicalize_expr(env, var_store, scope, condition.region, &condition.value);
|
||||||
|
|
||||||
|
let (loc_continuation, output2) = canonicalize_expr(
|
||||||
|
env,
|
||||||
|
var_store,
|
||||||
|
scope,
|
||||||
|
continuation.region,
|
||||||
|
&continuation.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
output.union(output1);
|
||||||
|
output.union(output2);
|
||||||
|
|
||||||
|
(
|
||||||
|
Dbg {
|
||||||
|
loc_condition: Box::new(loc_condition),
|
||||||
|
loc_continuation: Box::new(loc_continuation),
|
||||||
|
variable: var_store.fresh(),
|
||||||
|
symbol: scope.gen_unique_symbol(),
|
||||||
|
},
|
||||||
|
output,
|
||||||
|
)
|
||||||
|
}
|
||||||
ast::Expr::If(if_thens, final_else_branch) => {
|
ast::Expr::If(if_thens, final_else_branch) => {
|
||||||
let mut branches = Vec::with_capacity(if_thens.len());
|
let mut branches = Vec::with_capacity(if_thens.len());
|
||||||
let mut output = Output::default();
|
let mut output = Output::default();
|
||||||
|
@ -1838,6 +1874,7 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
||||||
loc_condition,
|
loc_condition,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable,
|
variable,
|
||||||
|
symbol,
|
||||||
} => {
|
} => {
|
||||||
let loc_condition = Loc {
|
let loc_condition = Loc {
|
||||||
region: loc_condition.region,
|
region: loc_condition.region,
|
||||||
|
@ -1853,6 +1890,7 @@ pub fn inline_calls(var_store: &mut VarStore, expr: Expr) -> Expr {
|
||||||
loc_condition: Box::new(loc_condition),
|
loc_condition: Box::new(loc_condition),
|
||||||
loc_continuation: Box::new(loc_continuation),
|
loc_continuation: Box::new(loc_continuation),
|
||||||
variable,
|
variable,
|
||||||
|
symbol,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2582,9 +2620,10 @@ impl Declarations {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expects(&self) -> VecMap<Region, Vec<ExpectLookup>> {
|
pub fn expects(&self) -> ExpectCollector {
|
||||||
let mut collector = ExpectCollector {
|
let mut collector = ExpectCollector {
|
||||||
expects: VecMap::default(),
|
expects: VecMap::default(),
|
||||||
|
dbgs: VecMap::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let var = Variable::EMPTY_RECORD;
|
let var = Variable::EMPTY_RECORD;
|
||||||
|
@ -2617,7 +2656,7 @@ impl Declarations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collector.expects
|
collector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2897,8 +2936,9 @@ fn toplevel_expect_to_inline_expect_help(mut loc_expr: Loc<Expr>, has_effects: b
|
||||||
loc_expr
|
loc_expr
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ExpectCollector {
|
pub struct ExpectCollector {
|
||||||
expects: VecMap<Region, Vec<ExpectLookup>>,
|
pub expects: VecMap<Region, Vec<ExpectLookup>>,
|
||||||
|
pub dbgs: VecMap<Symbol, DbgLookup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::traverse::Visitor for ExpectCollector {
|
impl crate::traverse::Visitor for ExpectCollector {
|
||||||
|
@ -2917,6 +2957,21 @@ impl crate::traverse::Visitor for ExpectCollector {
|
||||||
self.expects
|
self.expects
|
||||||
.insert(loc_condition.region, lookups_in_cond.to_vec());
|
.insert(loc_condition.region, lookups_in_cond.to_vec());
|
||||||
}
|
}
|
||||||
|
Expr::Dbg {
|
||||||
|
loc_condition,
|
||||||
|
variable,
|
||||||
|
symbol,
|
||||||
|
..
|
||||||
|
} => {
|
||||||
|
let lookup = DbgLookup {
|
||||||
|
symbol: *symbol,
|
||||||
|
var: *variable,
|
||||||
|
region: loc_condition.region,
|
||||||
|
ability_info: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.dbgs.insert(*symbol, lookup);
|
||||||
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,9 @@ use crate::annotation::{canonicalize_annotation, AnnotationFor};
|
||||||
use crate::def::{canonicalize_defs, Def};
|
use crate::def::{canonicalize_defs, Def};
|
||||||
use crate::effect_module::HostedGeneratedFunctions;
|
use crate::effect_module::HostedGeneratedFunctions;
|
||||||
use crate::env::Env;
|
use crate::env::Env;
|
||||||
use crate::expr::{ClosureData, Declarations, ExpectLookup, Expr, Output, PendingDerives};
|
use crate::expr::{
|
||||||
|
ClosureData, DbgLookup, Declarations, ExpectLookup, Expr, Output, PendingDerives,
|
||||||
|
};
|
||||||
use crate::pattern::{BindingsFromPattern, Pattern};
|
use crate::pattern::{BindingsFromPattern, Pattern};
|
||||||
use crate::scope::Scope;
|
use crate::scope::Scope;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
@ -131,6 +133,7 @@ pub struct Module {
|
||||||
pub rigid_variables: RigidVariables,
|
pub rigid_variables: RigidVariables,
|
||||||
pub abilities_store: PendingAbilitiesStore,
|
pub abilities_store: PendingAbilitiesStore,
|
||||||
pub loc_expects: VecMap<Region, Vec<ExpectLookup>>,
|
pub loc_expects: VecMap<Region, Vec<ExpectLookup>>,
|
||||||
|
pub loc_dbgs: VecMap<Symbol, DbgLookup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
@ -153,6 +156,7 @@ pub struct ModuleOutput {
|
||||||
pub pending_derives: PendingDerives,
|
pub pending_derives: PendingDerives,
|
||||||
pub scope: Scope,
|
pub scope: Scope,
|
||||||
pub loc_expects: VecMap<Region, Vec<ExpectLookup>>,
|
pub loc_expects: VecMap<Region, Vec<ExpectLookup>>,
|
||||||
|
pub loc_dbgs: VecMap<Symbol, DbgLookup>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_generate_with<'a>(
|
fn validate_generate_with<'a>(
|
||||||
|
@ -776,7 +780,7 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let loc_expects = declarations.expects();
|
let collected = declarations.expects();
|
||||||
|
|
||||||
ModuleOutput {
|
ModuleOutput {
|
||||||
scope,
|
scope,
|
||||||
|
@ -789,7 +793,8 @@ pub fn canonicalize_module_defs<'a>(
|
||||||
problems: env.problems,
|
problems: env.problems,
|
||||||
symbols_from_requires,
|
symbols_from_requires,
|
||||||
pending_derives,
|
pending_derives,
|
||||||
loc_expects,
|
loc_expects: collected.expects,
|
||||||
|
loc_dbgs: collected.dbgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -358,6 +358,14 @@ pub fn desugar_expr<'a>(arena: &'a Bump, loc_expr: &'a Loc<Expr<'a>>) -> &'a Loc
|
||||||
region: loc_expr.region,
|
region: loc_expr.region,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Dbg(condition, continuation) => {
|
||||||
|
let desugared_condition = &*arena.alloc(desugar_expr(arena, condition));
|
||||||
|
let desugared_continuation = &*arena.alloc(desugar_expr(arena, continuation));
|
||||||
|
arena.alloc(Loc {
|
||||||
|
value: Dbg(desugared_condition, desugared_continuation),
|
||||||
|
region: loc_expr.region,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -291,6 +291,7 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr, var: Variable) {
|
||||||
variable,
|
variable,
|
||||||
loc_condition,
|
loc_condition,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
|
symbol: _,
|
||||||
} => {
|
} => {
|
||||||
visitor.visit_expr(&loc_condition.value, loc_condition.region, *variable);
|
visitor.visit_expr(&loc_condition.value, loc_condition.region, *variable);
|
||||||
visitor.visit_expr(
|
visitor.visit_expr(
|
||||||
|
|
|
@ -660,6 +660,7 @@ pub fn constrain_expr(
|
||||||
loc_condition,
|
loc_condition,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable,
|
variable,
|
||||||
|
symbol: _,
|
||||||
} => {
|
} => {
|
||||||
let dbg_type = constraints.push_variable(*variable);
|
let dbg_type = constraints.push_variable(*variable);
|
||||||
let expected_dbg = constraints.push_expected_type(Expected::NoExpectation(dbg_type));
|
let expected_dbg = constraints.push_expected_type(Expected::NoExpectation(dbg_type));
|
||||||
|
|
|
@ -71,6 +71,7 @@ impl<'a> Formattable for Expr<'a> {
|
||||||
Expect(condition, continuation) => {
|
Expect(condition, continuation) => {
|
||||||
condition.is_multiline() || continuation.is_multiline()
|
condition.is_multiline() || continuation.is_multiline()
|
||||||
}
|
}
|
||||||
|
Dbg(condition, continuation) => condition.is_multiline() || continuation.is_multiline(),
|
||||||
|
|
||||||
If(branches, final_else) => {
|
If(branches, final_else) => {
|
||||||
final_else.is_multiline()
|
final_else.is_multiline()
|
||||||
|
@ -379,6 +380,9 @@ impl<'a> Formattable for Expr<'a> {
|
||||||
Expect(condition, continuation) => {
|
Expect(condition, continuation) => {
|
||||||
fmt_expect(buf, condition, continuation, self.is_multiline(), indent);
|
fmt_expect(buf, condition, continuation, self.is_multiline(), indent);
|
||||||
}
|
}
|
||||||
|
Dbg(condition, continuation) => {
|
||||||
|
fmt_dbg(buf, condition, continuation, self.is_multiline(), indent);
|
||||||
|
}
|
||||||
If(branches, final_else) => {
|
If(branches, final_else) => {
|
||||||
fmt_if(buf, branches, final_else, self.is_multiline(), indent);
|
fmt_if(buf, branches, final_else, self.is_multiline(), indent);
|
||||||
}
|
}
|
||||||
|
@ -843,6 +847,33 @@ fn fmt_when<'a, 'buf>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn fmt_dbg<'a, 'buf>(
|
||||||
|
buf: &mut Buf<'buf>,
|
||||||
|
condition: &'a Loc<Expr<'a>>,
|
||||||
|
continuation: &'a Loc<Expr<'a>>,
|
||||||
|
is_multiline: bool,
|
||||||
|
indent: u16,
|
||||||
|
) {
|
||||||
|
buf.ensure_ends_with_newline();
|
||||||
|
buf.indent(indent);
|
||||||
|
buf.push_str("dbg");
|
||||||
|
|
||||||
|
let return_indent = if is_multiline {
|
||||||
|
buf.newline();
|
||||||
|
indent + INDENT
|
||||||
|
} else {
|
||||||
|
buf.spaces(1);
|
||||||
|
indent
|
||||||
|
};
|
||||||
|
|
||||||
|
condition.format(buf, return_indent);
|
||||||
|
|
||||||
|
// Always put a blank line after the `dbg` line(s)
|
||||||
|
buf.ensure_ends_with_blank_line();
|
||||||
|
|
||||||
|
continuation.format(buf, indent);
|
||||||
|
}
|
||||||
|
|
||||||
fn fmt_expect<'a, 'buf>(
|
fn fmt_expect<'a, 'buf>(
|
||||||
buf: &mut Buf<'buf>,
|
buf: &mut Buf<'buf>,
|
||||||
condition: &'a Loc<Expr<'a>>,
|
condition: &'a Loc<Expr<'a>>,
|
||||||
|
|
|
@ -692,6 +692,10 @@ 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::Dbg(a, b) => Expr::Dbg(
|
||||||
|
arena.alloc(a.remove_spaces(arena)),
|
||||||
|
arena.alloc(b.remove_spaces(arena)),
|
||||||
|
),
|
||||||
Expr::Apply(a, b, c) => Expr::Apply(
|
Expr::Apply(a, b, c) => Expr::Apply(
|
||||||
arena.alloc(a.remove_spaces(arena)),
|
arena.alloc(a.remove_spaces(arena)),
|
||||||
b.remove_spaces(arena),
|
b.remove_spaces(arena),
|
||||||
|
|
|
@ -1123,7 +1123,7 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
||||||
// now what
|
// now what
|
||||||
arguments!(condition);
|
arguments!(condition);
|
||||||
|
|
||||||
let region = roc_region::all::Region::zero(); // todo
|
let region = unsafe { std::mem::transmute::<_, roc_region::all::Region>(args[0]) };
|
||||||
|
|
||||||
crate::llvm::expect::clone_to_shared_memory(
|
crate::llvm::expect::clone_to_shared_memory(
|
||||||
env,
|
env,
|
||||||
|
@ -1131,7 +1131,7 @@ pub(crate) fn run_low_level<'a, 'ctx, 'env>(
|
||||||
layout_ids,
|
layout_ids,
|
||||||
args[0],
|
args[0],
|
||||||
region,
|
region,
|
||||||
&[],
|
&[args[0]],
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::llvm::expect::send_dbg(env);
|
crate::llvm::expect::send_dbg(env);
|
||||||
|
|
|
@ -7,7 +7,7 @@ use parking_lot::Mutex;
|
||||||
use roc_builtins::roc::module_source;
|
use roc_builtins::roc::module_source;
|
||||||
use roc_can::abilities::{AbilitiesStore, PendingAbilitiesStore, ResolvedImpl};
|
use roc_can::abilities::{AbilitiesStore, PendingAbilitiesStore, ResolvedImpl};
|
||||||
use roc_can::constraint::{Constraint as ConstraintSoa, Constraints, TypeOrVar};
|
use roc_can::constraint::{Constraint as ConstraintSoa, Constraints, TypeOrVar};
|
||||||
use roc_can::expr::PendingDerives;
|
use roc_can::expr::{DbgLookup, PendingDerives};
|
||||||
use roc_can::expr::{Declarations, ExpectLookup};
|
use roc_can::expr::{Declarations, ExpectLookup};
|
||||||
use roc_can::module::{
|
use roc_can::module::{
|
||||||
canonicalize_module_defs, ExposedByModule, ExposedForModule, ExposedModuleTypes, Module,
|
canonicalize_module_defs, ExposedByModule, ExposedForModule, ExposedModuleTypes, Module,
|
||||||
|
@ -731,6 +731,7 @@ pub struct Expectations {
|
||||||
pub subs: roc_types::subs::Subs,
|
pub subs: roc_types::subs::Subs,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub expectations: VecMap<Region, Vec<ExpectLookup>>,
|
pub expectations: VecMap<Region, Vec<ExpectLookup>>,
|
||||||
|
pub dbgs: VecMap<Symbol, DbgLookup>,
|
||||||
pub ident_ids: IdentIds,
|
pub ident_ids: IdentIds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,6 +776,7 @@ struct ParsedModule<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
type LocExpects = VecMap<Region, Vec<ExpectLookup>>;
|
type LocExpects = VecMap<Region, Vec<ExpectLookup>>;
|
||||||
|
type LocDbgs = VecMap<Symbol, DbgLookup>;
|
||||||
|
|
||||||
/// A message sent out _from_ a worker thread,
|
/// A message sent out _from_ a worker thread,
|
||||||
/// representing a result of work done, or a request for further work
|
/// representing a result of work done, or a request for further work
|
||||||
|
@ -794,6 +796,7 @@ enum Msg<'a> {
|
||||||
module_timing: ModuleTiming,
|
module_timing: ModuleTiming,
|
||||||
abilities_store: AbilitiesStore,
|
abilities_store: AbilitiesStore,
|
||||||
loc_expects: LocExpects,
|
loc_expects: LocExpects,
|
||||||
|
loc_dbgs: LocDbgs,
|
||||||
},
|
},
|
||||||
FinishedAllTypeChecking {
|
FinishedAllTypeChecking {
|
||||||
solved_subs: Solved<Subs>,
|
solved_subs: Solved<Subs>,
|
||||||
|
@ -2403,6 +2406,7 @@ fn update<'a>(
|
||||||
mut module_timing,
|
mut module_timing,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
loc_expects,
|
loc_expects,
|
||||||
|
loc_dbgs,
|
||||||
} => {
|
} => {
|
||||||
log!("solved types for {:?}", module_id);
|
log!("solved types for {:?}", module_id);
|
||||||
module_timing.end_time = Instant::now();
|
module_timing.end_time = Instant::now();
|
||||||
|
@ -2424,6 +2428,7 @@ fn update<'a>(
|
||||||
|
|
||||||
let expectations = Expectations {
|
let expectations = Expectations {
|
||||||
expectations: loc_expects,
|
expectations: loc_expects,
|
||||||
|
dbgs: loc_dbgs,
|
||||||
subs: solved_subs.clone().into_inner(),
|
subs: solved_subs.clone().into_inner(),
|
||||||
path: path.to_owned(),
|
path: path.to_owned(),
|
||||||
ident_ids: ident_ids.clone(),
|
ident_ids: ident_ids.clone(),
|
||||||
|
@ -4552,6 +4557,7 @@ fn run_solve<'a>(
|
||||||
|
|
||||||
let mut module = module;
|
let mut module = module;
|
||||||
let loc_expects = std::mem::take(&mut module.loc_expects);
|
let loc_expects = std::mem::take(&mut module.loc_expects);
|
||||||
|
let loc_dbgs = std::mem::take(&mut module.loc_dbgs);
|
||||||
let module = module;
|
let module = module;
|
||||||
|
|
||||||
let (solved_subs, solved_implementations, exposed_vars_by_symbol, problems, abilities_store) = {
|
let (solved_subs, solved_implementations, exposed_vars_by_symbol, problems, abilities_store) = {
|
||||||
|
@ -4626,6 +4632,7 @@ fn run_solve<'a>(
|
||||||
module_timing,
|
module_timing,
|
||||||
abilities_store,
|
abilities_store,
|
||||||
loc_expects,
|
loc_expects,
|
||||||
|
loc_dbgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4832,6 +4839,7 @@ fn canonicalize_and_constrain<'a>(
|
||||||
rigid_variables: module_output.rigid_variables,
|
rigid_variables: module_output.rigid_variables,
|
||||||
abilities_store: module_output.scope.abilities_store,
|
abilities_store: module_output.scope.abilities_store,
|
||||||
loc_expects: module_output.loc_expects,
|
loc_expects: module_output.loc_expects,
|
||||||
|
loc_dbgs: module_output.loc_dbgs,
|
||||||
};
|
};
|
||||||
|
|
||||||
let constrained_module = ConstrainedModule {
|
let constrained_module = ConstrainedModule {
|
||||||
|
|
|
@ -6551,9 +6551,9 @@ pub fn from_can<'a>(
|
||||||
loc_condition,
|
loc_condition,
|
||||||
loc_continuation,
|
loc_continuation,
|
||||||
variable,
|
variable,
|
||||||
|
symbol: dbg_symbol,
|
||||||
} => {
|
} => {
|
||||||
let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache);
|
let rest = from_can(env, variable, loc_continuation.value, procs, layout_cache);
|
||||||
let dbg_symbol = env.unique_symbol();
|
|
||||||
|
|
||||||
let call = crate::ir::Call {
|
let call = crate::ir::Call {
|
||||||
call_type: CallType::LowLevel {
|
call_type: CallType::LowLevel {
|
||||||
|
|
|
@ -208,6 +208,7 @@ pub enum Expr<'a> {
|
||||||
Defs(&'a Defs<'a>, &'a Loc<Expr<'a>>),
|
Defs(&'a Defs<'a>, &'a Loc<Expr<'a>>),
|
||||||
Backpassing(&'a [Loc<Pattern<'a>>], &'a Loc<Expr<'a>>, &'a Loc<Expr<'a>>),
|
Backpassing(&'a [Loc<Pattern<'a>>], &'a Loc<Expr<'a>>, &'a Loc<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>>),
|
||||||
|
|
||||||
// Application
|
// Application
|
||||||
/// To apply by name, do Apply(Var(...), ...)
|
/// To apply by name, do Apply(Var(...), ...)
|
||||||
|
|
|
@ -327,6 +327,7 @@ fn expr_start<'a>(options: ExprParseOptions) -> impl Parser<'a, Loc<Expr<'a>>, E
|
||||||
loc!(specialize(EExpr::If, if_expr_help(options))),
|
loc!(specialize(EExpr::If, if_expr_help(options))),
|
||||||
loc!(specialize(EExpr::When, when::expr_help(options))),
|
loc!(specialize(EExpr::When, when::expr_help(options))),
|
||||||
loc!(specialize(EExpr::Expect, expect_help(options))),
|
loc!(specialize(EExpr::Expect, expect_help(options))),
|
||||||
|
loc!(specialize(EExpr::Dbg, dbg_help(options))),
|
||||||
loc!(specialize(EExpr::Closure, closure_help(options))),
|
loc!(specialize(EExpr::Closure, closure_help(options))),
|
||||||
loc!(expr_operator_chain(options)),
|
loc!(expr_operator_chain(options)),
|
||||||
fail_expr_start_e()
|
fail_expr_start_e()
|
||||||
|
@ -1912,6 +1913,7 @@ fn expr_to_pattern_help<'a>(arena: &'a Bump, expr: &Expr<'a>) -> Result<Pattern<
|
||||||
| Expr::If(_, _)
|
| Expr::If(_, _)
|
||||||
| Expr::When(_, _)
|
| Expr::When(_, _)
|
||||||
| Expr::Expect(_, _)
|
| Expr::Expect(_, _)
|
||||||
|
| Expr::Dbg(_, _)
|
||||||
| Expr::MalformedClosure
|
| Expr::MalformedClosure
|
||||||
| Expr::PrecedenceConflict { .. }
|
| Expr::PrecedenceConflict { .. }
|
||||||
| Expr::RecordUpdate { .. }
|
| Expr::RecordUpdate { .. }
|
||||||
|
@ -2330,6 +2332,36 @@ fn expect_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EExpe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dbg_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EExpect<'a>> {
|
||||||
|
move |arena: &'a Bump, state: State<'a>, min_indent| {
|
||||||
|
let start_column = state.column();
|
||||||
|
|
||||||
|
let (_, _, state) =
|
||||||
|
parser::keyword_e(keyword::DBG, EExpect::Dbg).parse(arena, state, min_indent)?;
|
||||||
|
|
||||||
|
let (_, condition, state) = space0_before_e(
|
||||||
|
specialize_ref(
|
||||||
|
EExpect::Condition,
|
||||||
|
set_min_indent(start_column + 1, expr_start(options)),
|
||||||
|
),
|
||||||
|
EExpect::IndentCondition,
|
||||||
|
)
|
||||||
|
.parse(arena, state, start_column + 1)
|
||||||
|
.map_err(|(_, f)| (MadeProgress, f))?;
|
||||||
|
|
||||||
|
let parse_cont = specialize_ref(
|
||||||
|
EExpect::Continuation,
|
||||||
|
space0_before_e(loc_expr(), EExpr::IndentEnd),
|
||||||
|
);
|
||||||
|
|
||||||
|
let (_, loc_cont, state) = parse_cont.parse(arena, state, min_indent)?;
|
||||||
|
|
||||||
|
let expr = Expr::Dbg(arena.alloc(condition), arena.alloc(loc_cont));
|
||||||
|
|
||||||
|
Ok((MadeProgress, expr, state))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn if_expr_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EIf<'a>> {
|
fn if_expr_help<'a>(options: ExprParseOptions) -> impl Parser<'a, Expr<'a>, EIf<'a>> {
|
||||||
move |arena: &'a Bump, state, min_indent| {
|
move |arena: &'a Bump, state, min_indent| {
|
||||||
let (_, _, state) =
|
let (_, _, state) =
|
||||||
|
|
|
@ -354,6 +354,7 @@ pub enum EExpr<'a> {
|
||||||
If(EIf<'a>, Position),
|
If(EIf<'a>, Position),
|
||||||
|
|
||||||
Expect(EExpect<'a>, Position),
|
Expect(EExpect<'a>, Position),
|
||||||
|
Dbg(EExpect<'a>, Position),
|
||||||
|
|
||||||
Closure(EClosure<'a>, Position),
|
Closure(EClosure<'a>, Position),
|
||||||
Underscore(Position),
|
Underscore(Position),
|
||||||
|
|
|
@ -416,6 +416,44 @@ pub fn render_expects_in_memory<'a>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn render_dbgs_in_memory<'a>(
|
||||||
|
writer: &mut impl std::io::Write,
|
||||||
|
arena: &'a Bump,
|
||||||
|
expectations: &mut VecMap<ModuleId, Expectations>,
|
||||||
|
interns: &'a Interns,
|
||||||
|
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
|
||||||
|
memory: &ExpectMemory,
|
||||||
|
) -> std::io::Result<usize> {
|
||||||
|
let shared_ptr = memory.ptr;
|
||||||
|
|
||||||
|
let frame = ExpectFrame::at_offset(shared_ptr, ExpectSequence::START_OFFSET);
|
||||||
|
let module_id = frame.module_id;
|
||||||
|
|
||||||
|
let data = expectations.get_mut(&module_id).unwrap();
|
||||||
|
let filename = data.path.to_owned();
|
||||||
|
let source = std::fs::read_to_string(&data.path).unwrap();
|
||||||
|
|
||||||
|
let renderer = Renderer::new(
|
||||||
|
arena,
|
||||||
|
interns,
|
||||||
|
RenderTarget::ColorTerminal,
|
||||||
|
module_id,
|
||||||
|
filename,
|
||||||
|
&source,
|
||||||
|
);
|
||||||
|
|
||||||
|
render_dbg_failure(
|
||||||
|
writer,
|
||||||
|
&renderer,
|
||||||
|
arena,
|
||||||
|
expectations,
|
||||||
|
interns,
|
||||||
|
layout_interner,
|
||||||
|
shared_ptr,
|
||||||
|
ExpectSequence::START_OFFSET,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn split_expect_lookups(subs: &Subs, lookups: &[ExpectLookup]) -> (Vec<Symbol>, Vec<Variable>) {
|
fn split_expect_lookups(subs: &Subs, lookups: &[ExpectLookup]) -> (Vec<Symbol>, Vec<Variable>) {
|
||||||
lookups
|
lookups
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -437,6 +475,69 @@ fn split_expect_lookups(subs: &Subs, lookups: &[ExpectLookup]) -> (Vec<Symbol>,
|
||||||
.unzip()
|
.unzip()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn render_dbg_failure<'a>(
|
||||||
|
writer: &mut impl std::io::Write,
|
||||||
|
renderer: &Renderer,
|
||||||
|
arena: &'a Bump,
|
||||||
|
expectations: &mut VecMap<ModuleId, Expectations>,
|
||||||
|
interns: &'a Interns,
|
||||||
|
layout_interner: &Arc<GlobalInterner<'a, Layout<'a>>>,
|
||||||
|
start: *const u8,
|
||||||
|
offset: usize,
|
||||||
|
) -> std::io::Result<usize> {
|
||||||
|
// we always run programs as the host
|
||||||
|
let target_info = (&target_lexicon::Triple::host()).into();
|
||||||
|
|
||||||
|
let frame = ExpectFrame::at_offset(start, offset);
|
||||||
|
let module_id = frame.module_id;
|
||||||
|
|
||||||
|
let failure_region = frame.region;
|
||||||
|
let dbg_symbol = unsafe { std::mem::transmute::<_, Symbol>(failure_region) };
|
||||||
|
let expect_region = Some(Region::zero());
|
||||||
|
|
||||||
|
let data = expectations.get_mut(&module_id).unwrap();
|
||||||
|
|
||||||
|
let current = match data.dbgs.get(&dbg_symbol) {
|
||||||
|
None => panic!("region {failure_region:?} not in list of expects"),
|
||||||
|
Some(current) => current,
|
||||||
|
};
|
||||||
|
let failure_region = current.region;
|
||||||
|
|
||||||
|
let subs = arena.alloc(&mut data.subs);
|
||||||
|
|
||||||
|
let current = ExpectLookup {
|
||||||
|
symbol: current.symbol,
|
||||||
|
var: current.var,
|
||||||
|
ability_info: current.ability_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
let (symbols, variables) = split_expect_lookups(subs, &[current]);
|
||||||
|
|
||||||
|
let (offset, expressions) = crate::get_values(
|
||||||
|
target_info,
|
||||||
|
arena,
|
||||||
|
subs,
|
||||||
|
interns,
|
||||||
|
layout_interner,
|
||||||
|
start,
|
||||||
|
frame.start_offset,
|
||||||
|
&variables,
|
||||||
|
);
|
||||||
|
|
||||||
|
renderer.render_dbg(
|
||||||
|
writer,
|
||||||
|
subs,
|
||||||
|
&symbols,
|
||||||
|
&variables,
|
||||||
|
&expressions,
|
||||||
|
expect_region,
|
||||||
|
failure_region,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(offset)
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn render_expect_failure<'a>(
|
fn render_expect_failure<'a>(
|
||||||
writer: &mut impl std::io::Write,
|
writer: &mut impl std::io::Write,
|
||||||
|
|
|
@ -164,6 +164,44 @@ impl<'a> Renderer<'a> {
|
||||||
write!(writer, "{}", buf)
|
write!(writer, "{}", buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn render_dbg<W>(
|
||||||
|
&self,
|
||||||
|
writer: &mut W,
|
||||||
|
subs: &mut Subs,
|
||||||
|
symbols: &[Symbol],
|
||||||
|
variables: &[Variable],
|
||||||
|
expressions: &[Expr<'_>],
|
||||||
|
expect_region: Option<Region>,
|
||||||
|
failure_region: Region,
|
||||||
|
) -> std::io::Result<()>
|
||||||
|
where
|
||||||
|
W: std::io::Write,
|
||||||
|
{
|
||||||
|
use crate::report::Report;
|
||||||
|
|
||||||
|
let line_col_region = self.to_line_col_region(expect_region, failure_region);
|
||||||
|
let doc = self.render_lookups(subs, line_col_region, symbols, variables, expressions);
|
||||||
|
|
||||||
|
let report = Report {
|
||||||
|
title: "DBG".into(),
|
||||||
|
doc,
|
||||||
|
filename: self.filename.clone(),
|
||||||
|
severity: crate::report::Severity::RuntimeError,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
report.render(
|
||||||
|
self.render_target,
|
||||||
|
&mut buf,
|
||||||
|
&self.alloc,
|
||||||
|
&crate::report::DEFAULT_PALETTE,
|
||||||
|
);
|
||||||
|
|
||||||
|
write!(writer, "{}", buf)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_panic<W>(
|
pub fn render_panic<W>(
|
||||||
&self,
|
&self,
|
||||||
writer: &mut W,
|
writer: &mut W,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue