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 {
|
mod convert {
|
||||||
//! Converts between major enums and enum variants
|
//! 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::*;
|
use cl_structures::span::*;
|
||||||
|
|
||||||
pub mod ast_impl;
|
pub mod ast_impl;
|
||||||
|
pub mod format;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||||
pub enum Mutability {
|
pub enum Mutability {
|
||||||
|
@ -84,7 +84,7 @@ pub mod program {
|
|||||||
env::Environment, error::IResult, interpret::Interpret, temp_type_impl::ConValue,
|
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_lexer::Lexer;
|
||||||
use cl_parser::{error::PResult, Parser};
|
use cl_parser::{error::PResult, Parser};
|
||||||
// use conlang::resolver::{error::TyResult, Resolver};
|
// use conlang::resolver::{error::TyResult, Resolver};
|
||||||
|
Loading…
Reference in New Issue
Block a user