;;;----- 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
(prin1 (temp-tag var) stream))
(format-temporary-name var stream)))
-;;;--------------------------------------------------------------------------
-;;; Instruction types.
-
-;; 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)
- (write-string "else" stream))))
-
-(definst while (stream :export t) (condition body)
- (format-compound-statement (stream body)
- (format stream "while (~A)" condition)))
-
-(definst do-while (stream :export t) (body condition)
- (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))
-
-(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))
-
;;;--------------------------------------------------------------------------
;;; Code generator objects.
(defmethod emit-insts ((codegen basic-codegen) insts)
(asetf (codegen-insts codegen) (revappend insts it)))
+(defmethod emit-decl ((codegen basic-codegen) inst)
+ (push inst (codegen-vars codegen)))
+
+(defmethod emit-decls ((codegen basic-codegen) insts)
+ (asetf (codegen-vars codegen) (revappend insts it)))
+
(defmethod ensure-var ((codegen basic-codegen) name type &optional init)
(let* ((vars (codegen-vars codegen))
(var (find name
(setf (codegen-vars codegen)
(cons (make-var-inst name type init) vars)))
((not (c-type-equal-p type (inst-type var)))
- (error "(Internal) Redefining type for variable ~A." name)))
+ (error "(Internal) Redefining type for variable ~A" name)))
name))
(export 'codegen)
(defclass codegen (basic-codegen)
- ((functions :initform nil :type list :accessor codegen-functions)
+ ((functions :initform nil :type list :reader codegen-functions)
(stack :initform nil :type list :accessor codegen-stack))
(:documentation
"A full-fat code generator which can generate and track functions.
:in-use-p t
:tag (prog1 temp-index
(incf temp-index)))))
- (push (make-var-inst name type nil) vars)
+ (push (make-var-inst name type) vars)
name))))
;;;----- That's all, folks --------------------------------------------------