diff --git a/schala-lib/src/language.rs b/schala-lib/src/language.rs index 6e84f03..6c9e531 100644 --- a/schala-lib/src/language.rs +++ b/schala-lib/src/language.rs @@ -75,6 +75,15 @@ impl UnfinishedComputation { } } +impl FinishedComputation { + pub fn to_string(&self) -> String { + match self.text_output { + Ok(ref s) => s.clone(), + Err(ref s) => format!("Error: {}", s) + } + } +} + /* //TODO I'll probably wanna implement this later #[derive(Debug)] @@ -115,10 +124,16 @@ impl TraceArtifact { } pub trait ProgrammingLanguageInterface { - fn evaluate_in_repl(&mut self, input: &str, eval_options: &EvalOptions) -> LanguageOutput; + fn evaluate_in_repl(&mut self, input: &str, eval_options: &EvalOptions) -> LanguageOutput { + LanguageOutput { output: format!("Defunct"), artifacts: vec![], failed: false } + } fn evaluate_noninteractive(&mut self, input: &str, eval_options: &EvalOptions) -> LanguageOutput { self.evaluate_in_repl(input, eval_options) } + + fn repl_evaluate(&mut self, input: &str, eval_options: &EvalOptions) -> FinishedComputation { + FinishedComputation { artifacts: HashMap::new(), text_output: Err(format!("REPL evaluation not implemented")) } + } fn get_language_name(&self) -> String; fn get_source_file_suffix(&self) -> String; fn compile(&mut self, _input: &str) -> LLVMCodeString { diff --git a/schala-lib/src/lib.rs b/schala-lib/src/lib.rs index 899822a..f41436b 100644 --- a/schala-lib/src/lib.rs +++ b/schala-lib/src/lib.rs @@ -32,7 +32,7 @@ pub mod llvm_wrap; include!(concat!(env!("OUT_DIR"), "/static.rs")); -pub use language::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput, LLVMCodeString}; +pub use language::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput, LLVMCodeString, FinishedComputation, UnfinishedComputation}; pub type PLIGenerator = Box Box + Send + Sync>; pub fn schala_main(generators: Vec) { @@ -198,7 +198,7 @@ impl Repl { fn input_handler(&mut self, input: &str) -> String { let ref mut language = self.languages[self.current_language_index]; - let interpreter_output = language.evaluate_in_repl(input, &self.options); + let interpreter_output = language.repl_evaluate(input, &self.options); interpreter_output.to_string() } diff --git a/src/schala_lang/mod.rs b/src/schala_lang/mod.rs index bdaa70a..0392559 100644 --- a/src/schala_lang/mod.rs +++ b/src/schala_lang/mod.rs @@ -1,5 +1,5 @@ use itertools::Itertools; -use schala_lib::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput}; +use schala_lib::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput, UnfinishedComputation, FinishedComputation}; macro_rules! bx { ($e:expr) => { Box::new($e) } @@ -12,6 +12,7 @@ mod parsing; mod typechecking; mod eval; + use self::typechecking::{TypeContext}; pub struct Schala { @@ -37,68 +38,54 @@ impl ProgrammingLanguageInterface for Schala { format!("schala") } - fn evaluate_in_repl(&mut self, input: &str, options: &EvalOptions) -> LanguageOutput { - let mut output = LanguageOutput::default(); + fn repl_evaluate(&mut self, input: &str, options: &EvalOptions) -> FinishedComputation { + let mut evaluation = UnfinishedComputation::default(); + + //tokenzing let tokens = tokenizing::tokenize(input); - if options.debug_tokens { - let token_string = tokens.iter().map(|t| format!("{:?}", t.token_type, t.offset.0, t.offset.1)).join(", "); - output.add_artifact(TraceArtifact::new("tokens", format!("{:?}", token_string))); - } + let token_string = tokens.iter().map(|t| format!("{:?}", t.token_type, t.offset.0, t.offset.1)).join(", "); + evaluation.add_artifact(TraceArtifact::new("tokens", token_string)); { let token_errors: Vec<&String> = tokens.iter().filter_map(|t| t.get_error()).collect(); if token_errors.len() != 0 { - output.add_output(format!("Tokenization error: {:?}\n", token_errors)); - output.failed = true; - return output; + return evaluation.output(Err(format!("Tokenization error: {:?}\n", token_errors))); } } + // parsing let ast = match parsing::parse(tokens) { (Ok(ast), trace) => { - if options.debug_parse { - output.add_artifact(TraceArtifact::new_parse_trace(trace)); - output.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast))); - } + evaluation.add_artifact(TraceArtifact::new_parse_trace(trace)); + evaluation.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast))); ast }, (Err(err), trace) => { - output.add_artifact(TraceArtifact::new_parse_trace(trace)); - output.add_output(format!("Parse error: {:?}\n", err.msg)); - output.failed = true; - return output; + evaluation.add_artifact(TraceArtifact::new_parse_trace(trace)); + return evaluation.output(Err(format!("Parse error: {:?}\n", err.msg))); } }; + + //symbol table match self.type_context.add_top_level_types(&ast) { Ok(()) => (), Err(msg) => { - output.add_artifact(TraceArtifact::new("type_check", msg)); - //return output + evaluation.add_artifact(TraceArtifact::new("type_check", msg)); } }; - if options.debug_symbol_table { - let text = self.type_context.debug_symbol_table(); - output.add_artifact(TraceArtifact::new("symbol_table", text)); - } - + //typechecking match self.type_context.type_check_ast(&ast) { - Ok(ty) => { - output.add_artifact(TraceArtifact::new("type_check", format!("{:?}", ty))); - }, - Err(msg) => { - output.add_artifact(TraceArtifact::new("type_check", msg)); - /* - output.add_output(format!("Type error")); - return output; - */ - } - } + Ok(ty) => evaluation.add_artifact(TraceArtifact::new("type_check", format!("{:?}", ty))), + Err(msg) => evaluation.add_artifact(TraceArtifact::new("type_check", msg)), + }; + + let text = self.type_context.debug_symbol_table(); + evaluation.add_artifact(TraceArtifact::new("symbol_table", text)); let evaluation_outputs = self.state.evaluate(ast); let text_output: String = evaluation_outputs.into_iter().intersperse(format!("\n")).collect(); - output.add_output(text_output); - return output; + evaluation.output(Ok(text_output)) } }