From c16dd441582b7c7c09cdb3e706f4767a5b266177 Mon Sep 17 00:00:00 2001 From: Siraaj Khandkar Date: Wed, 12 Sep 2018 18:30:12 -0400 Subject: [PATCH] Define (some) semantic errors --- compiler/src/exe/tigerc.ml | 4 +- compiler/src/lib/tiger/tiger_absyn.ml | 15 +++ compiler/src/lib/tiger/tiger_absyn.mli | 2 + compiler/src/lib/tiger/tiger_error.ml | 113 ++++++++++++++++++++++- compiler/src/lib/tiger/tiger_error.mli | 53 ++++++++++- compiler/src/lib/tiger/tiger_parser.mly | 3 +- compiler/src/lib/tiger/tiger_position.ml | 2 +- 7 files changed, 182 insertions(+), 10 deletions(-) diff --git a/compiler/src/exe/tigerc.ml b/compiler/src/exe/tigerc.ml index 5468ff7..4bf0c62 100644 --- a/compiler/src/exe/tigerc.ml +++ b/compiler/src/exe/tigerc.ml @@ -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) diff --git a/compiler/src/lib/tiger/tiger_absyn.ml b/compiler/src/lib/tiger/tiger_absyn.ml index 6e4a7e9..73a081a 100644 --- a/compiler/src/lib/tiger/tiger_absyn.ml +++ b/compiler/src/lib/tiger/tiger_absyn.ml @@ -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" diff --git a/compiler/src/lib/tiger/tiger_absyn.mli b/compiler/src/lib/tiger/tiger_absyn.mli index 662f637..b2f9406 100644 --- a/compiler/src/lib/tiger/tiger_absyn.mli +++ b/compiler/src/lib/tiger/tiger_absyn.mli @@ -138,3 +138,5 @@ and fundec = type t = exp val to_string : t -> string + +val op_show : oper -> string diff --git a/compiler/src/lib/tiger/tiger_error.ml b/compiler/src/lib/tiger/tiger_error.ml index 9e0d16a..20a1f7d 100644 --- a/compiler/src/lib/tiger/tiger_error.ml +++ b/compiler/src/lib/tiger/tiger_error.ml @@ -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) diff --git a/compiler/src/lib/tiger/tiger_error.mli b/compiler/src/lib/tiger/tiger_error.mli index 1f0d0ce..4009ed5 100644 --- a/compiler/src/lib/tiger/tiger_error.mli +++ b/compiler/src/lib/tiger/tiger_error.mli @@ -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 diff --git a/compiler/src/lib/tiger/tiger_parser.mly b/compiler/src/lib/tiger/tiger_parser.mly index f4fbff9..b40892a 100644 --- a/compiler/src/lib/tiger/tiger_parser.mly +++ b/compiler/src/lib/tiger/tiger_parser.mly @@ -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: diff --git a/compiler/src/lib/tiger/tiger_position.ml b/compiler/src/lib/tiger/tiger_position.ml index 217de6b..6d69ecb 100644 --- a/compiler/src/lib/tiger/tiger_position.ml +++ b/compiler/src/lib/tiger/tiger_position.ml @@ -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 -- 2.20.1