+;; 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#))
+