[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:
		| @@ -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でスコープ作る時だけか | ||||
		Reference in New Issue
	
	Block a user