new thing compiles

This commit is contained in:
greg 2018-03-20 20:29:07 -07:00
parent de073a6d9b
commit 6fcc7ded59
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)] #[derive(Debug, Default, Serialize, Deserialize)]
pub struct EvalOptions { pub struct EvalOptions {
pub debug: DebugOptions,
pub execution_method: ExecutionMethod
/*
pub debug_tokens: bool, pub debug_tokens: bool,
pub debug_parse: bool, pub debug_parse: bool,
pub debug_type: bool, pub debug_type: bool,
@ -14,6 +17,28 @@ pub struct EvalOptions {
pub show_llvm_ir: bool, pub show_llvm_ir: bool,
pub trace_evaluation: bool, pub trace_evaluation: bool,
pub compile: 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)] #[derive(Debug, Default)]
@ -76,22 +101,19 @@ impl UnfinishedComputation {
} }
impl FinishedComputation { impl FinishedComputation {
pub fn to_string(&self) -> String { pub fn to_repl(&self) -> String {
match self.text_output { match self.text_output {
Ok(ref s) => s.clone(), Ok(ref s) => s.clone(),
Err(ref s) => format!("Error: {}", s) 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)] #[derive(Debug)]
pub struct TraceArtifact { pub struct TraceArtifact {
@ -124,14 +146,17 @@ impl TraceArtifact {
} }
pub trait ProgrammingLanguageInterface { pub trait ProgrammingLanguageInterface {
/* old */
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 } LanguageOutput { output: format!("Defunct"), artifacts: vec![], failed: false }
} }
fn evaluate_noninteractive(&mut self, input: &str, eval_options: &EvalOptions) -> LanguageOutput { fn evaluate_noninteractive(&mut self, input: &str, eval_options: &EvalOptions) -> LanguageOutput {
self.evaluate_in_repl(input, eval_options) 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")) } FinishedComputation { artifacts: HashMap::new(), text_output: Err(format!("REPL evaluation not implemented")) }
} }
fn get_language_name(&self) -> String; fn get_language_name(&self) -> String;

View File

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

View File

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

View File

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