diff options
| -rw-r--r-- | src/semantic/analysis.rs | 80 | 
1 files changed, 49 insertions, 31 deletions
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<T> = ::std::result::Result<T, WithLocation<TypeError>>; @@ -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)              }  | 
