From 1c62effe91b5e50d1dbbc79c01655abfb3c17e16 Mon Sep 17 00:00:00 2001 From: David Li Date: Sun, 5 Nov 2017 09:33:03 -0500 Subject: Check types in add expressions --- src/semantic/translate.rs | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/semantic/translate.rs b/src/semantic/translate.rs index 7bcd646..d3ebd2c 100644 --- a/src/semantic/translate.rs +++ b/src/semantic/translate.rs @@ -5,16 +5,21 @@ use super::types::Ty; #[derive(Debug)] pub enum TypeError { Unimplemented, + Mismatch { + expected: Ty, + actual: Ty, + }, } type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>; pub type Result = ::std::result::Result>; pub fn translate(program: &ast::Program) -> Result { - trans_exp(TypeEnvironment::new(None), &*program.0) + let mut env = TypeEnvironment::new(None); + trans_exp(&mut env, &*program.0) } -fn trans_exp<'a>(venv: TypeEnvironment<'a>, exp: &WithLocation) -> Result { +fn trans_exp<'a>(venv: &mut TypeEnvironment<'a>, exp: &WithLocation) -> Result { use ast::Expression::*; match &exp.value { @@ -25,7 +30,39 @@ fn trans_exp<'a>(venv: TypeEnvironment<'a>, exp: &WithLocation) Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) }, &BinOp(ref op, ref left, ref right) => { - Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + use ast::BinOp::*; + match op { + &Add => { + let left = trans_exp(venv, left)?; + let right = trans_exp(venv, right)?; + match (left, right) { + (Ty::Int, Ty::Int) => { + Ok(Ty::Int) + } + (Ty::String, Ty::String) => { + Ok(Ty::String) + } + (Ty::Int, other) => { + Err(WithLocation::new(TypeError::Mismatch { + expected: Ty::Int, + actual: other, + }, exp.start, exp.end)) + } + (Ty::String, other) => { + Err(WithLocation::new(TypeError::Mismatch { + expected: Ty::String, + actual: other, + }, exp.start, exp.end)) + } + _ => { + Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + } + } + } + _ => { + Err(WithLocation::new(TypeError::Unimplemented, exp.start, exp.end)) + } + } }, &Number(_) => Ok(Ty::Int), &String(_) => Ok(Ty::String), -- cgit v1.2.3