chiark / gitweb /
src/classes.lisp: Fix `print-object' on `sod-initializer'.
[sod] / src / codegen-proto.lisp
index 571f0b0cdf7fd5b0a8f07997f87163103606bb2b..e7486fac9ba4c01cbfa9678ad5f6b217d35f0ffc 100644 (file)
@@ -7,7 +7,7 @@
 
 ;;;----- Licensing notice ---------------------------------------------------
 ;;;
-;;; This file is part of the Sensble Object Design, an object system for C.
+;;; This file is part of the Sensible Object Design, an object system for C.
 ;;;
 ;;; SOD is free software; you can redistribute it and/or modify
 ;;; it under the terms of the GNU General Public License as published by
@@ -55,18 +55,6 @@ (defclass temporary-name ()
   (:documentation
    "Base class for temporary variable and argument names."))
 
-;; Important variables.
-
-(defparameter *temporary-index* 0
-  "Index for temporary name generation.
-
-   This is automatically reset to zero before the output functions are
-   invoked to write a file.  This way, we can ensure that the same output
-   file is always produced from the same input.")
-
-(define-clear-the-decks reset-codegen-index
-  (setf *temporary-index* 0))
-
 ;; Important temporary names.
 
 (export '(*sod-ap* *sod-master-ap*))
@@ -76,6 +64,8 @@ (defparameter *sod-master-ap*
   (make-instance 'temporary-name :tag "sod__master_ap"))
 (defparameter *sod-tmp-ap*
   (make-instance 'temporary-name :tag "sod__tmp_ap"))
+(defparameter *sod-tmp-val*
+  (make-instance 'temporary-name :tag "sod__t"))
 
 ;;;--------------------------------------------------------------------------
 ;;; Instructions.
@@ -166,36 +156,43 @@        (defmethod print-object ((,inst-var ,class-name) ,streamvar)
               (print-unreadable-object (,inst-var ,streamvar :type t)
                 (format stream "~@<~@{~S ~@_~S~^ ~_~}~:>"
                         ,@(mappend #'list keys args)))
-              (progn ,@body))))
-       ,@(and export `((export '(,class-name ,constructor-name))))
+              (block ,code ,@body))))
+       ,@(and export `((export '(,class-name ,constructor-name
+                                ,@(mapcar (lambda (arg)
+                                            (symbolicate 'inst- arg))
+                                          args)))))
        ',code)))
 
 ;; Important instruction classes.
 
-(definst var (stream :export t) (name type init)
-  (pprint-c-type type stream name)
+;; HACK: use a gensym for the `expr' and `type' slots to avoid leaking the
+;; slot names, since the symbol `expr' is exported from our package and
+;; `type' belongs to the `common-lisp' package.
+
+(definst var (stream :export t) (name #1=#:type init)
+  (pprint-c-type #1# stream name)
   (when init
     (format stream " = ~A" init))
   (write-char #\; stream))
-(definst set (stream :export t) (var expr)
-  (format stream "~@<~A = ~@_~2I~A;~:>" var expr))
-(definst update (stream :export t) (var op expr)
-  (format stream "~@<~A ~A= ~@_~2I~A;~:>" var op expr))
-(definst return (stream :export t) (expr)
-  (format stream "return~@[ (~A)~];" expr))
+(definst set (stream :export t) (var #1=#:expr)
+  (format stream "~@<~A = ~@_~2I~A;~:>" var #1#))
+(definst update (stream :export t) (var op #1=#:expr)
+  (format stream "~@<~A ~A= ~@_~2I~A;~:>" var op #1#))
+(definst return (stream :export t) (#1=#:expr)
+  (format stream "return~@[ (~A)~];" #1#))
 (definst break (stream :export t) ()
   (format stream "break;"))
 (definst continue (stream :export t) ()
   (format stream "continue;"))
-(definst expr (stream :export t) (expr)
-  (format stream "~A;" expr))
+(definst expr (stream :export t) (#1=#:expr)
+  (format stream "~A;" #1#))
 (definst block (stream :export t) (decls body)
   (format stream "{~:@_~@<  ~2I~@[~{~A~:@_~}~:@_~]~{~A~^~:@_~}~:>~:@_}"
          decls body))
-(definst function (stream :export t) (name type body)
+(definst function (stream :export t) (name #1=#:type body)
   (pprint-logical-block (stream nil)
     (princ "static " stream)
-    (pprint-c-type type stream name)
+    (pprint-c-type #1# stream name)
     (format stream "~:@_~A~:@_~:@_" body)))
 
 ;; Formatting utilities.
@@ -339,10 +336,13 @@ (defmacro with-temporary-var ((codegen var type) &body body)
 
    During BODY, VAR will be marked in-use; when BODY ends, VAR will be marked
    available for re-use."
-  `(let ((,var (temporary-var ,codegen ,type)))
-     (unwind-protect
-         (progn ,@body)
-       (setf (var-in-use-p ,var) nil))))
+  (multiple-value-bind (doc decls body) (parse-body body :docp nil)
+    (declare (ignore doc))
+    `(let ((,var (temporary-var ,codegen ,type)))
+       ,@decls
+       (unwind-protect
+           (progn ,@body)
+        (setf (var-in-use-p ,var) nil)))))
 
 ;;;--------------------------------------------------------------------------
 ;;; Code generation idioms.