Skip to content

Commit

Permalink
Implement hir diagnostic collectors
Browse files Browse the repository at this point in the history
  • Loading branch information
DCNick3 committed Oct 22, 2023
1 parent 69fb749 commit ea5f751
Show file tree
Hide file tree
Showing 8 changed files with 101 additions and 31 deletions.
15 changes: 4 additions & 11 deletions shin-asm/src/compile/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,16 @@ impl DiagnosticLocation for Span {
}
}

/// A location specified by a HIR node range and a file id. Diagnostic machinery will use the HIR source map to get the actual source range.
#[derive(Debug, Copy, Clone)]
pub struct HirLocation(pub WithFile<(HirIdWithBlock, HirIdWithBlock)>);
pub type HirLocation = WithFile<HirIdWithBlock>;

impl HirLocation {
pub fn single_node(hir_id_in_block: HirIdWithBlock, file: File) -> Self {
Self(WithFile::new((hir_id_in_block, hir_id_in_block), file))
}
}
impl DiagnosticLocation for HirLocation {
type Context<'a> = &'a dyn Db;

fn span(&self, _db: Self::Context<'_>) -> Span {
let WithFile {
file: _file,
value: (_start_node, _end_node),
} = self.0;
value: _node,
} = self;

todo!("Collect HIR source maps and use them to get the location")
}
Expand Down Expand Up @@ -133,7 +126,7 @@ impl Diagnostic<HirId> {

impl Diagnostic<HirIdWithBlock> {
pub fn in_file(self, file: File) -> Diagnostic<HirLocation> {
self.map_location(|location| HirLocation::single_node(location, file))
self.map_location(|location| location.in_file(file))
}
}

Expand Down
57 changes: 53 additions & 4 deletions shin-asm/src/compile/from_hir.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::compile::diagnostics::{Diagnostic, HirLocation};
use crate::compile::{
hir::{self, HirBlockBody},
resolve, BlockId, MakeWithFile, WithFile,
resolve, BlockId, File, MakeWithFile, WithFile,
};
use crate::syntax::ast::visit::ItemIndex;

Expand Down Expand Up @@ -71,18 +71,67 @@ impl HirDiagnosticCollector {
}
}

pub fn emit(&mut self, _location: HirId, _message: String) {
todo!()
pub fn emit(&mut self, location: HirLocation, message: String) {
self.diagnostics.push(HirDiagnostic::new(message, location));
}

pub fn is_empty(&self) -> bool {
self.diagnostics.is_empty()
}

pub fn with_file(&mut self, file: File) -> HirDiagnosticCollectorWithFile<'_> {
HirDiagnosticCollectorWithFile::new(self, file)
}

pub fn into_diagnostics(self) -> Vec<HirDiagnostic> {
self.diagnostics
}
}

pub struct HirDiagnosticCollectorWithFile<'a> {
diagnostics: &'a mut HirDiagnosticCollector,
file: File,
}

impl<'a> HirDiagnosticCollectorWithFile<'a> {
pub fn new(
diagnostics: &'a mut HirDiagnosticCollector,
file: File,
) -> HirDiagnosticCollectorWithFile<'a> {
HirDiagnosticCollectorWithFile { diagnostics, file }
}

pub fn with_block(&'a mut self, block: HirBlockId) -> HirDiagnosticCollectorWithBlock<'a> {
HirDiagnosticCollectorWithBlock::new(self, block)
}

pub fn emit(&mut self, location: HirIdWithBlock, message: String) {
self.diagnostics.emit(location.in_file(self.file), message);
}
}

pub struct HirDiagnosticCollectorWithBlock<'a> {
diagnostics: &'a mut HirDiagnosticCollectorWithFile<'a>,
block: HirBlockId,
}

impl<'a> HirDiagnosticCollectorWithBlock<'a> {
pub fn new(
diagnostics: &'a mut HirDiagnosticCollectorWithFile<'a>,
block: HirBlockId,
) -> HirDiagnosticCollectorWithBlock<'a> {
HirDiagnosticCollectorWithBlock { diagnostics, block }
}

pub fn emit(&mut self, location: HirId, message: String) {
self.diagnostics
.emit(HirIdWithBlock::new(location, self.block), message);
}
}

pub trait FromHirExpr: Sized {
fn from_hir_expr(
diagnostics: &mut HirDiagnosticCollector,
diagnostics: &mut HirDiagnosticCollectorWithBlock<'_>,
resolve_ctx: &resolve::ResolveContext,
block: &HirBlockBody,
expr: hir::ExprId,
Expand Down
13 changes: 9 additions & 4 deletions shin-asm/src/compile/hir/lower/block.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::compile::{resolve, BlockIdWithFile, HirBlockBody, HirDiagnosticCollector};
use crate::compile::{resolve, BlockIdWithFile, HirBlockBody, HirDiagnosticCollectorWithBlock};
use binrw::io::NoSeek;
use binrw::BinWrite;
use shin_core::format::scenario::instructions::Instruction;
Expand Down Expand Up @@ -45,7 +45,7 @@ pub struct LoweredBlock {

impl LoweredBlock {
pub fn from_hir(

Check warning on line 47 in shin-asm/src/compile/hir/lower/block.rs

View workflow job for this annotation

GitHub Actions / build

associated items `from_hir`, `complete`, `size`, and `debug_dump` are never used
diagnostics: &mut HirDiagnosticCollector,
diagnostics: &mut HirDiagnosticCollectorWithBlock,
resolve_ctx: &resolve::ResolveContext,
block: &HirBlockBody,
) -> Self {
Expand Down Expand Up @@ -145,12 +145,17 @@ mod tests {
);
}

let block = bodies.get_block(db, bodies.get_block_ids(db)[0]).unwrap();
let block_id = bodies.get_block_ids(db)[0];
let block = bodies.get_block(db, block_id).unwrap();

let mut diagnostics = HirDiagnosticCollector::new();
let resolve_ctx = ResolveContext::new(db);

let lowered = LoweredBlock::from_hir(&mut diagnostics, &resolve_ctx, &block);
let lowered = LoweredBlock::from_hir(
&mut diagnostics.with_file(file).with_block(block_id.into()),
&resolve_ctx,
&block,
);

if !diagnostics.is_empty() {
panic!(
Expand Down
13 changes: 10 additions & 3 deletions shin-asm/src/compile/hir/lower/elements/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod prelude {
pub use crate::compile::{
hir, hir::ExprId, FromHirExpr, HirBlockBody, HirDiagnosticCollector, ResolveContext,
hir, hir::ExprId, FromHirExpr, HirBlockBody, HirDiagnosticCollectorWithBlock,
ResolveContext,
};
pub use crate::syntax::ast;
}
Expand Down Expand Up @@ -39,7 +40,8 @@ fn check_from_hir_ok<T: crate::compile::FromHirExpr + Eq + std::fmt::Debug>(
);
}

let block = bodies.get_block(db, bodies.get_block_ids(db)[0]).unwrap();
let block_id = bodies.get_block_ids(db)[0];
let block = bodies.get_block(db, block_id).unwrap();

let mut diagnostics = HirDiagnosticCollector::new();
let resolve_ctx = ResolveContext::new(db);
Expand All @@ -50,7 +52,12 @@ fn check_from_hir_ok<T: crate::compile::FromHirExpr + Eq + std::fmt::Debug>(
assert_eq!(args.len(), expected.len());

for (&expr_id, expected) in args.iter().zip(expected) {
let register = T::from_hir_expr(&mut diagnostics, &resolve_ctx, &block, expr_id);
let register = T::from_hir_expr(
&mut diagnostics.with_file(file).with_block(block_id.into()),
&resolve_ctx,
&block,
expr_id,
);
assert!(diagnostics.is_empty());

assert_eq!(register.as_ref(), Some(expected));
Expand Down
4 changes: 2 additions & 2 deletions shin-asm/src/compile/hir/lower/elements/numbers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn try_lit_i32(block: &HirBlockBody, expr: ExprId) -> Option<i32> {

impl FromHirExpr for i32 {
fn from_hir_expr(
diagnostics: &mut HirDiagnosticCollector,
diagnostics: &mut HirDiagnosticCollectorWithBlock,
_resolve_ctx: &ResolveContext,
block: &HirBlockBody,
expr: ExprId,
Expand All @@ -39,7 +39,7 @@ impl FromHirExpr for i32 {
// we probably want to allow symbolic names for constants if the type is an enum
impl FromHirExpr for NumberSpec {
fn from_hir_expr(
diagnostics: &mut HirDiagnosticCollector,
diagnostics: &mut HirDiagnosticCollectorWithBlock,
resolve_ctx: &ResolveContext,
block: &HirBlockBody,
expr: ExprId,
Expand Down
2 changes: 1 addition & 1 deletion shin-asm/src/compile/hir/lower/elements/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use shin_core::format::scenario::instruction_elements::Register;

impl FromHirExpr for Register {
fn from_hir_expr(
diagnostics: &mut HirDiagnosticCollector,
diagnostics: &mut HirDiagnosticCollectorWithBlock,
resolve_ctx: &ResolveContext,
block: &HirBlockBody,
expr: ExprId,
Expand Down
23 changes: 18 additions & 5 deletions shin-asm/src/compile/hir/lower/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::compile::{
hir, resolve, BlockIdWithFile, FromHirExpr, HirBlockBody, HirDiagnosticCollector,
hir, resolve, BlockIdWithFile, FromHirExpr, HirBlockBody, HirDiagnosticCollectorWithBlock,
};
use shin_core::format::scenario::instruction_elements::{NumberSpec, UntypedNumberSpec};
use shin_core::format::scenario::instructions::{Instruction, UnaryOperation, UnaryOperationType};

fn expect_no_more_args<const N: usize>(

Check warning on line 7 in shin-asm/src/compile/hir/lower/instruction.rs

View workflow job for this annotation

GitHub Actions / build

function `expect_no_more_args` is never used
diagnostics: &mut HirDiagnosticCollector,
diagnostics: &mut HirDiagnosticCollectorWithBlock,
block: &HirBlockBody,
instr: hir::InstructionId,
) -> [Option<hir::ExprId>; N] {
Expand All @@ -26,7 +26,7 @@ fn expect_no_more_args<const N: usize>(
}

pub fn instruction_from_hir(

Check warning on line 28 in shin-asm/src/compile/hir/lower/instruction.rs

View workflow job for this annotation

GitHub Actions / build

function `instruction_from_hir` is never used
diagnostics: &mut HirDiagnosticCollector,
diagnostics: &mut HirDiagnosticCollectorWithBlock,
resolve_ctx: &resolve::ResolveContext,
_code_addresses: &mut Vec<BlockIdWithFile>,
block: &HirBlockBody,
Expand Down Expand Up @@ -133,15 +133,16 @@ mod tests {
);
}

let block = bodies.get_block(db, bodies.get_block_ids(db)[0]).unwrap();
let block_id = bodies.get_block_ids(db)[0];
let block = bodies.get_block(db, block_id).unwrap();

let mut diagnostics = HirDiagnosticCollector::new();
let resolve_ctx = ResolveContext::new(db);

let mut code_addresses = Vec::new();
let (instr, _) = block.instructions.iter().next().unwrap();
let instr = hir::lower::instruction::instruction_from_hir(
&mut diagnostics,
&mut diagnostics.with_file(file).with_block(block_id.into()),
&resolve_ctx,
&mut code_addresses,
&block,
Expand Down Expand Up @@ -209,4 +210,16 @@ mod tests {
}),
);
}

#[test]
fn test_type_error() {
check_from_hir_ok(
"zero 42",
Instruction::uo(UnaryOperation {
ty: UnaryOperationType::Zero,
destination: "$v0".parse().unwrap(),
source: NumberSpec::new(UntypedNumberSpec::Register("$v1".parse().unwrap())),
}),
);
}
}
5 changes: 4 additions & 1 deletion shin-asm/src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ pub use db::Db;
pub use def_map::DefMap;
pub(crate) use diagnostics::make_diagnostic;
pub use file::{File, Program};
pub use from_hir::{FromHirExpr, HirDiagnosticCollector};
pub use from_hir::{
FromHirExpr, HirDiagnosticCollector, HirDiagnosticCollectorWithBlock,
HirDiagnosticCollectorWithFile,
};
pub use hir::HirBlockBody;
pub use resolve::ResolveContext;
pub use types::{BlockId, BlockIdRepr, BlockIdWithFile, MakeWithFile, WithFile};

0 comments on commit ea5f751

Please sign in to comment.