4

私は最近、C、Bison、Flex、およびこの投稿を出発点として使用しておもちゃのプログラミング言語を作成しました。コロンや空白のルールがないことを除けば、Pythonによく似ています。

コードはここにありますが、私が固執している概念/アルゴリズムほど重要ではありません。

上記のリンク先の投稿でRudiが行ったように、抽象構文ツリーを設計しました。

秘訣は、ユーザー定義関数から戻る、またはループから抜け出すための優れた方法を考えることができないということです。returnユーザー定義関数の最後に1つのステートメントだけが必要な場合、それは実行可能です(実際、これはユーザー定義関数で現在機能しているものです)。

例:

i = 0
while 1 do
  if i > 15 then
     break
  end
done

例2:

def mean(somelist)
  if len(list) == 0 then
    return 0  # throw error
  else
    return sum(somelist) / len(somelist)
  end
end
4

3 に答える 3

0

その答えは、コードがどのように機能するかの内部に大きく依存します。

私がMote Compiler (VB に似たコンパイラ)を書いMoteEngine.prototype.runFuncStartたとき、関数の開始時に を呼び出しました。すべてのローカル変数を保持する新しいオブジェクトを作成し、それをスタックにプッシュしました。

MoteEngine.prototype.runFuncEndスタックをクリーンアップしました。

于 2012-09-21T15:51:49.220 に答える
0

それは、実行エンジンをどのように正確に実装するかに大きく依存します。相互に再帰的に呼び出して AST をトラバースする関数を使用して実行エンジンを実装するという Rudi の提案に従う場合、breakまたはを実装するreturnには、C コール スタックのいくつかのレベルから戻る必要があります。これは setjmp/longjmp で行うことができます。たとえば、コードは次のようになります。

struct ExecEnviron {
    /* other contents of ExecEnviron, we're just adding a bit */
    jmp_buf *break_context;  /* where a 'break' or 'continue' should jump to */
    jmp_buf *return_context; /* where a 'return' should jump to */
};

void ExecWhile(ExecEnviron *e, AstElement *a) {
    jmp_buf local, *old = e->break_context;
    e->break_context = &local;

    if (setjmp(&local) != 1)
        while (dispatchExpression(a->whileStmt.cond))
            dispatchStatement(a->whileStmt.body);
    e->break_context = old;
}
void ExecBreak((ExecEnviron *e, AstElement *a) {
    longjmp(e->break_context, 1);
}
void ExecContinue((ExecEnviron *e, AstElement *a) {
    longjmp(e->break_context, 2);
}

setjmp/longjmp は、ネストされたコンテキストを抜け出すには適切に機能しますが、一般的なラベル/goto 処理には機能しません (ループの途中にジャンプすることができるため)。これに対処したい場合は、まったく異なる実行エンジンを使用し、AST をバイトコードやスレッド化されたコードなどのより直線的なものに変換する必要があります。

于 2012-09-21T18:27:05.367 に答える
0

一部の一般的なスタックベースの言語は、値をスタックにプッシュし、呼び出し元の関数によってポップされます。それはあなたのために働くかもしれません。

もちろん、これは既知の戻り値の型を持つ関数を持つことに依存しています。関数が 'void' の場合 (つまり、何も返さない場合)、Python は PyNone を返します。Python 関数は 1 つの値 (None、オブジェクト、タプルなど) のみを返します。

C 型言語も、関数から値を 1 つだけ返します。

要点は、厳密に型指定された言語では常に戻り値があり、常に戻り値を返す必要があるということだと思います。値を返すか返す可能性のある弱い型付け言語では、それでも値があります。

于 2012-09-21T15:46:25.550 に答える