minigo
遅延import
どこまで遅延できるんだろう?
あとパッケージの読み込みは結局のところディレクトリを全部読み込むことになる?
意外と型のシンボル名だけが欲しい場合にはimportを辿らなくて良い気がする
Package Object
FuncDeclとか辿っていきたい。
コメントとかも全部取得したい。
structもまぁそうかも?
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
}
astの値を陽に触りたくはないのでは?欲しい情報はなんだろう?
reflectshapeで取れるような情報がほしい?あるいはreflectで取れるような情報。
- function
- name
- params
- returns
- body
- struct
- name
- fields
- type
- fieldname
- tag
- comment
method, embedded
repl的な感じで使用したかったのだっけ? これは :import xxx
みたいな機能がないと無理なんだろうか?
💭あんまり嬉しくないような気がする
ある関数のアノテーションをつけたものだけを取り出したい go:xxx
のような形でなにかマーカーを付ける。
// Foo:
//minigo:XXX
func Foo(){ ... }
インタプリタ
コンセプト
コンセプト的なものの整理
感想
ここを一種のタイムラインとして使う。
思ったことを雑に書いていく。
どこから始めていくべきか…
インタプリタとしての完成度を高めていくべきか。パッケージオブジェクト的なもののインターフェイスを確認ししていく感じにするべきか。
今はまだ変数定義もできない
テストのことを考えるとインタプリタとしてパッケージを切ってしまい標準出力を渡す感じにするのも良い気がする。
利用方法も考えていきたい。typespecみたいなので十分なのでは?という気もしてるのだけれど…
とりあえずstdoutを受け取れる様にしてテストを書けるようにした
雑に変数を受け取れるようにした
きれいなスタックトレースが早めに欲しいかも?
テストを読みやすくした
‐関数呼び出し
‐Package Object
‐reflect value利用
‐条件分岐やループの対応
‐structのパース
‐ディレクトリを指定して実行
どちらに進もう。後者のほうが面白そう?ファイルとの関係があることを忘れるとダメかも。
Package Objectの方を勧めていきたいのだけれど、具体的な利用例が思いつかない気がする。
CurrentPackage()で現在の値が取れるがそれから先に進める方法がわからない。go/astのDeclが取れ得るのが嬉しいんだろうか?それをwrapしたようななにかが手に入ると嬉しいんだろうか?内部の実装がわかんない感じ担っていると楽な気がする。
スタックトレースとかの例を挙げてみた。
Package Objectの利用方法を考えていた。エントリーポイントを変えて実行するときに補完が効く用になるのが嬉しいところなのだけれどその常として実行時のバイナリのサイズは大きくなるかもしれない。それは仕方がないか。。
何をしたいんだろう?
ただエントリーポイントが変わるだけだとすると登録する系の関数の実装を差し替えるということはできる。
reflect.Valueを利用するようにしてみた。
ついでにprintlnとtrue,falseをトップレベルのscopeに入れて使えるようにしてみた。
多値を返す戻り値の取り扱いとかが上手くできていないかも?
どうにかimportと切り離そうとplugin経由で呼ぼうとしてみたけれどこれは無しな気がする
reflectの中で関数を定義するコードだけれど再帰的な呼び出しはできるんだろうか?
一応再帰的な定義はできるみたいだ
再帰的な型の定義は無理。こういう感じで抗おうとしたがだめだった。
実行用にreflect.Valueで包んだ関数が必要で、goplsを効かせるために既存の定義が必要で、浅い探索のためにimportは随時読み込む事が必要。この時読み取れるのはastだけなで読み取ったstructを使うことができない。走査することはできる。
手抜きのためにreflectで覆うのは良くないのかもしれない
自分でstructなどをparseして利用できる感じにしないと実行することができない。
前もってreflect.ValueOf()やTypeOf()で保持しておけると利用できるけれどそれは明示的なimportになる。
とりあえず雑だけどimportを見るようにした。次はどのあたりにしよう。
‐ 関数呼び出し (同一パッケージの別ファイルを含む)
‐ きれいなスタックトレース
‐複数の戻り値
funcdeclを辿って関数を呼べるようにしてみた
ある型からある型への変換のような定義を書くのは楽になるのかな。パッケージオブジェクト経由で辿らなくてもastからのdeclで良いような気もする。
インタプリタ上のエラーと実行時のエラーはしっかり分かれてるのだろうか?
reflect.ValueのCallで発生したエラーは実行時エラーだとしてFuncDeclは適切に対応できてる?
利用可能なモジュールをインストールできても良い気がする
スタックトレース
きれいなスタックトレースどうやるんだろ?
分かっていることは以下の2つがある
‐未実装
‐実行時エラー
その手前に構文エラーがある。
どこでエラーになったかがわかりたい。
あとpythonとかとは違ってgoの場合はコードが見られなかった記憶。
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>
必要な情報は
- ファイル名
- 関数名
- 行数
- (ソースコードの行)
stmtを見るとインデントがなくなるのが厳しいかもしれない?
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"