Mycelium/decomposer/src/main.rs
Ava Affine e4c6e0924a Decomposer: fixes from found code
This commit includes a new utility, the decomposer, which has
primarily been used to test the AST against found scheme code in
the wild (internet). Decomposer will time and test the lexing and
parsing of any document full of scheme.

This commit includes additional test cases and logical fixes for
issues found during the testing performed.

Signed-off-by: Ava Affine <ava@sunnypup.io>
2025-05-21 14:48:36 -07:00

81 lines
2.1 KiB
Rust

/* Mycelium Scheme
* Copyright (C) 2025 Ava Affine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#![feature(iter_collect_into)]
use mycelium::{lexer as l, parser as p};
use std::rc::Rc;
use std::path::PathBuf;
use std::fs;
use std::error::Error;
use std::time::Instant;
use clap::Parser;
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
/// display time to parse scripts
#[arg(short, long)]
time: bool,
/// output script AST once parsed
#[arg(short, long)]
debug: bool,
scripts: Vec<PathBuf>,
}
fn main() -> Result<(), Box<dyn Error>> {
let args = Args::parse();
for script in args.scripts {
println!("+ processing {:#?}", script);
let message = fs::read_to_string(script)?;
let start: Option<Instant>;
if args.time {
start = Some(Instant::now());
} else {
start = None;
}
let mut p = p::Parser::from(l::Lexer::from(Rc::from(message.as_str())));
let mut i = p.next();
while let Some(ref r) = i {
if args.debug {
println!(" > res: {}", r);
}
i = p.next();
}
if let Some(i) = start {
println!(" > time: {:#?}", i.elapsed());
}
if p.has_error_state.is_some() {
let e = p.has_error_state.unwrap();
if e.0 != l::E_END_OF_DOCUMENT {
println!(" > error!\n{}", e);
}
}
}
Ok(())
}