new thing compiles

This commit is contained in:
greg 2018-03-20 20:29:07 -07:00
parent 9f2fbda31f
commit 43ade31f3e
4 changed files with 61 additions and 40 deletions

View File

@ -7,6 +7,9 @@ pub struct LLVMCodeString(pub String);
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct EvalOptions {
pub debug: DebugOptions,
pub execution_method: ExecutionMethod
/*
pub debug_tokens: bool,
pub debug_parse: bool,
pub debug_type: bool,
@ -14,6 +17,28 @@ pub struct EvalOptions {
pub show_llvm_ir: bool,
pub trace_evaluation: bool,
pub compile: bool,
*/
}
#[derive(Debug, Serialize, Deserialize)]
pub enum ExecutionMethod {
Compile,
Interpret,
}
impl Default for ExecutionMethod {
fn default() -> ExecutionMethod {
ExecutionMethod::Interpret
}
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct DebugOptions {
pub tokens: bool,
pub parse_tree: bool,
pub ast: bool,
pub type_checking: bool,
pub symbol_table: bool,
pub evaluation: bool,
pub llvm_ir: bool,
}
#[derive(Debug, Default)]
@ -76,23 +101,20 @@ impl UnfinishedComputation {
}
impl FinishedComputation {
pub fn to_string(&self) -> String {
pub fn to_repl(&self) -> String {
match self.text_output {
Ok(ref s) => s.clone(),
Err(ref s) => format!("Error: {}", s)
}
}
pub fn to_noninteractive(&self) -> Option<String> {
match self.text_output {
Ok(ref s) => None,
Err(ref s) => Some(format!("Error: {}", s)),
}
}
}
/*
//TODO I'll probably wanna implement this later
#[derive(Debug)]
pub struct CompilationOutput {
output: LLVMCodeString,
artifacts: Vec<TraceArtifact>,
}
*/
#[derive(Debug)]
pub struct TraceArtifact {
stage_name: String,
@ -124,14 +146,17 @@ impl TraceArtifact {
}
pub trait ProgrammingLanguageInterface {
/* old */
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)
}
/* old */
fn repl_evaluate(&mut self, input: &str, eval_options: &EvalOptions) -> FinishedComputation {
fn execute(&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;

View File

@ -5,6 +5,7 @@
extern crate getopts;
extern crate rustyline;
extern crate itertools;
#[macro_use]
extern crate lazy_static;
#[macro_use]
@ -32,7 +33,7 @@ pub mod llvm_wrap;
include!(concat!(env!("OUT_DIR"), "/static.rs"));
pub use language::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput, LLVMCodeString, FinishedComputation, UnfinishedComputation};
pub use language::{ProgrammingLanguageInterface, EvalOptions, ExecutionMethod, TraceArtifact, LanguageOutput, LLVMCodeString, FinishedComputation, UnfinishedComputation};
pub type PLIGenerator = Box<Fn() -> Box<ProgrammingLanguageInterface> + Send + Sync>;
pub fn schala_main(generators: Vec<PLIGenerator>) {
@ -67,15 +68,14 @@ pub fn schala_main(generators: Vec<PLIGenerator>) {
.unwrap_or(0);
let mut options = EvalOptions::default();
options.compile = match option_matches.opt_str("eval-style") {
Some(ref s) if s == "compile" => true,
_ => false
options.execution_method = match option_matches.opt_str("eval-style") {
Some(ref s) if s == "compile" => ExecutionMethod::Compile,
_ => ExecutionMethod::Interpret,
};
match option_matches.free[..] {
[] | [_] => {
let mut repl = Repl::new(languages, initial_index);
repl.options.show_llvm_ir = true; //TODO make this be configurable
repl.run();
}
[_, ref filename, _..] => {
@ -102,17 +102,17 @@ fn run_noninteractive(filename: &str, languages: Vec<Box<ProgrammingLanguageInte
source_file.read_to_string(&mut buffer).unwrap();
if options.compile {
if !language.can_compile() {
panic!("Trying to compile a non-compileable language");
} else {
match options.execution_method {
ExecutionMethod::Compile => {
/*
let llvm_bytecode = language.compile(&buffer);
compilation_sequence(llvm_bytecode, filename);
}
} else {
let output = language.evaluate_in_repl(&buffer, &options);
if output.failed {
println!("{}", output.to_string());
*/
panic!("Not ready to go yet");
},
ExecutionMethod::Interpret => {
let output = language.execute(&buffer, &options);
output.to_noninteractive().map(|text| println!("{}", text));
}
}
}
@ -198,8 +198,8 @@ impl Repl {
fn input_handler(&mut self, input: &str) -> String {
let ref mut language = self.languages[self.current_language_index];
let interpreter_output = language.repl_evaluate(input, &self.options);
interpreter_output.to_string()
let interpreter_output = language.execute(input, &self.options);
interpreter_output.to_repl()
}
fn handle_interpreter_directive(&mut self, input: &str) -> bool {
@ -285,14 +285,11 @@ impl Repl {
}
};
match commands.get(2) {
Some(&"tokens") => self.options.debug_tokens = show,
Some(&"parse") => self.options.debug_parse = show,
Some(&"symbols") => self.options.debug_symbol_table = show,
Some(&"eval") => {
//let ref mut language = self.languages[self.current_language_index];
//language.set_option("trace_evaluation", show);
},
Some(&"llvm") => self.options.show_llvm_ir = show,
Some(&"tokens") => self.options.debug.tokens = show,
Some(&"parse") => self.options.debug.parse_tree = show,
Some(&"ast") => self.options.debug.ast = show,
Some(&"symbols") => self.options.debug.symbol_table = show,
Some(&"llvm") => self.options.debug.llvm_ir = show,
Some(e) => {
println!("Bad `show`/`hide` argument: {}", e);
return true;

View File

@ -43,7 +43,7 @@ impl<'a> ProgrammingLanguageInterface for Maaru<'a> {
let tokens = match tokenizer::tokenize(input) {
Ok(tokens) => {
if options.debug_tokens {
if options.debug.tokens {
output.add_artifact(TraceArtifact::new("tokens", format!("{:?}", tokens)));
}
tokens
@ -56,7 +56,7 @@ impl<'a> ProgrammingLanguageInterface for Maaru<'a> {
let ast = match parser::parse(&tokens, &[]) {
Ok(ast) => {
if options.debug_parse {
if options.debug.ast {
output.add_artifact(TraceArtifact::new("ast", format!("{:?}", ast)));
}
ast

View File

@ -1,5 +1,5 @@
use itertools::Itertools;
use schala_lib::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, LanguageOutput, UnfinishedComputation, FinishedComputation};
use schala_lib::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, UnfinishedComputation, FinishedComputation};
macro_rules! bx {
($e:expr) => { Box::new($e) }
@ -12,7 +12,6 @@ mod parsing;
mod typechecking;
mod eval;
use self::typechecking::{TypeContext};
pub struct Schala {
@ -38,7 +37,7 @@ impl ProgrammingLanguageInterface for Schala {
format!("schala")
}
fn repl_evaluate(&mut self, input: &str, options: &EvalOptions) -> FinishedComputation {
fn execute(&mut self, input: &str, options: &EvalOptions) -> FinishedComputation {
let mut evaluation = UnfinishedComputation::default();
//tokenzing