[m-rev.] for review: better error messages for lambda exprs
Zoltan Somogyi
zoltan.somogyi at runbox.com
Mon May 16 10:13:05 AEST 2016
On Wed, 11 May 2016 23:37:07 +1000 (AEST), "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> > I don't know exactly which operators or words you had in mind.
>
> Good point. I will make up a list for discussion.
>
> > Does it include '=' as used in comparison_result? Or 'not', as in
> > bool.not? Is the standard library going to be privileged?
>
> That is the key question. My instinct is to try to reserve every word
> or operator that would be used as a literal in a BNF grammar for Mercury
> (if the Mercury parser were based on BNF), and to make exceptions
> to this only as/when required by backward compatibility. Those two
> would have to be exceptions, at least for now; there may be others.
>
> We can discuss the details (e.g. can a module not named "bool" define
> a predicate named "not"? can you use "not" as a type name?) in person
> on monday. (My own preferred answers are "no" and "no", btw.)
As a basis for discussion, here is part of a diff (which I do not intend
to commit in its current form) that I used to find places where we now use
Mercury "keywords" in a non-keyword capacity:
diff --git a/compiler/parse_util.m b/compiler/parse_util.m
index 8612ced..1fd8d72 100644
--- a/compiler/parse_util.m
+++ b/compiler/parse_util.m
@@ -115,10 +115,24 @@
is det.
%---------------------------------------------------------------------------%
+
+:- pred is_reserved_name(string::in) is semidet.
+
+:- pred reserved_name_allowed_as_type_ctor_name(module_name::in, string::in)
+ is semidet.
+:- pred reserved_name_allowed_as_data_ctor_name(module_name::in, string::in)
+ is semidet.
+:- pred reserved_name_allowed_as_inst_name(module_name::in, string::in)
+ is semidet.
+:- pred reserved_name_allowed_as_mode_name(module_name::in, string::in)
+ is semidet.
+
+%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- implementation.
+:- import_module mdbcomp.builtin_modules.
:- import_module parse_tree.parse_sym_name.
:- import_module bool.
@@ -322,5 +336,360 @@ map_parser(Parser, [Head | Tail], Result) :-
).
%---------------------------------------------------------------------------%
+
+is_reserved_name(Name) :-
+ require_switch_arms_det [Name]
+ ( Name = "." % symname qualifier
+ ; Name = "(" % universal grouping
+ ; Name = ")" % universal grouping
+ ; Name = "!" % state variable notation
+ ; Name = "!." % state variable notation
+ ; Name = "!:" % state variable notation
+
+ ; Name = "int" % primitive type
+ ; Name = "float" % primitive type
+ ; Name = "character" % primitive type
+ ; Name = "string" % primitive type
+ ; Name = "{}" % type ctor
+ ; Name = "pred" % type ctor, inst ctor, decl kind, etc
+ ; Name = "func" % type ctor, inst ctor, decl kind, etc
+ ; Name = "is" % type ctor, mode ctor, detism prefix, etc
+ ; Name = "=" % type ctor, inst ctor, unify op, etc
+ ; Name = "" % type ctor (apply)
+ ; Name = "pure" % type ctor, attribute
+ ; Name = "impure" % type ctor, attribute
+ ; Name = "semipure" % type ctor, attribute
+
+ ; Name = "==" % type defn, mode defn
+ ; Name = "--->" % type defn
+ ; Name = ";" % type defn, goal
+ ; Name = "where" % type defn, typeclass defn, etc
+ ; Name = "equality" % type defn
+ ; Name = "comparison" % type defn
+ ; Name = "representation" % type defn
+ ; Name = "constraint_store" % type defn
+ ; Name = "direct_arg" % type defn
+ ; Name = "type_is_abstract_enum" % type defn
+ ; Name = "type_is_abstract_noncanonical" % type defn
+
+ ; Name = "free" % inst ctor
+ ; Name = "ground" % inst ctor, solver type defn
+ ; Name = "unique" % inst ctor
+ ; Name = "mostly_unique" % inst ctor
+ ; Name = "clobbered" % inst ctor
+ ; Name = "mostly_clobbered" % inst ctor
+ ; Name = "any" % inst ctor, solver type defn
+ ; Name = "unique_any" % inst ctor
+ ; Name = "mostly_unique_any" % inst ctor
+ ; Name = "clobbered_any" % inst ctor
+ ; Name = "mostly_clobbered_any" % inst ctor
+ ; Name = "not_reached" % inst ctor
+ ; Name = "bound" % inst ctor
+ ; Name = "bound_unique" % inst ctor
+ ; Name = "=<" % inst ctor
+ ; Name = "any_pred" % inst ctor, decl kind, etc
+ ; Name = "any_func" % inst ctor, decl kind, etc
+
+ ; Name = "for" % inst defn
+
+ ; Name = ">>" % mode ctor
+
+ ; Name = "module" % marker
+ ; Name = "end_module" % marker
+ ; Name = "interface" % marker
+ ; Name = "implementation" % marker
+ ; Name = "include_module" % marker
+ ; Name = "import_module" % marker
+ ; Name = "use_module" % marker
+ % ; Name = "version_numbers" % marker
+ ; Name = "type" % decl kind
+ ; Name = "solver" % decl kind
+ ; Name = "inst" % decl kind
+ ; Name = "mode" % decl kind
+ ; Name = "promise" % decl kind
+ ; Name = "promise_exclusive" % decl kind
+ ; Name = "promise_exhaustive" % decl kind
+ ; Name = "promise_exhaustive_exhaustive" % decl kind
+ ; Name = "typeclass" % decl kind
+ ; Name = "instance" % decl kind
+ ; Name = "initialise" % decl kind
+ ; Name = "initialize" % decl kind
+ ; Name = "finalise" % decl kind
+ ; Name = "finalize" % decl kind
+ ; Name = "mutable" % decl kind
+ ; Name = "pragma" % decl kind
+
+ ; Name = "source_file" % pragma decl
+ ; Name = "foreign_type" % pragma decl
+ ; Name = "foreign_decl" % pragma decl
+ ; Name = "foreign_proc" % pragma decl
+ ; Name = "foreign_export_enum" % pragma decl
+ ; Name = "foreign_export" % pragma decl
+ ; Name = "foreign_import_module" % pragma decl
+ ; Name = "external_pred" % pragma decl
+ ; Name = "external_func" % pragma decl
+ ; Name = "inline" % pragma decl
+ ; Name = "no_inline" % pragma decl
+ ; Name = "consider_used" % pragma decl
+ ; Name = "obsolete" % pragma decl
+ ; Name = "no_determinism_warning" % pragma decl
+ ; Name = "terminates" % pragma decl
+ ; Name = "does_not_terminate" % pragma decl
+ ; Name = "check_termination" % pragma decl
+ ; Name = "mode_check_clauses" % pragma decl
+ ; Name = "require_tail_recursion" % pragma decl
+ ; Name = "reserve_tag" % pragma decl
+ ; Name = "oisu" % pragma decl
+ ; Name = "memo" % pragma decl, require_feature_set
+ ; Name = "loop_check" % pragma decl
+ ; Name = "minimal_model" % pragma decl
+ ; Name = "unused_args" % pragma decl
+ ; Name = "type_spec" % pragma decl
+ ; Name = "fact_table" % pragma decl
+ ; Name = "termination_info" % pragma decl
+ ; Name = "termination2_info" % pragma decl
+ ; Name = "structure_sharing" % pragma decl
+ ; Name = "structure_reuse" % pragma decl
+ ; Name = "exceptions" % pragma decl
+ ; Name = "trailing_info" % pragma decl
+ ; Name = "mm_tabling_info" % pragma decl
+ ; Name = "require_feature_set" % pragma decl
+
+ ; Name = "/" % pragma decl pred specifiers
+ ; Name = "can_pass_as_mercury_type" % pragma decl foreign type
+ ; Name = "stable" % pragma decl foreign type
+ ; Name = "word_aligned_pointer" % pragma decl foreign type
+ ; Name = "local" % pragma decl foreign_decl
+ ; Name = "exported" % pragma decl foreign_decl
+ ; Name = "include_file" % pragma decl foreign_decl
+ ; Name = "recursive" % pragma decl foreign_proc
+ ; Name = "non_recursive" % pragma decl foreign_proc
+ ; Name = "may_call_mercury" % pragma decl foreign_proc
+ ; Name = "will_not_call_mercury" % pragma decl foreign_proc
+ ; Name = "thread_safe" % pragma decl foreign_proc
+ ; Name = "not_thread_safe" % pragma decl foreign_proc
+ ; Name = "maybe_thread_safe" % pragma decl foreign_proc
+ ; Name = "may_modify_trail" % pragma decl foreign_proc
+ ; Name = "will_not_modify_trail" % pragma decl foreign_proc
+ ; Name = "may_call_mm_tabled" % pragma decl foreign_proc
+ ; Name = "will_not_call_mm_tabled" % pragma decl foreign_proc
+ ; Name = "native_if_possible" % pragma decl foreign_proc
+ ; Name = "always_boxed" % pragma decl foreign_proc
+ ; Name = "affects_liveness" % pragma decl foreign_proc
+ ; Name = "doesnt_affect_liveness" % pragma decl foreign_proc
+ ; Name = "does_not_affect_liveness" % pragma decl foreign_proc
+ ; Name = "doesnt_allocate_memory" % pragma decl foreign_proc
+ ; Name = "does_not_allocate_memory" % pragma decl foreign_proc
+ ; Name = "allocate_bounded_memory" % pragma decl foreign_proc
+ ; Name = "allocate_unbounded_memory" % pragma decl foreign_proc
+ ; Name = "registers_roots" % pragma decl foreign_proc
+ ; Name = "does_not_register_roots" % pragma decl foreign_proc
+ ; Name = "doesnt_register_roots" % pragma decl foreign_proc
+ ; Name = "does_not_have_roots" % pragma decl foreign_proc
+ ; Name = "doesnt_have_roots" % pragma decl foreign_proc
+ ; Name = "may_duplicate" % pragma decl foreign_proc
+ ; Name = "may_not_duplicate" % pragma decl foreign_proc
+ ; Name = "tabled_for_io" % pragma decl foreign_proc
+ ; Name = "tabled_for_io_unitize" % pragma decl foreign_proc
+ ; Name = "tabled_for_descendant_io" % pragma decl foreign_proc
+ ; Name = "not_tabled_for_io" % pragma decl foreign_proc
+ ; Name = "low_level_backend" % pragma decl foreign_proc, external
+ ; Name = "high_level_backend" % pragma decl foreign_proc, external
+ ; Name = "will_not_throw_exception" % pragma decl foreign_proc
+ ; Name = "ordinary_despite_detism" % pragma decl foreign_proc
+ ; Name = "fast_loose" % pragma decl tabling
+ ; Name = "specified" % pragma decl tabling
+ ; Name = "hidden_arg_value" % pragma decl tabling
+ ; Name = "size_limit" % pragma decl tabling
+ ; Name = "statistics" % pragma decl tabling
+ ; Name = "allow_reset" % pragma decl tabling
+ ; Name = "value" % pragma decl tabling
+ ; Name = "addr" % pragma decl tabling
+ ; Name = "promise_implied" % pragma decl tabling
+ ; Name = "output" % pragma decl tabling
+ ; Name = "concurrency" % pragma decl require_feature_set
+ ; Name = "single_prec_float" % pragma decl require_feature_set
+ ; Name = "double_prec_float" % pragma decl require_feature_set
+ ; Name = "parallel_conj" % pragma decl require_feature_set
+ ; Name = "strict_sequential" % pragma decl require_feature_set
+ ; Name = "conservative_gc" % pragma decl require_feature_set
+
+ /*
+ ZZZ
+ ; Name = "not_set" % pragma decl termination
+ ; Name = "infinite" % pragma decl termination
+ ; Name = "finite" % pragma decl termination
+ ; Name = "can_loop" % pragma decl termination
+ ; Name = "cannot_loop" % pragma decl termination
+ ; Name = "le" % pragma decl termination
+ ; Name = "eq" % pragma decl termination
+ ; Name = "term" % pragma decl termination
+ ; Name = "r" % pragma decl termination
+ ; Name = "not_available" % pragma decl structure sharing
+ ; Name = "yes" % pragma decl structure sharing
+ ; Name = "vars" % pragma decl structure reuse
+ ; Name = "types" % pragma decl structure reuse
+ ; Name = "will_not_throw" % pragma decl exceptions
+ ; Name = "may_throw" % pragma decl exceptions
+ ; Name = "user_exception" % pragma decl exceptions
+ ; Name = "type_exception" % pragma decl exceptions
+ ; Name = "conditional" % pragma decl exceptions, trailing_info
+ ; Name = "predicate" % pragma decl exceptions, unused_args, etc
+ ; Name = "function" % pragma decl exceptions, unused_args, etc
+ ; Name = "will_not_modify_trail" % pragma decl trailing_info
+ ; Name = "may_modify_trail" % pragma decl trailing_info
+ ; Name = "mm_table_will_not_call" % pragma decl mm_tabling_info
+ ; Name = "mm_table_may_call" % pragma decl mm_tabling_info
+ ; Name = "mm_table_conditional" % pragma decl mm_tabling_info
+ */
+
+ ; Name = "trailed" % mutable decl
+ ; Name = "untrailed" % mutable decl
+ ; Name = "attach_to_io_state" % mutable decl
+ ; Name = "constant" % mutable decl
+ ; Name = "thread_local" % mutable decl
+ ; Name = "foreign_name" % mutable decl
+
+ ; Name = "::" % arg in predmode decl
+
+ ; Name = ":-" % clause neck
+ ; Name = "-->" % clause neck
+
+ ; Name = "if" % goal
+ ; Name = "then" % goal
+ ; Name = "else" % goal
+ ; Name = "promise_pure" % goal, pragma_decl
+ ; Name = "promise_semipure" % goal, pragma_decl
+ ; Name = "promise_impure" % goal
+ ; Name = "not" % goal
+ ; Name = "\\+" % goal
+ ; Name = "some" % goal
+ ; Name = "all" % goal
+ ; Name = "," % goal
+ ; Name = "&" % goal
+ ; Name = "catch" % goal
+ ; Name = "catch_any" % goal
+ ; Name = "->" % goal
+ ; Name = "=>" % goal
+ ; Name = "<=" % goal
+ ; Name = "<=>" % goal
+ ; Name = "atomic" % goal
+ ; Name = "or_else" % goal
+ ; Name = "outer" % goal
+ ; Name = "inner" % goal
+ ; Name = "vars" % goal
+ ; Name = "promise_equivalent_solutions" % goal
+ ; Name = "promise_equivalent_solution_sets" % goal
+ ; Name = "arbitrary" % goal
+ ; Name = "require_det" % goal
+ ; Name = "require_semidet" % goal
+ ; Name = "require_multi" % goal
+ ; Name = "require_nondet" % goal
+ ; Name = "require_cc_multi" % goal
+ ; Name = "require_cc_nondet" % goal
+ ; Name = "require_erroneous" % goal
+ ; Name = "require_failure" % goal
+ ; Name = "require_complete_switch" % goal
+ ; Name = "require_switch_arms_det" % goal
+ ; Name = "require_switch_arms_semidet" % goal
+ ; Name = "require_switch_arms_multi" % goal
+ ; Name = "require_switch_arms_nondet" % goal
+ ; Name = "require_switch_arms_cc_multi" % goal
+ ; Name = "require_switch_arms_cc_nondet" % goal
+ ; Name = "require_switch_arms_erroneous" % goal
+ ; Name = "require_switch_arms_failure" % goal
+ ; Name = "event" % goal
+ ; Name = "trace" % goal
+ ; Name = "compiletime" % goal
+ ; Name = "compile_time" % goal
+ ; Name = "runtime" % goal
+ ; Name = "run_time" % goal
+ ; Name = "flag" % goal
+ ; Name = "grade" % goal
+ ; Name = "tracelevel" % goal
+ ; Name = "env" % goal
+ ; Name = "io" % goal
+ ; Name = "state" % goal
+ ; Name = "or" % goal
+ ; Name = "and" % goal
+ ; Name = "try" % goal
+ ; Name = "@" % goal
+ ; Name = "true" % goal
+ ; Name = "fail" % goal
+ ; Name = "with_type" % goal
+ ; Name = "with_inst" % goal
+ ; Name = ":" % goal
+ ; Name = "^" % goal
+ ; Name = "^=" % goal
+ ; Name = ":=" % goal
+ ).
+
+reserved_name_allowed_as_type_ctor_name(ModuleName, Name) :-
+ (
+ Name = "io",
+ ModuleName = mercury_std_lib_module_name(unqualified("io"))
+ ;
+ Name = "state",
+ ( ModuleName = mercury_std_lib_module_name(unqualified("io"))
+ ; ModuleName = mercury_std_lib_module_name(
+ qualified(unqualified("string"), "builder"))
+ )
+ ;
+ Name = "vars",
+ ModuleName = mercury_std_lib_module_name(unqualified("robdd"))
+ ).
+
+reserved_name_allowed_as_data_ctor_name(ModuleName, Name) :-
+ (
+ Name = "=",
+ ModuleName = mercury_std_lib_module_name(unqualified("builtin"))
+ ;
+ Name = "->",
+ ModuleName = mercury_std_lib_module_name(unqualified("tree234"))
+ ;
+ Name = "bound",
+ ModuleName = mercury_std_lib_module_name(unqualified("type_desc"))
+ ;
+ Name = "int",
+ ( ModuleName = mercury_std_lib_module_name(unqualified("getopt"))
+ ; ModuleName = mercury_std_lib_module_name(unqualified("getopt_io"))
+ )
+ ;
+ Name = "float",
+ ( ModuleName = mercury_std_lib_module_name(unqualified("lexer"))
+ ; ModuleName = mercury_std_lib_module_name(unqualified("term"))
+ )
+ ;
+ Name = "string",
+ ( ModuleName = mercury_std_lib_module_name(unqualified("getopt"))
+ ; ModuleName = mercury_std_lib_module_name(unqualified("getopt_io"))
+ ; ModuleName = mercury_std_lib_module_name(unqualified("lexer"))
+ ; ModuleName = mercury_std_lib_module_name(unqualified("term"))
+ )
+ ;
+ Name = "state",
+ ModuleName = mercury_std_lib_module_name(
+ qualified(unqualified("string"), "builder"))
+ ;
+ Name = "output",
+ ModuleName = mercury_std_lib_module_name(unqualified("io"))
+ ;
+ Name = "unique",
+ ModuleName = mercury_std_lib_module_name(unqualified("term_to_xml"))
+ ;
+ Name = "value",
+ ModuleName = mercury_std_lib_module_name(unqualified("lazy"))
+ ).
+
+reserved_name_allowed_as_inst_name(_ModuleName, _Name) :-
+ semidet_fail.
+
+reserved_name_allowed_as_mode_name(ModuleName, Name) :-
+ (
+ Name = "output",
+ ModuleName = mercury_std_lib_module_name(unqualified("builtin"))
+ ).
+
+%---------------------------------------------------------------------------%
:- end_module parse_tree.parse_util.
%---------------------------------------------------------------------------%
Even after the diffs of the last few days, the workspace with this diff
still does not bootstrap; instead, it gets the following errors in stage 2.
elds.m:289: Error: the name `=<' is reserved for the Mercury implementation; it
elds.m:289: may not be used as the name of a data constructor.
hlds_goal.m:261: Error: the name `parallel_conj' is reserved for the Mercury
hlds_goal.m:261: implementation; it may not be used as the name of a data
hlds_goal.m:261: constructor.
hlds_goal.m:488: Error: the name `require_complete_switch' is reserved for the
hlds_goal.m:488: Mercury implementation; it may not be used as the name of a
hlds_goal.m:488: data constructor.
hlds_goal.m:1058: Error: the name `->' is reserved for the Mercury
hlds_goal.m:1058: implementation; it may not be used as the name of a data
hlds_goal.m:1058: constructor.
globals.m:044: Error: the name `high_level_backend' is reserved for the Mercury
globals.m:044: implementation; it may not be used as the name of a data
globals.m:044: constructor.
globals.m:045: Error: the name `low_level_backend' is reserved for the Mercury
globals.m:045: implementation; it may not be used as the name of a data
globals.m:045: constructor.
options.m:159: Error: the name `statistics' is reserved for the Mercury
options.m:159: implementation; it may not be used as the name of a data
options.m:159: constructor.
options.m:297: Error: the name `strict_sequential' is reserved for the Mercury
options.m:297: implementation; it may not be used as the name of a data
options.m:297: constructor.
options.m:308: Error: the name `grade' is reserved for the Mercury
options.m:308: implementation; it may not be used as the name of a data
options.m:308: constructor.
options.m:400: Error: the name `single_prec_float' is reserved for the Mercury
options.m:400: implementation; it may not be used as the name of a data
options.m:400: constructor.
prog_data.m:704: Error: the name `free' is reserved for the Mercury
prog_data.m:704: implementation; it may not be used as the name of a data
prog_data.m:704: constructor.
prog_data.m:705: Error: the name `free' is reserved for the Mercury
prog_data.m:705: implementation; it may not be used as the name of a data
prog_data.m:705: constructor.
prog_data.m:707: Error: the name `any' is reserved for the Mercury
prog_data.m:707: implementation; it may not be used as the name of a data
prog_data.m:707: constructor.
prog_data.m:711: Error: the name `bound' is reserved for the Mercury
prog_data.m:711: implementation; it may not be used as the name of a data
prog_data.m:711: constructor.
prog_data.m:714: Error: the name `ground' is reserved for the Mercury
prog_data.m:714: implementation; it may not be used as the name of a data
prog_data.m:714: constructor.
prog_data.m:718: Error: the name `not_reached' is reserved for the Mercury
prog_data.m:718: implementation; it may not be used as the name of a data
prog_data.m:718: constructor.
prog_data.m:840: Error: the name `unique' is reserved for the Mercury
prog_data.m:840: implementation; it may not be used as the name of a data
prog_data.m:840: constructor.
prog_data.m:843: Error: the name `mostly_unique' is reserved for the Mercury
prog_data.m:843: implementation; it may not be used as the name of a data
prog_data.m:843: constructor.
prog_data.m:847: Error: the name `clobbered' is reserved for the Mercury
prog_data.m:847: implementation; it may not be used as the name of a data
prog_data.m:847: constructor.
prog_data.m:851: Error: the name `mostly_clobbered' is reserved for the Mercury
prog_data.m:851: implementation; it may not be used as the name of a data
prog_data.m:851: constructor.
prog_data.m:1010: Error: the name `->' is reserved for the Mercury
prog_data.m:1010: implementation; it may not be used as the name of a data
prog_data.m:1010: constructor.
prog_data_pragma.m:277: Error: the name `structure_sharing' is reserved for the
prog_data_pragma.m:277: Mercury implementation; it may not be used as the
prog_data_pragma.m:277: name of a user defined type.
prog_data_pragma.m:456: Error: the name `require_tail_recursion' is reserved
prog_data_pragma.m:456: for the Mercury implementation; it may not be used as
prog_data_pragma.m:456: the name of a user defined type.
prog_item.m:745: Error: the name `foreign_name' is reserved for the Mercury
prog_item.m:745: implementation; it may not be used as the name of a user
prog_item.m:745: defined type.
prog_item.m:746: Error: the name `foreign_name' is reserved for the Mercury
prog_item.m:746: implementation; it may not be used as the name of a data
prog_item.m:746: constructor.
term_constr_main_types.m:085: Error: the name `termination2_info' is reserved
term_constr_main_types.m:085: for the Mercury implementation; it may not be
term_constr_main_types.m:085: used as the name of a user defined type.
term_constr_main_types.m:144: Error: the name `termination2_info' is reserved
term_constr_main_types.m:144: for the Mercury implementation; it may not be
term_constr_main_types.m:144: used as the name of a user defined type.
term_util.m:065: Error: the name `termination_info' is reserved for the Mercury
term_util.m:065: implementation; it may not be used as the name of a user
term_util.m:065: defined type.
Zoltan.
More information about the reviews
mailing list