Define (some) semantic errors
authorSiraaj Khandkar <siraaj@khandkar.net>
Wed, 12 Sep 2018 22:30:12 +0000 (18:30 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Thu, 13 Sep 2018 12:30:42 +0000 (08:30 -0400)
compiler/src/exe/tigerc.ml
compiler/src/lib/tiger/tiger_absyn.ml
compiler/src/lib/tiger/tiger_absyn.mli
compiler/src/lib/tiger/tiger_error.ml
compiler/src/lib/tiger/tiger_error.mli
compiler/src/lib/tiger/tiger_parser.mly
compiler/src/lib/tiger/tiger_position.ml

index 5468ff7..4bf0c62 100644 (file)
@@ -9,8 +9,8 @@ let () =
   let lexbuf = Lexing.from_channel ic in
   lexbuf_set_filename lexbuf path_to_program_file;
   (match Tiger.Parser.program Tiger.Lexer.token lexbuf with
-  | exception Tiger.Error.T msg ->
-      Printf.eprintf "%s\n" msg;
+  | exception Tiger.Error.T error ->
+      Printf.eprintf "%s\n" (Tiger.Error.to_string error);
       exit 1;
   | absyn ->
       print_endline (Tiger.Absyn.to_string absyn)
index 6e4a7e9..73a081a 100644 (file)
@@ -175,6 +175,21 @@ and fundec =
 
 type t = exp
 
+(* For printing error messages *)
+let op_show op =
+  match op with
+  | PlusOp   -> "+"
+  | MinusOp  -> "-"
+  | TimesOp  -> "*"
+  | DivideOp -> "/"
+  | EqOp     -> "="
+  | NeqOp    -> "<>"
+  | LtOp     -> "<"
+  | LeOp     -> "<="
+  | GtOp     -> ">"
+  | GeOp     -> ">="
+
+(* For printing AST *)
 let op_to_string op =
   match op with
   | PlusOp   -> "PlusOp"
index 662f637..b2f9406 100644 (file)
@@ -138,3 +138,5 @@ and fundec =
 type t = exp
 
 val to_string : t -> string
+
+val op_show : oper -> string
index 9e0d16a..20a1f7d 100644 (file)
@@ -1,7 +1,112 @@
+module Abs = Tiger_absyn
 module Pos = Tiger_position
+module Sym = Tiger_symbol
+module Typ = Tiger_env_type
 
-exception T of string
+type t =
+  | Invalid_syntax    of Pos.t
+  | Unknown_id        of {id    : Sym.t; pos : Pos.t}
+  | Unknown_type      of {ty_id : Sym.t; pos : Pos.t}
+  | Id_not_a_function of {id    : Sym.t; pos : Pos.t}
+  | Wrong_type_of_expression_in_var_dec of
+      { var_id   : Sym.t
+      ; expected : Typ.t
+      ; given    : Typ.t
+      ; pos      : Pos.t
+      }
+  | Wrong_type_used_as_record of
+      { ty_id    : Sym.t
+      ; ty       : Typ.t
+      ; pos      : Pos.t
+      }
+  | Wrong_type_of_field_value of
+      { field_id : Sym.t
+      ; expected : Typ.t
+      ; given    : Typ.t
+      ; pos      : Pos.t
+      }
+  | Wrong_type_of_arg of
+      { func     : Sym.t
+      ; expected : Typ.t
+      ; given    : Typ.t
+      ; pos      : Pos.t
+      }
+  | Wrong_number_of_args of
+      { func     : Sym.t
+      ; expected : int
+      ; given    : int
+      ; pos      : Pos.t
+      }
+  | Invalid_operand_type of
+      { oper  : Abs.oper
+      ; valid : string list
+      ; given : Typ.t
+      ; pos   : Pos.t
+      }
+  | Different_operand_types of
+      { oper  : Abs.oper
+      ; left  : Typ.t
+      ; right : Typ.t
+      ; pos   : Pos.t
+      }
 
-let exn ~pos msg =
-  let msg = Printf.sprintf "Error: %s. In %s." msg (Pos.to_string pos) in
-  raise (T msg)
+exception T of t
+
+let raise t =
+  raise (T t)
+
+let to_string =
+  let s = Printf.sprintf in
+  function
+  | Invalid_syntax pos ->
+      s "Invalid syntax in %s" (Pos.to_string pos)
+  | Unknown_id  {id; pos} ->
+      s "Unknown identifier %S in %s" (Sym.to_string id) (Pos.to_string pos)
+  | Unknown_type {ty_id; pos} ->
+      s "Unknown type %S in %s" (Sym.to_string ty_id) (Pos.to_string pos)
+  | Id_not_a_function {id; pos} ->
+      s "Identifier %S is not a function, it cannot be called in %s"
+        (Sym.to_string id) (Pos.to_string pos)
+  | Wrong_type_of_expression_in_var_dec {var_id; expected; given; pos} ->
+      s ( "Wrong type of expression in declaration of %S. "
+        ^^"Expected: %S, given: %S. In %s")
+        (Sym.to_string var_id)
+        (Typ.to_string expected)
+        (Typ.to_string given)
+        (Pos.to_string pos)
+  | Wrong_type_used_as_record {ty_id; ty; pos} ->
+      s ( "Identifier %S is bound to type %S, not a record. "
+        ^^"It cannot be used in %s")
+        (Sym.to_string ty_id) (Typ.to_string ty) (Pos.to_string pos)
+  | Wrong_type_of_field_value {field_id; expected; given; pos} ->
+      s ( "Field %S is declared to be of type %S, but is bound to expression "
+        ^^"of type %S in %s")
+        (Sym.to_string field_id)
+        (Typ.to_string expected)
+        (Typ.to_string given)
+        (Pos.to_string pos)
+  | Wrong_type_of_arg {func; expected; given; pos} ->
+      s ( "Incorrect type of argument to function %S, expected: %S, given: %S,"
+        ^^" in %s")
+        (Sym.to_string func)
+        (Typ.to_string expected)
+        (Typ.to_string given)
+        (Pos.to_string pos)
+  | Wrong_number_of_args {func; expected; given; pos} ->
+      s ( "Incorrect number of arguments to function %S, "
+        ^^"expected: %d, given: %d,"
+        ^^" in %s")
+        (Sym.to_string func) expected given (Pos.to_string pos)
+  | Invalid_operand_type {oper; valid; given; pos} ->
+      s ( "Invalid operand type %S for operator %S, which expects only: %s"
+        ^^". In %s")
+        (Typ.to_string given)
+        (Abs.op_show oper)
+        (String.concat ", " valid)
+        (Pos.to_string pos)
+  | Different_operand_types {oper; left; right; pos} ->
+      s "Operands of different types (%S %S %S) given in %s"
+        (Typ.to_string left)
+        (Abs.op_show oper)
+        (Typ.to_string right)
+        (Pos.to_string pos)
index 1f0d0ce..4009ed5 100644 (file)
@@ -1,3 +1,52 @@
-exception T of string
+type t =
+  | Invalid_syntax    of Tiger_position.t
+  | Unknown_id        of {id    : Tiger_symbol.t; pos : Tiger_position.t}
+  | Unknown_type      of {ty_id : Tiger_symbol.t; pos : Tiger_position.t}
+  | Id_not_a_function of {id    : Tiger_symbol.t; pos : Tiger_position.t}
+  | Wrong_type_of_expression_in_var_dec of
+      { var_id   : Tiger_symbol.t
+      ; expected : Tiger_env_type.t
+      ; given    : Tiger_env_type.t
+      ; pos      : Tiger_position.t
+      }
+  | Wrong_type_used_as_record of
+      { ty_id    : Tiger_symbol.t
+      ; ty       : Tiger_env_type.t
+      ; pos      : Tiger_position.t
+      }
+  | Wrong_type_of_field_value of
+      { field_id : Tiger_symbol.t
+      ; expected : Tiger_env_type.t
+      ; given    : Tiger_env_type.t
+      ; pos      : Tiger_position.t
+      }
+  | Wrong_type_of_arg of
+      { func     : Tiger_symbol.t
+      ; expected : Tiger_env_type.t
+      ; given    : Tiger_env_type.t
+      ; pos      : Tiger_position.t
+      }
+  | Wrong_number_of_args of
+      { func     : Tiger_symbol.t
+      ; expected : int
+      ; given    : int
+      ; pos      : Tiger_position.t
+      }
+  | Invalid_operand_type of
+      { oper  : Tiger_absyn.oper
+      ; valid : string list
+      ; given : Tiger_env_type.t
+      ; pos   : Tiger_position.t
+      }
+  | Different_operand_types of
+      { oper  : Tiger_absyn.oper
+      ; left  : Tiger_env_type.t
+      ; right : Tiger_env_type.t
+      ; pos   : Tiger_position.t
+      }
 
-val exn : pos:Tiger_position.t -> string -> 'a
+exception T of t
+
+val raise : t -> 'a
+
+val to_string : t -> string
index f4fbff9..b40892a 100644 (file)
@@ -1,5 +1,6 @@
 %{
   module Ast = Tiger_absyn
+  module Err = Tiger_error
   module Sym = Tiger_symbol
 
   let pos () =
@@ -75,7 +76,7 @@
 
 program:
   | exp EOF { $1 }
-  | error {Tiger_error.exn "invalid syntax" ~pos:(pos ())}
+  | error {Err.raise (Err.Invalid_syntax (pos ()))}
   ;
 
 exp:
index 217de6b..6d69ecb 100644 (file)
@@ -29,5 +29,5 @@ let to_string
   }
 =
   Printf.sprintf
-    "file: %S, between (line/char) %d/%d and %d/%d"
+    "file: %S, between (line,char) %d,%d and %d,%d"
     file start_line start_char end_line end_char
This page took 0.029301 seconds and 4 git commands to generate.