From: Siraaj Khandkar Date: Thu, 13 Sep 2018 22:57:50 +0000 (-0400) Subject: WIP type-checking -- check array subscript access X-Git-Url: https://git.xandkar.net/?a=commitdiff_plain;h=161a300dddce2df54b21863ae94e2dda281906fd;p=tiger.ml.git WIP type-checking -- check array subscript access --- diff --git a/compiler/src/lib/tiger/tiger_env_type.ml b/compiler/src/lib/tiger/tiger_env_type.ml index bb8cdd6..4d99a0d 100644 --- a/compiler/src/lib/tiger/tiger_env_type.ml +++ b/compiler/src/lib/tiger/tiger_env_type.ml @@ -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" diff --git a/compiler/src/lib/tiger/tiger_env_type.mli b/compiler/src/lib/tiger/tiger_env_type.mli index faeb84a..2716e59 100644 --- a/compiler/src/lib/tiger/tiger_env_type.mli +++ b/compiler/src/lib/tiger/tiger_env_type.mli @@ -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 diff --git a/compiler/src/lib/tiger/tiger_error.ml b/compiler/src/lib/tiger/tiger_error.ml index 782f138..e8af9eb 100644 --- a/compiler/src/lib/tiger/tiger_error.ml +++ b/compiler/src/lib/tiger/tiger_error.ml @@ -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 _ diff --git a/compiler/src/lib/tiger/tiger_error.mli b/compiler/src/lib/tiger/tiger_error.mli index 81a87e8..92fde5d 100644 --- a/compiler/src/lib/tiger/tiger_error.mli +++ b/compiler/src/lib/tiger/tiger_error.mli @@ -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 diff --git a/compiler/src/lib/tiger/tiger_semant.ml b/compiler/src/lib/tiger/tiger_semant.ml index 659bb85..3265c81 100644 --- a/compiler/src/lib/tiger/tiger_semant.ml +++ b/compiler/src/lib/tiger/tiger_semant.ml @@ -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