(.require
 [library
  [lux (.except)
   ["$" documentation]
   [data
    [text (.only \n)
     ["%" \\format (.only format)]]
    [collection
     ["[0]" list]]]
   [meta
    [macro
     ["[0]" template]]]]]
 ["[0]" \\parser]
 [\\library
  ["[0]" /]])

(`` (def \\parser
      (List $.Documentation)
      (list ($.module \\parser._
                      "")

            ($.definition (\\parser.Parser it)
              "A Lux code parser.")

            ($.definition \\parser.any
              "Yields the next input without applying any logic.")

            (,, (with_template [<query> <check>]
                  [(`` ($.definition <query>
                         (format "Parses the next " (,, (template.text [<query>])) " input.")))
                   (`` ($.definition <check>
                         (format "Checks for a specific " (,, (template.text [<query>])) " input.")))]

                  [\\parser.bit    \\parser.this_bit]
                  [\\parser.nat    \\parser.this_nat]
                  [\\parser.int    \\parser.this_int]
                  [\\parser.rev    \\parser.this_rev]
                  [\\parser.frac   \\parser.this_frac]
                  [\\parser.text   \\parser.this_text]
                  [\\parser.symbol \\parser.this_symbol]
                  ))

            ($.definition \\parser.this
              "Ensures the given Code is the next input."
              [(this code)])

            (,, (with_template [<query> <check> <desc>]
                  [($.definition <query>
                     (format "Parse a local " <desc> " (a " <desc> " that has no module prefix)."))
                   ($.definition <check>
                     (format "Checks for a specific local " <desc> " (a " <desc> " that has no module prefix)."))]

                  [\\parser.local \\parser.this_local "local symbol"]
                  ))

            (,, (with_template [<name>]
                  [(`` ($.definition <name>
                         (format "Parses the contents of a " (,, (template.text [<name>])) ".")))]

                  [\\parser.form]
                  [\\parser.variant]
                  [\\parser.tuple]
                  ))

            ($.definition \\parser.end
              "Verifies there are no more inputs.")

            ($.definition \\parser.end?
              "Checks whether there are no more inputs.")

            ($.definition \\parser.result
              "Executes a parser against a stream of code, and verifies all the inputs are consumed."
              [(result parser inputs)])

            ($.definition \\parser.locally
              "Runs parser against the given list of inputs."
              [(locally inputs parser)])

            ($.definition \\parser.not
              "Yields the next Code token if the parser fails."
              [(not expected_to_fail)])

            ($.definition \\parser.next
              "Yields the next Code token without consuming it from the input stream.")
            )))

(def .public documentation
  (List $.Documentation)
  (list.partial ($.module /._
                          "")

                ($.definition /.bit)
                ($.definition /.nat)
                ($.definition /.int)
                ($.definition /.rev)
                ($.definition /.frac)
                ($.definition /.text)
                ($.definition /.symbol)
                ($.definition /.form)
                ($.definition /.variant)
                ($.definition /.tuple)
                
                ($.definition /.equivalence)
                ($.definition /.format)

                ($.definition /.local
                  "Produces a local symbol (an symbol with no module prefix).")

                ($.definition /.replaced
                  ""
                  [(replaced original substitute ast)])

                ..\\parser
                ))
