1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
//! Code formatting for SML.
//!
//! This is intended for use internally within `pomelo`.
//! Beware, this currently discards comments. Not suitable for real code!
//!
//! This is intended to format the pretty-printed HIR, which is itself valid SML.
//! Currently, only dealing with the Core language, as [`pomelo_parse`](../pomelo_parse/index.html)
//! does not know how to handle modules.
//!
//! # Status
//!
//! - [x] format expressions (mostly done)
//! - [ ] format patterns
//! - [ ] format declarations
//! - [ ] format types
//! - [ ] deal with comments and other trivia.. maybe need to do a better job of attaching trivia to nodes in parsing?
//!
//! # Resources
//!
//! - ["Prettyprinting"](https://dl.acm.org/doi/pdf/10.1145/357114.357115), Derek C. Oppen (1980)
//!
//! - ["A prettier printer"](https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf), Phillip Wadler (2003)
//!
//! - ["Pretty Printing with Lazy Dequeues"](https://dl.acm.org/doi/pdf/10.1145/1053468.1053473), Olaf Chitil
//! (2005)
//!
//! - [`prettyplease`](https://github.com/dtolnay/prettyplease), an implementation of Oppen's algorithm in Rust by
//! David Tolnay
//!
//! The code here is based on the imperative algorithm from the Oppen paper.
//! The other papers give pure functional versions of the pretty printing algorithm -- I found
//! those a bit easier to understand than the Oppen paper but the imperative algorithm should be
//! easier to implement efficiently in Rust.
//!
//! David Tolnay's `prettyplease` crate is a nice implementation of Oppen's algorithm in Rust.
//! I mainly worked off of the description in Oppen's paper, but I peeked at `prettyplease`
//! a couple of times to help iron out some of the bugs in my implementation.
mod buffer;
mod printer;
use crate::printer::Printer;
mod dec;
mod expr;
mod pat;
mod ty;
mod util;
#[cfg(test)]
mod tests;
use pomelo_parse::{ast, AstNode, SyntaxTree};
const INDENT: isize = 2;
/// Pretty print the AST.
pub fn print(ast: SyntaxTree) -> String {
// TODO: handle errors
let _errors = ast.errors().cloned();
let node = ast::File::cast(ast.syntax()).unwrap();
let mut output = String::new();
for dec in node.declarations() {
output.push_str(&dec::print_dec(&dec));
}
output
}
trait Printable {
fn print(&self, printer: &mut Printer) -> Option<()>;
}