Skip to content

Commit

Permalink
Add rudimentary pretty printer
Browse files Browse the repository at this point in the history
  • Loading branch information
DropDemBits committed Jun 12, 2023
1 parent 5dd4dba commit e43eaaa
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 104 deletions.
35 changes: 4 additions & 31 deletions compiler/toc-driver/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,37 +67,10 @@ fn main() {
for &package in source_graph.all_packages(&db) {
// use new hir entities
println!("New HIR:");
let root = toc_hir::root_module(&db, package);
let mut queue = std::collections::VecDeque::new();
queue.push_front((0, toc_hir::Item::Module(root)));

while let Some((level, item)) = queue.pop_front() {
let indent = " ".repeat(level);

match item {
toc_hir::Item::Module(module) => {
let name = module.name(&db).text(&db);

println!("{indent}module {name} /* {module:?} */",);
println!("{indent}");

for &child in module.items(&db).iter().rev() {
queue.push_front((level + 1, child));
}
}
toc_hir::Item::ConstVar(cv) => {
let kind = match cv.mutability(&db) {
toc_hir::Mutability::Const => "const",
toc_hir::Mutability::Var => "var",
};
let name = cv.name(&db).text(&db);

println!("{indent}{kind} {name} /* {cv:?} */");
println!("{indent}");
}
}
}
println!();
println!(
"{}",
toc_hir::render_item_tree(&db, package).render_as_tree()
);

println!("Old HIR:");
let file = package.root(&db);
Expand Down
1 change: 1 addition & 0 deletions compiler/toc-hir-def/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
};

mod lower;
pub mod pretty;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Item {
Expand Down
74 changes: 74 additions & 0 deletions compiler/toc-hir-def/src/item/pretty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//! Pretty printing an item tree

use std::fmt;

use toc_source_graph::Package;

use crate::{
item::{root_module, Item},
Db, Mutability,
};

pub struct PrettyTree {
root: PrettyItem,
}

pub fn render_item_tree(db: &dyn Db, root: Package) -> PrettyTree {
fn render_sub_tree(db: &dyn Db, item: Item) -> PrettyItem {
match item {
Item::ConstVar(item) => {
PrettyItem::ConstVar(item.mutability(db), item.name(db).text(db), item.0.as_u32())
}
Item::Module(item) => PrettyItem::Module(
item.name(db).text(db),
item.items(db)
.iter()
.map(|child| render_sub_tree(db, *child))
.collect(),
item.0.as_u32(),
),
}
}

let root = root_module(db, root);
PrettyTree {
root: render_sub_tree(db, Item::Module(root)),
}
}

enum PrettyItem {
ConstVar(Mutability, String, u32),
Module(String, Vec<PrettyItem>, u32),
}

impl PrettyTree {
pub fn render_as_tree(self) -> String {
fn render_item(out: &mut dyn fmt::Write, level: usize, item: PrettyItem) -> fmt::Result {
let indent = " ".repeat(level);

match item {
PrettyItem::ConstVar(mutability, name, id) => {
let kind = match mutability {
Mutability::Const => "const",
Mutability::Var => "var",
};
writeln!(out, "{indent}{kind} {name} /* ConstVar({id}) */")?;
writeln!(out, "")?;
}
PrettyItem::Module(name, children, id) => {
writeln!(out, "{indent}module {name} /* Module({id}) */")?;
writeln!(out, "")?;
for child in children {
render_item(out, level + 1, child)?;
}
}
}

Ok(())
}

let mut out = String::new();
render_item(&mut out, 0, self.root).expect("failed to format tree");
out
}
}
147 changes: 75 additions & 72 deletions compiler/toc-hir-def/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,94 +8,97 @@ pub(crate) mod internals {
/// Only to be used inside of this crate.
#[macro_export]
macro_rules! arena_id_wrapper {
// Just a newtype for the index
(
$(#[$attrs:meta])*
$vis:vis struct $id:ident($wrap:path);
) => {
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
$(#[$attrs])*
$vis struct $id(pub(crate) ::la_arena::Idx<$wrap>);

$crate::arena_id_wrapper!(@impl_rest, $id, $wrap);
};
// Newtype + type alias for the index
(
$(#[$attrs_wrap:meta])*
$vis_wrap:vis struct $id:ident($wrap:path);
$(#[$attrs_alias:meta])*
$vis_alias:vis type $index_alias:ident = Index;
) => {
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
$(#[$attrs_wrap])*
$vis_wrap struct $id(pub(crate) $index_alias);

$(#[$attrs_alias])*
$vis_alias type $index_alias = ::la_arena::Idx<$wrap>;

$crate::arena_id_wrapper!(@impl_rest, $id, $wrap);
};
// Other impls
(
@impl_rest, $id:ident, $wrap:path
) => {
impl From<$id> for ::la_arena::Idx<$wrap> {
fn from(id: $id) -> Self {
id.0
// Just a newtype for the index
(
$(#[$attrs:meta])*
$vis:vis struct $id:ident($wrap:path);
) => {
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
$(#[$attrs])*
$vis struct $id(pub(crate) ::la_arena::Idx<$wrap>);

$crate::arena_id_wrapper!(@impl_rest, $id, $wrap);
};
// Newtype + type alias for the index
(
$(#[$attrs_wrap:meta])*
$vis_wrap:vis struct $id:ident($wrap:path);
$(#[$attrs_alias:meta])*
$vis_alias:vis type $index_alias:ident = Index;
) => {
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
$(#[$attrs_wrap])*
$vis_wrap struct $id(pub(crate) $index_alias);

$(#[$attrs_alias])*
$vis_alias type $index_alias = ::la_arena::Idx<$wrap>;

$crate::arena_id_wrapper!(@impl_rest, $id, $wrap);
};
// Other impls
(
@impl_rest, $id:ident, $wrap:path
) => {
impl From<$id> for ::la_arena::Idx<$wrap> {
fn from(id: $id) -> Self {
id.0
}
}
}

impl From<&$id> for ::la_arena::Idx<$wrap> {
fn from(id: &$id) -> Self {
id.0
impl From<&$id> for ::la_arena::Idx<$wrap> {
fn from(id: &$id) -> Self {
id.0
}
}
}

impl ::std::fmt::Debug for $id {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
let raw: u32 = self.0.into_raw().into();
f.debug_tuple(stringify!($id))
.field(&raw)
.finish()
impl ::std::fmt::Debug for $id {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
let raw: u32 = self.0.into_raw().into();
f.debug_tuple(stringify!($id))
.field(&raw)
.finish()
}
}
}
};
}
};
}

/// Simple named boolean
#[macro_export]
macro_rules! make_named_bool {
(
$(#[$attrs:meta])*
$vis:vis enum $ident:ident $(;)?
) => {
$(#[$attrs])*
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
$vis enum $ident {
No,
Yes
}
(
$(#[$attrs:meta])*
$vis:vis enum $ident:ident $(;)?
) => {
$(#[$attrs])*
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
$vis enum $ident {
No,
Yes
}

impl ::std::convert::From<bool> for $ident {
fn from(v: bool) -> Self {
match v {
false => Self::No,
true => Self::Yes,
impl ::std::convert::From<bool> for $ident {
fn from(v: bool) -> Self {
match v {
false => Self::No,
true => Self::Yes,
}
}
}
}

impl ::std::convert::From<$ident> for bool {
fn from(v: $ident) -> bool {
matches!(v, $ident::Yes)
impl ::std::convert::From<$ident> for bool {
fn from(v: $ident) -> bool {
matches!(v, $ident::Yes)
}
}
}
};
}
};
}
}

#[cfg(test)]
mod test;

pub mod body;
pub mod expr;
pub mod stmt;
Expand Down
Empty file.
2 changes: 1 addition & 1 deletion compiler/toc-hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ pub use toc_hir_expand::{

pub use toc_hir_def::{
body::Body,
item::{root_module, ConstVar, Item, Module},
item::{pretty::render_item_tree, root_module, ConstVar, Item, Module},
Jar as DefJar, Mutability,
};

Expand Down

0 comments on commit e43eaaa

Please sign in to comment.