From 5a335165bd60c068875d75d313c66e8bccc47a86 Mon Sep 17 00:00:00 2001
From: David Li 
Date: Tue, 28 Nov 2017 19:28:26 -0500
Subject: Distinguish between functions and values in environment
---
 src/semantic/analysis.rs | 80 +++++++++++++++++++++++++++++-------------------
 1 file changed, 49 insertions(+), 31 deletions(-)
(limited to 'src/semantic')
diff --git a/src/semantic/analysis.rs b/src/semantic/analysis.rs
index 829e7c2..c7acfc9 100644
--- a/src/semantic/analysis.rs
+++ b/src/semantic/analysis.rs
@@ -24,7 +24,12 @@ pub enum TypeError {
     UnboundName,
 }
 
-type VarEnvironment<'a> = environment::Environment<'a, String, (Expression, Ty)>;
+enum VarValue {
+    Function,
+    Variable(Expression, Ty),
+}
+
+type VarEnvironment<'a> = environment::Environment<'a, String, VarValue>;
 type TypeEnvironment<'a> = environment::Environment<'a, String, Ty>;
 pub type Result = ::std::result::Result>;
 
@@ -146,7 +151,7 @@ fn trans_exp<'a, 'b, F: frame::Frame>(
                 let (decl_exp, decl_ty) = trans_decl(tr, level, &mut new_venv, &mut new_tenv, decl)?;
                 match decl.declaration {
                     ast::DeclarationBody::Fun { .. } | ast::DeclarationBody::Var { .. } => {
-                        new_venv.add_binding(decl.name.clone(), (decl_exp, decl_ty));
+                        new_venv.add_binding(decl.name.clone(), VarValue::Variable(decl_exp, decl_ty));
                     }
                     ast::DeclarationBody::Ty { .. } => {
                         new_tenv.add_binding(decl.name.clone(), decl_ty);
@@ -161,37 +166,46 @@ fn trans_exp<'a, 'b, F: frame::Frame>(
                 arg_types.push(trans_exp(tr, level, venv, tenv, arg)?);
             }
 
-            let &(ref fun_exp, ref fun_ty) = venv.lookup(name)
+            let value = venv.lookup(name)
                 .ok_or(WithLocation::new(TypeError::UnboundName,
                                          exp.start, exp.end))?;
-            match fun_ty {
-                &Ty::Function(ref expected_args, ref result) => {
-                    if expected_args.len() != arg_types.len() {
-                        return err!(exp, TypeError::LengthMismatch {
-                            expected: expected_args.len(),
-                            actual: arg_types.len(),
-                        });
-                    }
-                    for (i, (&(_, ref provided_ty), expected_ty)) in
-                        arg_types.iter().zip(expected_args).enumerate() {
-                        if provided_ty != expected_ty {
-                            return err!(args[i], TypeError::Mismatch {
-                                expected: expected_ty.clone(),
-                                actual: provided_ty.clone(),
-                            })
-                        }
-                    }
+            match value {
+                &VarValue::Function => {
+                    // (ref fun_exp, ref fun_ty);
+                    // match fun_ty {
+                    //     &Ty::Function(ref expected_args, ref result) => {
+                    //         if expected_args.len() != arg_types.len() {
+                    //             return err!(exp, TypeError::LengthMismatch {
+                    //                 expected: expected_args.len(),
+                    //                 actual: arg_types.len(),
+                    //             });
+                    //         }
+                    //         for (i, (&(_, ref provided_ty), expected_ty)) in
+                    //             arg_types.iter().zip(expected_args).enumerate() {
+                    //                 if provided_ty != expected_ty {
+                    //                     return err!(args[i], TypeError::Mismatch {
+                    //                         expected: expected_ty.clone(),
+                    //                         actual: provided_ty.clone(),
+                    //                     })
+                    //                 }
+                    //             }
+                    //         err!(exp, TypeError::Unimplemented)
+                    //         // Ok((**result).clone())
+                    //     },
+                    //     otherwise => {
+                    //         err!(exp, TypeError::Mismatch {
+                    //             // TODO: better way to handle this
+                    //             expected: Ty::Function(
+                    //                 arg_types.into_iter().map(|v| v.1).collect(),
+                    //                 Box::new(Ty::Nil)),
+                    //             actual: otherwise.clone(),
+                    //         })
+                    //     }
+                    // }
+                    err!(exp, TypeError::Unimplemented)
+                }
+                &VarValue::Variable(..) => {
                     err!(exp, TypeError::Unimplemented)
-                    // Ok((**result).clone())
-                },
-                otherwise => {
-                    err!(exp, TypeError::Mismatch {
-                        // TODO: better way to handle this
-                        expected: Ty::Function(
-                            arg_types.into_iter().map(|v| v.1).collect(),
-                            Box::new(Ty::Nil)),
-                        actual: otherwise.clone(),
-                    })
                 }
             }
         },
@@ -259,10 +273,14 @@ fn trans_exp<'a, 'b, F: frame::Frame>(
         &String(_) => err!(exp, TypeError::Unimplemented),
         // &String(_) => Ok(Ty::String),
         &Name(ref name) => {
-            if let Some(&(ref exp, ref ty)) = venv.lookup(name) {
+            let result = venv.lookup(name);
+            if let Some(&VarValue::Variable(ref exp, ref ty)) = result {
                 // TODO: clone might be expensive, Rc?
                 Ok((exp.clone(), ty.clone()))
             }
+            else if let Some(&VarValue::Function) = result {
+                err!(exp, TypeError::Unimplemented)
+            }
             else {
                 err!(exp, TypeError::UnboundName)
             }
-- 
cgit v1.2.3