Commit Graph

51 Commits

Author SHA1 Message Date
Zoltan Somogyi
e2a8a8cbfa Break up mercury_to_mercury.m.
compiler/mercury_to_mercury.m:
    Delete this module, and replace it with ...

compiler/parse_tree_out_cons_id.m:
compiler/parse_tree_out_sym_name.m:
compiler/parse_tree_out_type.m:
compiler/parse_tree_out_misc.m:
    ... these four modules. The first three write out the entities
    in their names: cons_ids, sym_names, and types. The fourth contains
    the rest of the old mercury_to_mercury.m, plus a few predicates
    moved there from prog_out.m that deal with indentation.

compiler/parse_tree.m:
    Include the four new modules, and stop including the deleted module.

compiler/notes/compiler_design.html:
    Document the new modules.

compiler/prog_out.m:
    Delete the code moved to parse_tree_out_misc.m.

compiler/*.m:
    Adjust the imports as needed. Most modules need only one, maybe two
    of mercury_to_mercury's four successor modules.
2023-04-06 15:32:48 +10:00
Zoltan Somogyi
307b1dc148 Split up error_util.m into five modules.
compiler/error_spec.m:
    This new module contains the part of the old error_util.m that defines
    the error_spec type, and some functions that can help construct pieces
    of error_specs. Most modules of the compiler that deal with errors
    will need to import only this part of the old error_util.m.

    This change also renames the format_component type to format_piece,
    which matches our long-standing naming convention for variables containing
    (lists of) values of this type.

compiler/write_error_spec.m:
    This new module contains the part of the old error_util.m that
    writes out error specs, and converts them to strings.

    This diff marks as obsolete the versions of predicates that
    write out error specs to the current output stream, without
    *explicitly* specifying the intended stream.

compiler/error_sort.m:
    This new module contains the part of the old error_util.m that
    sorts lists of error specs and error msgs.

compiler/error_type_util.m:
    This new module contains the part of the old error_util.m that
    convert types to format_pieces that generate readable output.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Include and document the new modules.

compiler/error_util.m:
    The code remaining in the original error_util.m consists of
    general utility predicates and functions that don't fit into
    any of the modules above.

    Delete an unneeded pair of I/O states from the argument list
    of a predicate.

compiler/file_util.m:
    Move the unable_to_open_file predicate here from error_util.m,
    since it belongs here. Mark another predicate that writes
    to the current output stream as obsolete.

compiler/hlds_error_util.m:
    Mark two predicates that wrote out error_spec to the current output
    stream as obsolete, and add versions that take an explicit output stream.

compiler/Mercury.options:
    Compile the modules that call the newly obsoleted predicates
    with --no-warn-obsolete, for the time being.

compiler/*.m:
    Conform to the changes above, mostly by updating import_module
    declarations, and renaming format_component to format_piece.
2022-10-12 20:50:16 +11:00
Zoltan Somogyi
dd632327db Generalize component_list_to_line_pieces.
compiler/error_util.m:
    Do not automatically add an nl to the end of the output
    of component_list_to_line_pieces; instead, let the callers specify
    how the last line should end. Most will pass nl, but some will pass
    an nl_indent_delta to undo an earlier nl_indent_delta.

compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_mode.m:
compiler/add_pragma.m:
compiler/error_msg_inst.m:
compiler/post_typecheck.m:
compiler/prog_foreign_enum.m:
compiler/typecheck_errors.m:
    Conform to the change in error_util.m.
2022-02-16 13:59:55 +11:00
Zoltan Somogyi
01650a9f24 Fix a bug in the unused import computation.
compiler/unused_imports.m:
    The bug was that if a procedure is exported, then the code considered
    that any module mentioned in the type of *any* its variables was used
    in the interface, when in fact only the modules mentioned in the types
    of its *arguments* are used in the interface; the rest are used *only*
    in the implementation.

    Improve the debugging infrastructure.

NEWS:
    Announce the change in the behavior of --warn-unused-imports.

compiler/type_util.m:
    If a type_ctor has an unqualified sym_name, return "builtin" as its
    module name, since

    - after typechecking, all type_ctors will be module qualified, with
      the only exceptions being the type_ctors of builtin types; and
    - before typechecking, no type_ctors will be module qualified beyond
      whatever qualification may have been written down explicitly
      by the programmer, which makes calling the affected functions futile.

compiler/add_foreign_enum.m:
compiler/check_raw_comp_unit.m:
compiler/common.m:
compiler/hlds_out_inst_table.m:
compiler/hlds_out_module.m:
compiler/hlds_out_type_table.m:
compiler/lambda.m:
compiler/polymorphism_info.m:
compiler/polymorphism_post_copy.m:
compiler/polymorphism_type_class_info.m:
compiler/prog_foreign_enum.m:
compiler/simplify_tasks.m:
compiler/structure_reuse.analysis.m:
    Move imports from the interface to the implementation if, with the
    bug fix, we would get a warning from them remaining in the interface.
2021-08-09 14:36:31 +10:00
Zoltan Somogyi
09aff57259 Represent "is this a subtype" using a bespoke type.
compiler/prog_data.m:
compiler/hlds_data.m:
    Use a new type, maybe_subtype, to say whether a du type is a subtype.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_parse_tree_type_defns.m:
compiler/comp_unit_interface.m:
compiler/decide_type_repn.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/hlds_out_module.m:
compiler/ml_type_gen.m:
compiler/mlds.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/prog_type.m:
compiler/recompilation.usage.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
    Conform to the changes above.
2021-07-09 09:25:04 +10:00
Zoltan Somogyi
254cd500bf Add bespoke type for du types' details.
compiler/hlds_data.m:
    As above. The other kinds of types already had bespoke types
    for *their* details.

compiler/add_type.m:
compiler/du_type_layout.m:
    Instead of passing values of the hlds_type_body with an inst
    that said they were du types, pass values of the new types instead,
    which is significantly simpler.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/mlds.m:
compiler/mode_util.m:
compiler/post_term_analysis.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2021-07-01 08:26:04 +10:00
Zoltan Somogyi
6ea29f4f72 Factor common code into prog_foreign_enum.m.
compiler/prog_foreign_enum.m:
    This new module contains

    - code that used to be duplicated in add_foreign_enum.m and
      check_parse_tree_type_defns.m, and

    - utility predicates called by that common code.

    Moving all this code into a new module in the parse_tree package
    allows check_parse_tree_type_defns.m which is also in the parse_tree
    package, to avoid importing add_foreign_enum.m, which is in the hlds
    package.

compiler/parse_tree.m:
    Include the new module in the parse_tree package.

compiler/notes/compiler_design.html:
    Document the new module.

compiler/add_foreign_enum.m:
compiler/check_parse_tree_type_defns.m:
    Delete the code moved to prog_foreign_enum.m.
2021-06-23 23:25:53 +10:00
Peter Wang
74a31ba8ef Parse and check subtype definitions.
This is the first step towards implementing a subtypes feature.
It introduces type definitions of the form

    :- type subtype =< supertype ---> body.

Later, terms of a subtype should share a data representation with their
supertype, and it will be possible to convert terms between two types
that share "base types" using a coerce operation.

doc/reference_manual.texi:
    Add documentation for subtypes.

    Add documentation for a proposed `coerce' operation, commented out
    for now.

    Add "=<" to the list of reserved type names.

compiler/hlds_data.m:
    Add supertype field to hlds_du_type.

compiler/prog_data.m:
    Add du_supertype field to type_details_du.

    Add comment for future work.

compiler/parse_type_defn.m:
    Parse subtype definitions.

    Check that variables which occur in the "=< supertype" part
    also occur on the left hand side of the subtype definition.

compiler/parse_type_name.m:
    Add a new context for why_no_ho_inst_info.

    Add "=<" to is_known_type_name, i.e. prevent the user from defining
    a type of that name (any longer).

compiler/add_type.m:
    Rename add_du_ctors_check_foreign_type_for_cur_backend to
    add_du_ctors_check_subtype_check_foreign_type.

    In add_du_ctors_check_subtype_check_foreign_type, check that
    subtype definitions satisfy the conditions documented in the
    reference manual.

compiler/make_hlds_passes.m:
    Conform to previous renaming.

compiler/comp_unit_interface.m:
    Follow supertypes when computing the required type constructors
    whose definitions need to be kept in the implementation section
    of a .int file.

compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
    Replace equivalence types in supertypes.

compiler/module_qual.qualify_items.m:
    Perform module qualification in supertypes.

compiler/hlds_out_module.m:
    Write out the "=< supertype" part of subtype definitions.

compiler/parse_tree_out.m:
    Write out the "=< supertype" part of subtype definitions.

compiler/recompilation.usage.m:
    Follow supertypes when finding used items.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/det_report.m:
compiler/direct_arg_in_out.m:
compiler/du_type_layout.m:
compiler/foreign.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen_test.m:
compiler/ml_unify_gen_util.m:
compiler/post_term_analysis.m:
compiler/prog_type.m:
compiler/recompilation.check.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to HLDS changes.

    Add comments for future work.

tests/invalid/Mmakefile:
tests/invalid/subtype_abstract.err_exp:
tests/invalid/subtype_abstract.m:
tests/invalid/subtype_circular.err_exp:
tests/invalid/subtype_circular.m:
tests/invalid/subtype_ctor_arg.err_exp:
tests/invalid/subtype_ctor_arg.m:
tests/invalid/subtype_eqv.err_exp:
tests/invalid/subtype_eqv.m:
tests/invalid/subtype_exist_constraints.err_exp:
tests/invalid/subtype_exist_constraints.m:
tests/invalid/subtype_exist_vars.err_exp:
tests/invalid/subtype_exist_vars.m:
tests/invalid/subtype_foreign.err_exp:
tests/invalid/subtype_foreign.m:
tests/invalid/subtype_foreign_supertype.err_exp:
tests/invalid/subtype_foreign_supertype.m:
tests/invalid/subtype_foreign_supertype2.err_exp:
tests/invalid/subtype_foreign_supertype2.err_exp2:
tests/invalid/subtype_foreign_supertype2.m:
tests/invalid/subtype_ho.err_exp:
tests/invalid/subtype_ho.m:
tests/invalid/subtype_invalid_supertype.err_exp:
tests/invalid/subtype_invalid_supertype.m:
tests/invalid/subtype_not_subset.err_exp:
tests/invalid/subtype_not_subset.m:
tests/invalid/subtype_syntax.err_exp:
tests/invalid/subtype_syntax.m:
tests/invalid_submodules/Mercury.options:
tests/invalid_submodules/Mmakefile:
tests/invalid_submodules/subtype_submodule.err_exp:
tests/invalid_submodules/subtype_submodule.m:
tests/valid/Mmakefile:
tests/valid/subtype_basic.m:
    Add test cases.
2021-03-15 11:16:31 +11:00
Zoltan Somogyi
a19a5f0267 Delete the Erlang backend from the compiler.
compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_backend.m:
compiler/erl_call_gen.m:
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
compiler/erl_rtti.m:
compiler/erl_unify_gen.m:
compiler/erlang_rtti.m:
compiler/mercury_compile_erl_back_end.m:
    Delete these modules, which together constitute the Erlang backend.

compiler/notes/compiler_design.html:
    Delete references to the deleted modules.

compiler/parse_tree_out_type_repn.m:
    Update the format we use to represent the sets of foreign_type and
    foreign_enum declarations for a type as part of its item_type_repn_info,
    now that Erlang is no longer a target language.

compiler/parse_type_repn.m:
    Accept both the updated version of the item_type_repn_info and the
    immediately previous version, since the installed compiler will
    initially generate that previous version. However, stop accepting
    an even older version that we stopped generating several months ago.

compiler/parse_pragma_foreign.m:
    When the compiler finds a reference to Erlang as a foreign language,
    add a message about support for Erlang being discontinued to the error
    message.

    Make the code parsing foreign_decls handle the term containing
    the foreign language the same way as the codes parsing foreign
    codes, procs, types and enums.

    Add a mechanism to help parse_mutable.m to do the same.

compiler/parse_mutable.m:
    When the compiler finds a reference to Erlang as a foreign language,
    print an error message about support for Erlang being discontinued.

compiler/compute_grade.m:
    When the compiler finds a reference to Erlang as a grade component,
    print an informational message about support for Erlang being discontinued.

compiler/pickle.m:
compiler/make.build.m:
    Delete Erlang foreign procs and types.

compiler/add_foreign_enum.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/check_libgrades.m:
compiler/check_parse_tree_type_defns.m:
compiler/code_gen.m:
compiler/compile_target_code.m:
compiler/compute_grade.m:
compiler/const_struct.m:
compiler/convert_parse_tree.m:
compiler/dead_proc_elim.m:
compiler/decide_type_repn.m:
compiler/deps_map.m:
compiler/du_type_layout.m:
compiler/export.m:
compiler/foreign.m:
compiler/globals.m:
compiler/granularity.m:
compiler/handle_options.m:
compiler/hlds_code_util.m:
compiler/hlds_data.m:
compiler/hlds_module.m:
compiler/inlining.m:
compiler/int_emu.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/lco.m:
compiler/llds_out_file.m:
compiler/make.dependencies.m:
compiler/make.m:
compiler/make.module_dep_file.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.util.m:
compiler/make_hlds_separate_items.m:
compiler/make_hlds_warn.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_code_util.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_target_util.m:
compiler/ml_top_gen.m:
compiler/mlds.m:
compiler/mlds_dump.m:
compiler/mlds_to_c_export.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_cs_data.m:
compiler/mlds_to_cs_export.m:
compiler/mlds_to_cs_file.m:
compiler/mlds_to_cs_type.m:
compiler/mlds_to_java_export.m:
compiler/mlds_to_java_file.m:
compiler/mlds_to_java_type.m:
compiler/module_imports.m:
compiler/parse_pragma_foreign.m:
compiler/parse_tree_out.m:
compiler/polymorphism.m:
compiler/pragma_c_gen.m:
compiler/prog_data.m:
compiler/prog_data_foreign.m:
compiler/prog_foreign.m:
compiler/prog_item.m:
compiler/simplify_goal_scope.m:
compiler/special_pred.m:
compiler/string_encoding.m:
compiler/top_level.m:
compiler/uint_emu.m:
compiler/write_deps_file.m:
    Remove references to Erlang as a backend or as a target language.

tests/invalid/bad_foreign_code.{m,err_exp}:
tests/invalid/bad_foreign_decl.{m,err_exp}:
tests/invalid/bad_foreign_enum.{m,err_exp}:
tests/invalid/bad_foreign_export.{m,err_exp}:
tests/invalid/bad_foreign_export_enum.{m,err_exp}:
tests/invalid/bad_foreign_import_module.{m,err_exp}:
tests/invalid/bad_foreign_proc.{m,err_exp}:
tests/invalid/bad_foreign_type.{m,err_exp}:
    Add a test for Erlang as an invalid foreign language. Expect both the
    new error message for this new error, and the updated list of now-valid
    foreign languages on all errors.
2020-10-29 13:24:49 +11:00
Zoltan Somogyi
5c52cf0cde Standardize on "sym_name_arity" ...
... replacing "sym_name_AND_arity".
2020-03-15 19:37:18 +11:00
Zoltan Somogyi
9789375cc5 Make pre-HLDS passes use file-kind-specific parse trees.
Replacing item blocks file-kind-specific kinds of section markers with
file-kind-specific parse trees has several benefits.

- It allows us to encode the structural invariants of each kind of file
  we read in within the type of its representation. This makes the detection
  of any accidental violations of those invariants trivial.

- Since each file-kind-specific parse tree has separate lists for separate
  kinds of items, code that wants to operate on one or a few kinds of items
  can just operate on those kinds of items, without having to traverse
  item blocks containing many other kinds of items as well. The most
  important consequence of this is not the improved efficiency, though
  that is nice, but the increased clarity of the code.

- The new design is much more flexible. For example, it should be possible
  to record that e.g. an interface file we read in as a indirect dependency
  (i.e. a file we read not because its module was imported by the module
  we are compiling, but because its module was imported by *another* imported
  module) should be used *only* for the purpose it was read in for. This should
  avoid situations where deleting an import of A from a module, because it
  is not needed anymore, leads the compiler to generate an error message
  about a missing import of module B. This can happen if (a) module B
  always *should* have been imported, since it is used, but (b) module A's
  import of module B lead to module B's interface being available *without*
  an import of B.

  Specifically, this flexibility should enable us to establish each module's
  .int file as the single source of truth about how values of each type
  defined in that module should be represented. When compiling each source
  file, this approach requires the compiler to read in that module's .int file
  but using only the type_repn items from that .int file, and nothing else.

- By recording a single parse tree for each file we have read, instead of
  a varying number of item blocks, it should be significantly easier to
  derive the contents of .d files directly from the records of those
  parse trees, *without* having to maintain a separate set of fields
  in the module_and_imports structure for that purpose. We could also
  trivially avoid any possibility of inconsistencies between these two
  different sources of truth. (We currently fill in the fields used to
  drive the generation of .d files using two different pieces of code,
  one used for --generate-dependencies and one used for all other invocations,
  and these two *definitely* generate inconsistent results, as the significant
  differences in .d files between (a) just after an invocation of
  --generate-dependencies and (b) just after any other compiler invocation
  can witness.)

This change is big and therefore hard to review. Therefore in many files,
this change adds "XXX CLEANUP" comments to draw attention to places that
have issues that should be fixed, but whose fixes should come later, in
separate diffs.

compiler/module_imports.m:
    The compiler uses the module_and_imports structure defined here
    to go from a raw compilation unit (essentially a module to be compiled)
    to an augmented compilation unit (a raw compilation unit together
    with all the interface and optimization files its compilation needs).
    We used to store the contents of both the source file and of
    the interface and optimization files in the module_and_imports structure
    as item blocks. This diff replaces all those item blocks with
    file-kind-specific parse trees, for the reasons mentioned above.

    Separate out the .int0 files of ancestors modules from the .intN
    files for N>0 of directly imported modules. (Their item blocks
    used to be stored in the same list.)

    Maintain a database of the source, interface and optimization files
    we have read in so far. We use it to avoid reading in interface files
    if we have already read in a file for the same module that contains
    strictly more information (either an interface file with a smaller
    number as a suffix, or the source file itself).

    Shorten some field names.

compiler/prog_item.m:
    Define data structures for storing information about include_module,
    import_module and use_module declarations, both in a form that allows
    the representation of possibly erroneous code in actual source files,
    and in checked-and-cleaned-up form which is guaranteed to be free
    of the relevant kinds of errors. Add a block comment at the start
    of the module about the need for this distinction.

    Define parse_tree_module_src, a data structure for representing
    the source code of a single module. This is different from the existing
    parse_tree_src type, which represents the contents of a single source file
    but which may contain *more* than one module, and also different from
    a raw_compilation_unit, which is based on item blocks and is thus
    unable to express to invariants such as "no clauses in the interface".

    Modify the existing parse_tree_intN types to express the distinction
    mentioned just above, and to unify them "culturally", i.e. if they
    store the same information, make them store it using the same types.

    Fix a mistake by allowing promises to appear in .opt files.
    I originally ruled them out because the code that generates .opt files
    does not have any code to write out promises, but some of the predicates
    whose clauses it writes out have goal_type_promise, which means that
    they originated as promises, and get written out as promises.

    Split the existing pragma item kind into three item kinds, which have
    different invariants applying to them.

    - The decl (short for declarative) pragmas give the compiler some
      information, such as that a predicate is obsolete or that we
      want to type specialize some predicate or function, that is in effect
      part of the module's interface. Decl pragmas may appear in module
      interfaces, and the compiler may put them into interface files;
      neither statement is true of the other two kinds of pragmas.

    - The impl (short for implementation) pragmas are named so
      precisely because they may appear only in implementation sections.
      They give the compiler information that is private to that module.
      Examples include foreign_decls, foreign_codes, foreign_procs,
      and promises of clause equivalence, and requests for inlining,
      tabling etc. These will never be put into interface files,
      though some of them can affect the compilation of other modules
      by being included in .opt files.

    - The gen (short for generated) pragmas can never (legally) appear
      in source files at all. They record the results of compiler
      analyses e.g. about which arguments of a predicate are unused,
      or what exceptions a function can throw, and accordingly they
      should only ever occur in compiler-generated interface files.

    Use the new type differences between the three kinds of pragmas
    to encode the above invariants about which kinds of pragmas can appear
    where into the various kinds of parse trees.

    Make the augmented compilation unit, which is computed from
    the final module_and_imports structure, likewise switch from
    storing item blocks to storing the whole parse trees of the
    files that went into its construction. With each such parse tree,
    record *why* we read it, since this controls what permissions
    the source module being compiled has for access to the entities
    in the parse tree.

    Simplify the contains_foreign_code type, since one of three
    function symbols was equivalent to one possible use of another
    function symbol.

    Provide a way to record which method of which class a compiler-generated
    predicate is for. (See hlds_pred.m below.)

    Move the code of almost all utility operations to item_util.m
    (which is imported by many fewer modules than prog_item.m),
    keeping just the most "popular" ones.

compiler/item_util.m:
    Move most of the previously-existing utility operations here from
    prog_item.m, most in a pretty heavily modified form.

    Add a whole bunch of other utility operations that are needed
    in more than one other module.

compiler/convert_parse_tree.m:
    Provide predicates to convert from raw compilation units to
    parse_tree_module_srcs, and vice versa (though the reverse
    shouldn't be needed much longer).

    Update the conversion operations between the general parse_tree_int
    and the specific parse_tree_intN forms for the changes in prog_item.m
    mentioned above. In doing so, use a consistent approach, based on
    new operations in item_util.m, to detect errors such as duplicate
    include_module and import/use_module declarations in all kinds
    of parse trees.

    Enforce the invariants that the types of parse trees of various kinds
    can now express in types, generating error messages for their violations.

    Delete some utility operations that have been moved to item_util.m
    because now they are also needed by other modules.

compiler/grab_modules.m:
    Delete code that did tests on raw compilation units that are now done
    when that raw compilation unit is converted to a parse_tree_module_src.
    Use the results of the checks done during that conversion to decide
    which modules are imported/used and in which module section.

    Record a single reason for why we reading in each interface and
    optimization file. The code of make_hlds_separate_items.m will use
    this reason to set up the appropriate permissions for each item
    in those files.

    Use separate code for handling different kinds of interface and
    optimization files. Using generic traversal code was acceptable economy
    when we used the same data structure for every kind of interface file,
    but now that we *can* express different invariants for different kinds
    of interface and optimization file, we want to execute not just different
    code for each kind of file, but the data structures we want to work on
    are also of different types. Using file-kind-specific code is a bit
    longer, but it is significantly simpler and more robust, and it is
    *much* easier to read and understand.

    Delete the code that separates the parts of the implementation section
    that are exported to submodules, and the part that isn't, since that task
    is now done in make_hlds_separate_items.m.

    Pass a database of the files we have read through the relevant predicates.

    Give some predicates more meaningful names.

compiler/notes/interface_files.html:
    Note a problem with the current operation of grab_modules.

compiler/get_dependencies.m:
    Add operations to gather implicit references to builtin modules
    (which have to be made available even without an explicit import_module
    or use_module declaration) in all kinds of parse trees. These have
    more code overall, but will be at runtime, since we need only look at
    the item kinds that may *have* such implicit references.

    Add a mechanism to record the result of these gathering operations
    in import_and_or_use_maps.

    Give some types, function symbols, predicates and variables
    more meaningful names.

compiler/make_hlds_separate_items.m:
    When we stored the contents of the source module and the
    interface and optimization files we read in to augment it
    in the module_and_imports structure as a bunch of item blocks,
    the job of this module was to separate out the different kinds of items
    in the item blocks, returning a single list of each kind of item,
    with each such item being packaged up with its status (which encodes
    a set of permissions saying what the source module is allowed
    to do with it).

    Now that the module_and_imports structure stores this info in
    file-kind-specific parse trees, all of which have separate lists
    for each kind of item and none of which contain item blocks,
    the job of this module has changed. Now its job is to convert
    the reason why each file was read in into the (one or more) statuses
    that apply to the different kinds of items stored in it, wrap up
    each item with its status, and return the resulting overall list
    of status/item pairs for each kind of item.

compiler/read_modules.m:
    Add predicates that, when reading an interface file, return its contents
    in the tightest possible file-kind-specific parse tree.

    Refine the database of files we have read to allow us to store
    more file-kind-specific parse trees.

    Don't require that files in the database have associated timestamps,
    since in some cases, we read files we can put into the database
    *without* getting their timestamps.

    Allow the database to record that an attempt to read a file failed.

compiler/split_parse_tree_src.m:
    Rearchitect how this module separates out nested submodules from within
    the main module in a file.

    Another of the jobs of this module is to generate error messages for
    when module A includes module B twice, whether via nesting or via
    include_module declarations, with one special exception for the case
    where A's interface contains nested submodule A.B's interface,
    and A's implementation contains nested submodule A.B's implementation.
    The problem ironically was that while it reported duplicate include_module
    declarations as errors, split_parse_tree_src.m also *generated*
    duplicate include_module declarations. Since it replaced each nested
    submodule occurrence with an include_module declaration, in the scenario
    above, it generated two include_module declarations for A.B. Even worse,
    the interface incarnation of submodule A.B could contain
    (the interface of) its own nested submodule A.B.C, while its
    implementation incarnation could contain (the implementation section of)
    A.B.C. Each occurrence of A.B.C would be its only occurrence in the
    including part of its parent A.B, which means local tests for duplicates
    do not work. (I found this out the hard way.)

    The solution we now adopt adds include_module declarations to the
    parents of any submodule only once the parse tree of the entire
    file has been processed, since only then do we know all the
    includer/included relationships among nested modules. Until then,
    we just record such relationships in a database as we discover them,
    reporting duplicates when needed (e.g. when A includes B twice
    *in the same section*), but not reporting duplicates when not needed
    (e.g. when A.B includes A.B.C in *different* sections).

compiler/prog_data.m:
    Add a new type, pf_sym_name_and_arity, that exactly specifies
    a predicate or function. It is a clone of the existing simple_call_id
    type, but its name does NOT imply that the predicate or function
    is being called.

    Add XXXs that call for some other improvements in type names.

compiler/prog_data_foreign.m:
    Give a type, and the operations on that type, a more specific name.

compiler/error_util.m:
    Add an id field to all error_specs, which by convention should be
    filled in with $pred. Print out the value in this field if the compiler
    is invoked with the developer-only option --print-error-spec-id.
    This allows a person debugging the compiler find out where in the code
    an undesired error message is coming from significantly easier
    than was previously possible.

    Most of the modules that have changes only "to conform to the changes
    above" will be for this change. In many cases, the updated code
    will also simplify the creation of the affected error_specs.

    Fix a bug that looked for a phase in only one kind of error_spec.

    Add some utility operations needed by other parts of this change.

    Delete a previously internal function that has been moved to
    mdbcomp/prim_data.m to make it accessible in other modules as well.

compiler/Mercury.options:
    Ask the compiler to warn about dead predicates in every module
    touched by this change (at least in one its earlier versions).

compiler/add_foreign_enum.m:
    Replace a check for an inappropriately placed foreign_enum declaration
    with a sanity check, since with this diff, the error should be caught
    earlier.

compiler/add_mutable_aux_preds.m:
    Delete a check for an inappropriately placed mutable declaration,
    since with this diff, the error should be caught earlier.

compiler/add_pragma.m:
    Instead of adding pass2 and pass3 pragmas, add decl and impl and
    generated pragmas.

    Delete the tests for generated pragma occurring anywhere except
    .opt files, since those tests are now done earlier.

    Shorten some too-long predicate names.

compiler/comp_unit_interface.m:
    Operate on as specific kinds of parse trees as the interface of this
    module will allow. (We could operate on more specific parse trees
    if we changed the interface, but that is future work).

    Use the same predicates for handling duplicate include_module,
    import_module and use_module declarations as everywhere else.

    Delete the code of an experiment that shouldn't be needed anymore.

compiler/equiv_type.m:
    Replace code that operated on item blocks with code that operates
    on various kinds of parse trees.

    Move a giant block of comments to the front, where it belongs.

compiler/hlds_module.m:
    Add a field to the module_info that lets us avoid generating
    misleading error messages above missing definitions of predicates
    or functions when those definitions were present but were not
    added to the HLDS because they had errors.

    Give a field and its access predicates a more specific name.

    Mark a spot where an existing type cannot express everything
    it is supposed to.

compiler/hlds_pred.m:
    For predicates which the compiler creates to represent a class method
    (the virtual function, in OOP terms), record not just this fact,
    but the id of the class and of the method. Using this extra info
    in progress messages (with mmc -V) prevents the compiler from printing e.g.

        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method
        % Checking typeclass constraints on class method

    when checking three such predicates.

compiler/make.m:
    Provide a slot in the make_info structure to allow the database
    of the files we have read in to be passed around.

compiler/make_hlds_error.m:
    Delete predicates that are needed in just one other module,
    and have therefore been moved there.

compiler/make_hlds_passes.m:
    Add decl, impl and generated pragma separately, instead of adding
    pass2 and pass3 pragmas separately.

    Do not generate error messages for clauses, initialises or finalises
    in module interfaces, since with this diff, such errors should be
    caught earlier.

compiler/mercury_compile_main.m:
compiler/recompilation.check.m:
    Explicitly pass around the expanded database of parse trees
    of files that have been read in.

compiler/module_qual.collect_mq_info.m:
compiler/module_qual.m:
compiler/module_qual.qualify_items.m:
    Collect module qualification information, and do module qualification
    respectively on parse trees of various kinds, not item blocks.
    Take information about what the module may do with the contents
    of each interface or optimization file from the record of why
    we read that file, not from the section markers in item blocks.

    Break up some too-large predicates by carving smaller ones out of them.

compiler/options.m:
    Add an option to control whether errors and/or warnings detecting
    when deciding what should go into a .intN file be printed,
    thus (potentially) preventing the creation of that file.

    Add commented-out documentation for a previously totally undocumented
    option.

doc/user_guide.texi:
    Document the new option.

NEWS:
    Announce the new option.

    Mention that we now generate warnings for unused import_module and
    use_module declarations in the interface even if the module has
    submodules.

compiler/write_module_interface_files.m:
    Let the new option control whether we filter out any messages generated
    when deciding what should go into a .intN file.

compiler/parse_item.m:
    Delete actually_read_module_opt, since it is no longer needed;
    its callers now call actually_read_module_{plain,trans}_opt instead.

    Delete unneeded arguments from some predicates.

compiler/parse_module.m:
    Delete some long unused predicates.

compiler/parse_pragma.m:
    When parsing pragmas, wrap them up in the new decl, impl or generated
    pragma kinds.

compiler/parse_tree_out.m:
    Add predicates to write out each of the file-kind-specific parse trees.

compiler/parse_tree_out_pragma.m:
    Add predicates to write out decl, impl and generated pragmas.

compiler/polymorphism.m:
    Add a conditionally-enabled progress message, which can be useful
    in tracking down problems.

compiler/prog_item_stats.m:
    Conform NOT to the changes above beyond what is needed to let this module
    compile. Let that work be done the next time the functionality of
    this module is needed, by which time the affected data structures
    maybe have changed further.

compiler/typecheck.m:
    Fix a performance problem. With intermodule optimization, we read in
    .opt files, some of which (e.g. list.opt and int.opt) contain promises.
    These promises are read in as predicates with goal_type_promise,
    but they do not have declarations of the types of their arguments
    (since promises do not have declarations as such). Those argument types
    therefore have to be inferred. That inference replaces the original
    "I don't know" argument types with their actual types.

    The performance problem is that when we change the recorded argument types
    of a predicate, we require another loop over all the predicates in the
    module, so that any calls to this predicate can be checked against
    the updated types. This is as it should be for callable predicates,
    but promises are not callable. So if all the *only* predicates whose
    recorded argument types change during the first iteration to fixpoint
    are promises, then a second iteration is not needed, yet we used to do it.

    The fix is to replace the "Have the recorded types of this predicate
    changed?" boolean flag with a bespoke enum that says "Did the checking
    of this predicate discover a need for another iteration", and not
    setting it when processing predicates whose type is goal_type_promise.

compiler/typecheck_errors.m:
    Do not generate an error message for a predicate missing its clauses
    is the clauses existed but were not added to the HLDS because they were
    in the interface section.

    When reporting on ambiguities (when a call can match more than one
    predicate or function), sort the possible matches before reporting
    them.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/canonicalize_interface.m:
compiler/check_for_missing_type_defns.m:
compiler/check_parse_tree_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/common.m:
compiler/compile_target_code.m:
compiler/compiler_util.m:
compiler/dead_proc_elim.m:
compiler/deps_map.m:
compiler/det_analysis.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/field_access.m:
compiler/find_module.m:
compiler/float_regs.m:
compiler/format_call.m:
compiler/goal_expr_to_goal.m:
compiler/handle_options.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/introduce_parallelism.m:
compiler/layout_out.m:
compiler/make.dependencies.m:
compiler/make.module_dep_file.m:
compiler/make_hlds_warn.m:
compiler/mark_tail_calls.m:
compiler/mercury_compile_llds_back_end.m:
compiler/ml_top_gen.m:
compiler/mmakefiles.m:
compiler/mode_errors.m:
compiler/mode_robdd.equiv_vars.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/oisu_check.m:
compiler/old_type_constraints.m:
compiler/options_file.m:
compiler/parse_class.m:
compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_inst_mode_name.m:
compiler/parse_mutable.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/parse_type_name.m:
compiler/parse_type_repn.m:
compiler/parse_types.m:
compiler/parse_util.m:
compiler/parse_vars.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/prog_event.m:
compiler/prog_mode.m:
compiler/purity.m:
compiler/qual_info.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal.m:
compiler/simplify_goal_call.m:
compiler/simplify_goal_disj.m:
compiler/simplify_goal_ite.m:
compiler/simplify_proc.m:
compiler/state_var.m:
compiler/stratify.m:
compiler/style_checks.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_errors.m:
compiler/term_errors.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
    Conform to the changes above.

mdbcomp/prim_data.m:
    Move a utility function on pred_or_funcs here from a compiler module,
    to make it available to other compiler modules as well.

scripts/compare_s1s2_lib:
    A new script that helped debug this diff, and may help debug
    similar diffs the future. It can compare (a) .int* files, (b) .*opt
    files, (c) .mh/.mih files or (d) .c files between the stage 1 and
    stage 2 library directories. The reason for the restriction
    to the library directory is that any problems affecting the
    generation of any of these kinds of files are likely to manifest
    themselves in the library directory, and if they do, the bootcheck
    won't go on to compile any of the other stage 2 directories.

tests/debugger/breakpoints.a.m:
tests/debugger/breakpoints.b.m:
    Move import_module declarations to the implementation section
    when they are not used in the interface. Until now, the compiler
    has ignored this, but this diff causes the compiler to generate
    a warning for such misplaced import_module declarations even modules
    that have submodules. The testing of such warnings is not the point
    of the breakpoints test.

tests/invalid/Mercury.options:
    Since the missing_interface_import test case tests error messages
    generated during an invocation of mmc --make-interface, add the
    new option that *allows* that invocation to generate error messages.

tests/invalid/ambiguous_overloading_error.err_exp:
tests/invalid/max_error_line_width.err_exp:
tests/warnings/ambiguous_overloading.exp:
    Expect the updated error messages for ambiguity, in which
    the possible matches are sorted.

tests/invalid/bad_finalise_decl.m:
tests/invalid/bad_initialise_decl.m:
    Fix programming style.

tests/invalid/bad_item_in_interface.err_exp:
    Expect an error message for a foreign_export_enum item in the interface,
    where it should not be.

tests/invalid/errors.err_exp:
    Expect the expanded wording of a warning message.

tests/invalid/foreign_enum_invalid.err_exp:
    Expect a different wording for an error message. It is more "standard"
    but slightly less informative.

tests/invalid_submodules/children2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

tests/submodules/parent2.m:
    Move a badly placed import_module declaration, to avoid having
    the message the compiler now generates for it from affecting the test.

    Update programming style.
2020-03-13 12:58:33 +11:00
Zoltan Somogyi
36c2000516 Add the one_or_more and one_or_more_map modules to the library.
library/one_or_more.m:
    We used to have a type named one_or_more in the list module representing
    nonempty lists. It had literally just two predicates and two functions
    defined on it, three of which did conversions to and from lists, which
    limited their usefulness.

    This new module is the new home of the one_or_more type, together with
    a vastly expanded set of utility predicates and functions. Specifically,
    it implements every operation in list.m which makes sense for nonempty
    lists.

library/list.m:
    Delete the code moved over to one_or_more.m.

library/one_or_more_map.m:
    This new module is a near copy of multi_map.m, with the difference being
    that while the multi_map type defined in multi_map.m maps each key
    to a list(V) of values (a list that happens to always be nonempty),
    the one_or_more_map type defined in one_or_more_map.m maps each key
    to a one_or_more(V) of values (which enforces the presence of at least
    one value for each key in the type).

library/map.m:
    Mention the existence of one_or_more_map.m as well as multi_map.m.

library/MODULES_DOC:
library/library.m:
    List the new modules as belonging to the standard library.

NEWS:
    Mention the new modules, and the non-backwards-compatible changes to
    list.m.

compiler/*.m:
    Import the one_or_more module when needed.

tests/hard_coded/test_one_or_more_chunk.{m,exp}:
    Test the one predicate in one_or_more.m that is non-trivially different
    from the corresponding predicate in list.m: the chunk predicate.

tests/hard_coded/Mmakefile:
    Enable the new test case.
2020-02-28 14:29:05 +11:00
Julien Fischer
be2b00affc Minor documentation fixes. 2019-10-26 22:02:56 +11:00
Zoltan Somogyi
fbcd431d36 Decide simple representations using checked type definitions.
compiler/check_parse_tree_type_defns.m:
    Change the definition of a checked type to distinguish direct_dummy
    and enum types on the one hand, which may have foreign enum definitions,
    from other du types, which may not.

    Change the definition of a checked type to record the names of the
    function symbols in direct_dummy and enum types, since type representation
    items need this information, we have it, and requiring decide_type_repn.m
    to compute it again from scratch is wasteful.

    Do not explicitly record the number of function symbols in direct_dummy
    % and enum types, and the number bits needed to represent values of
    such types. We now store the list of function symbols in such types,
    and this information is trivially computable from that.

    Check foreign enum definitions for correctness. At the moment,
    this sort-of duplicates related functionality in add_foreign_enum.m,
    but the intention is that eventually, these checks will be done only here,
    with the sort-of duplicated code in add_foreign_enum.m being deleted there.

compiler/prog_item.m:
    Change the data structures we use to record type representation information
    in items to encode all the invariants that the updated checked type
    definition map encodes. This should allow code that reads such items
    from interface files to avoid having to check for violations of those
    invariants.

    Document the relationship between checked type definitions and
    type representation items, including why neither can subsume the other.

compiler/decide_type_repn.m:
    Rewrite this module almost completely. The old version gathered up
    all the type and enum definitions for each type constructor, and then
    did a limited, purpose-specific job of checking their consistency,
    before using the information in them to decide on the representations
    of simple types. The new version takes a checked type definition map
    as input, and so its task is limited to deciding type representations.

    The switch has two main benefits.

    - The consistency checks we now do in check_parse_tree_type_defns.m
      can replace not just the consistency checks we used to do in
      decide_type_repn.m, but in the future, it can also replace
      the consistency checks we now do in add_type.m and add_foreign_enum.m.
      Having a *consistent* set of consistency checks is a good idea,
      even though it is a bit too meta :-)

    - The consistency checks in check_parse_tree_type_defns.m
      are significantly more thorough than both the ones in the version
      of decide_type_repn.m, and the current version distributed through
      add_type.m and add_foreign_enum.m.

    The changes in check_parse_tree_type_defns.m and prog_item.m to bring
    the two representations as close together as possible should significantly
    simplify the code we will need to add to decide_type_repn.m to decide
    the representations of complex types.

compiler/comp_unit_interface.m:
    Pass the checked type definition map to decide_type_repn.m.

compiler/parse_type_repn.m:
    Parse the updated type representations.

compiler/parse_tree_out.m:
    Output the updated type representations.

compiler/du_type_layout.m:
compiler/prog_data.m:
    Move a predicate from du_type_layout.m to prog_data.m (split into
    two predicates), since decide_type_repn.m now wants access to its
    functionality as well.

compiler/prog_type.m:
    Export a utility predicate.

compiler/add_foreign_enum.m:
    Export some functionality to check_parse_tree_type_defns.m.
    That functionality should in fact be moved to check_parse_tree_type_defns,
    but that would make this diff harder to review, so that will be done later
    in a separate commit.

compiler/equiv_type.m:
compiler/module_qual.qualify_items.m:
    Conform to the changes above.

compiler/Mercury.options:
    Specify --warn-dead-preds for the modules touched by this change.
    Since several of them had large parts replaced by new code, this was
    needed to catch left-over parts of their old and now obsolete contents.
2019-10-26 19:30:07 +11:00
Zoltan Somogyi
3d37c6a442 Report wrongly qualified type names in foreign enums when parsing.
This fixes Mantis bug #486.

compiler/parse_pragma.m:
    Read in the name of the type in a foreign enum in whatever qualified
    form it is in the source code, and then try to implicitly qualify it,
    generating a specific error message if that attempt is unsuccessful.

compiler/parse_sym_name.m:
    To make the above possible, expose the code that does the
    implicit qualification. Do so not just in the form now needed
    by parse_pragma.m, but in the other forms used by other predicates
    in parse_sym_name.m as well, since they probably will be needed
    sooner or later. (The lack of such separated-out capability
    is what led to the code that caused bug 486 in the first place.)

    Avoid an unneeded asymmetry by providing mechanisms to parse
    implicitly qualified sym_names without arguments, as well as
    with arguments.

compiler/parse_util.m:
    Give several of the predicates involved in the above more expressive names.

compiler/parse_inst_mode_defn.m:
compiler/parse_type_defn.m:
compiler/parse_type_repn.m:
compiler/recompilation.check.m:
    Conform to the changes above.

compiler/error_util.m:
    Fix a bug that silently deleted the newly-added simplest_specs,
    which this diff uses for the first time. Add determinism requirements
    to avoid similar problems in the future.

compiler/add_foreign_enum.m:
    Note that the old code that diagnosed attempts to define foreign_enums
    for types in other modules should not be needed anymore.

tests/invalid/foreign_enum_import.err_exp:
    Expect the error message now generated by parse_pragma.m,
    which is more specific than the one generated by add_foreign_enum.m
    until now.

tests/valid/bug486.m:
tests/valid/bug486.window.m:
    A regression test for the bug.

tests/valid/Mmakefile:
    Enable the new test.
2019-09-29 13:26:44 +10:00
Zoltan Somogyi
8e62f93c4d Use maps for several kinds of items in interface file parse trees.
Using lists to store type-, inst- and mode definitions, foreign enum
definitions and type representation items does nothing to enforce
uniqueness requirements, such as "every inst constructor should have
at most one one non-abstract definition in the interface of a module".
However, one can encode such requirements using maps.

This diff therefore changes the representation of these kinds of items
inside the interface-kind-specific parse trees of interface files to use
these kinds of maps. It does not take advantage of the possilities
offered by this diff; that is for a later change.

compiler/prog_item.m:
    Make the change described above.

    Since after this diff, the info in foreign_enum pragmas will be in a map,
    while the info in other kinds of pragmas will still be in a list, avoid
    the possibility of being able to represent invalid states by giving
    foreign enums their own item kind, separate from that of pragmas.
    Since foreign export enums are handled very similarly to foreign enum
    pragmas in many places, given them their own item kind as well.

    Update the predicates converting generic interface file parse trees
    to interface-kind-specific parse trees, and vice versa, to conform
    to the changes above.

compiler/comp_unit_interface.m:
    Convert lists to maps before putting them into interface-kind-specific
    parse trees where the above change requires it.

compiler/hlds_module.m:
    Delete types that contain almost exactly the same info as the item
    information we now keep for foreign enum and foreign export enum items.

    Include the item status next to foreign enum items, since that is the
    one piece of info the deleted types had that we need.

compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
    Parse and print out foreign enums and foreign export enums as their
    own item kinds, not as kinds of pragmas.

compiler/add_foreign_enum.m:
compiler/canonicalize_interface.m:
compiler/equiv_type.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds.m:
compiler/make_hlds_separate_items.m:
compiler/module_qual.collect_mq_info.m:
compiler/module_qual.qual_errors.m:
compiler/module_qual.qualify_items.m:
compiler/prog_item_stats.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
    Conform to the changes above.
2019-09-12 03:52:10 +10:00
Zoltan Somogyi
3dbcc5adfa Delete an XXX.
Explain why the code it complained about is in fact ok.
2019-06-01 22:43:20 +02:00
Zoltan Somogyi
e9430b115a Prep for recording simple type representations in .int3 files.
compiler/decide_type_repn.m:
    New module for computing the set of type representation items
    to put into the interface files of a module. For now, it generates
    this information only for .int3 files.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Add the new module to the parse_tree package.

compiler/comp_unit_interface.m:
    Invoke the new module to add type representation items to .int3 files
    if the experiment option has the right value. Give it the information
    it needs to do its job.

compiler/add_foreign_enum.m:
    Export a predicate for use by decide_type_repn.m. Maybe eventually
    it should be *moved* to decide_type_repn.m.

compiler/hlds_data.m:
compiler/prog_data.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

compiler/prog_item.m:
    Change the representation of lists of constructors in a type
    from lists, which can be empty, with one_or_more, which cannot.
    This encodes the invariant that a type constructor cannot have
    zero data constructors in the structure of the type.

    Include information about assertions in type representation items
    about foreign types.

    Do not record whether a type whose representation item says its values
    are guaranteed to be word aligned is a Mercury type or a foreign type.
    We generate such items only for Mercury types; for foreign types,
    their assertions will contain that information. We need this separation
    because when we generate .int3 files, we don't the backend that we will
    eventually generate code for, and thus do not know whether a given
    foreign type declaration is in effect on that backend or not.

compiler/parse_tree_out.m:
    Fix the printing of type representation items.

compiler/prog_type.m:
    Conform to the changes above, and delete an unused predicate.

compiler/parse_type_repn.m:
    Factor out some common code.

    Fix an old bug about yes/no vs du_repn/no_du_repn.

    Conform to the changes above.

compiler/parse_pragma.m:
    Export a predicate for parse_type_repn.m.

    Note a possible improvement.

    Conform to the changes above.

compiler/add_special_pred.m:
compiler/add_type.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/parse_tree_out_pragma.m:
compiler/parse_type_defn.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/resolve_unify_functor.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_norm.m:
compiler/type_util.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.

compiler/simplify_goal_ite.m:
    Add a comment.

compiler/canonicalize_interface.m:
compiler/get_dependencies.m:
    Do not abort when seeing type representation items.

compiler/mmakefiles.m:
    Delete a predicate that this diff adds to list.m.

library/list.m:
    Add new predicates to convert from one_or_more to list
    and vice versa.

NEWS:
    Announce the new predicates.

library/bimap.m:
library/map.m:
library/tree234.m:
    Expand a comment.
2019-05-27 11:45:10 +02:00
Zoltan Somogyi
5c89991da6 Put related predicates together. 2018-02-27 15:19:41 +11:00
Zoltan Somogyi
7e93bbd325 Use the same code for foreign{_export,}_enums where possible.
compiler/add_foreign_enum.m:
    The biggest part of processing both foreign_enums and foreign_export_enums
    is validating the mapping from the Mercury names of the enum's constants
    to the string giving their user-chosen tag values (for foreign_enums)
    or to the string naming the foreign language variable to which their
    compiler chosen tag values should be assigned. There is a difference
    (the mapping must mention all constants in the type only for
    foreign_enums), but it is minor.

    We nevetheless used to use completely separate code for validating
    the maps, and for other related tasks (such as checking that the type
    consists *only* of constants) for the two pragmas. Change this, and use
    the same code for validation, with some minor parameterization.
    This also allows us to use the same, or closely related, error messages
    for the kinds of errors that can occur in both kinds of pragmas.

    Change the wording of those error messages to talk about mappings being
    "inconsistent", as opposed to them "not being a bijection", since the
    latter terminology will be unfamiliar to some Mercury users.

tests/invalid/bug436.err_exp:
    Expect the list of incorrectly-mentioned constants in the order of their
    appearance (which also happens to be their sorted order, in this case),
    since the code that generates the error message now preserves the order
    from the pragma.

tests/invalid/ee_invalid.err_exp:
    Expect the "inconsistent" wording for two error messages.

tests/invalid/foreign_enum_invalid.err_exp:
    Expect the "inconsistent" wording for two error messages,
    and expect the *reasons* for the inconsistency to be listed also,
    since we now generate this information for foreign_enums as well
    (not just for foreign_export_enums, as before).
2018-02-27 01:57:24 +11:00
Zoltan Somogyi
40be9fa33b Generate error_specs directly.
compiler/add_foreign_enum.m:
    Don't go through error-severity pairs.
2018-02-26 19:13:13 +11:00
Zoltan Somogyi
05689ec08d Delete the cons_id_to_tag_map field in du_type_repns.
compiler/hlds_data.m:
    As above. The last part of the compiler that still used this field
    was du_type_layout_old.m.

    Delete the definition of the type of that field, since it is not now
    needed in most places.

compiler/add_foreign_enum.m:
    Add the definition of the type of that field, since it *is* needed here.

compiler/add_special_pred.m:
compiler/du_type_layout.m:
    Don't fill in the deleted field.

compiler/equiv_type_hlds.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/ml_type_gen.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
    Don't copy or ignore the deleted field.
2018-02-24 16:20:40 +11:00
Zoltan Somogyi
f4bd666ec6 Simplify the handling of foreign_export_enums.
compiler/hlds_module.m:
    Change the representation of the mapping from Mercury constants
    to their exported foreign names from being a sym_name->string map
    to being a plain string->string map. Several parts of the compiler
    already required the sym_name key to be unqualified, which meant
    that its information content was just the constant's name anyway.
    This change enforces that invariant by encoding it in the data type.

    Document the fields of exported_enum_info. Put those fields into
    an order that makes this documentation flow logically.

compiler/add_foreign_enum.m:
    Rationalize the way foreign_export_enums (FEEs) are processed and checked.
    Check each entry in the override map just once, when it is first processed,
    and string away its module qualification then (after checking it).
    (Leaving the qualification check until later was probably the reason
    for the choice of a sym_name->string map in the old version.)

    Check whether the override map deviates from a bijection by keeping track
    of which Mercury constant names and which foreign names we have seen so
    far. This allows the error messages about "not a bijection" to say *why*
    the mapping is not a bijection. It also fixes an old bug that generated
    a "not a bijection" error for override maps that *were* bijections,
    but were bijections that covered only *some* of the enum type's constants.

    In error messages that include lists of constants or foreign names,
    consistently precede those lists with nl_indent_delta(2).

    Use a more consistent variable naming scheme.

compiler/export.m:
compiler/ml_type_gen.m:
    Conform to the changes in hlds_module.m.

tests/invalid/ee_invalid.err_exp:
tests/invalid/exported_foreign_enum.err_exp:
    Include the updated error messages in these expected outputs.

    Don't expect *any* error message for the FEE on line 75 of ee_invalid.m,
    which has a bijective (though incomplete) override map.
2018-02-24 13:50:52 +11:00
Zoltan Somogyi
dfe108251a Simplify the representation of foreign_export_enums.
compiler/hlds_module.m:
    The backends need to know how each constant in an enum type
    is represented if that type has a foreign_export_enum pragma.
    Transmit that information to them using the ctor_repns of the constants,
    so that they don't have to recreate it from the name of the constant
    and the cons_id_to_tag_map.

compiler/ml_type_gen.m:
    Conform to the change in hlds_module.m.

    Factor out a switch converting enums' tags to rvals that was duplicated
    in two places.

compiler/export.m:
    Conform to the change in hlds_module.m.

    Include the foreign name of an enum constant with its representation;
    this simplifies the code.

compiler/add_foreign_enum.m:
    Conform to the change in hlds_module.m.

compiler/mlds.m:
    Document the reason why the MLDS representation of exported enums
    needs to know the type constructor.
2018-02-21 20:15:47 +11:00
Zoltan Somogyi
4b98f58d9d Don't use reserved addresses to represent functors.
Late last year, we agreed to delete the ability to use the addresses
of reserved objects as cons_tags. After another (very short) discussion
on m-dev, this diff also deletes the ability to use small integers
(including zero) acting as pointers.

compiler/options.m:
    Delete the --num-reserved-addresses option.

    Add a synomym for --compiler-sufficiently-recent, with the intention
    that support for the representation of reserved addresses in RTTI
    code in the runtime will be deleted when all installed compilers
    have this new synonym.

compiler/hlds_data.m:
    Delete any mention of the reserved addresses from the cons_tag type,
    since we don't have reserved addresses anymore.

    Don't record for each type whether it uses reserved addresses;
    no type can do so anymore.

compiler/rtti.m:
    Delete the part of the RTTI representation that dealt with reserved
    addresses.

compiler/add_foreign_enum.m:
compiler/add_special_pred.m:
compiler/bytecode_gen.m:
compiler/code_info.m:
compiler/du_type_layout.m:
compiler/equiv_type_hlds.m:
compiler/erl_rtti.m:
compiler/export.m:
compiler/hlds_out_module.m:
compiler/intermod.m:
compiler/ml_switch_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/opt_debug.m:
compiler/prog_data.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_gen.m:
    Conform to the changes above, mostly by deleting code that used to deal
    with reserved addresses.
2018-02-06 16:03:44 +11:00
Julien Fischer
d6b3affdf8 Fix spelling.
compiler/add_foreign_enum.m:
    Fix spelling in a spot.
2018-02-02 10:44:10 -05:00
Zoltan Somogyi
ff00ba94e8 Delete now-stray comment. 2018-01-31 21:23:19 +11:00
Zoltan Somogyi
770251d4e5 Fix variable names. 2018-01-31 21:18:14 +11:00
Zoltan Somogyi
8e8141f515 Reorder add_foreign_enum.m.
Put the half that occurs first before the half that occurs second.

Add a comment at the top explaining this.
2018-01-31 20:29:23 +11:00
Zoltan Somogyi
fb97df69ed Make "compute type representations" a separate pass.
The ultimate purpose of this diff is to prepare for future improvements
in type representations, allowing values of some data types to be represented
more compactly than up to now.

The main way this diff does that is by creating a separate pass for deciding
how values of each type should be represented. We have traditionally decided
data representations for each type as its type definition was processed
during the make_hlds pass, but these decisions were always tentative,
and could be overridden later, e.g. when we processed foreign_type or
foreign_enum pragmas for the type. This dispersed decision making algorithm
is hard to understand, and therefore to change.

This diff centralizes decisions about type representations in a separate
pass that does nothing else. It leaves the algorithm distributed among
several files (du_type_layout.m, make_tags.m, and add_foreign_enum.m) for now,
to make reviewing this diff easier, but soon after it is committed I intend
to move all the relevant code to du_type_layout.m, to centralize the decision
code in "space" as well as in time.

For the reason why this pass runs before any of the semantic analysis
passes, instead of after all of them as I originally intended and as we
discussed on m-dev in late october 2017, see the big comment at the start of
du_type_layout.m.

As per another part of that same discussion on m-dev, this diff
makes a start on implementing a new type of item, the type_repn item,
which is intended *only* to be used in compiler-generated interface files,
*not* in source files. It is only a start because we can use these items
only *after* the creation of a separate type representation decision pass,
and this diff is already very big. The code for making the compiler understand
these items will be added later. The code for generating them will be added
later still, once the code for understanding them has been installed on
all our systems.

Since I was going to be working on the affected code anyway, this diff
also carries out two other decisions that came out of that discussion:

- the deletion of the ability to reserve a tag in a type for HAL,
  either via a compiler option or via a pragma, and

- the deletion of the ability to represent a functor using the address
  of a statically allocated object (which we haven't used and won't use,
  because it slows down accesses to *all the other functors* of the type).

compiler/mercury_compile_front_end.m:
    Invoke the new pass for making decisions about type representations
    after the make_hlds pass. (We used to do only the final part of it then.)

    Fix a bad dump stage name.

    Add an extra check for what it means for a module to be error free.

    Make a sub-switch explicit.

compiler/hlds.m:
compiler/make_hlds.m:
    Move the modules that implement the new pass from the make_hlds package
    to the hlds package, to give the compiler's top level access to them.

    Make the same move for the modules that the new pass's modules need.
    Since they are now part of hlds, they cannot reach into make_hlds,
    and I think this is a cleaner solution than forwarding predicates.

    Delete some forwarding predicates that are no longer needed.

compiler/notes/compiler_design.html:
    Document the updated location of the moved modules.

    Add an XXX to note a place where the documentation has not been
    updated in the past.

compiler/du_type_layout.m:
    Add code to implement the new pass.

    Keep the algorithm for deciding type representations as close
    to the previously used algorithm as possible, since this diff
    is already big enough. (The previous algorithm was scattered across
    add_type.m, add_foreign_enum.m, and make_hlds_passes.m.)

    Simplifications and optimizations will come later, after this module
    is merged with make_tags.m and with (at least) the foreign_enum half of
    add_foreign_enum.m.

compiler/make_tags.m:
    Keep the functionality of this module, which does both the first part
    of deciding type representations (tentatively assigning tags to functors,
    an assignment that may be overridden later), and the last part (packing
    multiple adjacent less-than-word-sized enum args into a single word,
    if possible.), but simplify it where possible, and note possibilities
    for further improvements.

compiler/add_foreign_enum.m:
    This module has two halves, one dealing with foreign_enum pragmas
    and one dealing with foreign_export_enum pragmas.

    Change the half that deals with foreign_enum pragmas to just build
    a data structure that du_type_layout.m will need to make its decisions,
    this structure being a map from type_ctors to the foreign enum
    specification applicable to the current target language. Include
    in this structure a component that add_foreign_enum.m itself can use
    to report better error messages for duplicate foreign_enum pragmas;
    this component records, for each type_ctor and language, the context
    of the previous foreign_enum pragma for that combo.

    Change the input for the half that deals with foreign_export_enum pragmas
    to reflect the fact that it is invoked by du_type_layout.m after all
    decisions about type representations have already been made.

compiler/add_special_pred.m:
    Move this module from the make_hlds package to the hlds package,
    since the code that adds special preds for type is now called from
    du_type_layout.m.

    Change the names of predicates to make clear whether they add
    only the declaration of a predicate, only its definition, or both.

    Don't try to pre-guess whether the implementation of a type's
    compare predicate will need an index predicate. Let the code
    that generates calls to the index predicate both declare and define
    the index predicate. This change removes the potential for
    inconsistencies between the two pieces of code.

compiler/add_pred.m:
    Move this module from the make_hlds package to the hlds package,
    since add_special_pred.m needs access to it.

compiler/add_type.m:
    When adding a type definition to the HLDS, don't try to decide
    its representation. Any such decision was tentative anyway, due
    to the possibility of e.g. the later processing of foreign_type
    or foreign_enum pragmas for the type. Likewise, don't try to
    create the special (unify, compare) predicates for the type.
    Leave both tasks to the du_type_layout pass.

    Likewise, don't try to pack the representation of types, or record
    no_tag types in the table of no_tag types, during the post-processing
    pass either; leave both of these to du_type_layout as well.
    Rename the predicate that post_processes type definitions to reflect
    the two tasks left for it to do.

compiler/prog_data.m:
    Do not store width information about the arguments of those data
    constructors in the parse tree. That information is not computed
    until later; until then, it was always filled in with dummy values.
    (But see hlds_data.m below.)

    Use bespoke types to represent the presence or absence of user-specified
    unify and compare predicates.

    Change the representation of data constructors to use a single "maybe"
    type, not two lists, to denote the presence or absence of existentially
    typed arguments.

    Give the HLDS the ability to hold representation information about
    abstract types that in the future we will get from type_repn items
    in the defining modules' interface files.

    Delete the uses_reserved_tag type, since we never use reserved tags
    anymore.

compiler/prog_item.m:
    Add the new type_repn item type, which is not used yet.

    Delete the reserve_tag pragma.

    Fix an earlier mistake in the wording of a context message.

compiler/hlds_data.m:
    Put all the fields of hlds_du_type (the type definition variant dealing
    with discriminated union types) that deal with type representation
    issues in a single "maybe" field that is set to "no" before the
    type representation decision pass has been run.

    Add new type, constructor_repn, that stores the same information as the old
    constructor type (defined in prog_data.m), PLUS the information
    describing how terms with that data constructor are stored.

    Likewise, add a new type ctor_arg_rep, which likewise stores
    the widths of each constructor argument. When we implement
    argument reordering, we would store the offset of the arg as well.

    Since the parse tree representations of constructors and their arguments
    don't store representation information anymore, the cons_table they
    are stored in doesn't either. Make the lookup of representation information
    for a given constructor possible by adding a map to the new "maybe" field
    of hlds_du_type.

    Provide some utility predicates.

    Optimize some existing predicates.

    Rename some types to better reflect their meaning.

compiler/hlds_module.m:
    Provide a slot in the module_info for storing the information
    gathered by make_hlds.m that is needed by the new pass.

compiler/make_hlds_separate_items.m:
    When we see either a foreign_enum or a foreign_export_enum pragma,
    return values of a bespoke type for them (a type defined in
    hlds_module.m), instead of an item_pragma. This makes handling them
    considerably easier.

compiler/make_hlds_passes.m:
    With the changes in this diff, adding a type to the HLDS won't
    decide its representation. Therefore delete the code that used
    to loop over foreign_export_enum pragmas; in the absence of
    the final type representation information, it won't work right.

    Record the information that the du_type_layout pass will need
    in the module_info.

compiler/add_pragma.m:
    Delete the code for passing on foreign_enum and foreign_export_enum
    pragmas to add_foreign_enum.m; they are now passed to add_foreign_enum.m
    by du_type_layout.m.

    Move a utility predicate to make_hlds_error.m, to allow add_foreign_enum.m
    to call it.

compiler/make_hlds_error.m:
    Add the utility predicate moved from add_pragma.m.

    Move the module from the make_hlds to the hlds package.

compiler/module_qual.m:
    Provide a mechanism for recording error messages about e.g. undefined
    types without recording that we found an undefined type. This sounds
    strange, but there is a valid use case.

    When a type definition declares a functor's argument to be of an
    undefined type, that error is usually fatal; we stop the compiler
    from proceeding even to typechecking, since the typechecker will
    probably abort with a map lookup failure. Most other references
    to undefined types are similarly fatal for the same reason. However,
    if e.g. a foreign_export_enum pragma refers to an undefined type,
    that error *won't* be visible to the typechecker, and therefore
    won't crash it. The error will still cause the compiler to exit
    without generating any target language code, but at least it will be
    able to run the typechecker and other semantic analysis passes.

    Without this change, the compiler will report only one error in
    the ee_invalid.m test case; with it, it reports *every* error
    in the test case expected output.

compiler/module_qual.qualify_items.m:
    Use the capability describe above for undefined types in
    foreign_export_enum pragmas.

compiler/module_qual.qual_errors.m:
    Delete a (somewhat incorrect) copy of a predicate in prog_item.m,
    to reduce code duplication.

compiler/prog_type.m:
    Add ways to represent abstract types whose representations are nevertheless
    known (from type_repn items in the defining modules' interface files)
    to be notag or dummy types. This will be needed to fix Mantis bug #441,
    a fix that will probably be one of the first later changes to build
    on this diff.

    Delete a type moved to type_util.m.

compiler/type_util.m:
    Provide extra versions of some predicates, with the difference between
    the old and the new versions being that one requires type representations
    to have been decided already, and the other one does not.

    Move the definition of the ctor_defn type here from prog_type.m,
    since prog_type.m itself does not use it, but type_util.m does.

    Give some predicates more meaningful names.

compiler/parse_type_defn.m:
    Simplify the code for parsing type definitions, to make it easier
    to reuse to parse type_repn items.

    Add a sanity check that requires existential constraints to have
    *some* existential variables to apply to.

    Allow "type_is_representable_in_n_bits" as a synonym for
    "type_is_abstract_enum", since in the future we want to be able to pack
    e.g. multiple int8s, not just multiple enums, into a single word.

    Generate more specific error messages for some classes of malformed input.

compiler/parse_type_repn.m:
    New module to parse type_repn items.

compiler/polymorphism.m:
    Make some predicates that operate on type constructors take
    the type constructors themselves as input arguments, not a whole type
    *using* that type constructor. Put the arguments of those predicates
    in a more standard order.

    Note that some predicates don't belong in this module.

compiler/special_pred.m:
    Make the code that decides whether a special predicate for a type
    constructor can be defined lazily avoid using type representation
    information. (Actually, we now make decisions about lazy vs eager
    definitions after type representation is available, but that was
    not so in an earlier version of this change, and the new code
    is more robust.)

compiler/unify_proc.m:
    When we decide to generate code for a compare predicate that needs
    the type to have an index predicate, don't presume that the index
    predicate has already been declared and defined; instead, declare
    and define it then and there. (Index predicates are *never* called
    from anywhere else.)

    Pack the information needed to define a special predicate
    into a single structure, to simplify the above.

    Since the creation of a clause for a compare predicate may now require
    the declaration and definition of an index predicate, the module_info
    field of the unify_proc_info is now a writeable field.

    Give some predicates and function symbols more meaningful names.

    Note some problems with the existing code.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_solver.m:
compiler/check_typeclass.m:
compiler/code_info.m:
compiler/comp_unit_interface.m:
compiler/ctgc.selector.m:
compiler/ctgc.util.m:
compiler/default_func_mode.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/goal_expr_to_goal.m:
compiler/hhf.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/inst_test.m:
compiler/inst_util.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_warn.m:
compiler/ml_accurate_gc.m:
compiler/ml_simplify_switch.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
compiler/mode_util.m:
compiler/modecheck_goal.m:
compiler/module_qual.collect_mq_info.m:
compiler/modules.m:
compiler/parse_item.m:
compiler/parse_pragma.m:
compiler/parse_tree.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_pragma.m:
compiler/post_term_analysis.m:
compiler/proc_requests.m:
compiler/prog_item_stats.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/simplify_goal_ite.m:
compiler/stack_opt.m:
compiler/state_var.m:
compiler/structure_reuse.direct.choose_reuse.m:
compiler/superhomogeneous.m:
compiler/switch_gen.m:
compiler/switch_util.m:
compiler/table_gen.m:
compiler/term_constr_build.m:
compiler/term_norm.m:
compiler/trailing_analysis.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/untupling.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/invalid/Mmakefile:
    Disable the reserve_tag test case, as it is not applicable anymore.

tests/invalid/exported_foreign_enum.{m,err_exp}:
tests/invalid/pragma_qual_error.{m,err_exp}:
    Delete reserve_tag pragmas from these test cases, and its effects
    from the expected outputs.

tests/invalid/bad_foreign_type.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
tests/invalid/type_lhs_var.err_exp:
tests/invalid/uu_type.err_exp:
tests/invalid/where_abstract_enum.err_exp:
tests/invalid/where_direct_arg.err_exp:
    Expect the updated messages for some errors.

tests/valid/Mmake.valid.common:
tests/valid/Mmakefile:
    Disable any reserve_tag test cases, as they are not applicable anymore.
2018-01-31 17:54:40 +11:00
Zoltan Somogyi
9e285e2b9d Generate better messages for bad inst definitions.
compiler/inst_check.m:
    When an inst for a named type has function symbols that don't appear
    in that type, print not just the incorrect function symbols, but also
    the function symbols that are "near misses", e.g. if error is in
    giving a function symbol the wrong arity.

    Use standard error_util.m functionality to format cons_ids in error
    messages.

compiler/error_util.m:
    Generalize two predicates to enable the error messages we now generate.

compiler/add_foreign_enum.m:
compiler/add_mode.m:
compiler/add_pragma.m:
compiler/hlds_error_util.m:
compiler/make_hlds_error.m:
compiler/module_qual.qual_errors.m:
compiler/modules.m:
compiler/parse_inst_mode_name.m:
compiler/parse_item.m:
compiler/recompilation.check.m:
compiler/typecheck_errors.m:
    Conform to the change in error_util.m.

tests/invalid/bad_inst_for_type.{m,err_exp}:
    Extend this test case with tests of the new functionality.
2017-08-06 23:13:52 +02:00
Zoltan Somogyi
2ac8465659 Make the code adding new types to the HLDS readable.
The motivation for this diff was that I wanted the compiler to generate
a warning if a module declared the same type twice. (During the cleanup
of unify_proc.m I did recently, I found and fixed such a duplicate
declaration.)

compiler/add_type.m:
    The old code of module_add_type_defn was not just long (210+ lines),
    it is also very complex.

    Part of this complexity was sort-of justified. It dealt with adding
    three separate kinds of item_type_defns: abstract type "definitions",
    which are actually declarations; the definitions of Mercury types,
    and the definitions of foreign types. A single type could have more than
    one of these (e.g. declaration and a definition, or a Mercury definition
    and a foreign definition), and it had to be prepared to process these
    in any order.

    Part of this complexity was self-inflicted. The parts of the predicate
    that dealt with the same kind of definition were not always next to each
    other, and for some parts, it wasn't even clear *what* kind of definition
    it was dealing with. It did the same tests on both the old and updated
    versions of definitions, when those definitions were guaranteed to be
    identical; the "updating" predicate was a no-op. And it used completely
    different code for detecting and handling related errors.

    This diff fixes the above problems. It separates the task of adding
    an item_type_defn to the HLDS into three subtasks, done in three separate
    predicates: adding type declarations, adding Mercury definitions, and
    adding foreign definitions. It specializes each predicate to its task,
    and simplifies its decision flow. It also delegates the creation of
    (most) error messages to separate predicates. Together, these changes
    make each of module_add_type_defn_{abstract,mercury,foreign} easily
    understandable.

    Generate a warning if a type is declared twice, i.e. if e.g.
    ":- type x." is followed by another ":- type x.".

    Call module_info_incr_errors to register the presence of errors in just
    one central place. (Before, some of the places that generated error
    messages incremented the error count, and some places didn't.)

    Improve the wording of some error messages.

    Refer to type names in error messages by unqualified sym_names
    in cases where the module qualifier being elided is obvious from
    the name of the module being compiled.

    Add documentation.

    Add descriptions of potential future improvements.

    Add some XXXs at places that I think deserve them.

    Give some predicates and variables better names.

compiler/prog_data.m:
    Change the parse tree representation of type definitions by
    explicitly specifying a type for storing the contents of each kind
    of type definition.

compiler/hlds_data.m:
    Give a predicate a better name.

    Use one of the new types in prog_data.m in the HLDS version of type
    definitions, to minimize differences between the parse tree and HLDS
    versions.

compiler/add_foreign_enum.m:
compiler/add_pragma.m:
compiler/add_special_pred.m:
compiler/check_typeclass.m:
compiler/du_type_layout.m:
compiler/equiv_type.m:
compiler/equiv_type_hlds.m:
compiler/foreign.m:
compiler/get_dependencies.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/make_hlds_passes.m:
compiler/make_hlds_separate_items.m:
compiler/make_tags.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/module_qual.qualify_items.m:
compiler/parse_pragma.m:
compiler/parse_tree_out.m:
compiler/parse_type_defn.m:
compiler/post_term_analysis.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/simplify_goal_ite.m:
compiler/special_pred.m:
compiler/switch_util.m:
compiler/term_norm.m:
compiler/type_ctor_info.m:
compiler/type_util.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/write_module_interface_files.m:
compiler/xml_documentation.m:
    Conform to the changes in prog_data.m.

library/io.m:
library/store.m:
    Delete duplicate type declarations that add_type.m now complains about.

tests/invalid/bad_foreign_type.{m,err_exp}:
    Extend this test to test the new warning.

    Expect the updated versions of some error messages.

tests/invalid/extra_info_prompt.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/user_eq_dummy.err_exp:
    Expect the updated versions of some error messages.
2017-06-27 18:15:58 +02:00
Zoltan Somogyi
61d0c67243 Improve diagnostics for foreign_{export_,}enum pragmas.
We can now generate error messages for types that have both foreign_enum
and reserve_tag pragmas, which we couldn't before. (In some cases,
we used to get a compiler abort.)

compiler/add_foreign_enum.m:
    Don't stop after finding the first problem with a foreign_export_enum
    or foreign_enum pragma; if a pragma has more than one problem,
    generate reports for them all.

    When reporting that the type named in a foreign_export_enum or
    foreign_enum is not an enum type, have the error message say *why*.

    Fill in the two new fields in exported_enum_infos (see below).

compiler/make_hlds_passes.m:
    Add reserve_tag pragmas to the HLDS before adding foreign_export_enum
    and foreign_enum pragmas. Since such a pragma would convert an enum
    type into a non-enum type, this is needed to ensure that the code
    in add_foreign_enum.m that checks whether a type is an enum type
    is operating on data that is final. Without that, it may make
    wrong decisions.

compiler/make_hlds_separate_items.m:
compiler/add_pragma.m:
    Provide the support needed by the new code in make_hlds_passes.m.

    In add_pragma.m, rename some insts to avoid name ambiguities,
    and simplify an if-then-else.

compiler/hlds_module.m:
    Add two fields to exported_enum_infos, to make processing them easier.
    (We couldn't do this earlier, since add_foreign_enum.m didn't have
    access to the final forms of the bodies of du type definitions,
    which is where the values of the two new fields come from.)

compiler/export.m:
compiler/ml_type_gen.m:
    Simplify some code using the new fields in exported_enum_infos.

compiler/error_util.m:
    Provide a mechanism to control whether sym_names in cons_ids
    are module qualified or not. This is "needed" by the new error
    messages created in add_foreign_enum.m.

compiler/check_promise.m:
compiler/det_report.m:
compiler/parse_inst_mode_name.m:
compiler/typecheck_errors.m:
    Conform to the change to error_util.m.

compiler/make_tags.m:
    Clean up some code and some comments.

tests/invalid/exported_foreign_enum.{m,err_exp}:
    A new test case to test the new capability to print more than one
    error message for the same pragma.

tests/invalid/Mmakefile:
    Enable the new test case.

tests/invalid/ee_invalid.err_exp:
    Expect improved error messages.
2017-06-05 12:34:58 +02:00
Julien Fischer
c40f4300f7 Fix bug #436.
Fix a bug in foreign_enum pragmas where the compiler was not checking if
symbols appearing in the third argument were actually constructors of the type
that is the subject of the pragma.  Such symbols would be silently ignored.

compiler/add_foreign_enum.m:
     Generate an error message if we encounter symbols in the third argument
     of a foreign_enum pragma that are not constructors of the type.

tests/invalid/Mmakefile:
tests/invalid/bug436.{m,err_exp}:
     Add a regression test for bug #436.

tests/invalid/fe_unmapped_nonverbose.{m,err_exp}:
tests/invalid/fe_unmapped_verbose.{m,err_exp}:
     Fix a misspelled constructor name in these tests.
2017-05-03 09:45:17 +10:00
Julien Fischer
1a77161e3a Minor fix for an error message.
compiler/add_foreign_enum.m:
    The error message for non-matching constructors in a
    foreign_export_enum pragma should include the word "error".

tests/invalid/ee_invalid.err_exp:
     Update the expected output.
2017-04-29 13:26:59 +10:00
Julien Fischer
8c09e2bacd 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 documenting 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.
2017-04-10 22:26:21 +10:00
Zoltan Somogyi
7b82c59c40 Remove unneeded module qualifications from error messages.
This should make error messages easier to read by removing clutter.

compiler/error_util.m:
    Split each of the sym_name and sym_name_and_arity error pieces into two;
    one which prints any module qualification present in the given sym_name,
    and one which does not. This forces people who use these pieces
    to think about whether they want the sym_name module qualified
    in the error message or not.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/check_for_missing_type_defns.m:
compiler/check_promise.m:
compiler/check_raw_comp_unit.m:
compiler/check_typeclass.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/format_call.m:
compiler/hlds_error_util.m:
compiler/inst_check.m:
compiler/introduce_parallelism.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_tags.m:
compiler/mercury_compile_main.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/modules.m:
compiler/oisu_check.m:
compiler/parse_inst_mode_defn.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_pragma.m:
compiler/parse_type_defn.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/prog_out.m:
compiler/recompilation.check.m:
compiler/resolve_unify_functor.m:
compiler/split_parse_tree_src.m:
compiler/type_constraints.m:
compiler/typecheck_errors.m:
compiler/unused_args.m:
compiler/unused_imports.m:
    Conform to the change above. For sym_name references for which
    the module qualifier is obvious (usually because it *has* to be
    the module being compiled), change the reference to the variant
    that omits that qualifier; otherwise, keep the qualifier.

    In a few places, improve the wording of an error message.

tests/invalid/bad_instance.err_exp:
tests/invalid/bug17.err_exp:
tests/invalid/builtin_int.err_exp:
tests/invalid/foreign_purity_mismatch.err_exp:
tests/invalid/foreign_type_visibility.err_exp:
tests/invalid/fp_dup_bug.err_exp:
tests/invalid/fundeps_vars.err_exp:
tests/invalid/impl_def_literal_syntax.err_exp:
tests/invalid/inline_conflict.err_exp:
tests/invalid/inst_list_dup.err_exp:
tests/invalid/instance_no_type.err_exp:
tests/invalid/invalid_typeclass.err_exp:
tests/invalid/missing_interface_import.err_exp:
tests/invalid/missing_interface_import2.err_exp:
tests/invalid/oisu_check_semantic_errors.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/transitive_import.err_exp:
tests/invalid/type_with_no_defn.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
tests/invalid/types2.err_exp:
tests/invalid/undef_inst.err_exp:
tests/invalid/undef_mode.err_exp:
tests/invalid/undef_mode_and_no_clauses.err_exp:
tests/invalid/undef_type.err_exp:
tests/invalid/undef_type_mod_qual.err_exp:
tests/invalid/uu_type.err_exp:
tests/invalid/where_direct_arg.err_exp:
tests/invalid/where_direct_arg2.err_exp:
tests/invalid/wrong_type_arity.err_exp:
tests/recompilation/add_type_re.err_exp.2:
tests/recompilation/field_r.err_exp.2:
tests/recompilation/remove_type_re.err_exp.2:
tests/warnings/inst_with_no_type.exp:
    Expect the updated versions of error messages.
2017-04-01 20:20:57 +11:00
Julien Fischer
5dd230ec19 Add a builtin unsigned word sized integer type -- Part 1c.
compiler/add_foreign_enum.m:
      Don't allow uints to be the subject of foreign_enum or
      foreign_export_enum pragmas.

compiler/check_for_missing_type_defns.m:
      Update a comment.
2016-10-31 10:22:51 +11:00
Paul Bone
dcb73375e1 Make an exception a little more friendly
This exception is now more specific about what is not implemented.

compiler/add_foreign_enum.m:
    As above.
2016-09-07 14:47:13 +10:00
Zoltan Somogyi
583aec32f0 Improve slightly the error messages for missing foreign enums.
compiler/add_foreign_enum.m:
    As above.

tests/invalid/fe_unmapped_nonverbose.err_exp:
tests/invalid/fe_unmapped_verbose.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
    Update the expected outputs.
2016-06-20 10:16:07 +02:00
Julien Fischer
934f5eee9a Improve error messages for missing foreign values in foreign_enum pragmas.
Currently, if a foreign_enum pragma is missing cases in the constructor -
foreign value mapping we report that there are some missing foreign values but
do not list the affected constructors unless --verbose-error-messages is
enabled.  For cases where there are a small number of missing foreign values
this is a bit irritating as you need to recompile to find out what they are.
Change the compiler so the error message lists upto the first 10 constructors
that do not have a foreign value.
(If --verbose-error-messages is enabled then we list all of them as before.)

compiler/add_foreign_enum.m:
    Make the above change.

    In error messages for foreign_enum and foreign_export_enum pragmas, add
    the word "type" before the name that is printed in error messages.

tests/invalid/Mmakefile:
tests/invalid/Mercury.options:
tests/fe_unmapped_nonverbose.{m,err_exp}:
tests/fe_napped_verbose.{m,err_exp}:
    Test the new error messages for missing constructors in the constructor -
    foreign value mapping.

tests/invalid/ee_invalid.err_exp:
tests/invalid/foreign_enum_import.err_exp:
tests/invalid/foreign_enum_invalid.err_exp:
    Conform to the above changes.
2016-06-17 22:43:16 +10:00
Julien Fischer
128f843e0b Add XXX comment about an error message.
compiler/add_foreign_enum.m:
    Add an XXX message about an error message that could
    be improved.
2016-06-02 10:55:44 +10:00
Julien Fischer
a8b8878286 Improve consistency in an error message.
compiler/add_foreign_enum.m:
    Refer to "builtin" types rather than "atomic" types in some
    error messages.

tests/invalid/ee_invalid.err_exp:
    Conform to the above change.
2016-05-16 15:30:22 +10:00
Zoltan Somogyi
9d4f1e6ae5 Avoid using some Mercury keywords.
compiler/pred_table.m:
compiler/prog_data.m:
    Avoid using / as a function symbol.

    Rename some function symbols to avoid ambiguity.

compiler/add_class.m:
compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_type.m:
compiler/check_for_missing_type_defns.m:
compiler/check_typeclass.m:
compiler/complexity.m:
compiler/det_report.m:
compiler/equiv_type.m:
compiler/error_util.m:
compiler/format_call.m:
compiler/hlds_error_util.m:
compiler/hlds_module.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/inst_check.m:
compiler/introduce_parallelism.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_tags.m:
compiler/mercury_to_mercury.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qual_errors.m:
compiler/oisu_check.m:
compiler/parse_mutable.m:
compiler/parse_sym_name.m:
compiler/parse_type_defn.m:
compiler/post_term_analysis.m:
compiler/prog_out.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/resolve_unify_functor.m:
compiler/type_constraints.m:
compiler/typecheck_errors.m:
compiler/unused_args.m:
compiler/write_module_interface_files.m:
    Conform to the changes above.

    In a few places, improve the format of error messages.

tests/invalid/cyclic_typeclass.err_exp:
tests/invalid/cyclic_typeclass_2.err_exp:
tests/invalid/cyclic_typeclass_3.err_exp:
tests/warnings/inst_with_no_type.exp:
    Expect the updated error messages.
2016-05-13 11:46:37 +10:00
Julien Fischer
94535ec121 Fix spelling and formatting throughout the system.
configure.ac:
browser/*.m:
compiler/*.m:
deep_profiler/*.m:
library/*.m:
ssdb/*.m:
runtime/mercury_conf.h.in:
runtime/*.[ch]:
scripts/Mmake.vars.in:
trace/*.[ch]:
util/*.c:
	Fix spelling and doubled-up words.

	Delete trailing whitespace.

	Convert tabs into spaces (where appropriate).
2015-12-02 18:46:14 +11:00
Julien Fischer
3dd02876a5 Delete the MLDS->IL backend.
compiler/mlds_to_il.m:
compiler/mlds_to_ilasm.m:
compiler/mlds_to_managed.m:
compiler/il_peephole.m:
compiler/ilasm.m:
compiler/ilds.m:
    Delete the modules making up the MLDS->IL code generator.

compiler/globals.m:
compiler/prog_data.m:
    Delete IL as a target and foreign language.

compiler/prog_io_pragma.m:
    Delete the max_stack_size/1 foreign proc attribute.  This was only
    ever required by the IL backend.

compiler/options.m
    Delete options used for the IL backend.

compiler/write_deps_file.m:
    Don't generate mmake targets for .il files etc.

compiler/*.m:
    Conform to the above changes.

compiler/notes/compiler_design.html
compiler/notes/work_in_progress.html
    Conform to the above changes.

library/*.m:
    Delete IL foreign_proc and foreign_export pragmas.

README.DotNet:
    Delete this file.

browser/Mmakefile:
compiler/Mmakefile:
deep_profiler/Mmakefile:
mdbcomp/Mmakefile:
mfilterjavac/Mmakefile:
profiler/Mmakefile:
runtime/Mmakefile:
slice/Mmakefile:
    Conform the above changes.

configure.ac:
    Don't check that IL is a supported foreign language when performing the
    up-to-date check.

    Delete the '--enable-dotnet-grades' option.

scripts/Mmake.vars.in:
    Delete variables used for the IL backend (and in on case by the Aditi
    backend).

scripts/Mercury.config.bootstrap.in:
scripts/Mercury.config.in:
scripts/Mmake.rules:
scripts/canonical_grade.sh-subr:
tools/bootcheck:
    Delete stuff related to the 'il' and 'ilc' grades.

doc/reference_manual.texi:
     Delete the documentation of the 'max_stack_size' option.

doc/user_guide.texi:
     Delete stuff related to the IL backend.

tests/hard_coded/csharp_test.{m,exp}:
tests/invalid/foreign_type_missing.{m,err_exp}:
tests/valid/csharp_hello.m:
	Delete these tests: they are no longer relevant.

tests/hard_coded/equality_pred_which_requires_boxing.m:
tests/hard_coded/foreign_import_module.m:
tests/hard_coded/foreign_import_module_2.m:
tests/hard_coded/foreign_type.m:
tests/hard_coded/foreign_type2.m:
tests/hard_coded/foreign_type3.m:
tests/hard_coded/intermod_foreign_type2.m:
tests/hard_coded/lp.m:
tests/hard_coded/user_compare.m:
tests/invalid/foreign_type_2.m:
tests/invalid/foreign_type_missing.{m,err_exp}:
tests/invalid/foreign_type_visibility.m:
tests/invalid/illtyped_compare.{m,err_exp}:
tests/submodules/external_unification_pred.m
tests/valid/big_foreign_type.m
tests/valid/solver_type_bug.m
tests/valid_seq/foreign_type_spec.m
tests/valid_seq/intermod_impure2.m
    Delete IL foreign_procs where necessary.

tests/hard_coded/Mmakefile
tests/invalid/Mercury.options
tests/invalid/Mmakefile
tests/submodules/Mmakefile
tests/valid/Mercury.options
tests/valid/Mmake.valid.common
tests/valid/Mmakefile
tests/valid_seq/Mmakefile
tests/valid_seq/Mercury.options
    Conform to the above changes.
2015-09-21 11:34:46 +10:00
Zoltan Somogyi
656493dfdf Use separate types for the status of different entity kinds.
We used the old import_status type to represent the status of six different
kinds of entities:

- types
- insts
- modes
- typeclasses
- instances
- predicates

even though some statuses that made sense for one kind of entity didn't for
another another (e.g. predicates can be pseudo imported/exported, but the
other five kinds of entities cannot).

Create the new types type_status, inst_status, ..., pred_status to represent
the status of these entities in the HLDS. For now, these are just wrappers
around the renamed old_import_status type, but I plan to replace them with
status types that *are* specialized to the applicable kind of entity,
along the lines of compiler/notes/status_proposal. This is a necessary
first step towards that proposal.

compiler/status.m:
    Define the six new entity-kind-specific status types, and replicate
    the test predicates that used to work on the import_status type
    to work on these instead.

    Define a status type, item_mercury_status, that contains just the info
    that is common to all entities in an item block, for use during
    the process of adding items to the HLDS.

    Move the predicates that converted section markers to statuses
    from here to make_hlds_passes.m, since that is the only place
    where they are used, or can be used.

    Move the combine_status predicate here from add_type.m, since
    it is needed for combining the statuses of other kinds of entities
    as well, not just types.

compiler/hlds_data.m:
    Change the HLDS types that record the information we have about
    types, du type fields, insts, modes, typeclasses and instances
    to have kind-specific status fields, instead of the old generic
    import_status type.

    Change the prefix on the field names of the hlds_instance_defn type
    to avoid a name clash, and to make them more meaningful.

    Change the prefix on the field names of the hlds_class_defn type
    to make them more meaningful.

compiler/hlds_pred.m:
    Change the HLDS type that records the information we have about predicates
    to have a kind-specific status field, instead of the old generic
    import_status type.

    Update the predicates that test predicate statuses accordingly.

compiler/hlds_module.m:
    Change the HLDS types that record the information we have about
    type constructors to be type_status, not the old generic import_status.

compiler/make_hlds_passes.m:
    As we process each item block, pass along an item_mercury_status
    instead of an import_status. The code used to use only a subset
    of the possible values of the import_status type, since we can never say
    that all the entities in an item block are e.g. pseudo-exported.
    An item_mercury_status has just the information we actually *know*
    about the item block as a whole. We convert the item_mercury_status
    to a kind-specific status if and when we need to, but for several purposes,
    the item_mercury_status is enough on its own.

    In a few cases, add a new predicate to do this conversion.

    Pass the need_qualifier flag separately from the status. It is needed
    in only a few places, but this was not apparent when we always passed it
    around paired with the import_status.

    Move the predicates that converted section markers to statuses
    to here from status.m, since here is the only place where they are used,
    or can be used.

compiler/add_class.m:
    Convert the statuses of typeclasses and instances to the statuses
    of the predicates implementing their virtual and concrete methods.

compiler/check_typeclass.m:
    Simplify some over-complex code.

compiler/add_special_pred.m:
    Convert the statuses of types to the statuses of the predicates
    implementing their unify, index, compare and solver init operations.
    Note some places where the process of this conversion is (to say the least)
    unclear and undocumented.

compiler/hlds_out_util.m:
    Provide utility predicates to print all the new kinds of statuses.
    These replace the old predicate that did the same in hlds_out_pred.m,
    but printing e.g. type statuses in hlds_out_pred doesn't seem right.

compiler/intermod.m:
    Conform to the changes above.

    Consistently use switches on the booleans returned by xxx_status_to_write,
    instead wrapping a semidet predicate around it and calling that.
    The switches yield code that is both smaller and more maintainable.

compiler/make_hlds_error.m:
    Conform to the changes above.

    Delete a simple wrapper predicate that was used only in one place.
    That place now does the wrapping itself.

compiler/qual_info.m:
    Replace the import_status field in the qual_info with a simple
    is_opt_imported/is_not_opt_imported flag, since that was the only
    thing we used the import_status field for.

compiler/accumulator.m:
compiler/add_clause.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_mutable_aux_preds.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pragma_type_spec.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_type.m:
compiler/base_typeclass_info.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/dep_par_conj.m:
compiler/dependency_graph.m:
compiler/det_report.m:
compiler/elds_to_erlang.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/float_regs.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_out_module.m:
compiler/hlds_out_pred.m:
compiler/inst_check.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make_hlds.m:
compiler/make_hlds_warn.m:
compiler/make_tags.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/mode_errors.m:
compiler/oisu_check.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/prop_mode_constraints.m:
compiler/recompilation.usage.m:
compiler/simplify_proc.m:
compiler/smm_common.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/status.m:
compiler/stm_expand.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/superhomogeneous.m:
compiler/table_gen.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/type_class_info.m:
compiler/type_constraints.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_info.m:
compiler/typeclasses.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the changes above.
2015-09-12 09:07:45 +10:00
Zoltan Somogyi
8a9e623546 Convert (C->T;E) to (if C then T else E).
compiler/add_*.m:
    Convert the syntax of if-then-elses in the modules that construct
    the HLDS.

    In a few places, eliminate double negation by replacing (~C->T;E)
    with (if C then E else T). In a few other places, replace if-then-elses
    by switches.

    In add_foreign_enum.m, make an error message more informative
    if --verbose-errors is not given, and more compact if it is given.

tests/invalid/ee_invalid.err_exp:
    Expect the updated error message.
2015-09-05 12:39:27 +10:00
Zoltan Somogyi
f2043fc9bd Replace the item list with more structured ASTs.
The parts of the compiler that run before the HLDS is constructed used to use
a raw list of items to represent source files (.m), interface files (.int0,
.int3, .int2 and .int) and optimization files (.opt, and .trans_opt).
These lists had structure, but this structure was implicit, not explicit,
and its invariants were never really documented.

This diff changes that. It replaces the item list with FIVE separate types.

Three of these each represent the unprocessed content of one file:

- parse_tree_int represents the contents of one interface file;
- parse_tree_opt represents the contents of one optimization file;
- parse_tree_src represents the contents of one source file.

Two of these each represent the processed contents of one or more files:

- raw_compilation_unit represents the contents of one module in a source file.
  (The source file may contain several nested modules; the compilation unit
  represents just one.)
- aug_compilation_unit represents the contents of one module in a source file,
  just like raw_compilation_unit, but it is augmented with the contents of the
  interface and optimization files of the other modules imported (directly or
  indirectly) by the original module.

These five separate concepts all used to be represented by the same type,
list(item), but different invariants applied to the structure of those lists.
The most important of those invariants at least are now explicit in the types.
I think it is entirely possible that there are other invariants I haven't
discovered and documented (for example, .int3 files must have stricter
invariants on what can appear in them than .int files), but discovering
and documenting these should be MUCH easier after this change.

I have marked many further opportunities for improvements with "XXX ITEM_LIST".
Some of these include moving code between modules, and the creation of new
modules. However, I have left acting on those XXXs until later, in order to
keep the size of this diff down as much as possible, for easier reviewing.

compiler/prog_item.m:
    Define the five new AST types described above, and utility predicates
    that operate on them.

    In the rest of this change, I tried, as much as possible, to change
    predicates that used to take item lists as arguments to make them change
    one of these types instead. In many cases, this required putting
    the argument lists of those predicates into a more consistent order.
    (Often, predicates that operated on the contents of the module
    took the name of the module and the list of items in the module
    not just as separate arguments, but as separate arguments that
    weren't even next to each other.)

    Define types that identify the different kinds of interface and
    optimization files (.int, .int2 etc). These replace the string suffixes
    we used to use to identify file types. Predicates that used to take strings
    representing suffixes as arguments now have to specify whether they can
    handle all these file types (source, interface and optimization),
    or just (e.g.) all interface file types.

    We used to have items corresponding to `:- module' and `:- end_module'.
    Delete these; this information is now implicit in the structure of the
    relevant AST. The parser handles the corresponding terms as markers,
    not items; these markers are live only during parsing.

    We used to have module_defns corresponding to `:- interface' and
    `:- implementation'. Delete these; this information is now also implicit
    in the structure of the relevant AST. Delete also, for the same reason,
    the module_defns used to mark the starts of sublists in the overall lists
    of items whose items came from the interface files or optimization files
    of other modules. The former are now markers during parsing. The latter
    are never parsed, but are created directly, after parsing has been done.

    Delete the pragma type for `:- pragma source_file'. This is never
    needed later; it is now a marker during parsing.

    Change the internal representation of `:- import' and `:- use'.
    It used to store a list of module names, but that list was an actual list
    only during parsing; after that, it always had exactly one element.
    It now stores one module name, and the parser has a mechanism to convert
    one read-in term to more than one item, for use with terms such as
    `:- import_module a, b'.

    Delete the internal representation of `:- export', which was never
    implemented, since if it IS ever implemented, it will almost certainly
    be in a different form, which will need different support.

    Document some further opportunities for simplification, later.
    (This diff is already more than big enough.)

compiler/prog_io_item.m:
    Rewrite the top-level part of this module. Instead of returning an item
    for every parsed term, distinguish between parsing items that end up
    in item lists inside ASTs, and parsing markers that end up creating
    the STRUCTURE of those ASTs.

compiler/prog_io.m:
    Rewrite the meat of this module. Instead of reading in a simple item list,
    we now have to read in three different parse trees with three different
    grammars, each of which is more complex than a simple list.

compiler/read_modules.m:
    We used to have a map that mapped file names to the contents of those
    files. We now need three separate maps, for interface files, optimization
    files and source files, due to their separate types.
    (We don't actually use the map for optimization files, which seems
    to be a potential performance bug. The root cause of that problem
    us that while intermod.m and the grab_*modules part of modules.m do
    similar jobs, they don't use the same mechanisms.)

    Replace the read_module predicate with the predicates read_module_src
    and read_module_int, since these now return different types.

    To avoid having to create AST-type-specialized variants of
    read_module_ignore_errors and read_module_if_changed, give each of
    read_module_{src,int} arguments that optionally tell them to ignore errors
    and/or to read the module only if changed (though the "and" part of
    "and/or" should not be needed.) These options already existed, but
    they weren't exported.

compiler/timestamp.m:
    Define the type we use for this option in read_modules.

compiler/status.m:
    New module, containing mostly

    - stuff carved out of hlds_pred.m, which defines the import_status type,
      and the predicates that operate on it;
    - stuff carved out of make_hlds_passes.m, which defines the item_status
      type and the predicates that operate on that; and
    - stuff carved out prog_data.m, which defines the section (now
      module_section) and import_locn types.

    It also contains the new section kinds we now use to represent item blocks
    that were imported from interface and optimization files.

compiler/parse_tree.m:
compiler/notes/compiler_design.html:
    Add status.m to the parse_tree package.

compiler/hlds_pred.m:
compiler/prog_data.m:
    Remove the stuff now in status.m.

compiler/error_util.m:
    Provide a mechanism to control the order of messages with respect to
    ALL other messages, not just those that also specify ordering.

compiler/mercury_to_mercury.m:
    Provide predicates for printing out parse_tree_* and *_compilation_unit,
    since printing out a simple item list is no longer enough for debugging.

    Pretty-print type definitions nicely.

    Replace a boolean with a purpose-specific enum.

compiler/modules.m:
    Rewrite virtually all this module to make it work on the new AST
    representations. Generate more detailed error messages for duplicate
    module inclusions. Note lots of possibilities for further improvements,
    including in the documentation. Mark places I am still not sure about,
    especially places where I am not sure *why* the code is doing
    what it is doing.

compiler/module_imports.m:
    This module stores the data structure in which we accumulate the stuff
    imported into a compilation unit, i.e. it is in these data structures
    that a raw_compilation_unit becomes an aug_compilation_unit. Modify
    the data structure and the predicates that operate on it to work on the
    new AST representations, not on an (apparently) simple list of items.

    Avoid ambiguities by adding a prefix to field names.

    Add some convenience predicates.

compiler/module_qual.m:
    Perform module qualification on both raw lists of items (for use when
    generating .int3 files) but also on item blocks (for use pretty much
    in every other situation).

    Generate warnings about module imports that are unnecessarily in the
    module interface using the module's context (the context of the `:- module'
    declaration), not line 1 of the relevant file.

compiler/prog_io_error.m:
    Split some error categories more finely, since some error kinds here
    actually used to be reported for more than one distinct situation.

compiler/prog_io_util.m:
    Provide utility predicates that operate on nonempty lists.

compiler/recompilation.version.m:
    Make the comparison of the old and new contents of the interface file
    work on two parse_tree_ints, not on two raw sequences of items.

    Delete a boolean option that was always `yes', never 'no'.

compiler/recompilation.m:
    Turn some functions into predicates to allow the use of state variable
    notation.

    Avoid ambiguities by adding a prefix to field names.

compiler/write_module_interface_files.m:
    Besides updating the code in this module to work on the new parse tree
    representations, also use cords instead of reversed lists in several cases.
    Note many possibilities for further improvements.

library/list.m:
    Move the type one_or_more here from the compiler directory, since
    we now use it in more than one compiler module, and this is its natural
    home.

mdbcomp/sym_name.m:
    Rename "match_sym_name" to "partial_sym_name_matches_full", since this
    better describes its job.

    Add a det version of sym_name_get_module_name.

compiler/equiv_type.m:
    Rename some types to make them more expressive.

compiler/accumulator.m:
compiler/add_class.m:
compiler/add_foreign_enum.m:
compiler/add_foreign_proc.m:
compiler/add_mode.m:
compiler/add_pragma.m:
compiler/add_pragma_tabling.m:
compiler/add_pred.m:
compiler/add_solver.m:
compiler/add_special_pred.m:
compiler/add_type.m:
compiler/assertion.m:
compiler/base_typeclass_info.m:
compiler/check_typeclass.m:
compiler/ctgc.util.m:
compiler/dead_proc_elim.m:
compiler/dep_par_conj.m:
compiler/dependency_graph.m:
compiler/deps_map.m:
compiler/det_report.m:
compiler/elds_to_erlang.m:
compiler/equiv_type_hlds.m:
compiler/erl_code_gen.m:
compiler/export.m:
compiler/format_call.m:
compiler/higher_order.m:
compiler/hlds_data.m:
compiler/hlds_module.m:
compiler/hlds_out_pred.m:
compiler/inst_check.m:
compiler/intermod.m:
compiler/item_util.m:
compiler/lambda.m:
compiler/lco.m:
compiler/make.module_dep_file.m:
compiler/make_hlds.m:
compiler/make_hlds_error.m:
compiler/make_hlds_passes.m:
compiler/make_tags.m:
compiler/mercury_compile.m:
compiler/ml_proc_gen.m:
compiler/ml_type_gen.m:
compiler/mode_errors.m:
compiler/oisu_check.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/post_term_analysis.m:
compiler/post_typecheck.m:
compiler/pred_table.m:
compiler/prog_io_dcg.m:
compiler/prog_io_find.m:
compiler/prog_io_pragma.m:
compiler/prog_io_sym_name.m:
compiler/prog_io_type_defn.m:
compiler/prog_io_typeclass.m:
compiler/prop_mode_constraints.m:
compiler/push_goals_together.m:
compiler/qual_info.m:
compiler/recompilation.check.m:
compiler/recompilation.usage.m:
compiler/simplify_proc.m:
compiler/smm_common.m:
compiler/special_pred.m:
compiler/ssdebug.m:
compiler/stm_expand.m:
compiler/structure_reuse.analysis.m:
compiler/structure_reuse.direct.m:
compiler/structure_reuse.indirect.m:
compiler/structure_reuse.versions.m:
compiler/structure_sharing.analysis.m:
compiler/structure_sharing.domain.m:
compiler/table_gen.m:
compiler/term_constr_initial.m:
compiler/term_constr_main.m:
compiler/termination.m:
compiler/trace_params.m:
compiler/trans_opt.m:
compiler/type_class_info.m:
compiler/type_ctor_info.m:
compiler/typecheck.m:
compiler/typecheck_errors.m:
compiler/typecheck_info.m:
compiler/unify_proc.m:
compiler/untupling.m:
compiler/unused_args.m:
compiler/unused_imports.m:
compiler/write_deps_file.m:
compiler/xml_documentation.m:
    Conform to the changes above.

tests/hard_coded/higher_order_func_test.m:
tests/hard_coded/higher_order_syntax.m:
    Avoid a warning about importing a module in the interface, not the
    implementation.

tests/invalid/after_end_module.err_exp:
tests/invalid/any_mode.err_exp:
tests/invalid/bad_end_module.err_exp:
tests/invalid/bigtest.err_exp:
tests/invalid/bug113.err_exp:
tests/invalid/duplicate_modes.err_exp:
tests/invalid/errors.err_exp:
tests/invalid/errors1.err_exp:
tests/invalid/errors2.err_exp:
tests/invalid/funcs_as_preds.err_exp:
tests/invalid/inst_list_dup.err_exp:
tests/invalid/invalid_main.err_exp:
tests/invalid/missing_interface_import2.err_exp:
tests/invalid/no_exports.err_exp:
tests/invalid/occurs.err_exp:
tests/invalid/predmode.err_exp:
tests/invalid/prog_io_erroneous.err_exp:
tests/invalid/type_inf_loop.err_exp:
tests/invalid/typeclass_missing_det_3.err_exp:
tests/invalid/typeclass_test_11.err_exp:
tests/invalid/types.err_exp:
tests/invalid/undef_inst.err_exp:
tests/invalid/undef_mode.err_exp:
tests/invalid/undef_type.err_exp:
tests/invalid/unicode1.err_exp:
tests/invalid/unicode2.err_exp:
tests/invalid/vars_in_wrong_places.err_exp:
tests/warnings/unused_import.exp:
tests/warnings/unused_interface_import.exp:
    Update the expected outputs in the invalid and warnings directories
    to account for one or more of the following five changes.

    Error messages that warn about a module not exporting anything
    used to always refer to line 1 of the module's source file.
    Now expect these messages to refer to the actual context of the module,
    which is the context of its `:- module' declaration.

    Expect a similarly updated context for messages that warn about
    unnecessarily importing modules in the interface, not in the
    implementation.

    Expect a similarly updated context for messages that warn about
    importing a module via both `:- import_module' and `:- use_module'.

    For the modules that follow the `:- module' declaration directly with code,
    also expect an error message about the missing section marker.

    For modules that have terms after the `:- end_module' declaration,
    replace "end_module" with "`:- end_module'" in the error message.

tests/invalid/func_class.{m,err_exp}:
    New test case. It is a copy of the old tests/valid/func_class.m, which
    is missing more than one module marker. The expected output is what I think
    we should generate. The test case currently fails, because we currently
    print only a subset of the expected errors. I am pretty sure the reason
    for that is that old code I have not modified simply throws away the
    missing error messages. Fixing this is work for the near future.

tests/invalid/Mmakefile:
    Enable the new test case.

tests/misc_tests/pretty_print_test.exp:
    Expect the pretty-printed output to use four-space indentation,
    per our current style guide, since the compiler now generates such output.

tests/misc_tests/pretty_print_test.m:
    Clean up the source code of the test as well.

tests/valid/complicated_unify.m:
tests/valid/det_switch.m:
tests/valid/easy_nondet_test.m:
tests/valid/error.m:
tests/valid/func_class.m:
tests/valid/func_int_bug_main.m:
tests/valid/higher_order.m:
tests/valid/higher_order2.m:
tests/valid/implied_mode.m:
tests/valid/indexing.m:
tests/valid/multidet_test.m:
tests/valid/nasty_func_test.m:
tests/valid/semidet_disj.m:
tests/valid/stack_alloc.m:
tests/valid/switches.m:
    Add missing section markers to these modules. They used to follow
    the `:- module' declaration directly with code.
2015-07-21 04:06:52 +10:00
Zoltan Somogyi
4e3af446ef Give some verbose error explanations only once.
compiler/error_util.m:
    Some of the messages we print if --verbose-errors are enabled just explain
    what an always-printed error message means. If a compiler invocation
    reports several instances of an error, the explanation is useful
    only the first time. This diff provides a mechanism for printing
    such verbose messages only once per invocation of write_error_specs.

compiler/*.m:
    Specify verbose_once for verbose error message components which are
    (a) not specific to the specific instance of the error they are generated
    for, and (b) whose usefulness/size ratio is not high enough. Part (b)
    means that it is ok to repeatedly print a single-line reminder,
    but not a 20-line missive that reads like an extract from the
    reference manual.

    In one case, make an error message clearer.

tests/invalid/*.err_exp:
tests/warnings/*.exp:
    Expect the new, slimmed-down output.
2015-02-19 12:38:07 +11:00