Start building out type inference.
This commit is contained in:
76
src/repl.rs
76
src/repl.rs
@@ -1,4 +1,5 @@
|
||||
use crate::backend::{Backend, BackendError};
|
||||
use crate::ir::TypeInferenceResult;
|
||||
use crate::syntax::{ConstantType, Location, ParserError, Statement};
|
||||
use codespan_reporting::diagnostic::Diagnostic;
|
||||
use codespan_reporting::files::SimpleFiles;
|
||||
@@ -128,18 +129,32 @@ impl REPL {
|
||||
.source();
|
||||
let syntax = Statement::parse(entry, source)?;
|
||||
|
||||
// if this is a variable binding, and we've never defined this variable before,
|
||||
// we should tell cranelift about it. this is optimistic; if we fail to compile,
|
||||
// then we won't use this definition until someone tries again.
|
||||
if let Statement::Binding(_, ref name, _) = syntax {
|
||||
if !self.variable_binding_sites.contains_key(name.as_str()) {
|
||||
self.jitter.define_string(name)?;
|
||||
self.jitter
|
||||
.define_variable(name.clone(), ConstantType::U64)?;
|
||||
let program = match syntax {
|
||||
Statement::Binding(loc, name, expr) => {
|
||||
// if this is a variable binding, and we've never defined this variable before,
|
||||
// we should tell cranelift about it. this is optimistic; if we fail to compile,
|
||||
// then we won't use this definition until someone tries again.
|
||||
if !self.variable_binding_sites.contains_key(&name) {
|
||||
self.jitter.define_string(&name)?;
|
||||
self.jitter
|
||||
.define_variable(name.clone(), ConstantType::U64)?;
|
||||
}
|
||||
|
||||
crate::syntax::Program {
|
||||
statements: vec![
|
||||
Statement::Binding(loc.clone(), name.clone(), expr),
|
||||
Statement::Print(loc, name),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
nonbinding => crate::syntax::Program {
|
||||
statements: vec![nonbinding],
|
||||
},
|
||||
};
|
||||
|
||||
let (mut errors, mut warnings) = syntax.validate(&mut self.variable_binding_sites);
|
||||
let (mut errors, mut warnings) =
|
||||
program.validate_with_bindings(&mut self.variable_binding_sites);
|
||||
let stop = !errors.is_empty();
|
||||
let messages = errors
|
||||
.drain(..)
|
||||
@@ -154,16 +169,39 @@ impl REPL {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let ir = crate::syntax::Program {
|
||||
statements: vec![syntax],
|
||||
match program.type_infer() {
|
||||
TypeInferenceResult::Failure {
|
||||
mut errors,
|
||||
mut warnings,
|
||||
} => {
|
||||
let messages = errors
|
||||
.drain(..)
|
||||
.map(Into::into)
|
||||
.chain(warnings.drain(..).map(Into::into));
|
||||
|
||||
for message in messages {
|
||||
self.emit_diagnostic(message)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
TypeInferenceResult::Success {
|
||||
result,
|
||||
mut warnings,
|
||||
} => {
|
||||
for message in warnings.drain(..).map(Into::into) {
|
||||
self.emit_diagnostic(message)?;
|
||||
}
|
||||
let name = format!("line{}", line_no);
|
||||
let function_id = self.jitter.compile_function(&name, result)?;
|
||||
self.jitter.module.finalize_definitions()?;
|
||||
let compiled_bytes = self.jitter.bytes(function_id);
|
||||
let compiled_function =
|
||||
unsafe { std::mem::transmute::<_, fn() -> ()>(compiled_bytes) };
|
||||
compiled_function();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
.type_infer();
|
||||
let name = format!("line{}", line_no);
|
||||
let function_id = self.jitter.compile_function(&name, ir)?;
|
||||
self.jitter.module.finalize_definitions()?;
|
||||
let compiled_bytes = self.jitter.bytes(function_id);
|
||||
let compiled_function = unsafe { std::mem::transmute::<_, fn() -> ()>(compiled_bytes) };
|
||||
compiled_function();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user