src/codegen-{proto,impl}.lisp: Gather `definst' forms together.
[sod] / src / codegen-proto.lisp
index 5364f72..264fd03 100644 (file)
                                           args)))))
        ',code)))
 
-;; Important instruction classes.
-
-;; 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 #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) (#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 #1=#:type body)
-  (pprint-logical-block (stream nil)
-    (princ "static " stream)
-    (pprint-c-type #1# stream name)
-    (format stream "~:@_~A~:@_~:@_" body)))
-
 ;; Formatting utilities.
 
 (defun format-compound-statement* (stream child morep thunk)
   `(format-compound-statement* ,stream ,child ,morep
                               (lambda (,stream) ,@body)))
 
+;; Important instruction classes.
+
+;; HACK: Some of the slot names we'd like to use are external symbols in our
+;; 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)
+  (pprint-c-type #1# stream name)
+  (when init
+    (format stream " = ~A" init))
+  (write-char #\; stream))
+
+(definst function (stream :export t) (name #1=#:type body)
+  (pprint-logical-block (stream nil)
+    (princ "static " stream)
+    (pprint-c-type #1# stream name)
+    (format stream "~:@_~A~:@_~:@_" body)))
+
+;; Expression statements.
+(definst expr (stream :export t) (#1=#:expr)
+  (format stream "~A;" #1#))
+(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#))
+
+;; Special kinds of expressions.
+(definst call (stream :export t) (#1=#:func args)
+  (format stream "~A(~@<~{~A~^, ~_~}~:>)" #1# args))
+
+;; Simple statements.
+(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;"))
+
+;; Compound statements.
+
+(definst block (stream :export t) (decls body)
+  (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 while (stream :export t) (#1=#:cond body)
+  (format-compound-statement (stream body)
+    (format stream "while (~A)" #1#)))
+
+(definst do-while (stream :export t) (body #1=#:cond)
+  (format-compound-statement (stream body :space)
+    (write-string "do" stream))
+  (format stream "while (~A);" #1#))
+
 ;;;--------------------------------------------------------------------------
 ;;; Code generation.