From 82b71e25173d8d27b91d98e10c3f34063b7fd320 Mon Sep 17 00:00:00 2001 From: John Date: Sun, 21 Jul 2024 01:46:20 -0500 Subject: [PATCH] cl-typeck: Refactor display for Def. - Use the FmtAdapter from cl-ast - Add a new delimiter-constructing delimit_with function. --- compiler/cl-ast/src/format.rs | 6 +- compiler/cl-typeck/src/definition/display.rs | 67 ++++++-------------- compiler/cl-typeck/src/format_utils.rs | 23 +++++++ compiler/cl-typeck/src/lib.rs | 2 + 4 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 compiler/cl-typeck/src/format_utils.rs diff --git a/compiler/cl-ast/src/format.rs b/compiler/cl-ast/src/format.rs index 9bc95d0..13f8fa4 100644 --- a/compiler/cl-ast/src/format.rs +++ b/compiler/cl-ast/src/format.rs @@ -1,4 +1,3 @@ - use delimiters::Delimiters; use std::fmt::Write; @@ -7,9 +6,14 @@ pub trait FmtAdapter: Write { fn indent(&mut self) -> Indent { Indent { f: self } } + fn delimit(&mut self, delim: Delimiters) -> Delimit { Delimit::new(self, delim) } + + fn delimit_with(&mut self, open: &'static str, close: &'static str) -> Delimit { + Delimit::new(self, Delimiters { open, close }) + } } /// Pads text with leading indentation after every newline diff --git a/compiler/cl-typeck/src/definition/display.rs b/compiler/cl-typeck/src/definition/display.rs index 923efd6..e5d4d88 100644 --- a/compiler/cl-typeck/src/definition/display.rs +++ b/compiler/cl-typeck/src/definition/display.rs @@ -1,34 +1,9 @@ //! [Display] implementations for [TypeKind], [Adt], and [Intrinsic] -use crate::node::Node; - use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind}; +use crate::{format_utils::*, node::Node}; use cl_ast::format::FmtAdapter; -use std::{ - 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 + '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) - } -} +use std::fmt::{self, Display, Write}; impl Display for Def<'_> { 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::Tuple(defs) => { let mut defs = defs.iter(); - sep("tuple (", ")", || { + separate(", ", || { let def = defs.next()?; - Some(move |f: &mut fmt::Formatter| write!(f, "#{def}")) - })(f) + Some(move |f: &mut Delimit<_>| write!(f, "#{def}")) + })(f.delimit_with("tuple (", ")")) } TypeKind::FnSig { args, rety } => write!(f, "fn (#{args}) -> #{rety}"), TypeKind::Empty => f.write_str("()"), @@ -110,43 +85,43 @@ impl Display for Adt { match self { Adt::Enum(variants) => { let mut variants = variants.iter(); - sep("enum {", "}", || { + separate(", ", || { 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}"), None => write!(f, "{name}"), }) - })(f) + })(f.delimit_with("enum {", "}")) } Adt::CLikeEnum(variants) => { let mut variants = variants.iter(); - sep("enum {", "}", || { + separate(", ", || { let (name, descrim) = variants.next()?; - Some(move |f: &mut fmt::Formatter| write!(f, "{name} = {descrim}")) - })(f) + Some(move |f: &mut Delimit<_>| write!(f, "{name} = {descrim}")) + })(f.delimit_with("enum {", "}")) } Adt::FieldlessEnum => write!(f, "enum"), Adt::Struct(members) => { let mut members = members.iter(); - sep("struct {", "}", || { + separate(", ", || { let (name, vis, def) = members.next()?; - Some(move |f: &mut fmt::Formatter| write!(f, "{vis}{name}: #{def}")) - })(f) + Some(move |f: &mut Delimit<_>| write!(f, "{vis}{name}: #{def}")) + })(f.delimit_with("struct {", "}")) } Adt::TupleStruct(members) => { let mut members = members.iter(); - sep("struct (", ")", || { + separate(", ", || { let (vis, def) = members.next()?; - Some(move |f: &mut fmt::Formatter| write!(f, "{vis}#{def}")) - })(f) + Some(move |f: &mut Delimit<_>| write!(f, "{vis}#{def}")) + })(f.delimit_with("struct (", ")")) } - Adt::UnitStruct => write!(f, "struct ()"), + Adt::UnitStruct => write!(f, "struct"), Adt::Union(variants) => { let mut variants = variants.iter(); - sep("union {", "}", || { + separate(", ", || { let (name, def) = variants.next()?; - Some(move |f: &mut fmt::Formatter| write!(f, "{name}: #{def}")) - })(f) + Some(move |f: &mut Delimit<_>| write!(f, "{name}: #{def}")) + })(f.delimit_with("union {", "}")) } } } diff --git a/compiler/cl-typeck/src/format_utils.rs b/compiler/cl-typeck/src/format_utils.rs new file mode 100644 index 0000000..dbfc349 --- /dev/null +++ b/compiler/cl-typeck/src/format_utils.rs @@ -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 + '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(()) + } +} diff --git a/compiler/cl-typeck/src/lib.rs b/compiler/cl-typeck/src/lib.rs index 756dd3b..f88ae19 100644 --- a/compiler/cl-typeck/src/lib.rs +++ b/compiler/cl-typeck/src/lib.rs @@ -87,6 +87,8 @@ pub mod type_resolver; pub mod inference; +pub(crate) mod format_utils; + /* LET THERE BE NOTES: