Advertisement
Guest User

Untitled

a guest
Oct 19th, 2019
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (*
  2.    The Interpret function assumes a "parse" function,
  3.       written in another file.
  4.  
  5. This is a skeleton, with 9 places where code needs to be changed/inserted.
  6. Each such place is marked with "CHANGE #k" where k is a number,
  7. indicating the suggested order in which to make the changes.
  8.  
  9.  #1  how to evaluate a number
  10.  #2  how to execute a sequence of commands
  11.        (make sure it is in the right order, and that each command has an effect)
  12.  #3  how to handle an assignment
  13.        (observe that LeftEval computes a location)
  14.  #4  think about which runtime-errors there can be,
  15.         and add suitable exception declarations
  16.  #5  handle those exceptions you added in #4
  17.        (you may need to adjust #4 and #5 along the way)
  18.  #6  how to read from the input stream
  19.  #7  how to execute an "if" conditional
  20.        (remember which integers are considered 'true')
  21.  #8  how to execute a "while" loop
  22.        (hint: the question text mentions an equivalent command)
  23.  #9  how to calculate the 'displacement', that is how far a given array element
  24.         is located from the start of the array
  25.        (the current code works only for 1-dimensional arrays,
  26.          and doesn't catch out-of-bounds errors).
  27.  
  28. *)
  29.  
  30.  
  31. (* ABSTRACT SYNTAX
  32.  
  33. type Id = string
  34. type Num = int
  35.  
  36. datatype Exp =
  37.   NumE of Num
  38. | GetE of Left
  39. | AddE of Exp * Exp
  40. | SubE of Exp * Exp
  41. | MulE of Exp * Exp
  42. and Left =
  43.   LocOf of Id * Exp list
  44.  
  45. datatype Comm =
  46.   SkipC
  47. | SeqC of Comm * Comm
  48. | IfC of Exp * Comm * Comm
  49. | WhileC of Exp * Comm
  50. | AssignC of Left * Exp
  51. | OutputC of Exp
  52. | InputC of Left
  53.  
  54. type Decl = (Id * Num list) list
  55.  
  56. datatype Prog =
  57.   ProgP of Decl * Comm
  58. | ErrorP of string   (* to report errors *)
  59.  
  60. *)
  61.  
  62. (* EXCEPTIONS *)
  63.  
  64. exception NotDeclared of string
  65. exception BoundsError of string
  66. exception ArrayDiscrepancy of string
  67. (* CHANGE #4 *)
  68.  
  69. (* ENVIRONMENTS and STORES *)
  70.  
  71. type Loc = int    (* locations in stores *)
  72.  
  73. type Value = int    (* values of expressions *)
  74.  
  75. type Env = Id -> Loc * Num list
  76.   (* associates identifiers with locations
  77.       and with their dimensions (null if integers) *)
  78.  
  79. (* InitEnv: Env *)
  80. fun InitEnv id = raise (NotDeclared id)
  81.  
  82. (* EnvInsert: Id -> Loc * Num list -> Env -> Env *)
  83. fun EnvInsert id0 (loc,dims) env =
  84.    fn id => if id = id0 then (loc,dims) else env id
  85.  
  86. (* EnvLookup: Env -> Id -> Loc * Num list *)
  87. fun EnvLookup env id = env id
  88.  
  89. (* Stores *)
  90.  
  91. type Store = Loc -> Value
  92.  
  93. (* InitSto: Store *)
  94. fun InitSto loc = 0 (* all locations are initially zero *)
  95.  
  96. (* StoUpdate: Loc -> Value -> Store -> Store)  *)
  97. fun StoUpdate loc0 v sto =
  98.    fn loc => if loc = loc0 then v else sto loc
  99.  
  100. (* StoLookup: Store -> Loc -> Value *)
  101. fun StoLookup sto loc = sto loc
  102.  
  103. (* INDEX CALCULATION *)
  104.  
  105. (* calculate_displacement: Id -> int list -> int list -> int *)
  106. fun calculate_displacement id indices bounds = case (indices, bounds) of
  107.    ([],[]) => 0
  108.  | ((index1 :: indices'), (bound1 :: bounds')) =>
  109.            index1 (* CHANGE #9 *)
  110.  | _ => raise (ArrayDiscrepancy id)
  111.  
  112. (* EVALUATION OF EXPRESSIONS
  113.      ExpEval: Exp -> Env -> Store -> Val
  114. *)
  115.  
  116. fun ExpEval (NumE n) _ _ = n (* CHANGED #1 *)
  117. |   ExpEval (GetE lhs) env sto = StoLookup sto (LeftEval lhs env sto)
  118. |   ExpEval (AddE(exp1,exp2)) env sto =
  119.       let val v1 = ExpEval exp1 env sto
  120.           val v2 = ExpEval exp2 env sto
  121.        in v1 + v2
  122.       end
  123. |   ExpEval (SubE(exp1,exp2)) env sto =
  124.       let val v1 = ExpEval exp1 env sto
  125.           val v2 = ExpEval exp2 env sto
  126.        in v1 - v2
  127.       end
  128. |   ExpEval (MulE(exp1,exp2)) env sto =
  129.       let val v1 = ExpEval exp1 env sto
  130.           val v2 = ExpEval exp2 env sto
  131.        in v1 * v2
  132.       end
  133. (* LeftEval: Left -> Env -> Store -> Loc   *)
  134. and LeftEval (LocOf (id, exps)) env sto = let
  135.         val (loc,bounds) = EnvLookup env id
  136.         val indices = map (fn exp => ExpEval exp env sto) exps
  137.         val displ = calculate_displacement id indices bounds
  138.        in loc + displ
  139.       end
  140.  
  141. (* PROCESSING OF DECLARATIONS
  142.      DeclExec: Decl -> Env * int -> Env * int
  143. *)
  144.  
  145. fun DeclExec [] (env,next) = (env,next)
  146. |   DeclExec ((id, bounds) :: decl) (env,next) =
  147.       if List.all (fn bound => bound > 0) bounds
  148.       then DeclExec decl
  149.               (EnvInsert id (next, bounds) env,
  150.                next + (foldr op* 1 bounds))
  151.       else raise (BoundsError id)
  152.  
  153. (* EXECUTION OF COMMANDS *)
  154.  
  155. type InputStream = Num list
  156. type OutputStream = Value list
  157. type RunTimeState = Store * InputStream * OutputStream
  158.  
  159. (*
  160. CommExec: Comm -> Env -> RunTimeState -> RunTimeState
  161. *)
  162.  
  163. fun CommExec SkipC env state = state
  164. |   CommExec (SeqC(cmd1,cmd2)) env state = (* CHANGE #2 *)
  165.       let val state1 = CommExec cmd2 env state
  166.           val state2 = CommExec cmd1 env state
  167.        in state2 end
  168. |   CommExec (IfC(exp,cmd1,cmd2)) env state = (* CHANGE #7 *)
  169.           CommExec cmd1 env state
  170. |   CommExec (WhileC(exp,cmd)) env state = (* CHANGE #8 *)
  171.           state
  172. |   CommExec (AssignC(lhs, rhs)) env (sto,inp,outp) = (* CHANGED #3 *)
  173.           let val loc = LeftEval (lhs) env sto
  174.               val value = ExpEval rhs env sto
  175.               val sto' = StoUpdate loc value sto
  176.           in (sto', inp, outp)
  177.           end
  178. |   CommExec (OutputC exp) env (sto,inp,outp) =
  179.       let val v = ExpEval exp env sto
  180.        in (sto, inp, (v::outp))   (* we eventually reverse the order *)
  181.       end
  182. |   CommExec (InputC lhs) env (sto,inp,outp) = (* CHANGE #6 *)
  183.        (sto, inp, outp)
  184.  
  185. (* RUNNING THE PROGRAM *)
  186.  
  187. fun ProgRun (ProgP(decl,comm)) inp =
  188.        let val (env,_) = DeclExec decl (InitEnv, 0)
  189.            val (_,_,outp) = CommExec comm  env (InitSto, inp, [])
  190.          in rev outp
  191.         end
  192. |   ProgRun(ErrorP s) _ = (print ("*** syntax error: "^s^"\n"); [0])
  193.  
  194. fun Interpret prog inp = ProgRun (parse prog) inp
  195.    handle (* CHANGE #5 *)
  196.       (NotDeclared x) =>
  197.          (print ("*** error: "^x^" used but not declared\n"); [0])
  198.     | (BoundsError x) =>
  199.          (print ("*** error: "^x^" declared with a zero bound\n"); [0])
  200.     | (ArrayDiscrepancy x) =>
  201.          (print ("*** error: "^x^" not used with same dimensions as declared\n"); [0])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement