;;;; 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 pl0
; according to N. Wirth, "Compilerbau", ISBN 3-519-32338-9

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

    (source (
        () ; take no parameter, return the source position:
        ([(source)])))

    (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")
              (source))
            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)
              (source)
              (list "type" (list "signed" (list (list "size" "32"))))))
          (list "know"
            (list
              (list "name" "?")
              (list "ref" read-ref)
              (source)
              (list "import" "_readint")
              (list "type" (list "function"
                (list
                  (list "type" (list "void" (list)))
                  (list "argcount" "1"))
                (list "byref" (list)
                  (list "use"
                    (list (list "name" ".int"))))))))
          (list "know"
            (list
              (list "name" "!")
              (list "ref" write-ref)
              (source)
              (list "import" "_writeint")
              (list "type" (list "function"
                (list
                  (list "type" (list "void" (list)))
                  (list "argcount" "1"))
                (list "byvalue" (list)
                  (list "use"
                    (list (list "name" ".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))
  )
)
