defex-user.lisp Unix DownloadWindows Download
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; File		     - defex-user.lisp
;; Description	     - 
;; Author	     - Tim Bradshaw (tfb at lostwithiel)
;; Created On	     - Wed Feb  2 13:18:19 2000
;; Last Modified On  - Mon Jul  9 08:04:40 2001
;; Last Modified By  - Gail Anderson (ga at lostwithiel)
;; Update Count	     - 73
;; Status	     - Unknown
;; 
;; $Id: defex-user.lisp,v 1.1 2003/01/09 02:11:34 colin Exp $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;; User part of DEFINE-EXERCISE, does not do much.

;;; this should be edited to reference whatever package the student's
;;; solution should be defined and run in

(in-package :exercise)


;;; used to store details about the current student submission 
(defparameter *current-submission* nil)	

;;; hash table containing details about all the student submissions
(defparameter *submissions* (make-hash-table :test #'equalp))


;;; the marker can edit the call to define-exercise in the student's
;;; submission to note whether the file loaded into
;;; Lisp OK, whether it compiled OK, and to add comments about the
;;; result of loading, compiling, or general comments.

(defmacro define-exercise (name &key 
				;; name of student/author
				author 
				;; login name of student author
				;; (used to name submission)
				login-name 
				;; list of all symbols for which student
				;; has submitted a definition
				defined-symbols
				;; list of symbols for which student has
				;; submitted a non-working, partial 
				;; definition (subset of DEFINED-SYMBOLS)
				nonworking-symbols
				;; list of symbols for which student has
				;; tried to define, but which are submitted
				;; as comments because they don't compile
				commented-symbols
				;; any comments which the student wishes to
				;; make about the submission
				commentary
				;; for marker's use: whether an error
				;; occurred on loading the file
				load-error
				;; for marker's use: comments about cause
				;; of load errors, etc
				load-comment
				;; for marker's use: whether an error occurred
				;; on compiling the file
				compile-error
				;; for marker's use: comments about cause of
				;; compile errors, etc
				compile-comment
				;; for marker's use: any other
				;; comments about the submission
				other-comments)
  "Define an exercise"
  ;;; calls a function do-define-exercise to do the work
  `(do-define-exercise ',name		; name of the exercise (e.g. :ex1)
     :author ',author
     :login-name ',login-name
     :defined-symbols ',defined-symbols
     :nonworking-symbols ',nonworking-symbols
     :commented-symbols ',commented-symbols
     :commentary ',commentary
     :load-error ',load-error
     :load-comment ',load-comment
     :compile-error ',compile-error
     :compile-comment ',compile-comment
     :other-comments ',other-comments))
     



;;; Structure to store information about the submission
;;; Information supplied by do-define-exercise; entered either by the 
;;; student, or by the marker.


(defstruct exercise
  author 
  login-name
  defined-symbols
  nonworking-symbols
  commented-symbols
  (commentary "")
  (load-error nil)
  (load-comment "")
  (compile-error nil)
  (compile-comment "")
  (other-comments "")
  (tests nil))



;;; The guts of define-exercise
(defun do-define-exercise (name &rest args
			   &key 
			   author 
			   login-name 
			   defined-symbols
			   nonworking-symbols 
			   commented-symbols
			   commentary
			   load-error
			   load-comment
			   compile-error
			   compile-comment
			   other-comments)
  ;; syntax checks
  (assert (typep name 'symbol)
      (name)
    "exercise name, ~S must be a symbol" name)
  (assert (first *exercise*)
      (name)
    "exercise name ~S is not a legal name, should be a member of ~S"
    name *exercise*)
  (assert (typep author 'string)
      (author)
    "author ~S is not a string" author)
  (assert (typep login-name 'string)
      (login-name)
    "login name ~S is not a string" login-name)
  (assert (typep defined-symbols 'list)
      (defined-symbols)
    "The `list of defined symbols' ~S is not a list!" defined-symbols)
  (assert (every #'symbolp defined-symbols)
      (defined-symbols)
    "Not every element of the `list of defined symbols' ~S is a symbol!"
    defined-symbols)
  (assert (typep nonworking-symbols 'list)
      (nonworking-symbols)
    "The `list of nonworking symbols' ~S is not a list!" nonworking-symbols)
  (assert (every #'symbolp nonworking-symbols)
      (nonworking-symbols)
    "Not every element of the `list of nonworking symbols' ~S is a symbol!"
    nonworking-symbols)
  (assert (typep commented-symbols 'list)
      (commented-symbols)
    "The `list of commented symbols' ~S is not a list!" commented-symbols)
  (assert (every #'symbolp commented-symbols)
      (commented-symbols)
    "Not every element of the `list of commented symbols' ~S is a symbol!"
    commented-symbols)
  (assert (typep commentary 'string)
      (commentary)
    "The commentary ~S should be a string, if provided" commentary)
  (assert (typep load-error 'boolean)
      (load-error)
    "The value of load-error should be T or NIL.")
  (assert (typep load-comment 'string)
      (load-comment)
    "login name ~S is not a string" load-comment)
  (assert (typep compile-error 'boolean)
      (compile-error)
    "The value of compile-error should be T or NIL.")
  (assert (typep compile-comment 'string)
      (compile-comment)
    "login name ~S is not a string" compile-comment)
  (assert (typep other-comments 'string)
      (other-comments)
     "login name ~S is not a string" other-comments)
 
  ;; create a new submission for this student's exercise, and add it to
  ;; the list of all submissions
  (setf (gethash login-name *submissions*)
    (make-exercise
     :author author
     :login-name login-name
     :defined-symbols defined-symbols
     :nonworking-symbols nonworking-symbols
     :commented-symbols commented-symbols))
  ;; remember this as the current submission
  (setf *current-submission* 
    (gethash login-name *submissions*))
  ;; store the marking information in the submission
  (setf (exercise-load-error *current-submission*)
    load-error)
  (setf (exercise-load-comment *current-submission*)
    load-comment)
  (setf (exercise-compile-error *current-submission*)
    compile-error)
  (setf (exercise-compile-comment *current-submission*)
    compile-comment)
  (setf (exercise-other-comments *current-submission*)
    other-comments))

;;; undefine all student symbols; should be provided to the students if
;;; appropriate

(defun clean-student-symbols ()
  "Make all the names you are meant to define have no definitions.
You can run this function after loading the compiled one, but before 
loading your version to make sure you have not missed anything.
Returns a list of the symbols it has undefined."
  (dolist (s (second *exercise*) (second *exercise*))
    (makunbound s)
    (fmakunbound s)))