;;;; mother modular generic compiler project
; (c)2001,2002/GPL Oskar Schirmer <oskar@scara.com>
; see file COPYING for GPL license details

; evaluator predicates description for pascal
; according to K. Jensen, N. Wirth, "Pascal User Manual and Report",
;   ISBN 0-387-90144-2, ISBN 3-540-90144-2

(predicates
  '(
    (term-value (
        (( ; take the terminal and split it up:
          term value rest))
        (( ; return solely the value string:
          value))))

    (unique (
        () ; take no parameter, return an unique value:
        (((unique)))))

    (compare-value (
        (( ; take the terminal and match for the right value:
          term "=" rest))
        (( ; return the desired string:
          "equal"))))
    (compare-value (
        ((term "#" rest))
        (("notequal"))))
    (compare-value (
        ((term ">" rest))
        (("greater"))))
    (compare-value (
        ((term "<" rest))
        (("less"))))
    (compare-value (
        ((term ">=" rest))
        (("greaterorequal"))))
    (compare-value (
        ((term "<=" rest))
        (("lessorequal"))))

    (optional-sign (
        (( ; take the terminal and match for the right sign:
          term "+" rest)
         (code)) ; ...and take the code
        ((code)))) ; do not negate when "+"
    (optional-sign (
        ((term "-" rest)
         (code))
        (( ; negate when "-":
          (list "op"
            (list
              (list "name" "subtract"))
            code)))))

    (sign-value (
        (( ; take the terminal and match for the right sign:
          term "+" rest))
        (( ; return the desired string:
          "add"))))
    (sign-value (
        ((term "-" rest))
        (("subtract"))))

    (multiply-value (
        (( ; take the terminal and match for the right operator:
          term "*" rest))
        (( ; return the desired string:
          "multiply"))))
    (multiply-value (
        ((term "/" rest))
        (("divide"))))

    (global-frame (
        () ; take no parameter,...
        (( ; return prolog:
          (list "knowtype"
            (list
              (list "name" "int")
              (list "ref" int-ref)
              (list "type" (list "signed" (list (list "size" "32"))))))
          (list "know"
            (list
              (list "name" "?")
              (list "ref" read-ref)
              (list "import" "_readint")
              (list "type" (list "function"
                (list
                  (list "resulttype" (list "void" (list)))
                  (list "argcount" "1"))
                (list "byref" (list) "int")))))
          (list "know"
            (list
              (list "name" "!")
              (list "ref" write-ref)
              (list "import" "_writeint")
              (list "type" (list "function"
                (list
                  (list "resulttype" (list "void" (list)))
                  (list "argcount" "1"))
                (list "byvalue" (list) "int"))))))
         ( ; ...and epilog:
          (list "forget" (list (list "ref" write-ref)))
          (list "forget" (list (list "ref" read-ref)))
          (list "forgettype" (list (list "ref" int-ref)))
         )))
      ((()((int-ref))) unique)
      ((()((read-ref))) unique)
      ((()((write-ref))) unique))
  )
)
