ast: fn main, structification

parser: unified post/infix, context-full grammar
repl: modes
This commit is contained in:
2025-09-21 02:57:20 -04:00
parent 434fa225e7
commit 8640ec4261
4 changed files with 342 additions and 151 deletions

View File

@@ -1,4 +1,8 @@
//! Tests the lexer
use doughlang::{
ast::{Anno, Pat},
parser::PPrec,
};
#[allow(unused_imports)]
use doughlang::{
ast::{
@@ -25,7 +29,19 @@ fn main() -> Result<(), Box<dyn Error>> {
print!("\x1b[H\x1b[2J");
Ok(Response::Deny)
}
"lex" => {
lex()?;
Ok(Response::Deny)
}
"expr" => {
exprs()?;
Ok(Response::Deny)
}
"pat" => {
pats()?;
Ok(Response::Deny)
}
"macro" => {
if let Err(e) = subst() {
println!("\x1b[31m{e}\x1b[0m");
}
@@ -38,28 +54,79 @@ fn main() -> Result<(), Box<dyn Error>> {
})?;
} else {
let doc = std::io::read_to_string(stdin())?;
lex(&doc);
// lex(&doc);
parse(&doc);
}
Ok(())
}
fn lex(document: &str) {
let mut lexer = Lexer::new(document);
loop {
match lexer.scan() {
Ok(Token { lexeme, kind, span: Span { head, tail } }) => {
println!(
fn lex() -> Result<(), Box<dyn Error>> {
read_and("\x1b[93m", " >", "?>", |line| {
let mut lexer = Lexer::new(line);
if line.trim().is_empty() {
return Ok(Response::Break);
}
loop {
match lexer.scan() {
Err(LexError { res: "EOF", .. }) => {
break Ok(Response::Accept);
}
Err(e) => {
println!("\x1b[31m{e}\x1b[0m");
break Ok(Response::Deny);
}
Ok(Token { lexeme, kind, span: Span { head, tail } }) => println!(
"{kind:?}\x1b[11G {head:<4} {tail:<4} {}",
lexeme.escape_debug()
)
}
Err(e) => {
eprintln!("{e}");
break;
),
}
}
}
})?;
Ok(())
}
fn exprs() -> Result<(), Box<dyn Error>> {
read_and("\x1b[93m", " >", "?>", |line| {
let mut parser = Parser::new(Lexer::new(line));
if line.trim().is_empty() {
return Ok(Response::Break);
}
loop {
match parser.parse::<Anno<Expr>>(0) {
Err(ParseError::FromLexer(LexError { res: "EOF", .. })) => {
break Ok(Response::Accept);
}
Err(e) => {
println!("\x1b[31m{e}\x1b[0m");
break Ok(Response::Deny);
}
Ok(v) => println!("{v}\n{v:#?}"),
}
}
})?;
Ok(())
}
fn pats() -> Result<(), Box<dyn Error>> {
read_and("\x1b[94m", " >", "?>", |line| {
let mut parser = Parser::new(Lexer::new(line));
if line.trim().is_empty() {
return Ok(Response::Break);
}
loop {
match parser.parse::<Pat>(PPrec::Max) {
Err(ParseError::FromLexer(LexError { res: "EOF", .. })) => {
break Ok(Response::Accept);
}
Err(e) => {
println!("\x1b[31m{e}\x1b[0m");
break Ok(Response::Deny);
}
Ok(v) => println!("{v}\n{v:#?}"),
}
}
})?;
Ok(())
}
fn subst() -> Result<(), Box<dyn Error>> {