use ariadne::{Color, Label, Report, ReportKind, sources};
use chumsky::prelude::*;
use std::{env, fs};
use grabapl::semantics::example::ExampleSemantics;
use grabapl_syntax::custom_syntax::example::MyCustomSyntax;
use grabapl_syntax::interpreter::interpret;
use grabapl_syntax::*;
fn main() {
let filename = env::args().nth(1).expect("Expected file argument");
let src = fs::read_to_string(&filename).expect("Failed to read file");
println!("Source: {src}");
let (tokens, errs) = lexer().parse(src.as_str()).into_output_errors();
println!("Tokens: {tokens:?}");
let parse_errs = if let Some(tokens) = &tokens {
let (ast, parse_errs) = program_parser::<_, MyCustomSyntax>()
.map_with(|ast, e| (ast, e.span()))
.parse(
tokens
.as_slice()
.map((src.len()..src.len()).into(), |(t, s)| (t, s)),
)
.into_output_errors();
if let Some((program, file_span)) = ast.filter(|_| errs.len() + parse_errs.len() == 0) {
println!("Parsed: {program:#?}");
println!("interpreting...");
let (op_ctx, fns_to_ids) = interpret::<ExampleSemantics>(program)
.op_ctx_and_map
.unwrap();
let json = serde_json::to_string_pretty(&op_ctx)
.expect("Failed to serialize operation context to JSON");
println!("Operation Context: {json}");
println!("Function IDs: {fns_to_ids:#?}");
}
parse_errs
} else {
Vec::new()
};
errs.into_iter()
.map(|e| e.map_token(|c| c.to_string()))
.chain(
parse_errs
.into_iter()
.map(|e| e.map_token(|tok| tok.to_string())),
)
.for_each(|e| {
Report::build(ReportKind::Error, (filename.clone(), e.span().into_range()))
.with_config(ariadne::Config::new().with_index_type(ariadne::IndexType::Byte))
.with_message(e.to_string())
.with_label(
Label::new((filename.clone(), e.span().into_range()))
.with_message(e.reason().to_string())
.with_color(Color::Red),
)
.with_labels(e.contexts().map(|(label, span)| {
Label::new((filename.clone(), span.into_range()))
.with_message(format!("while parsing this {label}"))
.with_color(Color::Yellow)
}))
.finish()
.print(sources([(filename.clone(), src.clone())]))
.unwrap()
});
}