Start building out type inference.

This commit is contained in:
2023-06-21 21:56:54 -07:00
parent 3687785540
commit 1ad3d6c517
14 changed files with 1286 additions and 305 deletions

View File

@@ -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(())
}
}