Clearing out most of the cruft from typechecking
This commit is contained in:
parent
642e9da8ee
commit
7a2a4df297
@ -1,9 +1,34 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt;
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
use typechecking::{Type, TypeResult, TConstOld};
|
|
||||||
use self::Type::*; use self::TConstOld::*;
|
use self::Type::*; use self::TConstOld::*;
|
||||||
|
|
||||||
|
|
||||||
|
//TODO get rid of these types and replace them with the right MonoType or whatever ones later
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum Type {
|
||||||
|
Const(TConstOld),
|
||||||
|
Func(Box<Type>, Box<Type>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum TConstOld {
|
||||||
|
Nat,
|
||||||
|
Int,
|
||||||
|
Float,
|
||||||
|
StringT,
|
||||||
|
Bool,
|
||||||
|
Custom(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Type {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct BinOp {
|
pub struct BinOp {
|
||||||
sigil: Rc<String>
|
sigil: Rc<String>
|
||||||
@ -16,7 +41,7 @@ impl BinOp {
|
|||||||
pub fn sigil(&self) -> &Rc<String> {
|
pub fn sigil(&self) -> &Rc<String> {
|
||||||
&self.sigil
|
&self.sigil
|
||||||
}
|
}
|
||||||
pub fn get_type(&self) -> TypeResult<Type> {
|
pub fn get_type(&self) -> Result<Type, String> {
|
||||||
let s = self.sigil.as_str();
|
let s = self.sigil.as_str();
|
||||||
BINOPS.get(s).map(|x| x.0.clone()).ok_or(format!("Binop {} not found", s))
|
BINOPS.get(s).map(|x| x.0.clone()).ok_or(format!("Binop {} not found", s))
|
||||||
}
|
}
|
||||||
@ -44,7 +69,7 @@ impl PrefixOp {
|
|||||||
pub fn is_prefix(op: &str) -> bool {
|
pub fn is_prefix(op: &str) -> bool {
|
||||||
PREFIX_OPS.get(op).is_some()
|
PREFIX_OPS.get(op).is_some()
|
||||||
}
|
}
|
||||||
pub fn get_type(&self) -> TypeResult<Type> {
|
pub fn get_type(&self) -> Result<Type, String> {
|
||||||
let s = self.sigil.as_str();
|
let s = self.sigil.as_str();
|
||||||
PREFIX_OPS.get(s).map(|x| x.0.clone()).ok_or(format!("Prefix op {} not found", s))
|
PREFIX_OPS.get(s).map(|x| x.0.clone()).ok_or(format!("Prefix op {} not found", s))
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ mod eval;
|
|||||||
pub struct Schala {
|
pub struct Schala {
|
||||||
state: eval::State<'static>,
|
state: eval::State<'static>,
|
||||||
symbol_table: Rc<RefCell<symbol_table::SymbolTable>>,
|
symbol_table: Rc<RefCell<symbol_table::SymbolTable>>,
|
||||||
//type_context
|
type_context: typechecking::TypeContext,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Schala {
|
impl Schala {
|
||||||
@ -45,6 +45,7 @@ impl Schala {
|
|||||||
Schala {
|
Schala {
|
||||||
symbol_table: symbols.clone(),
|
symbol_table: symbols.clone(),
|
||||||
state: eval::State::new(symbols),
|
state: eval::State::new(symbols),
|
||||||
|
type_context: typechecking::TypeContext::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,6 @@ use std::collections::{HashSet, HashMap};
|
|||||||
use std::collections::hash_set::Union;
|
use std::collections::hash_set::Union;
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
//use std::char;
|
//use std::char;
|
||||||
use std::fmt;
|
|
||||||
use std::fmt::Write;
|
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
@ -17,7 +15,13 @@ pub struct TypeContext {
|
|||||||
environment: TypeEnvironment,
|
environment: TypeEnvironment,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* real meat of type stuff here */
|
impl TypeContext {
|
||||||
|
pub fn new() -> TypeContext {
|
||||||
|
TypeContext { environment: TypeEnvironment::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type TypeResult<T> = Result<T, String>;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
enum MonoType {
|
enum MonoType {
|
||||||
@ -135,33 +139,9 @@ impl TypeEnvironment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub enum Type {
|
|
||||||
Const(TConstOld),
|
|
||||||
Func(Box<Type>, Box<Type>),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub enum TConstOld {
|
|
||||||
Nat,
|
|
||||||
Int,
|
|
||||||
Float,
|
|
||||||
StringT,
|
|
||||||
Bool,
|
|
||||||
Custom(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Type {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "{:?}", self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO this should just check the name against a map, and that map should be pre-populated with
|
/* TODO this should just check the name against a map, and that map should be pre-populated with
|
||||||
* types */
|
* types */
|
||||||
|
/*
|
||||||
impl parsing::TypeName {
|
impl parsing::TypeName {
|
||||||
fn to_type(&self) -> TypeResult<Type> {
|
fn to_type(&self) -> TypeResult<Type> {
|
||||||
use self::parsing::TypeSingletonName;
|
use self::parsing::TypeSingletonName;
|
||||||
@ -184,15 +164,12 @@ impl parsing::TypeName {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub type TypeResult<T> = Result<T, String>;
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
impl TypeContext {
|
impl TypeContext {
|
||||||
pub fn new() -> TypeContext {
|
|
||||||
TypeContext { environment: TypeEnvironment::default(), /*type_var_count: 0*/ }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn type_check_ast(&mut self, ast: &parsing::AST) -> TypeResult<String> {
|
pub fn type_check_ast(&mut self, ast: &parsing::AST) -> TypeResult<String> {
|
||||||
let ref block = ast.0;
|
let ref block = ast.0;
|
||||||
let mut infer = Infer::default();
|
let mut infer = Infer::default();
|
||||||
@ -221,6 +198,7 @@ enum InferError {
|
|||||||
|
|
||||||
type InferResult<T> = Result<T, InferError>;
|
type InferResult<T> = Result<T, InferError>;
|
||||||
|
|
||||||
|
|
||||||
impl Infer {
|
impl Infer {
|
||||||
fn fresh(&mut self) -> MonoType {
|
fn fresh(&mut self) -> MonoType {
|
||||||
let i = self._idents;
|
let i = self._idents;
|
||||||
@ -293,30 +271,6 @@ impl Infer {
|
|||||||
},
|
},
|
||||||
None => return Err(InferError::UnknownIdentifier(name.clone())),
|
None => return Err(InferError::UnknownIdentifier(name.clone())),
|
||||||
},
|
},
|
||||||
/*
|
|
||||||
PrefixExp(op, expr) => match op.get_type()? {
|
|
||||||
Func(box t1, box t2) => {
|
|
||||||
let expr_ty = self.infer(expr)?;
|
|
||||||
self.unify(t1, expr_ty)?;
|
|
||||||
Ok(t2)
|
|
||||||
},
|
|
||||||
other => Err(format!("{:?} is not a prefix op function type", other))
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
BinExp(op, lhs, rhs) => { /* remember there are both the haskell convention talk and the write you a haskell ways to do this! */
|
|
||||||
match op.get_type()? {
|
|
||||||
Func(box t1, box Func(box t2, box t3)) => {
|
|
||||||
let lhs_ty = self.infer(lhs)?;
|
|
||||||
let rhs_ty = self.infer(rhs)?;
|
|
||||||
self.unify(t1, lhs_ty)?;
|
|
||||||
self.unify(t2, rhs_ty)?;
|
|
||||||
Ok(t3)
|
|
||||||
},
|
|
||||||
other => return Err(format!("{:?} is not a binary function type", other))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
e => return Err(InferError::Custom(format!("Type inference for {:?} not done", e)))
|
e => return Err(InferError::Custom(format!("Type inference for {:?} not done", e)))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -332,6 +286,20 @@ impl Infer {
|
|||||||
ty.apply_substitution(&subst)
|
ty.apply_substitution(&subst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* OLD STUFF DOWN HERE */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user