WIP type-checking -- check array subscript access
authorSiraaj Khandkar <siraaj@khandkar.net>
Thu, 13 Sep 2018 22:57:50 +0000 (18:57 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Thu, 13 Sep 2018 22:57:50 +0000 (18:57 -0400)
compiler/src/lib/tiger/tiger_env_type.ml
compiler/src/lib/tiger/tiger_env_type.mli
compiler/src/lib/tiger/tiger_error.ml
compiler/src/lib/tiger/tiger_error.mli
compiler/src/lib/tiger/tiger_semant.ml

index bb8cdd6..4d99a0d 100644 (file)
@@ -97,6 +97,18 @@ let if_record t ~f ~otherwise =
   | Array  _ ->
       otherwise ()
 
+let if_array t ~f ~otherwise =
+  match t with
+  | Array {ty=t; _} ->
+      f t
+  | Unit
+  | Int
+  | String
+  | Name _
+  | Nil
+  | Record _ ->
+      otherwise ()
+
 let to_string = function
   | Unit               -> "unit"
   | Nil                -> "nil"
index faeb84a..2716e59 100644 (file)
@@ -31,6 +31,7 @@ val is_record : t -> bool
 val is_name   : t -> bool
 
 val if_record : t -> f:(record_fields -> 'a) -> otherwise:(unit -> 'a) -> 'a
+val if_array  : t -> f:(t -> 'a)             -> otherwise:(unit -> 'a) -> 'a
 
 val new_record : record_fields -> t
 val new_array  : t -> t
index 782f138..e8af9eb 100644 (file)
@@ -11,6 +11,7 @@ type t =
   | Id_not_a_function of {id    : Sym.t; pos : Pos.t}
   | No_such_field_in_record of {field : Sym.t; record : Typ.t; pos : Pos.t}
   | Exp_not_a_record  of {ty    : Typ.t; pos : Pos.t}
+  | Exp_not_an_array  of {ty    : Typ.t; pos : Pos.t}
   | Wrong_type of
       { expected : Typ.t
       ; given    : Typ.t
@@ -82,7 +83,11 @@ let to_string =
       s "No field %S in record %S in %s"
         (Sym.to_string field) (Typ.to_string record) (Pos.to_string pos)
   | Exp_not_a_record {ty; pos} ->
-      s ( "This expression has type %S, it is not a record, it cannot be"
+      s ( "The expression of type %S is not a record, it cannot be"
+        ^^"accessed in %s")
+        (Typ.to_string ty) (Pos.to_string pos)
+  | Exp_not_an_array {ty; pos} ->
+      s ( "The expression of type %S is not an array, it cannot be"
         ^^"accessed in %s")
         (Typ.to_string ty) (Pos.to_string pos)
   | Wrong_type {expected; given; pos} ->
@@ -144,6 +149,7 @@ let is_unknown_id t =
   | Id_not_a_function _
   | No_such_field_in_record _
   | Exp_not_a_record _
+  | Exp_not_an_array _
   | Wrong_type _
   | Wrong_type_of_expression_in_var_dec _
   | Wrong_type_used_as_record _
index 81a87e8..92fde5d 100644 (file)
@@ -11,6 +11,7 @@ type t =
   | Id_not_a_function of {id    : Sym.t; pos : Pos.t}
   | No_such_field_in_record of {field : Sym.t; record : Typ.t; pos : Pos.t}
   | Exp_not_a_record  of {ty    : Typ.t; pos : Pos.t}
+  | Exp_not_an_array  of {ty    : Typ.t; pos : Pos.t}
   | Wrong_type of
       { expected : Typ.t
       ; given    : Typ.t
index 659bb85..3265c81 100644 (file)
@@ -134,8 +134,13 @@ end = struct
               )
             )
             ~otherwise:(fun () -> E.raise (E.Exp_not_a_record {ty; pos}))
-      | A.SubscriptVar {var=_; exp=_; pos=_} ->
-          unimplemented ()
+      | A.SubscriptVar {var; exp; pos} ->
+          let {exp=_; ty} = trvar var in
+          check_int (trexp exp) ~pos;
+          Type.if_array
+            ty
+            ~f:(fun ty_elements -> return ty_elements)
+            ~otherwise:(fun () -> E.raise (E.Exp_not_an_array {ty; pos}))
       )
     and trop oper ~left ~right ~pos =
       let expty_left  = trexp left in
This page took 0.033567 seconds and 4 git commands to generate.