[obsidian] vault backup: 2024-12-25 16:00:07[
All checks were successful
Build / build (push) Successful in 4m16s
All checks were successful
Build / build (push) Successful in 4m16s
This commit is contained in:
parent
841bb40266
commit
c88ebcc7ee
@ -3,6 +3,9 @@ date: "2023-09-01T12:44:46+0900"
|
||||
---
|
||||
#programming-language #compiler-design
|
||||
|
||||
微妙だったので作り直す。
|
||||
[[エラーフレンドリーな評価環境の実装]]
|
||||
|
||||
## 動機
|
||||
|
||||
[chumskyのチュートリアル](https://github.com/zesterer/chumsky/blob/main/tutorial.md)で、評価する関数の実装がライフタイム付きでこんな感じになってたの頭いいなと思ったので、RAIIにしたらもっとシンプルに見えるのではと思った
|
||||
|
BIN
content/img/スクリーンショット 2024-12-25 15.23.26.png
Normal file
BIN
content/img/スクリーンショット 2024-12-25 15.23.26.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 50 KiB |
62
content/エラーフレンドリーな評価環境の実装.md
Normal file
62
content/エラーフレンドリーな評価環境の実装.md
Normal file
@ -0,0 +1,62 @@
|
||||
---
|
||||
date: 2024-12-25 15:10
|
||||
---
|
||||
#programming-language #compiler-design
|
||||
|
||||
例えば似た変数名の候補を返すとか、スコープ外にある変数の候補をサジェストしてくれるような評価環境を作りたい
|
||||
|
||||
また、単に見つかった変数への参照を返すだけでなく、それがローカル、upvalue、global、externalなのかの区別も欲しい
|
||||
|
||||
これも参照を引き回すのがだるいのでSlotmapとかで実装するのがいいかもしれない
|
||||
|
||||
ネストされたletは1つずつ環境を作っていくが、ブロックとかで閉じたスコープを作れる
|
||||
|
||||
```rust
|
||||
fn test(arg1,arg2){
|
||||
let a = {
|
||||
let hoge = 100
|
||||
hoge + 20
|
||||
};
|
||||
let b = 200
|
||||
let c = hoge //this should be an error but suggested by language server
|
||||
b
|
||||
}
|
||||
```
|
||||
|
||||
ほかにも、let-tupleや複数引数のラムダなど、単に変数-値のペアのシングルリストではなく、レベルごとに複数のペアが混ざってるような形を取りうる。
|
||||
|
||||
上のコードでcを評価する直前の変数環境はこんな感じ
|
||||
|
||||
![[img/スクリーンショット 2024-12-25 15.23.26.png]]
|
||||
|
||||
- とりあえず親のリストへ辿る方向で探索する
|
||||
- 見つからなかった(セマンティクス的にエラーになる)場合は親を兄弟含めて検索して、候補が見つかったら返す
|
||||
- このときはついでに類似度検索で近いやつが否いかも探す
|
||||
|
||||
|
||||
```rust
|
||||
#[derive(Default)]
|
||||
pub struct Env<K,T>{
|
||||
parent: Option<Rc<Self>>,
|
||||
siblings: Vec<Rc<Self>>,
|
||||
local: Vec<(K,T)>
|
||||
}
|
||||
|
||||
impl <K,T> Env<K,T>{
|
||||
pub fn from_iter(parent:Rc<Self>,iter:impl Iterator<Item=(K,T)>)->Self{
|
||||
Self{
|
||||
parent,
|
||||
local: HashMap::from_iter(iter)
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
pub fn is_global(&self)->bool{
|
||||
self.parent.is_none()
|
||||
}
|
||||
pub fn lookup(&self,name:K)->Result<T,Error>{
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
結局siblingを作るケースはblockでスコープ作る時だけか
|
Loading…
Reference in New Issue
Block a user