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