classic-java.ss
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;  ClassicJava: an implementation of the ClassicJava programming language
;;  classic-java.ss: functions that run CJ programs and display the results in
;;      various styles
;;  Copyright (C) 2005  Richard Cobbe
;;
;;  This library is free software; you can redistribute it and/or modify it
;;  under the terms of the GNU Lesser General Public License as published by
;;  the Free Software Foundation; either version 2.1 of the License, or (at
;;  your option) any later version.
;;
;;  This library is distributed in the hope that it will be useful, but WITHOUT
;;  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;;  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
;;  License for more details.
;;
;;  You should have received a copy of the GNU Lesser General Public License
;;  along with this library; if not, write to the Free Software Foundation,
;;  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(module classic-java mzscheme

  (require (planet "gui.ss" ("robby" "redex.plt" 1 0))
           (lib "pretty.ss")
           "store.ss"
           "elaboration.ss"
           "parser.ss"
           "reduction.ss"
           "ast.ss"
           "utils.ss")

  (provide cj-trace cj-eval cj-step)

  ;; (List Program Store Term) -> Sexpr
  ;; Renders a config triple as a human-readable s-expression, without the
  ;; program.
  (define render-config
    (lambda (config)
      (let ([store (cadr config)]
            [term (caddr config)])
        (list (render-store store) term))))

  ;; Store -> Sexpr
  ;; Translates a store to a human-readable s-expression
  (define render-store
    (lambda (store)
      (map render-store-entry (store->alist store))))

  ;; (Pair Number Instance) -> Sexpr
  ;; Renders a single store entry to a human-readable s-expression
  (define render-store-entry
    (lambda (entry)
      (let ([addr (car entry)]
            [value (cdr entry)])
        (list addr (render-instance value)))))

  ;; Instance -> Sexpr
  ;; Renders a single instance to a human-readable s-expression
  (define render-instance
    (lambda (inst)
      (cons (class-type-name (instance-class inst))
            (map render-ivar (instance-fields inst)))))

  ;; IVar -> Sexpr
  ;; Renders a single instance variable to a human-readable s-expression
  (define render-ivar
    (lambda (ivar)
      (list (class-type-name (ivar-class ivar))
            (ivar-name ivar)
            (ivar-value ivar))))

  ;; (List Program Store Term) Output-Port N Any -> ()
  ;; Pretty-printer function for GUI (render store to readable; omit program)
  (define pretty-print-config
    (lambda (config port width text%)
      (let ([store (cadr config)]
            [term (caddr config)])
        (parameterize ([pretty-print-columns width])
          (pretty-print (list (render-store store) term) port)))))

  ;; Expects a program written in the input syntax of parser.ss
  ;; and displays its evaluation in the PLT Redex GUI.
  (define cj-trace
    (lambda (program)
      (let ([program (elab-program (parse-program program))])
        (traces cj-lang
                cj-reductions
                (list program empty-store
                      (texpr->rexpr (program-main program)))
                pretty-print-config))))

  ;; Expects a program written in the input syntax of parser.ss
  ;; and produces its result.
  (define cj-eval
    (lambda (program)
      (let* ([program (elab-program (parse-program program))]
             [last-config
              (big-step cj-reductions
                        (list program empty-store
                              (texpr->rexpr (program-main program))))])
        (render-config last-config))))

  ;; Expects a program written in the input syntax of parser.ss
  ;; and produces a list of all of the configurations in the evaluation
  ;; sequence.
  (define cj-step
    (lambda (program)
      (let ([program (elab-program (parse-program program))])
        (map render-config
             (small-step-sequence
              cj-reductions
              (list program
                    empty-store
                    (texpr->rexpr (program-main program)))))))))