[m-rev.] for review: do not hardcode the list of builtin primtive types in so many places

Julien Fischer jfischer at opturion.com
Mon Apr 10 00:50:14 AEST 2017


For review by anyone.

--------------------

Do not hardcode the list of builtin primitive types in so many places.

compiler/prog_data.m:
     Add new predicates to test whether a string or sym_name corresponds
     to a builtin primitive type in Mercury.  Arrange things so that when
     a new alternative is added to the type builtin_type/0, these new
     predicates will need to be updated.

     Add a comment document other places in the compiler that will need
     to be updated if a new primitive type is added.

compiler/add_foreign_enum.m:
compiler/module_qual.qualify_items.m:
compiler/special_pred.m:
compiler/write_module_interface_files.m:
      Use the new predicates rather than listing the primitive types
      directly.

compiler/type_ctor_info.m:
     Add a second mode to builtin_type_ctor/4 in order to to force there to be a
     complete switch on the fourth argument.  The aim is again to force this
     code to be updated if a new primitive type is added.

Julien.

diff --git a/compiler/add_foreign_enum.m b/compiler/add_foreign_enum.m
index 7694c68..37c7e26 100644
--- a/compiler/add_foreign_enum.m
+++ b/compiler/add_foreign_enum.m
@@ -55,12 +55,7 @@ add_pragma_foreign_export_enum(FEEInfo, _TypeStatus, Context,
          % Emit an error message for foreign_export_enum pragmas for the
          % builtin atomic types.
          TypeArity = 0,
-        ( TypeName = unqualified("character")
-        ; TypeName = unqualified("float")
-        ; TypeName = unqualified("uint")
-        ; TypeName = unqualified("int")
-        ; TypeName = unqualified("string")
-        )
+        is_builtin_type_sym_name(TypeName)
      then
          ErrorPieces = [words("error: "),
              unqual_sym_name_and_arity(sym_name_arity(TypeName, TypeArity)),
@@ -379,12 +374,7 @@ add_pragma_foreign_enum(FEInfo, PragmaStatus, Context, !ModuleInfo, !Specs) :-
          % Emit an error message for foreign_enum pragmas for the
          % builtin atomic types.
          TypeArity = 0,
-        ( TypeName = unqualified("character")
-        ; TypeName = unqualified("float")
-        ; TypeName = unqualified("int")
-        ; TypeName = unqualified("uint")
-        ; TypeName = unqualified("string")
-        )
+        is_builtin_type_sym_name(TypeName)
      then
          ErrorPieces = [words("error: "),
              unqual_sym_name_and_arity(sym_name_arity(TypeName, TypeArity)),
diff --git a/compiler/module_qual.qualify_items.m b/compiler/module_qual.qualify_items.m
index bd729b6..95c045f 100644
--- a/compiler/module_qual.qualify_items.m
+++ b/compiler/module_qual.qualify_items.m
@@ -535,11 +535,9 @@ qualify_type_ctor(InInt, ErrorContext, TypeCtor0, TypeCtor,
      %
  :- pred is_builtin_atomic_type(type_ctor::in) is semidet.

-is_builtin_atomic_type(type_ctor(unqualified("int"), 0)).
-is_builtin_atomic_type(type_ctor(unqualified("uint"), 0)).
-is_builtin_atomic_type(type_ctor(unqualified("float"), 0)).
-is_builtin_atomic_type(type_ctor(unqualified("string"), 0)).
-is_builtin_atomic_type(type_ctor(unqualified("character"), 0)).
+is_builtin_atomic_type(TypeCtor) :-
+    TypeCtor = type_ctor(SymName, 0),
+    is_builtin_type_sym_name(SymName).

  %---------------------------------------------------------------------------%
  %
diff --git a/compiler/prog_data.m b/compiler/prog_data.m
index 14b0c9a..eeb14d6 100644
--- a/compiler/prog_data.m
+++ b/compiler/prog_data.m
@@ -482,6 +482,16 @@ cons_id_is_const_struct(ConsId, ConstNum) :-
              % A type expression with an explicit kind annotation.
              % (These are not yet used.)

+
+    % This type enumerates all of the builtin primitive types in Mercury.
+    % If you add a new alternative then you may also need to update the
+    % following predicates:
+    %
+    %     - parse_type_name.is_known_type_name_args/3
+    %     - inst_check.check_inst_defn_has_matching_type/7
+    %     - llds_out_data.output_type_ctor_addr/5
+    %     - type_util.classify_type_ctor/2
+    %
  :- type builtin_type
      --->    builtin_type_int
      ;       builtin_type_uint
@@ -489,6 +499,10 @@ cons_id_is_const_struct(ConsId, ConstNum) :-
      ;       builtin_type_string
      ;       builtin_type_char.

+:- pred is_builtin_type_sym_name(sym_name::in) is semidet.
+
+:- pred is_builtin_type_name(string::in) is semidet.
+
  :- type type_term == term(tvar_type).

  :- type tvar_type
@@ -534,6 +548,23 @@ cons_id_is_const_struct(ConsId, ConstNum) :-

  :- implementation.

+is_builtin_type_sym_name(SymName) :-
+    SymName = unqualified(Name),
+    builtin_type_name(_, Name).
+
+is_builtin_type_name(Name) :-
+    builtin_type_name(_, Name).
+
+:- pred builtin_type_name(builtin_type, string).
+:- mode builtin_type_name(in, out) is det.
+:- mode builtin_type_name(out, in) is semidet.
+
+builtin_type_name(builtin_type_int, "int").
+builtin_type_name(builtin_type_uint, "uint").
+builtin_type_name(builtin_type_float, "float").
+builtin_type_name(builtin_type_string, "string").
+builtin_type_name(builtin_type_char, "character").
+
  tvarset_merge_renaming(TVarSetA, TVarSetB, TVarSet, Renaming) :-
      varset.merge_renaming(TVarSetA, TVarSetB, TVarSet, Renaming).

diff --git a/compiler/special_pred.m b/compiler/special_pred.m
index afa3e19..1a4d51c 100644
--- a/compiler/special_pred.m
+++ b/compiler/special_pred.m
@@ -340,11 +340,7 @@ can_generate_special_pred_clauses_for_type(ModuleInfo, TypeCtor, TypeBody) :-
  is_builtin_type_special_preds_defined_in_mercury(TypeCtor, TypeName) :-
      Builtin = mercury_public_builtin_module,
      TypeCtor = type_ctor(qualified(Builtin, TypeName), 0),
-    ( TypeName = "int"
-    ; TypeName = "uint"
-    ; TypeName = "string"
-    ; TypeName = "character"
-    ; TypeName = "float"
+    ( is_builtin_type_name(TypeName)
      ; TypeName = "pred"
      ).

diff --git a/compiler/type_ctor_info.m b/compiler/type_ctor_info.m
index d6696b5..70280f9 100644
--- a/compiler/type_ctor_info.m
+++ b/compiler/type_ctor_info.m
@@ -428,8 +428,9 @@ construct_type_ctor_info(TypeCtorGenInfo, ModuleInfo, RttiData) :-
      ),
      RttiData = rtti_data_type_ctor_info(TypeCtorData).

-:- pred builtin_type_ctor(string::in, string::in, int::in, builtin_ctor::out)
-    is semidet.
+:- pred builtin_type_ctor(string, string, int, builtin_ctor).
+:- mode builtin_type_ctor(in, in, in, out) is semidet.
+:- mode builtin_type_ctor(out, out, out, in) is det.

  % Some of these type_ctors are listed in prog_type.m in the function
  % builtin_type_ctors_with_no_hlds_type_defn; any changes here may need
diff --git a/compiler/write_module_interface_files.m b/compiler/write_module_interface_files.m
index ba09cb5..9769983 100644
--- a/compiler/write_module_interface_files.m
+++ b/compiler/write_module_interface_files.m
@@ -1196,12 +1196,7 @@ type_to_type_ctor_set(Type, !TypeCtors) :-
              % arguments.
              true
          else if
-            ( SymName = unqualified("int")
-            ; SymName = unqualified("uint")
-            ; SymName = unqualified("float")
-            ; SymName = unqualified("string")
-            ; SymName = unqualified("character")
-            )
+            is_builtin_type_sym_name(SymName)
          then
              % We don't need to import these modules as the types are builtin.
              true



More information about the reviews mailing list