wip: anyone know how to write a type checker?
This commit is contained in:
parent
9675e7fff5
commit
de99800349
4 changed files with 59 additions and 7 deletions
|
@ -4,7 +4,6 @@ use crate::source::Source;
|
|||
use crate::span::Span;
|
||||
use miette::Diagnostic;
|
||||
use std::io::Error as IoError;
|
||||
use std::num::{ParseFloatError, ParseIntError};
|
||||
use std::sync::Arc;
|
||||
use thiserror::Error;
|
||||
|
||||
|
|
|
@ -98,6 +98,39 @@ impl Type {
|
|||
matches!(self, Type::External { .. })
|
||||
}
|
||||
|
||||
pub fn is_bound(&self) -> bool {
|
||||
match self {
|
||||
Type::Struct { .. } => true,
|
||||
Type::Protocol { .. } => true,
|
||||
Type::Impl { .. } => true,
|
||||
Type::Union { types, .. } => types.iter().all(|t| t.is_bound()),
|
||||
Type::Atom => true,
|
||||
Type::Boolean => true,
|
||||
Type::Integer => true,
|
||||
Type::Float => true,
|
||||
Type::String => true,
|
||||
Type::Array => true,
|
||||
Type::Map => true,
|
||||
Type::Function {
|
||||
associated_type,
|
||||
arguments,
|
||||
result,
|
||||
..
|
||||
} => {
|
||||
associated_type.is_bound()
|
||||
&& result.is_bound()
|
||||
&& arguments.iter().all(|t| t.is_bound())
|
||||
}
|
||||
Type::Variable { r#type, .. } => r#type.borrow().is_bound(),
|
||||
Type::External { .. } => true,
|
||||
Type::Alias { target, .. } => target.is_bound(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unbound(&self) -> bool {
|
||||
!self.is_bound()
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Option<Span> {
|
||||
match self {
|
||||
Type::Struct { span, .. } => Some(span.clone()),
|
||||
|
@ -190,6 +223,14 @@ impl TypeVariable {
|
|||
pub fn is_reference(&self) -> bool {
|
||||
matches!(self, TypeVariable::Reference { .. })
|
||||
}
|
||||
|
||||
pub fn is_bound(&self) -> bool {
|
||||
match self {
|
||||
TypeVariable::Unbound { .. } => false,
|
||||
TypeVariable::Reference { .. } => false,
|
||||
TypeVariable::Link { target } => target.is_bound(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToString for TypeVariable {
|
||||
|
|
|
@ -22,6 +22,7 @@ use std::sync::Arc;
|
|||
|
||||
pub use error::Error;
|
||||
pub use ir::Context;
|
||||
pub use ir::Type;
|
||||
pub use source::Source;
|
||||
|
||||
pub fn compile(source: Arc<Source>) -> Result<Context, Error> {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#[macro_use]
|
||||
extern crate miette;
|
||||
|
||||
extern crate outrun_compiler;
|
||||
|
||||
use outrun_compiler::{Context, Error, Source};
|
||||
|
@ -17,7 +15,7 @@ pub fn init() -> Result<Vec<Context>, Error> {
|
|||
|
||||
let mut results = Vec::new();
|
||||
|
||||
for path in files.iter() {
|
||||
for path in files.iter().take(1) {
|
||||
let source = Source::from_file(path)?;
|
||||
let source = Arc::new(source);
|
||||
let context = outrun_compiler::compile(source)?;
|
||||
|
@ -50,13 +48,26 @@ mod test {
|
|||
use super::*;
|
||||
|
||||
use miette::Result;
|
||||
use outrun_compiler::Type;
|
||||
|
||||
#[test]
|
||||
fn test_init() -> Result<()> {
|
||||
let result = init()?;
|
||||
let results = init()?;
|
||||
|
||||
println!("results: {:#?}", results);
|
||||
|
||||
for context in results {
|
||||
let unbound_types: Vec<Arc<Type>> = context
|
||||
.types
|
||||
.iter()
|
||||
.filter(|t| t.is_unbound())
|
||||
.cloned()
|
||||
.collect();
|
||||
println!("unbound_types: {:#?}", unbound_types);
|
||||
|
||||
assert_eq!(unbound_types.len(), 0);
|
||||
}
|
||||
|
||||
println!("result: {:?}", result);
|
||||
assert!(false);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue