;; This is an implementation of the virtual library:
;; the file Driver.ml is present,
;; the file Driver.mli is absent.
(library
  (name driver_stage2)
  (implements driver)
  (libraries menhirSdk menhirLib base front)
  (flags :standard -open MenhirSdk -open MenhirLib -open Base -open Front)
)

;; The lexer is the same in all stages.
;; It must be placed in this directory because it depends on Parser.

(copy_files# ../stage1/Lexer.mll)
(ocamllex  Lexer)

;; In stage 2, Menhir's parser is generated by the stage1 Menhir executable.

;; -----------------------------------------------------------------------------

;; The flags that are passed to every invocation of Menhir in the rules below
;; are set in the file "menhir_flags". Any flags that affect the construction
;; of the automaton, such as --canonical, *must* be listed there.

;; We need these flags in "s-expression" format in order to use them in the
;; "menhir" stanza below. The following rule generates a file in this format
;; by wrapping the list of arguments in parentheses.

(rule
  (with-stdout-to menhir_flags.sexp
    (progn
      (echo "(")
      (cat %{dep:menhir_flags})
      (echo ")")
    )
  )
)

;; -----------------------------------------------------------------------------

;; Bind the name "menhir" to the stage 1 executable within the present scope.
;; This is so that the "menhir" stanza below will use *that* executable
;; instead of whatever "menhir" executable (if any) is available on the
;; developer's machine.

(env
  (_ (binaries
       ../../executable/stage1/main.exe
      (../../executable/stage1/main.exe as menhir)
  ))
)

;; Menhir's parser is generated by Menhir.

;; We include the flags found in the file "menhir_flags" plus extra flags
;; specified here.

(menhir
  (flags
    (:include menhir_flags.sexp)
    -lg 1 -la 1 -lc 1
    -v
  )
  (modules Parser)
)

;; -----------------------------------------------------------------------------

;; This section deals with the .messages file.

;; The module [ParserMessages] is generated by Menhir based on the source file
;; "ParserMessages.messages". The completeness check is performed first.

(rule
  (deps ParserMessages.check)
  (action (with-stdout-to ParserMessages.ml
    (run menhir
      %{read-lines:menhir_flags}
      %{dep:Parser.mly}
      --compile-errors %{dep:ParserMessages.messages}
    )
  ))
)

;; In order to perform the completeness check, we must first generate a file
;; "ParserMessages.auto.messages" that contains a list of all error states.

(rule
  (with-stdout-to ParserMessages.auto.messages
    (run menhir
       %{read-lines:menhir_flags}
       %{dep:Parser.mly}
       --list-errors
    )
  )
)

;; The completeness check verifies that all error messages are listed in the
;; ".messages" file. It compares the ".messages" file with that generated by
;; Menhir using the above rule.

(rule
  (with-stdout-to ParserMessages.check
  (run menhir
    %{read-lines:menhir_flags}
    %{dep:Parser.mly}
    --compare-errors %{dep:ParserMessages.auto.messages}
    --compare-errors %{dep:ParserMessages.messages}
  ))
)

;; -----------------------------------------------------------------------------

;; The following rule is used under the programmer's manual control,
;; after the grammar in [Parser.mly] has been modified.

;; This rule updates the file [ParserMessages.messages] with new
;; auto-generated comments for all error states.

;; It is invoked by running [make update].

(rule
  (with-stdout-to ParserMessages.messages.updated
    (run menhir
      %{read-lines:menhir_flags}
      --update-errors %{dep:ParserMessages.messages}
                      %{dep:Parser.mly}
    )
  )
)
