18:- module(graphql, [graphql/4]).   19
   20:- use_module(library(dcg/basics)).   21:- use_module(library(quasi_quotations)).   22
   23:- quasi_quotation_syntax(graphql).   24
   25%%
   26tokenize(_QQDict, []) -->
   27    eos,
   28    %{ writeln(eos) },
   29    !.
   30tokenize(QQDict, [' '|Tokens]) -->
   31    blank, blanks,
   32    %{ writeln(blanks) },
   33    !, tokenize(QQDict, Tokens).
   34tokenize(QQDict, [Value|Tokens]) -->
   35    prolog_var_name(Key),
   36    %{ writeln(prolog_var_name(Key, Value)) },
   37    { ( memberchk(Key=Value, QQDict)
   38        ; Value = Key ) },
   39    !, tokenize(QQDict, Tokens).
   40tokenize(QQDict, ['"',Atom,'"'|Tokens]) -->
   41    `\"`,
   42     upto_quote(Atom),
   43    %{ writeln(upto_quote(Atom)) },
   44    !, tokenize(QQDict, Tokens).
   45tokenize(QQDict, [Atom, Sep|Tokens]) -->
   46    upto_sep(Atom, Sep),
   47    %{ writeln(upto_sep(Atom, Sep)) },
   48    !, tokenize(QQDict, Tokens).
   49
   50upto_sep(Atom, Sep) -->
   51        string(Codes), [S],
   52        { atom_codes(Atom, Codes),
   53          ( code_type(S, space)
   54            ; code_type(S, prolog_symbol)
   55            ; code_type(S, paren(_))
   56            ; code_type(_, paren(S))
   57            ; code_type(S, end_of_line)
   58          ),
   59          !,
   60          ( code_type(S, end_of_line)
   61            -> Sep = ''
   62            ;  atom_codes(Sep, [S])
   63          )
   64        }.
   65
   66upto_quote(Atom) -->
   67    string(Codes), `\"`, !,
   68    { atom_codes(Atom, Codes) }.
   69
   70%%
   71graphql(Content, Vars, Dict, List) :-
   72    % format(user_error, 'graphql(~p, ~p, ~p, ~p)~n', [Content, Vars, Dict, List]),
   73
   74    include(qq_var(Vars), Dict, QQDict),
   75
   76    % format(user_error, 'qq_var(~p), ~p, ~p))~n', [Vars, Dict, QQDict]),
   77
   78    phrase_from_quasi_quotation(tokenize(QQDict, List), Content).
   79
   80qq_var(Vars, _=Var) :- member(V, Vars), V == Var, !