cl-ast: Move matched brace indenter out of ast_impl (it doesn't impl the ast)
This commit is contained in:
parent
276f0b1031
commit
1eec1b06ce
@ -563,106 +563,6 @@ mod display {
|
||||
}
|
||||
}
|
||||
|
||||
pub mod format {
|
||||
//! Code formatting for the [AST](super::super)
|
||||
|
||||
use std::{
|
||||
io::{Result, Write as IoWrite},
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
/// Trait which adds a function to [Writers](IoWrite) to turn them into [Prettifier]
|
||||
pub trait Pretty {
|
||||
/// Indents code according to the number of matched curly braces
|
||||
fn pretty(self) -> Prettifier<'static, Self>
|
||||
where Self: IoWrite + Sized;
|
||||
}
|
||||
impl<W: IoWrite> Pretty for W {
|
||||
fn pretty(self) -> Prettifier<'static, Self>
|
||||
where Self: IoWrite + Sized {
|
||||
Prettifier::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Prettifier<'i, T: IoWrite> {
|
||||
level: isize,
|
||||
indent: &'i str,
|
||||
writer: T,
|
||||
}
|
||||
impl<'i, W: IoWrite> 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 }
|
||||
}
|
||||
pub fn indent<'scope>(&'scope mut self) -> Indent<'scope, 'i, W> {
|
||||
Indent::new(self)
|
||||
}
|
||||
fn write_indentation(&mut self) -> Result<usize> {
|
||||
let Self { level, indent, writer } = self;
|
||||
let mut count = 0;
|
||||
for _ in 0..*level {
|
||||
count += writer.write(indent.as_bytes())?;
|
||||
}
|
||||
Ok(count)
|
||||
}
|
||||
}
|
||||
impl<W: IoWrite> From<W> for Prettifier<'static, W> {
|
||||
fn from(value: W) -> Self {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
||||
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.write_indentation()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(size)
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> std::io::Result<()> {
|
||||
self.writer.flush()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Indent<'scope, 'i, T: IoWrite> {
|
||||
formatter: &'scope mut Prettifier<'i, T>,
|
||||
}
|
||||
impl<'s, 'i, T: IoWrite> Indent<'s, 'i, T> {
|
||||
pub fn new(formatter: &'s mut Prettifier<'i, T>) -> Self {
|
||||
formatter.level += 1;
|
||||
Self { formatter }
|
||||
}
|
||||
}
|
||||
impl<'s, 'i, T: IoWrite> Deref for Indent<'s, 'i, T> {
|
||||
type Target = Prettifier<'i, T>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.formatter
|
||||
}
|
||||
}
|
||||
impl<'s, 'i, T: IoWrite> DerefMut for Indent<'s, 'i, T> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.formatter
|
||||
}
|
||||
}
|
||||
impl<'s, 'i, T: IoWrite> Drop for Indent<'s, 'i, T> {
|
||||
fn drop(&mut self) {
|
||||
self.formatter.level -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod convert {
|
||||
//! Converts between major enums and enum variants
|
||||
|
106
cl-ast/src/format.rs
Normal file
106
cl-ast/src/format.rs
Normal file
@ -0,0 +1,106 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
/// 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)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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,
|
||||
}
|
||||
|
||||
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,
|
||||
_ => (),
|
||||
}
|
||||
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()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@
|
||||
use cl_structures::span::*;
|
||||
|
||||
pub mod ast_impl;
|
||||
pub mod format;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
pub enum Mutability {
|
||||
|
@ -84,7 +84,7 @@ pub mod program {
|
||||
env::Environment, error::IResult, interpret::Interpret, temp_type_impl::ConValue,
|
||||
};
|
||||
|
||||
use cl_ast::{self as ast, ast_impl::format::Pretty};
|
||||
use cl_ast::{self as ast, format::*};
|
||||
use cl_lexer::Lexer;
|
||||
use cl_parser::{error::PResult, Parser};
|
||||
// use conlang::resolver::{error::TyResult, Resolver};
|
||||
|
Loading…
Reference in New Issue
Block a user