From 2f10426abf3caf7aeb012d3f88160913b3d1b5f2 Mon Sep 17 00:00:00 2001 From: "Tomoya Matsuura(MacBookPro)" Date: Sat, 2 Sep 2023 21:37:00 +0900 Subject: [PATCH] [obsidian] vault backup: 2023-09-02 21:37:00[ --- ...ustでの評価文脈(環境)のRAIIっぽい実装.md | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/content/Rustでの評価文脈(環境)のRAIIっぽい実装.md b/content/Rustでの評価文脈(環境)のRAIIっぽい実装.md index a04e996e..dd9fbabb 100644 --- a/content/Rustでの評価文脈(環境)のRAIIっぽい実装.md +++ b/content/Rustでの評価文脈(環境)のRAIIっぽい実装.md @@ -54,4 +54,44 @@ impl<'a, T: Clone> Drop for EnvironmentT<'a, T> { self.0.truncate(self.1); } } +``` + +--- + +なんかDropのタイミングがうまく制御できずコンパイルを通せない、、、 +し、綺麗ではあるけど言うほど記述量が減るわけではない + +ので、evalを相互再帰するヘルパー関数とかでこういう感じにした方が楽かも + +```rust +fn eval_with_new_env<'a>( + e_meta: Box>, + env: &'a mut Vec<(String, Value)>, + mut names: Vec<(String, Value)>, +) -> Result { + let len_origin = env.len(); + env.append(&mut names); + let res = eval_ast(e_meta, env); + env.truncate(len_origin); + res +} +fn eval_ast<'a>( + e_meta: Box>, + env: &'a mut Vec<(String, Value)>, +) -> Result{ + ... + match e { + ... + ast::Expr::Let(TypedId { id, ty: _t }, e, then) => { + let e_v = eval_ast(e, env)?; + match then { + Some(t) => eval_with_new_env(t, env, vec![(id, e_v)]), + None => Ok(Value::Unit), + } + } + ... + + } + +} ``` \ No newline at end of file