cl-typeck: Refactor display for Def.
- Use the FmtAdapter from cl-ast - Add a new delimiter-constructing delimit_with function.
This commit is contained in:
parent
46bd44bd99
commit
82b71e2517
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
use delimiters::Delimiters;
|
use delimiters::Delimiters;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
@ -7,9 +6,14 @@ pub trait FmtAdapter: Write {
|
|||||||
fn indent(&mut self) -> Indent<Self> {
|
fn indent(&mut self) -> Indent<Self> {
|
||||||
Indent { f: self }
|
Indent { f: self }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delimit(&mut self, delim: Delimiters) -> Delimit<Self> {
|
fn delimit(&mut self, delim: Delimiters) -> Delimit<Self> {
|
||||||
Delimit::new(self, delim)
|
Delimit::new(self, delim)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn delimit_with(&mut self, open: &'static str, close: &'static str) -> Delimit<Self> {
|
||||||
|
Delimit::new(self, Delimiters { open, close })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pads text with leading indentation after every newline
|
/// Pads text with leading indentation after every newline
|
||||||
|
@ -1,34 +1,9 @@
|
|||||||
//! [Display] implementations for [TypeKind], [Adt], and [Intrinsic]
|
//! [Display] implementations for [TypeKind], [Adt], and [Intrinsic]
|
||||||
|
|
||||||
use crate::node::Node;
|
|
||||||
|
|
||||||
use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind};
|
use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind};
|
||||||
|
use crate::{format_utils::*, node::Node};
|
||||||
use cl_ast::format::FmtAdapter;
|
use cl_ast::format::FmtAdapter;
|
||||||
use std::{
|
use std::fmt::{self, Display, Write};
|
||||||
fmt::{self, Display, Write},
|
|
||||||
iter,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn sep<'f, 's, Item, F>(
|
|
||||||
before: &'s str,
|
|
||||||
after: &'s str,
|
|
||||||
t: F,
|
|
||||||
) -> impl FnOnce(&mut fmt::Formatter<'f>) -> fmt::Result + 's
|
|
||||||
where
|
|
||||||
Item: FnMut(&mut fmt::Formatter<'f>) -> fmt::Result,
|
|
||||||
F: FnMut() -> Option<Item> + 's,
|
|
||||||
{
|
|
||||||
move |f| {
|
|
||||||
f.write_str(before)?;
|
|
||||||
for (idx, mut disp) in iter::from_fn(t).enumerate() {
|
|
||||||
if idx > 0 {
|
|
||||||
f.write_str(", ")?;
|
|
||||||
}
|
|
||||||
disp(f)?;
|
|
||||||
}
|
|
||||||
f.write_str(after)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Def<'_> {
|
impl Display for Def<'_> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
@ -92,10 +67,10 @@ impl Display for TypeKind {
|
|||||||
TypeKind::Array(def, size) => write!(f, "array [#{def}; {size}]"),
|
TypeKind::Array(def, size) => write!(f, "array [#{def}; {size}]"),
|
||||||
TypeKind::Tuple(defs) => {
|
TypeKind::Tuple(defs) => {
|
||||||
let mut defs = defs.iter();
|
let mut defs = defs.iter();
|
||||||
sep("tuple (", ")", || {
|
separate(", ", || {
|
||||||
let def = defs.next()?;
|
let def = defs.next()?;
|
||||||
Some(move |f: &mut fmt::Formatter| write!(f, "#{def}"))
|
Some(move |f: &mut Delimit<_>| write!(f, "#{def}"))
|
||||||
})(f)
|
})(f.delimit_with("tuple (", ")"))
|
||||||
}
|
}
|
||||||
TypeKind::FnSig { args, rety } => write!(f, "fn (#{args}) -> #{rety}"),
|
TypeKind::FnSig { args, rety } => write!(f, "fn (#{args}) -> #{rety}"),
|
||||||
TypeKind::Empty => f.write_str("()"),
|
TypeKind::Empty => f.write_str("()"),
|
||||||
@ -110,43 +85,43 @@ impl Display for Adt {
|
|||||||
match self {
|
match self {
|
||||||
Adt::Enum(variants) => {
|
Adt::Enum(variants) => {
|
||||||
let mut variants = variants.iter();
|
let mut variants = variants.iter();
|
||||||
sep("enum {", "}", || {
|
separate(", ", || {
|
||||||
let (name, def) = variants.next()?;
|
let (name, def) = variants.next()?;
|
||||||
Some(move |f: &mut fmt::Formatter| match def {
|
Some(move |f: &mut Delimit<_>| match def {
|
||||||
Some(def) => write!(f, "{name}: #{def}"),
|
Some(def) => write!(f, "{name}: #{def}"),
|
||||||
None => write!(f, "{name}"),
|
None => write!(f, "{name}"),
|
||||||
})
|
})
|
||||||
})(f)
|
})(f.delimit_with("enum {", "}"))
|
||||||
}
|
}
|
||||||
Adt::CLikeEnum(variants) => {
|
Adt::CLikeEnum(variants) => {
|
||||||
let mut variants = variants.iter();
|
let mut variants = variants.iter();
|
||||||
sep("enum {", "}", || {
|
separate(", ", || {
|
||||||
let (name, descrim) = variants.next()?;
|
let (name, descrim) = variants.next()?;
|
||||||
Some(move |f: &mut fmt::Formatter| write!(f, "{name} = {descrim}"))
|
Some(move |f: &mut Delimit<_>| write!(f, "{name} = {descrim}"))
|
||||||
})(f)
|
})(f.delimit_with("enum {", "}"))
|
||||||
}
|
}
|
||||||
Adt::FieldlessEnum => write!(f, "enum"),
|
Adt::FieldlessEnum => write!(f, "enum"),
|
||||||
Adt::Struct(members) => {
|
Adt::Struct(members) => {
|
||||||
let mut members = members.iter();
|
let mut members = members.iter();
|
||||||
sep("struct {", "}", || {
|
separate(", ", || {
|
||||||
let (name, vis, def) = members.next()?;
|
let (name, vis, def) = members.next()?;
|
||||||
Some(move |f: &mut fmt::Formatter| write!(f, "{vis}{name}: #{def}"))
|
Some(move |f: &mut Delimit<_>| write!(f, "{vis}{name}: #{def}"))
|
||||||
})(f)
|
})(f.delimit_with("struct {", "}"))
|
||||||
}
|
}
|
||||||
Adt::TupleStruct(members) => {
|
Adt::TupleStruct(members) => {
|
||||||
let mut members = members.iter();
|
let mut members = members.iter();
|
||||||
sep("struct (", ")", || {
|
separate(", ", || {
|
||||||
let (vis, def) = members.next()?;
|
let (vis, def) = members.next()?;
|
||||||
Some(move |f: &mut fmt::Formatter| write!(f, "{vis}#{def}"))
|
Some(move |f: &mut Delimit<_>| write!(f, "{vis}#{def}"))
|
||||||
})(f)
|
})(f.delimit_with("struct (", ")"))
|
||||||
}
|
}
|
||||||
Adt::UnitStruct => write!(f, "struct ()"),
|
Adt::UnitStruct => write!(f, "struct"),
|
||||||
Adt::Union(variants) => {
|
Adt::Union(variants) => {
|
||||||
let mut variants = variants.iter();
|
let mut variants = variants.iter();
|
||||||
sep("union {", "}", || {
|
separate(", ", || {
|
||||||
let (name, def) = variants.next()?;
|
let (name, def) = variants.next()?;
|
||||||
Some(move |f: &mut fmt::Formatter| write!(f, "{name}: #{def}"))
|
Some(move |f: &mut Delimit<_>| write!(f, "{name}: #{def}"))
|
||||||
})(f)
|
})(f.delimit_with("union {", "}"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
compiler/cl-typeck/src/format_utils.rs
Normal file
23
compiler/cl-typeck/src/format_utils.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
pub use cl_ast::format::*;
|
||||||
|
use std::{fmt, iter};
|
||||||
|
|
||||||
|
/// Separates the items yielded by iterating the provided function
|
||||||
|
pub const fn separate<'f, 's, Item, F, W>(
|
||||||
|
sep: &'s str,
|
||||||
|
t: F,
|
||||||
|
) -> impl FnOnce(W) -> fmt::Result + 's
|
||||||
|
where
|
||||||
|
Item: FnMut(&mut W) -> fmt::Result,
|
||||||
|
F: FnMut() -> Option<Item> + 's,
|
||||||
|
W: fmt::Write,
|
||||||
|
{
|
||||||
|
move |mut f| {
|
||||||
|
for (idx, mut disp) in iter::from_fn(t).enumerate() {
|
||||||
|
if idx > 0 {
|
||||||
|
f.write_str(sep)?;
|
||||||
|
}
|
||||||
|
disp(&mut f)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -87,6 +87,8 @@ pub mod type_resolver;
|
|||||||
|
|
||||||
pub mod inference;
|
pub mod inference;
|
||||||
|
|
||||||
|
pub(crate) mod format_utils;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
LET THERE BE NOTES:
|
LET THERE BE NOTES:
|
||||||
|
Loading…
Reference in New Issue
Block a user