Add desugar command and desugar programs

This commit is contained in:
Joscha 2022-11-21 09:32:07 +01:00
parent 6eee1ba930
commit 8b21acac9e
6 changed files with 106 additions and 12 deletions

View file

@ -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,

1
src/desugar.rs Normal file
View file

@ -0,0 +1 @@
mod program;

48
src/desugar/program.rs Normal file
View file

@ -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)
}
}
}
}
}

View file

@ -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));
}
}
}

View file

@ -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: Pretty<'static, RcAllocator>>(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")
}

View file

@ -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 {