src/: Abolish the special `va-*' instructions.
[sod] / src / codegen-impl.lisp
index acb0da1..bc6f11d 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
   ((in-use-p :initarg :in-use-p :initform nil
             :type boolean :accessor var-in-use-p)))
 
+(define-module-var *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))
+
 (defmethod commentify-argument-name ((name temporary-name))
   nil)
 
-(export 'temporary-function)
 (defun temporary-function ()
   "Return a temporary function name."
   (make-instance 'temporary-function
 
 ;; Compound statements.
 
-(definst if (stream :export t) (condition consequent alternative)
-  (format-compound-statement (stream consequent alternative)
-    (format stream "if (~A)" condition))
-  (when alternative
-    (format-compound-statement (stream alternative)
+;; HACK: use gensyms for the `condition' slots to avoid leaking the slot
+;; names, since the symbol `condition' actually comes from the `common-lisp'
+;; package.  The `definst' machinery will symbolicate the various associated
+;; methods correctly despite this subterfuge.
+
+(definst if (stream :export t) (#1=#:cond conseq alt)
+  (format-compound-statement (stream conseq alt)
+    (format stream "if (~A)" #1#))
+  (when alt
+    (format-compound-statement (stream alt)
       (write-string "else" stream))))
 
-(definst while (stream :export t) (condition body)
+(definst while (stream :export t) (#1=#:cond body)
   (format-compound-statement (stream body)
-    (format stream "while (~A)" condition)))
+    (format stream "while (~A)" #1#)))
 
-(definst do-while (stream :export t) (body condition)
+(definst do-while (stream :export t) (body #1=#:cond)
   (format-compound-statement (stream body :space)
     (write-string "do" stream))
-  (format stream "while (~A);" condition))
-
-;; Special varargs hacks.
-
-(definst va-start (stream :export t) (ap arg)
-  (format stream "va_start(~@<~A, ~_~A~:>);" ap arg))
-
-(definst va-copy (stream :export t) (to from)
-  (format stream "va_copy(~@<~A, ~_~A~:>);" to from))
+  (format stream "while (~A);" #1#))
 
-(definst va-end (stream :export t) (ap)
-  (format stream "va_end(~A);" ap))
 
 ;; Expressions.
 
-(definst call (stream :export t) (func args)
-  (format stream "~A(~@<~{~A~^, ~_~}~:>)" func args))
+;; HACK: use a gensym for the `func' slot to avoid leaking the slot name,
+;; since the symbol `func' is exported from our package.
+(definst call (stream :export t) (#1=#:func args)
+  (format stream "~A(~@<~{~A~^, ~_~}~:>)" #1# args))
 
 ;;;--------------------------------------------------------------------------
 ;;; Code generator objects.