X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/sod/blobdiff_plain/9468000c436d725e6569d0bfe36dccd308b04de2..418752c55a29e2380d6d1aef767b7cfba02cf4be:/src/codegen-proto.lisp diff --git a/src/codegen-proto.lisp b/src/codegen-proto.lisp index b8206fa..29ff35b 100644 --- a/src/codegen-proto.lisp +++ b/src/codegen-proto.lisp @@ -120,7 +120,7 @@ (defgeneric inst-metric (inst) ;; Instruction definition. (export 'definst) -(defmacro definst (code (streamvar) args &body body) +(defmacro definst (code (streamvar &key export) args &body body) "Define an instruction type and describe how to output it. An `inst' can represent any structured piece of output syntax: a @@ -138,10 +138,14 @@ (defmacro definst (code (streamvar) args &body body) * A print method, which prints a diagnostic dump if `*print-escape*' is set, or invokes the BODY (with STREAMVAR bound to the output stream) otherwise. The BODY is expected to produce target code at this - point." + point. + + 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))) `(progn @@ -149,7 +153,7 @@ (defclass ,class-name (inst) ,(mapcar (lambda (arg key) `(,arg :initarg ,key :reader ,(symbolicate 'inst- arg))) args keys)) - (defun ,(symbolicate 'make- code '-inst) (,@args) + (defun ,constructor-name (,@args) (make-instance ',class-name ,@(mappend #'list keys args))) (defmethod inst-metric ((,inst-var ,class-name)) (with-slots (,@args) ,inst-var @@ -160,30 +164,26 @@ (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))))))) + (progn ,@body)))) + ,@(and export `((export '(,class-name ,constructor-name)))) + ',code))) ;; Important instruction classes. -(export '(block-inst make-block-inst var-inst make-var-inst - function-inst make-function-inst set-inst make-set-inst - return-inst make-return-inst expr-inst make-expr-inst - inst-decls inst-body inst-name inst-type inst-init inst-var - inst-expr)) - -(definst var (stream) (name type init) +(definst var (stream :export t) (name type init) (pprint-c-type type stream name) (when init (format stream " = ~A" init))) -(definst set (stream) (var expr) +(definst set (stream :export t) (var expr) (format stream "~@<~A = ~@_~2I~A;~:>" var expr)) -(definst return (stream) (expr) +(definst return (stream :export t) (expr) (format stream "return~@[ (~A)~];" expr)) -(definst expr (stream) (expr) +(definst expr (stream :export t) (expr) (format stream "~A;" expr)) -(definst block (stream) (decls body) +(definst block (stream :export t) (decls body) (format stream "{~:@_~@< ~2I~@[~{~A;~:@_~}~:@_~]~{~A~^~:@_~}~:>~:@_}" decls body)) -(definst function (stream) (name type body) +(definst function (stream :export t) (name type body) (pprint-logical-block (stream nil) (princ "static " stream) (pprint-c-type type stream name)