Open50

minigo

podhmopodhmo

遅延import

podhmopodhmo

どこまで遅延できるんだろう?
あとパッケージの読み込みは結局のところディレクトリを全部読み込むことになる?

意外と型のシンボル名だけが欲しい場合にはimportを辿らなくて良い気がする

podhmopodhmo

Package Object

podhmopodhmo

FuncDeclとか辿っていきたい。
コメントとかも全部取得したい。
structもまぁそうかも?

podhmopodhmo

name,pathが取れる事はわかる。そしてファイルを持っている事はわかる。
そしてSymbolsないしはFunctionsを持っているのはわかる。

type Package struct {
  Name string
  Path string
  Files []File
  // ...
}

いつ内部のファイルをopenする?

ファイルはそれぞれimportされてimport時に別名が入る

type File struct {
  Name string
  Symbols []Symbol // decls?
  Imports []Import
}

type Import struct {
  Name string
  Path string
}
podhmopodhmo

astの値を陽に触りたくはないのでは?欲しい情報はなんだろう?
reflectshapeで取れるような情報がほしい?あるいはreflectで取れるような情報。

  • function
    • name
    • params
    • returns
    • body
  • struct
    • name
    • fields
      • type
      • fieldname
      • tag
      • comment

method, embedded

podhmopodhmo

repl的な感じで使用したかったのだっけ? これは :import xxx みたいな機能がないと無理なんだろうか?

podhmopodhmo

ある関数のアノテーションをつけたものだけを取り出したい go:xxx のような形でなにかマーカーを付ける。

// Foo: 
//minigo:XXX
func Foo(){ ... }
podhmopodhmo

インタプリタ

podhmopodhmo

どんな実験が必要だろう?

‐エントリーポイントを変えて実行
‐既存のライブラリを呼ぶ
‐再帰的な呼び出しや関数呼び出しの対応
‐ブロックスコープの対応
‐deferの対応
‐各種分岐用の構文の対応

podhmopodhmo

yiegiみたいに全部reflectで覆う必要があるんだろうか?

podhmopodhmo

コンセプト

コンセプト的なものの整理

podhmopodhmo

go/astやdave/dstを直接触ったコマンドラインツールを使うのと何が違うんだろう?

これは直接オプションなどを記述できるところが違う。

podhmopodhmo

go runで実行することと何が違うんだろう?

これは全てのパッケージをimportしてbuildする必要がなく表層をなぞるような形で実行できる。

あと、main()以外のエントリーポイントから実行することができる。

podhmopodhmo

感想

ここを一種のタイムラインとして使う。
思ったことを雑に書いていく。

podhmopodhmo

どこから始めていくべきか…

インタプリタとしての完成度を高めていくべきか。パッケージオブジェクト的なもののインターフェイスを確認ししていく感じにするべきか。

今はまだ変数定義もできない

podhmopodhmo

テストのことを考えるとインタプリタとしてパッケージを切ってしまい標準出力を渡す感じにするのも良い気がする。

podhmopodhmo

利用方法も考えていきたい。typespecみたいなので十分なのでは?という気もしてるのだけれど…

podhmopodhmo

とりあえずstdoutを受け取れる様にしてテストを書けるようにした

podhmopodhmo

きれいなスタックトレースが早めに欲しいかも?

podhmopodhmo

‐関数呼び出し
‐Package Object
‐reflect value利用
‐条件分岐やループの対応
‐structのパース
‐ディレクトリを指定して実行

どちらに進もう。後者のほうが面白そう?ファイルとの関係があることを忘れるとダメかも。

podhmopodhmo

Package Objectの方を勧めていきたいのだけれど、具体的な利用例が思いつかない気がする。
CurrentPackage()で現在の値が取れるがそれから先に進める方法がわからない。go/astのDeclが取れ得るのが嬉しいんだろうか?それをwrapしたようななにかが手に入ると嬉しいんだろうか?内部の実装がわかんない感じ担っていると楽な気がする。

podhmopodhmo

Package Objectの利用方法を考えていた。エントリーポイントを変えて実行するときに補完が効く用になるのが嬉しいところなのだけれどその常として実行時のバイナリのサイズは大きくなるかもしれない。それは仕方がないか。。

何をしたいんだろう?

podhmopodhmo

ただエントリーポイントが変わるだけだとすると登録する系の関数の実装を差し替えるということはできる。

podhmopodhmo

reflect.Valueを利用するようにしてみた。
ついでにprintlnとtrue,falseをトップレベルのscopeに入れて使えるようにしてみた。

多値を返す戻り値の取り扱いとかが上手くできていないかも?

podhmopodhmo

実行用にreflect.Valueで包んだ関数が必要で、goplsを効かせるために既存の定義が必要で、浅い探索のためにimportは随時読み込む事が必要。この時読み取れるのはastだけなで読み取ったstructを使うことができない。走査することはできる。

podhmopodhmo

手抜きのためにreflectで覆うのは良くないのかもしれない

podhmopodhmo

自分でstructなどをparseして利用できる感じにしないと実行することができない。
前もってreflect.ValueOf()やTypeOf()で保持しておけると利用できるけれどそれは明示的なimportになる。

podhmopodhmo

とりあえず雑だけどimportを見るようにした。次はどのあたりにしよう。

‐ 関数呼び出し (同一パッケージの別ファイルを含む)
‐ きれいなスタックトレース
‐複数の戻り値

podhmopodhmo

ある型からある型への変換のような定義を書くのは楽になるのかな。パッケージオブジェクト経由で辿らなくてもastからのdeclで良いような気もする。

podhmopodhmo

インタプリタ上のエラーと実行時のエラーはしっかり分かれてるのだろうか?

reflect.ValueのCallで発生したエラーは実行時エラーだとしてFuncDeclは適切に対応できてる?

podhmopodhmo

利用可能なモジュールをインストールできても良い気がする

podhmopodhmo

スタックトレース

podhmopodhmo

きれいなスタックトレースどうやるんだろ?

分かっていることは以下の2つがある

‐未実装
‐実行時エラー

その手前に構文エラーがある。

podhmopodhmo

どこでエラーになったかがわかりたい。
あとpythonとかとは違ってgoの場合はコードが見られなかった記憶。

podhmopodhmo

stacktraceの例

<details>

go panic

stacktrace from panic: 
goroutine 1 [running]:
runtime/debug.Stack(0x1042ff18, 0x98b2, 0xf0ba0, 0x17d048)
    /usr/local/go/src/runtime/debug/stack.go:24 +0xc0
main.main.func1()
    /tmp/sandbox973508195/main.go:11 +0x60
panic(0xf0ba0, 0x17d048)
    /usr/local/go/src/runtime/panic.go:502 +0x2c0
main.main()
    /tmp/sandbox973508195/main.go:16 +0x60

python

Traceback (most recent call last):
  File "<doctest...>", line 10, in <module>
    lumberjack()
  File "<doctest...>", line 4, in lumberjack
    bright_side_of_life()
IndexError: tuple index out of range

node

Error: Cannot find module 'some-module'
Require stack:
- /Users/yourusername/project/file.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)
    at Function.Module._load (internal/modules/cjs/loader.js:745:27)
    at Module.require (internal/modules/cjs/loader.js:974:19)
    at require (internal/modules/cjs/helpers.js:93:18)
    at Object.<anonymous> (/Users/yourusername/project/file.js:1:1)
    at Module._compile (internal/modules/cjs/loader.js:1085:14)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
    at Module.load (internal/modules/cjs/loader.js:950:32)
    at Function.Module._load (internal/modules/cjs/loader.js:790:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:76:12) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/yourusername/project/file.js'
  ]
}

</details>

podhmopodhmo

必要な情報は

  • ファイル名
  • 関数名
  • 行数
  • (ソースコードの行)
podhmopodhmo

stmtを見るとインデントがなくなるのが厳しいかもしれない?

podhmopodhmo

hmm

Error: unsupported types: int64 + bool

Traceback (most recent call first):
	File "./internal/interpreter/testdata/func.go", line 19, in G()
		return n + 10 + true
	File "./internal/interpreter/testdata/func.go", line 15, in F()
		return G(n) + G(n) + 10
time=2024-09-23T15:22:35.000+09:00 level=ERROR msg="failed to run" error="failed to eval stmt[6]: failed to eval expr: failed to eval argument[0]: failed to eval return expr: failed to eval binary expr lhs: failed to eval binary expr lhs: failed to eval return expr: unsupported types: int64 + bool"