HCl インタプリタ

HCl はインタプリタを無視しないCommon Lisp処理系 です。高速なインタプリタとデバッガにより効率的なデバッグが可能 となっています。

インタプリタのセマンテイクス

HCl ではCLの仕様に基づき、コンパイラと完全に同じセマンテイクスのインタ プリタを提供しています。また、インタプリタ高速化のためloop,doなどの制御マクロ や一部のsetfマクロなどは内部的にspecial formとして 処理することもあります。

トップレベルループ

HCl とユーザとの対話はトップレベルループによって 行われます。トップレベルの関数名はsystem:top-level[引数無し]ですからこれを再定義すれば トップレベルループのスタイルを好みのものに変えることができます。 デフォルトのtop-levelの定義はlsp/hcl.init にあります。HCl のトップレベルループではCLの標準機能の他に簡単な ヒストリ機能が組み込まれています。 トップレベルがスタートすると次のメッセージを印刷し入力待ちになります。
% hcl
HCL Version 1.6, Release 2.0(Last change: July 20, 1991)
                 [April 29, 1991,The Green-Day version] 
                 (C) Tsuyoshi    Yamamoto,
                     Hokkaido  University.


Starting Lisp Listener [USER]
[1]->(do-symbols (x) (print x))
	
[1]はこの入力が1回目の対話であることを示し、後でこのformを 再実行したい場合は(redo 1)でできます。この数字は対話の度に増加します。 redoにはこの他にいくつかの機能が組み込まれています。
(redo n)
正のnに対しては[n]の入力formを実行する。\\ 負のnに対してはn回前の入力formを実行する。
(redo)
直前の入力を再実行する。
(redo t)
過去の入力を番号と共にリストする。
(redo function-name)
(function-name ...)で始まる過去の入力を捜して実行する。
[3]->(print *gc*)
  .......
[12]->(redo print)
   ;;過去に行ったprintのうちもっとも最近
   ;;行ったものを捜して再実行する。
	
(redo x key substitute)
xは整数、あるは関数名であり入力パターンの探索に使われる。もし パターンが見つかったならばその中のkeyをすべてsubstituteで置き換えてそ れを実行する。
[3]-> (defun foo (x)(+ x 100))
foo
[4]-> (redo 3 + *)
   ;; (defun foo (x)(* x 100))と等価
	
(reset)
過去の対話履歴をリセットする。

デバッグ支援

インタプリテイブモードで実行中のプログラムについては、エラー発生時ある いはコンソールからのブレーク(int 2)により自動的に デバッガが起動され、エラーの解析を支援します。 デバッガはエラー発生時点の動的環境、関数呼び出し履歴などを表示できます。 またコンソールブレークあるいはcontinuable error によるデバッガの起動の場合にはその後実行を継続できます。ブレークを連続し て3回行うことは無限ループに陥った時以外は危険で、3回目のブレーク は emergency breakとみなされ続行不能なモードで デバッガに入ることになります。

コンパイルされた関数がエラーを検出した場合にもデバッガが起動されますが その場合にはコンパイルされた環境はもはや見ることはできません。関数呼び出 し履歴も陽にeval,apply,funcallによって呼び出された場合以外は見えなくなります。 デバッガのコマンドについてはデバッガ起動後 :hを入力すればその時点で 使用できるコマンドがリストされます。

HCl ではエラー発生時にデフオルトで組み込みデバッガが起動されプログラムの 実行が中断されます。PSL等では error-set 等によってエラー後のプログラムの自動実行を可能とするメカニズムが組み 込まれていますがCommon Lispの規格にはこの機能が定められていません。 HCl ではデバッガのデフオルトコマンドの機能を用いてerror-setを シミュレートします。このためにシステム変数、 system::*debug-defaultsが用意されています。この値は通常はnilですが ここにデバッガコマンドのリストをセットすることができます。その場合、 デバッガはデバッグコマンドをコンソールからではなく system::*debug-defaultsから順次取り出し実行します。このコマンドとして (throw exit {form}*)をセットすればデバッガはそのコントロール を直接指定されたcatcherに渡しますのでエラー発生後でもコンソールとの 対話を経ずプログラムの実行を継続できます。

[1]->(setq system::*debug-defaults
           '(:q) )
     ;;エラーが発生した場合にデバッガに
     ;;留まらずにすぐトップレベルに戻る。
[2]->(setq system::*debug-defaults
           '(:t (throw 'error-set nil)))
     ;;エラーが発生したら関数呼び出し履歴を印刷し、
     ;;error-setキャッチヤ へ制御を渡す。
	

ステッパー

コンパイルされていない関数のシングルステップ動作はマクロ関数 stepによって行われます。
[1]->(step (foo 1 2 3))
	
は(foo 1 2 3)の実行をeval,apply,funcallの度にデバッガモードに入り 動作状態を監視できます。ステップモードでのコマンドはデバッガのそれと 基本的に同じですが、ステッパ特有の機能もあるので詳細は:hコマンドに よるhelpメニューを参照してください。

システム変数system::*step-defaults はステッパが起動された時、自動的に実行されるデバッグコマンドのリスト を保持します。デフオルトはnilです。このリストのコマンドが全部実行された あと、コンソールとの対話モードに入ります。


プロファイラー

コンパイルされていない関数の実行の解析(呼び出し頻度分析)をサポート するために静的な プロファイラが組み込まれています。 ある関数の実行中に使用された関数名および呼び出し回数は次のようにして 計測されます。
[1]->(defun fac (x)(if (= 0 x) 1 (* x (fact (1- x))))
fact
[2]->(system::*profile (fact 3))
fact        4        ;;factは4回呼び出された
*           3
1-          3
=           3
if          4
nil
[3]->
	

ブレークポイント機能

込み入った状況でのデバッグをサポートするため任意の関数に ブレークポイントを設定できます。
Macro (system::set-break-point {symbols}*)
[1]->(system::set-break-point caaar)
Setting breakpoint at function caaar
nil    ;; caaarにブレークポイントをセット
[2]->(let ((x '(((2)))) (caaar x))
Continuable error: Break point at function caaar
Error signaled by function cerror
If continued: Continue
[1]DEBUG>>:v   ;;デバッグモードコマンド
((system::args ((((2)))) (x (((2)))))
              ;;argsはcaaarに渡された引数のリスト
[1]DEBUG>>:c
Continue execution.   ;;実行の継続
2
[2]->
	
ブレークポイントは何個設定しても構いません。解除は
Macro(system::reset-break-point {symbols}* )
によります。引数なしで reset-break-pointを実行するとその時点の全ての ブレークポイントを解除します。
もくじ