cl-ast: Add Fold and Visit traits, to more easily map or collect nodes in the AST

typeck.rs: Since this is apparently my testbed now, add a new mode.
TODO: replace the main `conlang` binary with this, since it's so much better.
This commit is contained in:
2024-04-19 03:21:07 -05:00
parent de024b6cb7
commit 01ffdb67a6
9 changed files with 998 additions and 3 deletions

View File

@@ -1,3 +1,7 @@
use cl_ast::{
ast_visitor::fold::Fold,
desugar::{squash_groups::SquashGroups, while_else::WhileElseDesugar},
};
use cl_lexer::Lexer;
use cl_parser::Parser;
use cl_repl::repline::{error::Error as RlError, Repline};
@@ -33,6 +37,7 @@ fn main() -> Result<(), Box<dyn Error>> {
Err(e)?
}
};
unsafe { TREES.push(code) }.collect_in_root(&mut prj)?;
main_menu(&mut prj)
@@ -81,6 +86,7 @@ fn main_menu(prj: &mut Project) -> Result<(), Box<dyn Error>> {
"l" | "list" => list_types(prj),
"q" | "query" => query_type_expression(prj),
"r" | "resolve" => resolve_all(prj),
"d" | "desugar" => live_desugar(),
"h" | "help" => {
println!(
"Valid commands are:
@@ -88,6 +94,7 @@ fn main_menu(prj: &mut Project) -> Result<(), Box<dyn Error>> {
list (l): List all known types
query (q): Query the type system
resolve (r): Perform type resolution
desugar (d): WIP: Test the experimental desugaring passes
help (h): Print this list
exit (e): Exit the program"
);
@@ -105,7 +112,7 @@ fn enter_code(prj: &mut Project) -> Result<(), Box<dyn Error>> {
return Ok(Response::Break);
}
let code = Parser::new(Lexer::new(line)).file()?;
let code = WhileElseDesugar.fold_file(code);
// Safety: this is totally unsafe
unsafe { TREES.push(code) }.collect_in_root(prj)?;
@@ -113,6 +120,21 @@ fn enter_code(prj: &mut Project) -> Result<(), Box<dyn Error>> {
})
}
fn live_desugar() -> Result<(), Box<dyn Error>> {
read_and(C_RESV, "se>", |line| {
let code = Parser::new(Lexer::new(line)).stmt()?;
println!("Raw, as parsed:\n{C_LISTING}{code}\x1b[0m");
let code = SquashGroups.fold_stmt(code);
println!("SquashGroups\n{C_LISTING}{code}\x1b[0m");
let code = WhileElseDesugar.fold_stmt(code);
println!("WhileElseDesugar\n{C_LISTING}{code}\x1b[0m");
Ok(Response::Accept)
})
}
fn query_type_expression(prj: &mut Project) -> Result<(), Box<dyn Error>> {
read_and(C_RESV, "ty>", |line| {
if line.trim().is_empty() {

View File

@@ -112,10 +112,16 @@ pub mod program {
self.parse_file().or_else(|_| self.parse_stmt())
}
pub fn parse_stmt(&self) -> PResult<Program<'t, Parsed>> {
Ok(Program { data: Parsed::Stmt(Parser::new(self.lex()).stmt()?), text: self.text })
let stmt = Parser::new(self.lex()).stmt()?;
// let stmt = WhileElseDesugar.fold_stmt(stmt);
Ok(Program { data: Parsed::Stmt(stmt), text: self.text })
}
pub fn parse_file(&self) -> PResult<Program<'t, Parsed>> {
Ok(Program { data: Parsed::File(Parser::new(self.lex()).file()?), text: self.text })
let file = Parser::new(self.lex()).file()?;
// let file = WhileElseDesugar.fold_file(file);
Ok(Program { data: Parsed::File(file), text: self.text })
}
}