diff --git a/src/schala_lang/eval.rs b/src/schala_lang/eval.rs index c0c0167..485da58 100644 --- a/src/schala_lang/eval.rs +++ b/src/schala_lang/eval.rs @@ -1,4 +1,4 @@ -use schala_lang::parsing::{AST, Statement, Declaration, Expression, ExpressionType, Operation, TypeAnno}; +use schala_lang::parsing::{AST, Statement, Declaration, Expression, ExpressionType, Operation}; pub struct ReplState { } @@ -107,52 +107,3 @@ impl ReplState { }) } } - - -// from Niko's talk -/* fn type_check(expression, expected_ty) -> Ty { - let ty = bare_type_check(expression, expected_type); - if ty icompatible with expected_ty { - try_coerce(expression, ty, expected_ty) - } else { - ty - } - } - - fn bare_type_check(exprssion, expected_type) -> Ty { ... } - */ -pub enum TypeCheck { - OK, - Error(String) -} -impl TypeCheck { - fn new(msg: &str) -> TypeCheck { - TypeCheck::Error(msg.to_string()) - } -} - -impl ReplState { - pub fn type_check(&mut self, ast: &AST) -> TypeCheck { - use self::ExpressionType::*; - for statement in ast.0.iter() { - match statement { - &Statement::Declaration(ref _decl) => { - return TypeCheck::new("Declarations not supported"); - }, - &Statement::ExpressionStatement(ref expr) => { - match (&expr.0, &expr.1) { - (&IntLiteral(_), &Some(ref t)) => { - match t { - &TypeAnno::Singleton { ref name, ref params } if **name == "Int" && params.len() == 0 => (), - t => return TypeCheck::new(&format!("Bad type {:?} for int literal", t)), - } - }, - _ => (), - } - } - } - } - TypeCheck::OK - } -} - diff --git a/src/schala_lang/mod.rs b/src/schala_lang/mod.rs index 8410284..c0758e1 100644 --- a/src/schala_lang/mod.rs +++ b/src/schala_lang/mod.rs @@ -2,18 +2,21 @@ use itertools::Itertools; use language::{ProgrammingLanguageInterface, EvalOptions, TraceArtifact, ReplOutput}; mod parsing; +mod type_check; mod eval; -use self::eval::TypeCheck; +use self::type_check::{TypeContext, TypeCheckResult}; pub struct Schala { - state: eval::ReplState + state: eval::ReplState, + type_context: TypeContext } impl Schala { pub fn new() -> Schala { Schala { state: eval::ReplState::new(), + type_context: TypeContext::new(), } } } @@ -59,9 +62,9 @@ impl ProgrammingLanguageInterface for Schala { } }; - match self.state.type_check(&ast) { - TypeCheck::OK => (), - TypeCheck::Error(s) => { + match self.type_context.type_check(&ast) { + TypeCheckResult::OK => (), + TypeCheckResult::Error(s) => { output.add_artifact(TraceArtifact::new("type_check", s)); output.add_output(format!("Type error")); return output; diff --git a/src/schala_lang/type_check.rs b/src/schala_lang/type_check.rs new file mode 100644 index 0000000..964d6ee --- /dev/null +++ b/src/schala_lang/type_check.rs @@ -0,0 +1,57 @@ +use schala_lang::parsing::{AST, Statement, Declaration, Expression, ExpressionType, Operation, TypeAnno}; + +pub struct TypeContext { +} + +impl TypeContext { + pub fn new() -> TypeContext { + TypeContext { } + } +} + +pub enum TypeCheckResult { + OK, + Error(String) +} +impl TypeCheckResult { + fn new(msg: &str) -> TypeCheckResult { + TypeCheckResult::Error(msg.to_string()) + } +} + +// from Niko's talk +/* fn type_check(expression, expected_ty) -> Ty { + let ty = bare_type_check(expression, expected_type); + if ty icompatible with expected_ty { + try_coerce(expression, ty, expected_ty) + } else { + ty + } + } + + fn bare_type_check(exprssion, expected_type) -> Ty { ... } + */ +impl TypeContext { + pub fn type_check(&mut self, ast: &AST) -> TypeCheckResult { + use self::ExpressionType::*; + for statement in ast.0.iter() { + match statement { + &Statement::Declaration(ref _decl) => { + return TypeCheckResult::new("Declarations not supported"); + }, + &Statement::ExpressionStatement(ref expr) => { + match (&expr.0, &expr.1) { + (&IntLiteral(_), &Some(ref t)) => { + match t { + &TypeAnno::Singleton { ref name, ref params } if **name == "Int" && params.len() == 0 => (), + t => return TypeCheckResult::new(&format!("Bad type {:?} for int literal", t)), + } + }, + _ => (), + } + } + } + } + TypeCheckResult::OK + } +}