From 8b21acac9e88c4eb3206afe9589c79b623fa949c Mon Sep 17 00:00:00 2001 From: Joscha Date: Mon, 21 Nov 2022 09:32:07 +0100 Subject: [PATCH] Add desugar command and desugar programs --- src/ast/basic.rs | 9 ++++++++ src/desugar.rs | 1 + src/desugar/program.rs | 48 ++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 42 +++++++++++++++++++++++++----------- src/pretty.rs | 10 +++++++++ src/span.rs | 8 +++++++ 6 files changed, 106 insertions(+), 12 deletions(-) create mode 100644 src/desugar.rs create mode 100644 src/desugar/program.rs diff --git a/src/ast/basic.rs b/src/ast/basic.rs index 33562f2..49d867f 100644 --- a/src/ast/basic.rs +++ b/src/ast/basic.rs @@ -30,6 +30,15 @@ impl HasSpan for Space { } } +impl Space { + pub fn empty(span: Span) -> Self { + Self { + lines: vec![], + span, + } + } +} + #[derive(Clone)] pub struct Ident { pub name: String, diff --git a/src/desugar.rs b/src/desugar.rs new file mode 100644 index 0000000..3847c62 --- /dev/null +++ b/src/desugar.rs @@ -0,0 +1 @@ +mod program; diff --git a/src/desugar/program.rs b/src/desugar/program.rs new file mode 100644 index 0000000..d97a6e0 --- /dev/null +++ b/src/desugar/program.rs @@ -0,0 +1,48 @@ +use crate::ast::{Expr, Lit, Program, Space, TableLit}; +use crate::span::HasSpan; + +impl Program { + pub fn desugar(self) -> (Self, bool) { + match self { + Self::Expr { s0, expr, s1, span } => { + let (expr, desugared) = (expr, false); // TODO Implement + (Self::Expr { s0, expr, s1, span }, desugared) + } + + Self::Module { + s0, + s1, + elems, + s2, + span, + } => { + let (elems, desugared) = (elems, false); // TODO Implement + if desugared { + let new = Self::Module { + s0, + s1, + elems, + s2, + span, + }; + (new, true) + } else { + let elems_span = elems.span(); + let table = TableLit { + s0: s1, + elems, + s1: Space::empty(elems_span.at_end()), + span: elems_span, + }; + let new = Self::Expr { + s0, + expr: Expr::Lit(Lit::Table(table)), + s1: s2, + span, + }; + (new, true) + } + } + } + } +} diff --git a/src/main.rs b/src/main.rs index 90cc696..0192a59 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,12 +17,13 @@ use std::fs; use std::path::PathBuf; -use ::pretty::{Pretty, RcAllocator}; +use anyhow::anyhow; use chumsky::Parser as _; use clap::Parser; mod ast; mod builtin; +mod desugar; mod parser; mod pretty; mod span; @@ -33,6 +34,7 @@ mod value; enum Command { Parse { file: PathBuf }, Pretty { file: PathBuf }, + Desugar { file: PathBuf }, } #[derive(Parser)] @@ -59,21 +61,37 @@ fn main() -> anyhow::Result<()> { } } } + Command::Pretty { file } => { let content = fs::read_to_string(&file)?; let stream = span::stream_from_str(&content); - match parser::parser().parse(stream) { - Ok(program) => { - let mut out = vec![]; - program.pretty(&RcAllocator).render(100, &mut out)?; - println!("{}", String::from_utf8(out)?); - } - Err(errs) => { - eprintln!("Parsing failed"); - for err in errs { - eprintln!("{err:?}"); - } + let program = parser::parser() + .parse(stream) + .map_err(|e| anyhow!("{e:?}"))?; + + println!("{}", pretty::pretty_to_string(program, 100)); + } + + Command::Desugar { file } => { + let content = fs::read_to_string(&file)?; + let stream = span::stream_from_str(&content); + let mut program = parser::parser() + .parse(stream) + .map_err(|e| anyhow!("{e:?}"))?; + + println!("{}", pretty::pretty_to_string(program.clone(), 100)); + + loop { + let (new_program, desugared) = program.desugar(); + program = new_program; + if !desugared { + break; } + + println!(); + println!("================================================================================"); + println!(); + println!("{}", pretty::pretty_to_string(program.clone(), 100)); } } } diff --git a/src/pretty.rs b/src/pretty.rs index e15aa53..20844f6 100644 --- a/src/pretty.rs +++ b/src/pretty.rs @@ -1,3 +1,5 @@ +use pretty::{Pretty, RcAllocator}; + mod basic; mod call; mod expr; @@ -10,3 +12,11 @@ mod table_destr; mod var; const NEST_DEPTH: isize = 4; + +pub fn pretty_to_string>(p: P, width: usize) -> String { + let mut out = vec![]; + p.pretty(&RcAllocator) + .render(width, &mut out) + .expect("p could not be rendered"); + String::from_utf8(out).expect("p created non-utf8 string") +} diff --git a/src/span.rs b/src/span.rs index 296f992..42cf32c 100644 --- a/src/span.rs +++ b/src/span.rs @@ -24,6 +24,14 @@ impl Span { let end = self.end.max(other.end); Self::new(start, end) } + + pub fn at_start(self) -> Self { + Self::new(self.start, self.start) + } + + pub fn at_end(self) -> Self { + Self::new(self.end, self.end) + } } impl fmt::Debug for Span {