2012-03-09 7 views
5

私は 'foo'という別のプログラミング言語を実装するためにpythonを使用しています。 fooのコードはすべてPythonに翻訳され、同じPythonインタプリタでも実行されるため、JITはPythonに変換します。ここでPythonで実装された言語にトレースバック/デバッグ機能を追加するには?

は、fooのコードの小片である:

に変換します
function bar(arg1, arg2) { 
    while (arg1 > arg2) { 
     arg2 += 5; 
    } 
    return arg2 - arg1; 
} 

def _bar(arg1, arg2): 
    while arg1 > arg2: 
     arg2 += 5 
     watchdog.switch() 
    watchdog.switch() 
    return arg2 - arg1 

「ウォッチドッグが」(生成されたコードもgreenletコンテキストで実行されているgreenletです)これは、言語が信頼できないコードを実行するため、リソース使用量を監視/制限します。

例からわかるように、Pythonコードが生成される前に、ウォッチドッグスイッチを追加して関数識別子を少し変更するために、構文木に小さな変更が加えられます。

言語にトレースバック/デバッグ機能を追加する必要があります。そのため、Pythonランタイムが例外をスローすると、ユーザーに表示されるのはfooのコードトレースバックです(生成されたPythonコードトレースバック)。

1 function bar() { 
2  throw Exception('Some exception message'); 
3 } 
4 
5 function foo() { 
6  output('invoking function bar'); 
7  bar(); 
8 } 
9 
10 foo(); 

に変換します:次に

def _bar(): 
    watchdog.switch() 
    raise Exception('Some exception message') 

def _foo(): 
    print 'invoking function bar' 
    watchdog.switch() 
    _bar() 

watchdog.switch() 
_foo() 

、program.foo」の出力

は、ユーザーが次の内容の 'program.foo' という名前のファイルを作成することを考えてみましょう'は次のようになります:

invoking function bar 
Traceback (most recent call last): 
    File "program.foo", line 10 
    foo(); 
    File "program.foo", line 7, inside function 'foo' 
    bar(); 
    File "program.foo", line 2, inside function 'bar' 
    throw Exception('Some exception message'); 
Exception: Some exception message 

簡単な方法がありますか?私はインタプリタの実装の内部であるため、Pythonのバイトコードのインストゥルメントを伴わないソリューションを好むでしょうが、他に何もなければ、バイトコードを実装することもできます。

+0

翻訳は、Pythonコードの行とfooコードの行との間にあらゆる種類のマッピングを格納しますか?あなたは確かにトレースバックをカスタマイズすることができます:IPythonには、これについては[ultratb](https://github.com/ipython/ipython/blob/master/IPython/core/ultratb.py)というモジュールがありますが、かなり長く複雑ですが、いくつかのクリーンアップを行うことができます。 –

+0

これまでのところ翻訳のみです。しかし、それが解決策の一部なら、私は確かにpythonの行をfooの行にマップすることができます。 –

答えて

2

コンテキスト(ファイル名、関数、行番号など)をグローバルスタックに記録するデコレータで、生成された各Python関数を飾ることができます。次に、あなた自身のExceptionクラスを派生させ、インタプリタのトップレベルでキャッチすることができます。最後に、グローバルデバッグスタックの情報を使用して、好きなものを表示します。

+0

これは良いリードのようです。私はこの解決策を適用することができ、各関数をデコレートする代わりに、関数呼び出しを追加して、現在のfoo行をそれにマップされている各Python文のグループの前に記録します。しかし、なぜ私はカスタム例外クラスが必要でしょうか?私はちょうどすべてのPythonの例外をキャッチし、グローバルコンテキストスタック内の情報を印刷できませんでしたか? –

+0

もちろんできます。しかし、独自の例外クラスを宣言すると、問題に固有の例外にカスタム情報を記録することができます。 –

+0

これはこれまでのところ最高のソリューションです。ありがとうございます。 –

関連する問題