Advertisement
Guest User

Untitled

a guest
May 10th, 2015
183
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 3.33 KB | None | 0 0
  1. module TypeChecker
  2. open Syntax
  3. open Util
  4.  
  5. let getFunParmamType funName env =
  6.     let funType = Map.find funName env
  7.     match funType with
  8.     | FuncType(left, right) -> left
  9.     | BoolType              -> BoolType
  10.     | IntType               -> IntType
  11.  
  12. let addParamType env param =
  13.     let (Parameter(name, paramType)) = param
  14.     Map.add name paramType env
  15.  
  16. let addFuncType env funcDef =
  17.     match funcDef with
  18.     | FuncDef (name, _, typeDef, _) -> Map.add name typeDef env
  19.  
  20. let rec checkExpr expr env =
  21.     match expr with
  22.     | ConstBool b                       -> BoolType
  23.     | ConstInt i                        -> IntType
  24.     | Var name                          -> Map.find name env
  25.     | PrimOp ("+", lOper, rOper)        -> checkIntOp lOper rOper env
  26.     | PrimOp ("-", lOper, rOper)        -> checkIntOp lOper rOper env
  27.     | PrimOp ("*", lOper, rOper)        -> checkIntOp lOper rOper env
  28.     | PrimOp ("/", lOper, rOper)        -> checkIntOp lOper rOper env
  29.     | PrimOp (">", lOper, rOper)        -> checkIntOp lOper rOper env
  30.     | PrimOp ("<", lOper, rOper)        -> checkIntOp lOper rOper env
  31.     | PrimOp ("=", lOper, rOper)        -> checkBinOp lOper rOper env
  32.     | If (ifExpr, thenExpr, elseExpr )  -> checkIf ifExpr thenExpr elseExpr env
  33.     | Let(name, valExpr, restExpr)      -> checkLet name valExpr restExpr env
  34.     | FunCall (name, arg)               -> checkFunCall name arg env
  35.     | _                                 -> failwith "Syntax error"  
  36.  
  37. and checkLet name valExpr restExpr env =
  38.     let valType = checkExpr valExpr env
  39.     let updatedEnv = Map.add name valType env
  40.     checkExpr restExpr updatedEnv
  41.  
  42. and checkIf ifExpr thenExpr elseExpr env =
  43.     let ifType = checkExpr ifExpr env
  44.     let thenType = checkExpr thenExpr env
  45.     let elseType = checkExpr elseExpr env
  46.     if ifType = BoolType || ifType = IntType && thenType = elseType then thenType else failwith "Error"
  47.  
  48. and checkIntOp lOper rOper env =
  49.     let lType = checkExpr lOper env
  50.     let rType = checkExpr rOper env
  51.     if lType = rType && rType = IntType then lType else failwith "Error"
  52.  
  53. and checkBinOp lOper rOper env =
  54.     let lType = checkExpr lOper env
  55.     let rType = checkExpr rOper env
  56.     if (lType = IntType || lType = BoolType) && lType = rType then rType else failwith "Error"
  57.  
  58. and checkFunCall name arg env =
  59.     let argType = checkExpr arg env
  60.     match name with
  61.     | (Var funName) -> if (getFunParmamType funName env) = argType then argType else failwith "Illegal param type"
  62.     | _             -> failwith "Syntax error: expected (Var name)"      
  63.  
  64. let checkFunc funcDef env =
  65.     let (FuncDef(name, paramList, typeDef, expr)) = funcDef
  66.     let paramTypes = getParamTypes paramList typeDef  
  67.     let updatedEnv = List.fold addParamType env paramTypes
  68.     let checkType = checkExpr expr updatedEnv
  69.     checkType = IntType || checkType = BoolType
  70.  
  71. let checkProgram program =
  72.     match program with
  73.     | Program (funcDefs, expr) -> let env = List.fold addFuncType Map.empty funcDefs
  74.                                   let funcsValid = List.forall (fun funcDef -> checkFunc funcDef env) funcDefs
  75.                                   let mainType = checkExpr expr env
  76.                                   let mainValid = mainType = IntType || mainType = BoolType
  77.                                   mainValid && funcsValid
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement