use std::{collections::HashMap, process::exit}; use clap::error::Result; use codespan_reporting::{ files::SimpleFiles, term::{ self, termcolor::{ColorChoice, StandardStream}, }, }; use crate::{ builtins::initialise_globals, error::{ErrorKind, Errors}, syntax::{ check::{self, check}, parse_syntax, PipelineElement, }, typed::into_typed_repr, }; // this is also bad // need a better architecture for this pub struct Evaluator<'a> { curr_phase: EvalPhase, files: SimpleFiles<&'a str, String>, errors: HashMap>, } impl<'a> Evaluator<'a> { pub fn init() -> Self { Self { curr_phase: EvalPhase::Lex, files: SimpleFiles::new(), errors: HashMap::new(), } } pub fn run(&mut self, input: String, name: Option<&'a str>) { let fid = self.files.add(name.unwrap_or("input"), input.clone()); let syntax = parse_syntax(&input); match syntax { Ok(syntax) => self.curr_phase = EvalPhase::Check(fid, syntax), Err(errs) => { self.errors.insert( fid, vec![Errors { kind: ErrorKind::InvalidToken, locs: errs, }], ); self.curr_phase = EvalPhase::Failed } }; } pub fn next(mut self) { match self.curr_phase { EvalPhase::Lex => { todo!() } EvalPhase::Check(file_id, syntax) => { let r = check(&syntax); if let Err(errs) = r { self.errors.insert(file_id, errs); self.curr_phase = EvalPhase::Failed; } else { self.curr_phase = EvalPhase::BareTyped(file_id, syntax.clone()) } } EvalPhase::BareTyped(file_id, syntax) => { let ns = initialise_globals(); let r = into_typed_repr(&ns, syntax); if let Err(errs) = r { self.errors.insert(file_id, vec![errs]); self.curr_phase = EvalPhase::Failed; } else { todo!() } } EvalPhase::Failed => self.error_out().unwrap(), } self.next() } pub fn error_out(self) -> Result { let Evaluator { curr_phase, files, errors, } = self; let writer = StandardStream::stderr(ColorChoice::Always); let config = term::Config::default(); for (file_id, errors) in errors.iter() { let writer = &mut writer.lock(); for error in errors { term::emit(writer, &config, &files, &error.into_diag(*file_id, &files))?; } } exit(1) } } enum EvalPhase { Lex, Check(usize, Vec), BareTyped(usize, Vec), Failed, }