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>
This commit is contained in:
parent
86f905ba1d
commit
e4c6e0924a
7 changed files with 417 additions and 40 deletions
9
decomposer/Cargo.toml
Normal file
9
decomposer/Cargo.toml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "decomposer"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Ava Affine <ava@sunnypup.io>"]
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.38", features = [ "derive" ] }
|
||||
mycelium = { path = "../mycelium" }
|
||||
81
decomposer/src/main.rs
Normal file
81
decomposer/src/main.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/* 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(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue