(defparameter *sod-tmp-val*
(make-instance 'temporary-name :tag "sod__t"))
+(export '*null-pointer*)
+(defparameter *null-pointer* "NULL")
+
;;;--------------------------------------------------------------------------
;;; Instructions.
* Instance slots named after the ARGS, with matching keyword initargs,
and `inst-ARG' readers.
- * A constructor `make-CODE-inst' which accepts the ARGS (in order, not
- with keywords) as arguments and returns a fresh instance.
+ * A constructor `make-CODE-inst' which accepts the ARGS (as an ordinary
+ BVL) as arguments and returns a fresh instance.
* A print method, which prints a diagnostic dump if `*print-escape*' is
set, or invokes the BODY (with STREAMVAR bound to the output stream)
If EXPORT is non-nil, then export the `CODE-inst' and `make-CODE-inst'
symbols."
- (let ((inst-var (gensym "INST"))
- (class-name (symbolicate code '-inst))
- (constructor-name (symbolicate 'make- code '-inst))
- (keys (mapcar (lambda (arg) (intern (symbol-name arg) :keyword))
- args)))
+ (let* ((inst-var (gensym "INST"))
+ (class-name (symbolicate code '-inst))
+ (constructor-name (symbolicate 'make- code '-inst))
+ (slots (mapcan (lambda (arg)
+ (if (listp arg) (list (car arg))
+ (let ((name (symbol-name arg)))
+ (if (and (plusp (length name))
+ (char/= (char name 0) #\&))
+ (list arg)
+ nil))))
+ args))
+ (keys (mapcar (lambda (arg) (intern (symbol-name arg) :keyword))
+ slots)))
`(progn
(defclass ,class-name (inst)
- ,(mapcar (lambda (arg key)
- `(,arg :initarg ,key :reader ,(symbolicate 'inst- arg)))
- args keys))
+ ,(mapcar (lambda (slot key)
+ `(,slot :initarg ,key
+ :reader ,(symbolicate 'inst- slot)))
+ slots keys))
(defun ,constructor-name (,@args)
- (make-instance ',class-name ,@(mappend #'list keys args)))
+ (make-instance ',class-name ,@(mappend #'list keys slots)))
(defmethod inst-metric ((,inst-var ,class-name))
- (with-slots (,@args) ,inst-var
- (+ 1 ,@(mapcar (lambda (arg) `(inst-metric ,arg)) args))))
+ (with-slots (,@slots) ,inst-var
+ (+ 1 ,@(mapcar (lambda (slot) `(inst-metric ,slot)) slots))))
(defmethod print-object ((,inst-var ,class-name) ,streamvar)
- (with-slots (,@args) ,inst-var
+ (with-slots (,@slots) ,inst-var
(if *print-escape*
(print-unreadable-object (,inst-var ,streamvar :type t)
(format stream "~@<~@{~S ~@_~S~^ ~_~}~:>"
- ,@(mappend #'list keys args)))
+ ,@(mappend #'list keys slots)))
(block ,code ,@body))))
,@(and export `((export '(,class-name ,constructor-name
- ,@(mapcar (lambda (arg)
- (symbolicate 'inst- arg))
- args)))))
+ ,@(mapcar (lambda (slot)
+ (symbolicate 'inst- slot))
+ slots)))))
',code)))
;; Formatting utilities.
;; package or the `common-lisp' package. Use gensyms for these slot names to
;; prevent them from leaking.
-(definst var (stream :export t) (name #1=#:type init)
+(definst var (stream :export t) (name #1=#:type &optional init)
(pprint-c-type #1# stream name)
(when init
(format stream " = ~A" init))
(format stream "~@<~A ~A= ~@_~2I~A;~:>" var op #1#))
;; Special kinds of expressions.
-(definst call (stream :export t) (#1=#:func args)
+(definst call (stream :export t) (#1=#:func &rest args)
(format stream "~A(~@<~{~A~^, ~_~}~:>)" #1# args))
;; Simple statements.
(format stream "{~:@_~@< ~2I~@[~{~A~:@_~}~:@_~]~{~A~^~:@_~}~:>~:@_}"
decls body))
-(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 if (stream :export t) (#1=#:cond conseq &optional alt)
+ (let ((stmt "if"))
+ (loop (format-compound-statement (stream conseq (if alt t nil))
+ (format stream "~A (~A)" stmt #1#))
+ (typecase alt
+ (null (return))
+ (if-inst (setf stmt "else if"
+ #1# (inst-cond alt)
+ conseq (inst-conseq alt)
+ alt (inst-alt alt)))
+ (t (format-compound-statement (stream alt)
+ (format stream "else"))
+ (return))))))
(definst while (stream :export t) (#1=#:cond body)
(format-compound-statement (stream body)
(export 'deliver-call)
(defun deliver-call (codegen target func &rest args)
"Emit a statement to call FUNC with ARGS and deliver the result to TARGET."
- (deliver-expr codegen target (make-call-inst func args)))
+ (deliver-expr codegen target (apply #'make-call-inst func args)))
;;;----- That's all, folks --------------------------------------------------