3

複数の LUA スクリプトをプレーン テキスト (つまり C 文字列) から取得して実行する単純な LUA オンライン インタープリターを実装しています。すべて正常に動作していますが、これらのスクリプトで構文エラーまたは実行時エラーが発生したときのプログラムの応答をテストしています。

これまでのところ、エラーが発生した場合、呼び出した後lua_pcall、スタック メッセージから次のようなエラーが表示されます。

[string "..."]:7: attempt to call field 'push' (a nil value)

ここで、LUA のランタイムでトークン[string "..."]を仮想ファイル名 (インタープリターが文字列から LUA コードを取得することを思い出してください) に置き換えて、ユーザーが「my.lua」という名前を使用して仮想スクリプトを送信すると、エラー メッセージが表示されるようにする必要があります。そのスクリプトの LUA のランタイムから生成されたものは、次のようにフォーマットされます。

my.lua:7: attempt to call field 'push' (a nil value)

LUA のソース コードを分析して、LUA インタープリターがこの目的を達成する方法を調べてみました。これまでのところ、私が見つけたのはlua_loadstring()lua_loadfile()後者が「@」で始まるファイルの名前をスタックにプッシュするという点だけです。LUA のソース コードから ( lauxlib.c):

LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
                                         const char *mode) {
  LoadF lf;
  int status, readstatus;
  int c;
  int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
  if (filename == NULL) {
    lua_pushliteral(L, "=stdin");
    lf.f = stdin;
  }
  else {
    lua_pushfstring(L, "@%s", filename);
    lf.f = fopen(filename, "r");
    if (lf.f == NULL) return errfile(L, "open", fnameindex);
  }
  //...
  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
  //...

}

LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
  return luaL_loadbuffer(L, s, strlen(s), s); //eventually calls lua_load
}

どちらの関数もluaL_loadfilex()luaL_loadstring()を呼び出すことlua_load()になるため、両者の違いは、前者が を呼び出す前に「=stdin」またはファイル名をスタックにプッシュすることlua_load()です。私のコードは を呼び出すだけluaL_loadstring()なので、呼び出す前に仮想ファイル名をプッシュしても同じ効果があると思いましたが、そうではありません。

私はいくつかのポイントを逃していますか?ありがとうございました。

4

1 に答える 1