mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-20 11:54:02 +00:00
to allow even very long disjunctions to be parsed in constant stack space. This fixes Mantis bug #559. compiler/prog_item.m: We used to represent a disjunction like ( GoalA ; GoalB ; GoalC ; GoalD ) in the parse tree as disj_expr(ContextA, GoalA, disj_expr(ContextB, GoalB, disj_expr(ContextC, GoalC, GoalD))) To enable the changes in parse_goal.m and parse_dcg_goal.m, switch over to representing them as disj_expr(ContextA, GoalA, GoalB, [GoalC, GoalD]) The type of this term enforces the invariant that a disjunction must have at least two disjuncts. The fact that this throws away ContextB and ContextC is not a problem; they were never used, being thrown away when converting the parse tree to the HLDS. compiler/parse_goal.m: compiler/parse_dcg_goal.m: After seeing the first comma in the above disjunction, these parsers used to (1) parse its left operand, GoalA, (2) parse its right operand, ( GoalB ; GoalC ; GoalD), and then (3) check for errors. This code was prevented from being tail recursive both by the presence of step 3, and the fact that step 2 indirectly invokes another predicate that (until my previous change to parse_goal.m) had a different determinism. Fix the first issue by having the new predicate parse_goal_disjunction, and its DCG variant, accumulate errors *alongside* disjuncts, to be checked just once, at the end, outside the loop. Fix the second issue by having parse_goal_disjunction test whether the right operand of the semicolon has the form of a disjunction, and if it does, recursing on it directly. This makes parse_goal_disjunction self-tail-recursive, which should allow it to process disjunctions of arbtrary length using fixed stack space (in grades that support tail recursion, that is). Move the code to flatten disjunctions from goal_expr_to_goal.m to these modules, because it is simpler to get the right result this way in DCG clauses (for non-DCG clauses, it works simply either way). compiler/goal_expr_to_goal.m: Convert the updated parse tree representation of disjunctions to HLDS, and don't flatten disjunctions here anymore. compiler/parse_item.m: Add some infrastructure for debugging changes like this. compiler/add_clause.m: Improve the infrastructure of debugging changes like this, by making it more selective. To make this possible, pass the predicate name to a predicate that did not need it before. Fix the argument order of that predicate. compiler/make_hlds_warn.m: Don't flatten parse tree disjunctions, since the code constructing them has done it already. compiler/get_dependencies.m: compiler/module_qual.collect_mq_info.m: compiler/parse_tree_out_clause.m: compiler/prog_item_stats.m: compiler/prog_util.m: Conform to the change in prog_item.m. compiler/instance_method_clauses.m: Conform to the change in add_clause.m. tests/hard_coded/flatten_disjunctions.{m,exp}: A new test case both testing and documenting the need for flattening disjunctions. tests/hard_coded/Mmakefile: Enable the new test case. tests/invalid/require_switch_arms_detism.err_exp: Expect updated numbers for anonymous variables. This is due to goal_expr_to_goal.m now processing disjuncts in a different order than before.
40 lines
2.6 KiB
Plaintext
40 lines
2.6 KiB
Plaintext
require_switch_arms_detism.m:042: Error: the arms of the switch on Functor are
|
|
require_switch_arms_detism.m:042: required have a determinism that is
|
|
require_switch_arms_detism.m:042: acceptable in a `det' context, but the
|
|
require_switch_arms_detism.m:042: actual determinism of the arm for ":-" is
|
|
require_switch_arms_detism.m:042: `semidet'.
|
|
require_switch_arms_detism.m:043: Unification of `Args' and `list.[Arg1 |
|
|
require_switch_arms_detism.m:043: V_9]' can fail.
|
|
require_switch_arms_detism.m:043: In argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:043: unification with `list.[Arg2 | V_10]' can
|
|
require_switch_arms_detism.m:043: fail.
|
|
require_switch_arms_detism.m:043: In argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:043: in argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:043: unification with `list.[]' can fail.
|
|
require_switch_arms_detism.m:046: Error: the arms of the switch on Functor are
|
|
require_switch_arms_detism.m:046: required have a determinism that is
|
|
require_switch_arms_detism.m:046: acceptable in a `det' context, but the
|
|
require_switch_arms_detism.m:046: actual determinism of the arm for "--->" is
|
|
require_switch_arms_detism.m:046: `semidet'.
|
|
require_switch_arms_detism.m:047: Unification of `Args' and `list.[Arg1 |
|
|
require_switch_arms_detism.m:047: V_13]' can fail.
|
|
require_switch_arms_detism.m:047: In argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:047: unification with `list.[Arg2 | V_14]' can
|
|
require_switch_arms_detism.m:047: fail.
|
|
require_switch_arms_detism.m:047: In argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:047: in argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:047: unification with `list.[]' can fail.
|
|
require_switch_arms_detism.m:050: Error: the arms of the switch on Functor are
|
|
require_switch_arms_detism.m:050: required have a determinism that is
|
|
require_switch_arms_detism.m:050: acceptable in a `det' context, but the
|
|
require_switch_arms_detism.m:050: actual determinism of the arm for "=" is
|
|
require_switch_arms_detism.m:050: `semidet'.
|
|
require_switch_arms_detism.m:051: Unification of `Args' and `list.[Arg1 |
|
|
require_switch_arms_detism.m:051: V_17]' can fail.
|
|
require_switch_arms_detism.m:051: In argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:051: unification with `list.[Arg2 | V_18]' can
|
|
require_switch_arms_detism.m:051: fail.
|
|
require_switch_arms_detism.m:051: In argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:051: in argument 2 of functor `[|]/2':
|
|
require_switch_arms_detism.m:051: unification with `list.[]' can fail.
|