1:- module(plammar_options, [
    2    normalise_options/2,
    3    normalise_options/3,
    4    revise_options/2,
    5    style_option/2
    6  ]).    7
    8:- use_module(library(option), [merge_options/3, option/2, option/3]).    9:- use_module(library(apply), [maplist/3]).   10
   11:- use_module(operators).   12:- use_module(environments).   13:- use_module(util).   14
   15normalise_options(User_Options, Options) :-
   16  O1 = User_Options,
   17  normalise_options(prolog_tokens, O1, O2),
   18  normalise_options(prolog_parsetree, O2, O3),
   19  normalise_options(prolog_ast, O3, O4),
   20  Options = O4.
   21
   22normalise_options(prolog_tokens, User_Options, Options) :-
   23  option(targets(Targets), User_Options, [iso]),
   24  ( Targets = [] ->
   25    Target = iso
   26  ; Targets = [Target|_] ),
   27  target_options(Target, Target_Options),
   28  merge_options(User_Options, Target_Options, Options0),
   29  Options = Options0.
   30
   31normalise_options(prolog_parsetree, User_Options, Options) :-
   32  default_options(prolog_parsetree, Options0),
   33  % merge target options
   34  option(targets(Targets), User_Options, [iso]),
   35  ( Targets = [] ->
   36    Target = iso
   37  ; Targets = [Target|_] ),
   38  target_options(Target, Target_Options),
   39  merge_options(Target_Options, Options0, Options1),
   40  % merge user options
   41  merge_options(User_Options, Options1, Options2),
   42  % option: infer_operators
   43  option(infer_operators(Opt_Infer_Operators), Options2),
   44  ( yes(Yes), Opt_Infer_Operators == Yes ->
   45    merge_options([ infer_operators(_) ], Options2, Options3)
   46  ; Options3 = Options2 % user provided `no` or an unbound variable
   47  ),
   48  % option: operators
   49  option(operators(Operators0), Options3),
   50  normalise_operators(Operators0, Operators1),
   51  merge_options([operators(Operators1)], Options3, Options4),
   52  Options = Options4.
   53
   54normalise_options(prolog_ast, User_Options, Options) :-
   55  default_options(prolog_ast, Default_Options),
   56  merge_options(User_Options, Default_Options, Options0),
   57  option(style(User_Style), Options0, []),
   58  normalise_style(User_Style, Style),
   59  merge_options([style(Style)], Options0, Options1),
   60  Options = Options1.
   61
   62default_options(prolog_parsetree, Options) :-
   63  Options = [
   64    operators([]),
   65    specified_operators(L),
   66    infer_operators(no),
   67    targets([iso]),
   68    allow_variable_name_as_functor(no),
   69    arg_precedence_lt_1000(yes)
   70  ],
   71  list_open([], L).
   72
   73default_options(prolog_ast, Options) :-
   74  Options = [
   75    end_state(_)
   76  ].
   77
   78revise_options(prolog_tokens, _).
   79
   80% take the open lists from option `infer_operators`
   81%   and make them closed
   82revise_options(prolog_parsetree, Options) :-
   83  option(infer_operators(Inferred_Ops), Options),
   84  ( no(No), Inferred_Ops == No
   85  ; list_close(Inferred_Ops)).
   86
   87normalise_style(User_Style, Style) :-
   88  default_style(Default_Style),
   89  maplist(add_secondary, User_Style, User_Style_With_Secondaries),
   90  merge_options(User_Style_With_Secondaries, Default_Style, Style).
   91
   92default_style(Style) :-
   93  Style0 = [
   94    % general formatting
   95    indent(2),
   96    max_line_length(78),
   97    no_eol_whitespace(yes),
   98
   99    % format of rules
  100    max_subgoals(inf),
  101    max_rule_lines(inf),
  102    newline_after_rule_op(yes),
  103    newline_after_subgoal(yes),
  104
  105    % format of clauses
  106    newline_after_clause(yes),
  107
  108    % predicates
  109    space_after_arglist_comma(yes),
  110
  111    % format of numbers
  112    integer_exponential_notation(no),
  113    digit_groups(no), % one of: [no, '_', ' ']
  114    single_quote_char_in_character_code_constant(no),
  115
  116    % format of quoted items
  117    tab_in_quotes(no),
  118    missing_closing_backslash_in_character_escape(no),
  119    unicode_character_escape(yes),
  120
  121    % dicts
  122    dicts(yes),
  123
  124    shebang(no),
  125    compounds_with_zero_arguments(no),
  126
  127    symbolic_chars(yes)
  128  ],
  129  maplist(add_secondary, Style0, Style).
  130
  131add_secondary(Opt, Opt_With_Secondary) :-
  132  Opt =.. [Prop, Value|Possibly_Secondary],
  133  ( Possibly_Secondary = [] ->
  134    Secondary = []
  135  ; otherwise ->
  136    Possibly_Secondary = [Secondary]
  137  ),
  138  Opt_With_Secondary =.. [Prop, Value/Secondary].
  139
  140style_option(Prop, Opts) :-
  141  option(style(Style), Opts),
  142  option(Prop, Style)