Skip to content

Commit

Permalink
Finish implementing Display for Def and Expr.
Browse files Browse the repository at this point in the history
Except for enums.
  • Loading branch information
Vlamonster committed Nov 11, 2023
1 parent d6212eb commit aaac4d9
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 34 deletions.
2 changes: 1 addition & 1 deletion compiler/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clap::Parser;
use compiler::compile;
use compiler::passes::parse::parse::{parse_program, PrettyParseError};
use compiler::passes::parse::parse::PrettyParseError;
use compiler::passes::validate::error::TypeError;
use miette::{Diagnostic, IntoDiagnostic};
use std::fs;
Expand Down
127 changes: 102 additions & 25 deletions compiler/src/passes/parse/display.rs
Original file line number Diff line number Diff line change
@@ -1,55 +1,132 @@
use std::fmt::{Display, Formatter};
use crate::passes::parse::{Def, Expr, Op, TypeDef};
use indenter::indented;
use itertools::Itertools;
use crate::passes::parse::{Def, Expr, Op};
use std::fmt::Write;
use std::fmt::{Display, Formatter};

impl<IdentVars: Display, IdentFields: Display, Expr: Display> Display for Def<IdentVars, IdentFields, Expr> {
impl<IdentVars: Display, IdentFields: Display, Expr: Display> Display
for Def<IdentVars, IdentFields, Expr>
{
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Def::Fn { sym, params, typ, bdy } => {
Def::Fn {
sym,
params,
typ,
bdy,
} => {
writeln!(f, "fn {sym}({}) -> {typ} {{", params.iter().format(", "))?;
writeln!(indented(f), "{bdy}")?;
writeln!(f, "}}")?;
Ok(())
}
Def::TypeDef { sym, def } => todo!(),
Def::TypeDef { sym, def } => match def {
TypeDef::Struct { fields } => {
writeln!(f, "struct {sym} {{")?;
writeln!(
indented(f),
"{}",
fields
.iter()
.map(|(sym, bnd)| format!("{sym}: {bnd},"))
.format("\n")
)?;
writeln!(f, "}}")
}
TypeDef::Enum { .. } => todo!(),
},
}
}
}

impl<IdentVars: Display, IdentFields: Display> Display for Expr<'_, IdentVars, IdentFields> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Expr::Lit { val } => write!(f, "{val}"),
Expr::Var { sym } => write!(f, "{sym}"),
Expr::Prim { op: Op::Read, ..} => write!(f, "read()"),
Expr::Prim { op: Op::Print, args} => write!(f, "print({})", args[0].inner),
Expr::Prim { op, args } if args.len() == 1 => write!(f, "({op} {})", args[0].inner),
Expr::Prim { op, args } if args.len() == 2 => write!(f, "({} {op} {})", args[0].inner, args[1].inner),
Expr::Prim { .. } => unreachable!(),
Expr::Let { sym, mutable, bnd, bdy } => {
writeln!(f, "let {}{sym} = {bnd};", if *mutable { "mut " } else { "" })?;
Expr::Lit { val } => {
write!(f, "{val}")
}
Expr::Var { sym } => {
write!(f, "{sym}")
}
Expr::Prim { op: Op::Read, .. } => {
write!(f, "read()")
}
Expr::Prim {
op: Op::Print,
args,
} => {
write!(f, "print({})", args[0].inner)
}
Expr::Prim { op, args } if args.len() == 1 => {
write!(f, "({op} {})", args[0].inner)
}
Expr::Prim { op, args } if args.len() == 2 => {
write!(f, "({} {op} {})", args[0].inner, args[1].inner)
}
Expr::Prim { .. } => {
unreachable!()
}
Expr::Let {
sym,
mutable,
bnd,
bdy,
} => {
writeln!(
f,
"let {}{sym} = {bnd};",
if *mutable { "mut " } else { "" }
)?;
write!(f, "{bdy}")
},
}
Expr::If { cnd, thn, els } => {
writeln!(f, "if {cnd} {{")?;
writeln!(indented(f), "{thn}")?;
writeln!(f, "}} else {{")?;
writeln!(indented(f), "{els}")?;
write!(f, "}}")
}
Expr::Apply { .. } => todo!(),
Expr::Loop { .. } => todo!(),
Expr::Break { .. } => todo!(),
Expr::Continue => todo!(),
Expr::Return { .. } => todo!(),
Expr::Seq { .. } => todo!(),
Expr::Assign { .. } => todo!(),
Expr::Struct { .. } => todo!(),
Expr::Apply { fun, args } => {
write!(f, "{fun}({})", args.iter().format(", "))
}
Expr::Loop { bdy } => {
writeln!(f, "loop {{")?;
writeln!(indented(f), "{bdy}")?;
write!(f, "}}")
}
Expr::Break { bdy } => {
write!(f, "break {bdy}")
}
Expr::Continue => {
write!(f, "continue")
}
Expr::Return { bdy } => {
write!(f, "return {bdy}")
}
Expr::Seq { stmt, cnt } => {
writeln!(f, "{stmt};")?;
write!(f, "{cnt}")
}
Expr::Assign { sym, bnd } => {
write!(f, "{sym} = {bnd}")
}
Expr::Struct { sym, fields } => {
writeln!(f, "{sym} {{")?;
writeln!(
indented(f),
"{}",
fields
.iter()
.map(|(sym, bnd)| format!("{sym}: {bnd},"))
.format("\n")
)?;
write!(f, "}}")
}
Expr::AccessField { strct, field } => {
write!(f, "{strct}.{field}")
}
Expr::Variant { .. } => todo!(),
Expr::AccessField { .. } => todo!(),
Expr::Switch { .. } => todo!(),
}
}
}
}
26 changes: 21 additions & 5 deletions compiler/src/passes/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@
#[rustfmt::skip]
#[allow(clippy::all, clippy::pedantic)]
mod grammar;
mod display;
pub mod interpreter;
pub mod parse;
#[cfg(test)]
mod tests;
pub mod types;
mod display;

use crate::utils::gen_sym::UniqueSym;
use derive_more::Display;
use functor_derive::Functor;
use itertools::Itertools;
use std::fmt::{Display, Formatter};
use types::Type;
use itertools::Itertools;

/// A parsed program with global definitions and an entry point.
#[derive(Display)]
#[display(fmt = "{}", r#"defs.into_iter().format("\n\n")"#)]
#[display(fmt = "{}", r#"defs.iter().format("\n")"#)]
pub struct PrgParsed<'p> {
/// The global program definitions.
pub defs: Vec<DefParsed<'p>>,
Expand Down Expand Up @@ -81,8 +81,7 @@ impl<IdentVars, IdentFields, Expr> Def<IdentVars, IdentFields, Expr> {
///
/// Parameters are generic and can use symbols that are either `&str` or
/// [`UniqueSym`](crate::utils::gen_sym::UniqueSym) for all passes after uniquify.
#[derive(Clone)]
#[derive(Display)]
#[derive(Clone, Display)]
#[display(bound = "A: Display")]
#[display(fmt = "{}{sym}: {typ}", r#"if *mutable { "mut " } else { "" }"#)]
pub struct Param<A> {
Expand Down Expand Up @@ -256,38 +255,55 @@ impl<T: Display> Display for Spanned<T> {
#[derive(Display)]
pub enum Op {
/// Read signed integer from stdin.
#[display(fmt = "")]
Read,
/// Print signed integer to stdout.
#[display(fmt = "")]
Print,
/// Integer addition.
#[display(fmt = "+")]
Plus,
/// Integer subtraction or negation.
#[display(fmt = "-")]
Minus,
/// Integer multiplication.
#[display(fmt = "*")]
Mul,
/// Integer division.
#[display(fmt = "/")]
Div,
/// Modulo operation.
#[display(fmt = "%")]
Mod,
/// Logical AND.
#[display(fmt = "&&")]
LAnd,
/// Logical OR,
#[display(fmt = "||")]
LOr,
/// Logical NOT.
#[display(fmt = "!")]
Not,
/// XOR operation.
#[display(fmt = "^")]
Xor,
/// Greater Than comparison.
#[display(fmt = ">")]
GT,
/// Greater Than or Equal To comparison.
#[display(fmt = ">=")]
GE,
/// Equality comparison. Operates on `Int` and `Bool`.
#[display(fmt = "==")]
EQ,
/// Less Than or Equal To comparison.
#[display(fmt = "<=")]
LE,
/// Less Than comparison.
#[display(fmt = "<")]
LT,
/// Inequality comparison. Operates on `Int` and `Bool`.
#[display(fmt = "!=")]
NE,
}

Expand Down
3 changes: 0 additions & 3 deletions compiler/src/passes/parse/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ fn parse([test]: [&str; 1]) {

let result = parse_program(test);

print!("{}", result.unwrap());
panic!();

match (result, expected_error) {
(Ok(_), None) => {}
(Err(error), None) => {
Expand Down

0 comments on commit aaac4d9

Please sign in to comment.