なんだこれは

はてなダイアリーから移転しました。

それCommon Lisp でもできるよ

Common Lisp

C++ コンパイル時「出力」~C++にできないことはない~ らしいですよ。

C++ コンパイル時「出力」~C++にできないことはない~ らしいですよ。大変そうですね。

一方、Common Lisper は eval-when を使った。

eval-when:compile-toplevel などの指定したシチュエーションで任意のフォームを実行させることができます。

;;;; コンパイル時の実行
(eval-when (:compile-toplevel)
  (format t "at Compile time ~%"))

;;;;  ロード時の実行
(eval-when (:load-toplevel)
  (format t "at load ~%"))

;;;; 実行時の実行
(eval-when (:execute)
  (format t "at execute ~%"))

ここで任意のフォームというものには数の制限もないので、普通に 数をFizzBuzz文字列に変換する fizzbuzz 関数や、引数で指定した範囲の数のリストを返す iota 関数をいれて最後に format で表示してやればOKですね。

(eval-when (:compile-toplevel)
  (defun fizzbuzz (num)
    "convert number to FizzBuzz string or number"
    (cond
      ((= 0 (mod num 15)) "FizzBuzz")
      ((= 0 (mod num 3)) "Fizz")
      ((= 0 (mod num 5)) "Buzz")
      (t num)))
  (defun iota (n)
    "make a list where it contains 1 to n"
    (labels
    ((iter (x acc)
       (if (< x 1)
           acc
           (iter (1- x) (cons x acc)))))
      (iter n '())))
  ;; convert number list to fizzbuzz list and then output them
  (format t "~{~a~%~}" (mapcar #'FIZZBUZZ (iota 100))))

HyperSpec EVAL-WHEN