cl-ast: Overhaul pretty-printing using std::fmt::Write adapters.

Now you don't have to import cl_ast::format::*!!!
This commit is contained in:
John 2024-04-18 20:47:28 -05:00
parent e4f270da17
commit f315fb5af7
6 changed files with 228 additions and 219 deletions

View File

@ -3,57 +3,24 @@ use super::*;
mod display {
//! Implements [Display] for [AST](super::super) Types
use super::*;
pub use delimiters::*;
use format::{delimiters::*, *};
use std::{
borrow::Borrow,
fmt::{Display, Write},
};
mod delimiters {
#![allow(dead_code)]
#[derive(Clone, Copy, Debug)]
pub struct Delimiters<'t> {
pub open: &'t str,
pub close: &'t str,
}
/// Delimits with braces decorated with spaces `" {n"`, ..., `"\n}"`
pub const SPACED_BRACES: Delimiters = Delimiters { open: " {\n", close: "\n}" };
/// Delimits with braces on separate lines `{\n`, ..., `\n}`
pub const BRACES: Delimiters = Delimiters { open: "{\n", close: "\n}" };
/// Delimits with parentheses on separate lines `{\n`, ..., `\n}`
pub const PARENS: Delimiters = Delimiters { open: "(\n", close: "\n)" };
/// Delimits with square brackets on separate lines `{\n`, ..., `\n}`
pub const SQUARE: Delimiters = Delimiters { open: "[\n", close: "\n]" };
/// Delimits with braces on the same line `{ `, ..., ` }`
pub const INLINE_BRACES: Delimiters = Delimiters { open: "{ ", close: " }" };
/// Delimits with parentheses on the same line `( `, ..., ` )`
pub const INLINE_PARENS: Delimiters = Delimiters { open: "(", close: ")" };
/// Delimits with square brackets on the same line `[ `, ..., ` ]`
pub const INLINE_SQUARE: Delimiters = Delimiters { open: "[", close: "]" };
}
fn delimit<'a>(
func: impl Fn(&mut std::fmt::Formatter<'_>) -> std::fmt::Result + 'a,
delim: Delimiters<'a>,
) -> impl Fn(&mut std::fmt::Formatter<'_>) -> std::fmt::Result + 'a {
move |f| {
write!(f, "{}", delim.open)?;
func(f)?;
write!(f, "{}", delim.close)
}
}
fn separate<'iterable, I>(
iterable: &'iterable [I],
sep: impl Display + 'iterable,
) -> impl Fn(&mut std::fmt::Formatter<'_>) -> std::fmt::Result + 'iterable
where
I: Display,
{
move |f| {
for (idx, item) in iterable.iter().enumerate() {
fn separate<I: Display, W: Write>(
iterable: impl IntoIterator<Item = I>,
sep: &'static str,
) -> impl FnOnce(W) -> std::fmt::Result {
move |mut f| {
for (idx, item) in iterable.into_iter().enumerate() {
if idx > 0 {
write!(f, "{sep}")?;
f.write_str(sep)?;
}
item.fmt(f)?;
write!(f, "{item}")?;
}
Ok(())
}
@ -67,6 +34,7 @@ mod display {
}
}
}
impl Display for Visibility {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -76,6 +44,23 @@ mod display {
}
}
impl Display for Identifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl Display for Literal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Literal::Bool(v) => v.fmt(f),
Literal::Char(v) => write!(f, "'{v}'"),
Literal::Int(v) => v.fmt(f),
Literal::String(v) => write!(f, "\"{v}\""),
}
}
}
impl Display for File {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
separate(&self.items, "\n\n")(f)
@ -89,22 +74,24 @@ mod display {
return Ok(());
}
"#".fmt(f)?;
delimit(separate(meta, ", "), INLINE_SQUARE)(f)?;
separate(meta, ", ")(&mut f.delimit(INLINE_SQUARE))?;
"\n".fmt(f)
}
}
impl Display for Meta {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, kind } = self;
write!(f, "{name}{kind}")
}
}
impl Display for MetaKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MetaKind::Plain => Ok(()),
MetaKind::Equals(v) => write!(f, " = {v}"),
MetaKind::Func(args) => delimit(separate(args, ", "), INLINE_PARENS)(f),
MetaKind::Func(args) => separate(args, ", ")(f.delimit(INLINE_PARENS)),
}
}
}
@ -114,7 +101,13 @@ mod display {
let Self { extents: _, attrs, vis, kind } = self;
attrs.fmt(f)?;
vis.fmt(f)?;
match kind {
kind.fmt(f)
}
}
impl Display for ItemKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ItemKind::Alias(v) => v.fmt(f),
ItemKind::Const(v) => v.fmt(f),
ItemKind::Static(v) => v.fmt(f),
@ -126,6 +119,7 @@ mod display {
}
}
}
impl Display for Alias {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { to, from } = self;
@ -135,35 +129,40 @@ mod display {
}
}
}
impl Display for Const {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, ty, init } = self;
write!(f, "const {name}: {ty} = {init}")
}
}
impl Display for Static {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { mutable, name, ty, init } = self;
write!(f, "static {mutable}{name}: {ty} = {init}")
}
}
impl Display for Module {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, kind } = self;
write!(f, "mod {name}{kind}")
}
}
impl Display for ModuleKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ModuleKind::Inline(items) => {
' '.fmt(f)?;
delimit(|f| items.fmt(f), BRACES)(f)
write!(f.delimit(BRACES), "{items}")
}
ModuleKind::Outline => ';'.fmt(f),
}
}
}
impl Display for Function {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, sign: sign @ TyFn { args, rety }, bind, body } = self;
@ -178,18 +177,15 @@ mod display {
debug_assert_eq!(bind.len(), types.len());
write!(f, "fn {name} ")?;
delimit(
|f| {
{
let mut f = f.delimit(INLINE_PARENS);
for (idx, (arg, ty)) in bind.iter().zip(types.iter()).enumerate() {
if idx != 0 {
f.write_str(", ")?;
}
write!(f, "{arg}: {ty}")?;
}
Ok(())
},
INLINE_PARENS,
)(f)?;
}
if let Some(rety) = rety {
write!(f, " -> {rety}")?;
}
@ -199,70 +195,80 @@ mod display {
}
}
}
impl Display for Param {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { mutability, name } = self;
write!(f, "{mutability}{name}")
}
}
impl Display for Struct {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, kind } = self;
write!(f, "struct {name}{kind}")
}
}
impl Display for StructKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StructKind::Empty => ';'.fmt(f),
StructKind::Tuple(v) => delimit(separate(v, ", "), INLINE_PARENS)(f),
StructKind::Struct(v) => delimit(separate(v, ",\n"), SPACED_BRACES)(f),
StructKind::Tuple(v) => separate(v, ", ")(f.delimit(INLINE_PARENS)),
StructKind::Struct(v) => separate(v, ",\n")(f.delimit(SPACED_BRACES)),
}
}
}
impl Display for StructMember {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { vis, name, ty } = self;
write!(f, "{vis}{name}: {ty}")
}
}
impl Display for Enum {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, kind } = self;
write!(f, "enum {name}{kind}")
}
}
impl Display for EnumKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
EnumKind::NoVariants => ';'.fmt(f),
EnumKind::Variants(v) => delimit(separate(v, ",\n"), SPACED_BRACES)(f),
EnumKind::Variants(v) => separate(v, ",\n")(f.delimit(SPACED_BRACES)),
}
}
}
impl Display for Variant {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, kind } = self;
write!(f, "{name}{kind}")
}
}
impl Display for VariantKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
VariantKind::Plain => Ok(()),
VariantKind::CLike(n) => write!(f, " = {n}"),
VariantKind::Tuple(v) => v.fmt(f),
VariantKind::Struct(v) => delimit(separate(v, ", "), INLINE_BRACES)(f),
VariantKind::Struct(v) => separate(v, ", ")(f.delimit(INLINE_BRACES)),
}
}
}
impl Display for Impl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { target, body } = self;
write!(f, "impl {target} ")?;
delimit(|f| body.fmt(f), BRACES)(f)
write!(f.delimit(BRACES), "{body}")
}
}
impl Display for ImplKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -279,6 +285,7 @@ mod display {
self.kind.fmt(f)
}
}
impl Display for TyKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -292,11 +299,13 @@ mod display {
}
}
}
impl Display for TyTuple {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
delimit(separate(&self.types, ", "), INLINE_PARENS)(f)
separate(&self.types, ", ")(f.delimit(INLINE_PARENS))
}
}
impl Display for TyRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let &Self { count, mutable, ref to } = self;
@ -306,6 +315,7 @@ mod display {
write!(f, "{mutable}{to}")
}
}
impl Display for TyFn {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { args, rety } = self;
@ -317,21 +327,53 @@ mod display {
}
}
impl Display for Path {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { absolute, parts } = self;
if *absolute {
"::".fmt(f)?;
}
separate(parts, "::")(f)
}
}
impl Display for PathPart {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PathPart::SuperKw => "super".fmt(f),
PathPart::SelfKw => "self".fmt(f),
PathPart::Ident(id) => id.fmt(f),
}
}
}
impl Display for Stmt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Stmt { extents: _, kind, semi } = self;
match kind {
write!(f, "{kind}{semi}")
}
}
impl Display for StmtKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
StmtKind::Empty => Ok(()),
StmtKind::Local(v) => v.fmt(f),
StmtKind::Item(v) => v.fmt(f),
StmtKind::Expr(v) => v.fmt(f),
}?;
match semi {
}
}
}
impl Display for Semi {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Semi::Terminated => ';'.fmt(f),
Semi::Unterminated => Ok(()),
}
}
}
impl Display for Let {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { mutable, name, ty, init } = self;
@ -351,9 +393,11 @@ mod display {
self.kind.fmt(f)
}
}
impl Display for ExprKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ExprKind::Empty => "()".fmt(f),
ExprKind::Assign(v) => v.fmt(f),
ExprKind::Binary(v) => v.fmt(f),
ExprKind::Unary(v) => v.fmt(f),
@ -364,7 +408,6 @@ mod display {
ExprKind::ArrayRep(v) => v.fmt(f),
ExprKind::AddrOf(v) => v.fmt(f),
ExprKind::Block(v) => v.fmt(f),
ExprKind::Empty => "()".fmt(f),
ExprKind::Group(v) => v.fmt(f),
ExprKind::Tuple(v) => v.fmt(f),
ExprKind::Loop(v) => v.fmt(f),
@ -377,12 +420,14 @@ mod display {
}
}
}
impl Display for Assign {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { kind, parts } = self;
write!(f, "{} {kind} {}", parts.0, parts.1)
}
}
impl Display for AssignKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -401,6 +446,7 @@ mod display {
.fmt(f)
}
}
impl Display for Binary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { kind, parts } = self;
@ -412,6 +458,7 @@ mod display {
}
}
}
impl Display for BinaryKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -442,12 +489,14 @@ mod display {
.fmt(f)
}
}
impl Display for Unary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { kind, tail } = self;
write!(f, "{kind}{tail}")
}
}
impl Display for UnaryKind {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@ -460,62 +509,28 @@ mod display {
.fmt(f)
}
}
impl Display for Tuple {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
delimit(separate(&self.exprs, ", "), INLINE_PARENS)(f)
}
}
impl Display for Index {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { head, indices } = self;
write!(f, "{head}")?;
delimit(separate(indices, ", "), INLINE_SQUARE)(f)
}
}
impl Display for Path {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { absolute, parts } = self;
if *absolute {
"::".fmt(f)?;
}
separate(parts, "::")(f)
}
}
impl Display for PathPart {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PathPart::SuperKw => "super".fmt(f),
PathPart::SelfKw => "self".fmt(f),
PathPart::Ident(id) => id.fmt(f),
}
}
}
impl Display for Identifier {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl Display for Literal {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Literal::Bool(v) => v.fmt(f),
Literal::Char(v) => write!(f, "'{v}'"),
Literal::Int(v) => v.fmt(f),
Literal::String(v) => write!(f, "\"{v}\""),
}
separate(indices, ", ")(f.delimit(INLINE_SQUARE))
}
}
impl Display for Array {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
delimit(separate(&self.values, ", "), INLINE_SQUARE)(f)
separate(&self.values, ", ")(f.delimit(INLINE_SQUARE))
}
}
impl Display for ArrayRep {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { value, repeat } = self;
write!(f, "[{value}; {repeat}]")
}
}
impl Display for AddrOf {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { count, mutable, expr } = self;
@ -525,40 +540,53 @@ mod display {
write!(f, "{mutable}{expr}")
}
}
impl Display for Block {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
delimit(separate(&self.stmts, "\n"), BRACES)(f)
separate(&self.stmts, "\n")(f.delimit(BRACES))
}
}
impl Display for Group {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "({})", self.expr)
}
}
impl Display for Tuple {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
separate(&self.exprs, ", ")(f.delimit(INLINE_PARENS))
}
}
impl Display for Loop {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { body } = self;
write!(f, "loop {body}")
}
}
impl Display for While {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { cond, pass, fail } = self;
write!(f, "while {cond} {pass}{fail}")
}
}
impl Display for If {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { cond, pass, fail } = self;
write!(f, "if {cond} {pass}{fail}")
}
}
impl Display for For {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { bind, cond, pass, fail } = self;
write!(f, "for {bind} in {cond} {pass}{fail}")
}
}
impl Display for Else {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self.body {
@ -567,6 +595,7 @@ mod display {
}
}
}
impl Display for Break {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "break")?;
@ -576,6 +605,7 @@ mod display {
}
}
}
impl Display for Return {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "return")?;
@ -585,6 +615,12 @@ mod display {
}
}
}
impl Display for Continue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
"continue".fmt(f)
}
}
}
mod convert {

View File

@ -1,106 +1,78 @@
use std::{
fmt::{Result as FmtResult, Write as FmtWrite},
io::{Result as IoResult, Write as IoWrite},
};
/// Trait which adds a function to [fmt Writers](FmtWrite) to turn them into [Prettifier]
pub trait FmtPretty: FmtWrite {
/// Indents code according to the number of matched curly braces
fn pretty(self) -> Prettifier<'static, Self>
where Self: Sized {
Prettifier::new(self)
use delimiters::Delimiters;
use std::fmt::Write;
impl<W: Write + ?Sized> FmtAdapter for W {}
pub trait FmtAdapter: Write {
fn indent(&mut self) -> Indent<Self> {
Indent { f: self }
}
}
/// Trait which adds a function to [io Writers](IoWrite) to turn them into [Prettifier]
pub trait IoPretty: IoWrite {
/// Indents code according to the number of matched curly braces
fn pretty(self) -> Prettifier<'static, Self>
where Self: Sized;
}
impl<W: FmtWrite> FmtPretty for W {}
impl<W: IoWrite> IoPretty for W {
fn pretty(self) -> Prettifier<'static, Self> {
Prettifier::new(self)
fn delimit(&mut self, delim: Delimiters) -> Delimit<Self> {
Delimit::new(self, delim)
}
}
/// Intercepts calls to either [std::io::Write] or [std::fmt::Write],
/// and inserts indentation between matched parentheses
pub struct Prettifier<'i, T: ?Sized> {
level: isize,
indent: &'i str,
writer: T,
/// Pads text with leading indentation after every newline
pub struct Indent<'f, F: Write + ?Sized> {
f: &'f mut F,
}
impl<'i, W> Prettifier<'i, W> {
pub fn new(writer: W) -> Self {
Self { level: 0, indent: " ", writer }
}
pub fn with_indent(indent: &'i str, writer: W) -> Self {
Self { level: 0, indent, writer }
}
}
impl<'i, W: FmtWrite> Prettifier<'i, W> {
#[inline]
fn fmt_write_indentation(&mut self) -> FmtResult {
let Self { level, indent, writer } = self;
for _ in 0..*level {
writer.write_str(indent)?;
}
Ok(())
}
}
impl<'i, W: IoWrite> Prettifier<'i, W> {
pub fn io_write_indentation(&mut self) -> IoResult<usize> {
let Self { level, indent, writer } = self;
let mut count = 0;
for _ in 0..*level {
count += writer.write(indent.as_bytes())?;
}
Ok(count)
}
}
impl<'i, W: FmtWrite> FmtWrite for Prettifier<'i, W> {
fn write_str(&mut self, s: &str) -> FmtResult {
for s in s.split_inclusive(['{', '}']) {
match s.as_bytes().last() {
Some(b'{') => self.level += 1,
Some(b'}') => self.level -= 1,
_ => (),
}
impl<'f, F: Write + ?Sized> Write for Indent<'f, F> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
for s in s.split_inclusive('\n') {
self.writer.write_str(s)?;
if let Some(b'\n') = s.as_bytes().last() {
self.fmt_write_indentation()?;
}
self.f.write_str(s)?;
if s.ends_with('\n') {
self.f.write_str(" ")?;
}
}
Ok(())
}
}
impl<'i, W: IoWrite> IoWrite for Prettifier<'i, W> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let mut size = 0;
for buf in buf.split_inclusive(|b| b"{}".contains(b)) {
match buf.last() {
Some(b'{') => self.level += 1,
Some(b'}') => self.level -= 1,
_ => (),
}
for buf in buf.split_inclusive(|b| b'\n' == *b) {
size += self.writer.write(buf)?;
if let Some(b'\n') = buf.last() {
self.io_write_indentation()?;
}
}
}
Ok(size)
}
fn flush(&mut self) -> std::io::Result<()> {
self.writer.flush()
/// Prints [Delimiters] around anything formatted with this. Implies [Indent]
pub struct Delimit<'f, F: Write + ?Sized> {
f: Indent<'f, F>,
delim: Delimiters,
}
impl<'f, F: Write + ?Sized> Delimit<'f, F> {
pub fn new(f: &'f mut F, delim: Delimiters) -> Self {
let mut f = f.indent();
let _ = f.write_str(delim.open);
Self { f, delim }
}
}
impl<'f, F: Write + ?Sized> Drop for Delimit<'f, F> {
fn drop(&mut self) {
let Self { f: Indent { f, .. }, delim } = self;
let _ = f.write_str(delim.close);
}
}
impl<'f, F: Write + ?Sized> Write for Delimit<'f, F> {
fn write_str(&mut self, s: &str) -> std::fmt::Result {
self.f.write_str(s)
}
}
pub mod delimiters {
#![allow(dead_code)]
#[derive(Clone, Copy, Debug)]
pub struct Delimiters {
pub open: &'static str,
pub close: &'static str,
}
/// Delimits with braces decorated with spaces `" {n"`, ..., `"\n}"`
pub const SPACED_BRACES: Delimiters = Delimiters { open: " {\n", close: "\n}" };
/// Delimits with braces on separate lines `{\n`, ..., `\n}`
pub const BRACES: Delimiters = Delimiters { open: "{\n", close: "\n}" };
/// Delimits with parentheses on separate lines `{\n`, ..., `\n}`
pub const PARENS: Delimiters = Delimiters { open: "(\n", close: "\n)" };
/// Delimits with square brackets on separate lines `{\n`, ..., `\n}`
pub const SQUARE: Delimiters = Delimiters { open: "[\n", close: "\n]" };
/// Delimits with braces on the same line `{ `, ..., ` }`
pub const INLINE_BRACES: Delimiters = Delimiters { open: "{ ", close: " }" };
/// Delimits with parentheses on the same line `( `, ..., ` )`
pub const INLINE_PARENS: Delimiters = Delimiters { open: "(", close: ")" };
/// Delimits with square brackets on the same line `[ `, ..., ` ]`
pub const INLINE_SQUARE: Delimiters = Delimiters { open: "[", close: "]" };
}

View File

@ -282,9 +282,7 @@ pub mod temp_type_impl {
')'.fmt(f)
}
ConValue::Function(func) => {
use cl_ast::format::*;
use std::fmt::Write;
write!(f.pretty(), "{}", func.decl())
write!(f, "{}", func.decl())
}
ConValue::BuiltIn(func) => {
write!(f, "{}", func.description())

View File

@ -12,6 +12,7 @@ const STDLIB: &str = include_str!("../../stdlib/lib.cl");
const C_MAIN: &str = "\x1b[30m";
const C_RESV: &str = "\x1b[35m";
const C_CODE: &str = "\x1b[36m";
const C_LISTING: &str = "\x1b[38;5;117m";
/// A home for immutable intermediate ASTs
///
@ -144,12 +145,15 @@ fn list_types(prj: &mut Project) -> Result<(), Box<dyn Error>> {
fn pretty_def(def: &Def, id: impl Into<usize>) {
let id = id.into();
let Def { vis, name, kind, module, meta, source: _ } = def;
let Def { vis, name, kind, module, meta, source } = def;
for meta in *meta {
println!("#[{meta}]")
}
println!("{vis}{name} [id: {id}] = {kind}");
println!("Module:\n\x1b[97m{module}\x1b[0m");
if let Some(source) = source {
println!("Source:\n{C_LISTING}{source}\x1b[0m");
}
println!("\x1b[90m{module}\x1b[0m");
}
fn clear() -> Result<(), Box<dyn Error>> {

View File

@ -85,11 +85,11 @@ pub mod program {
env::Environment, error::IResult, interpret::Interpret, temp_type_impl::ConValue,
};
use cl_ast::{self as ast, format::*};
use cl_ast as ast;
use cl_lexer::Lexer;
use cl_parser::{error::PResult, Parser};
// use conlang::resolver::{error::TyResult, Resolver};
use std::{fmt::Display, io::Write};
use std::fmt::Display;
pub struct Parsable;
@ -136,13 +136,11 @@ pub mod program {
}
}
pub fn print(&self) {
let mut f = std::io::stdout().pretty();
let _ = match &self.data {
Parsed::File(v) => writeln!(f, "{v}"),
Parsed::Stmt(v) => writeln!(f, "{v}"),
Parsed::Expr(v) => writeln!(f, "{v}"),
match &self.data {
Parsed::File(v) => println!("{v}"),
Parsed::Stmt(v) => println!("{v}"),
Parsed::Expr(v) => println!("{v}"),
};
// println!("{self}")
}
pub fn run(&self, env: &mut Environment) -> IResult<ConValue> {

View File

@ -1,7 +1,7 @@
//! [Display] implementations for [TypeKind], [Adt], and [Intrinsic]
use super::{Adt, Def, DefKind, Intrinsic, TypeKind, ValueKind};
use cl_ast::format::FmtPretty;
use cl_ast::format::FmtAdapter;
use std::{
fmt::{self, Display, Write},
iter,
@ -31,13 +31,14 @@ where
impl Display for Def<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let Self { name, vis, meta, kind, source, module } = self;
if !meta.is_empty() {
writeln!(f, "#{meta:?}")?;
}
writeln!(f, "{vis}{name}: ")?;
writeln!(f, "kind: {kind}")?;
if !meta.is_empty() {
writeln!(f, "meta: {meta:?}")?;
}
if let Some(source) = source {
writeln!(f.pretty(), "source: {{\n{source}\n}}")?;
writeln!(f, "source:")?;
writeln!(f.indent(), "\n{source}")?;
}
write!(f, "module: {module}")
}