|
|
@@ -167,10 +167,34 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
|
|
|
Sym(ref a0sym) if a0sym == "def!" => {
|
|
|
env_set(&env, l[1].clone(), eval(l[2].clone(), env.clone())?)
|
|
|
}
|
|
|
+ Sym(ref a0sym) if a0sym == "zk*" => {
|
|
|
+ let (a1, a2) = (l[1].clone(), l[2].clone());
|
|
|
+ match a1 {
|
|
|
+ List(ref binds, _) | Vector(ref binds, _) => {
|
|
|
+ for (b, e) in binds.iter().tuples() {
|
|
|
+ match b {
|
|
|
+ Sym(_) => {
|
|
|
+ let _ = env_set(
|
|
|
+ &env,
|
|
|
+ b.clone(),
|
|
|
+ eval(e.clone(), env.clone())?,
|
|
|
+ );
|
|
|
+ }
|
|
|
+ _ => {
|
|
|
+ return error("let* with non-Sym binding");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _ => {
|
|
|
+ return error("let* with non-List bindings");
|
|
|
+ }
|
|
|
+ };
|
|
|
+ ast = a2;
|
|
|
+ continue 'tco;
|
|
|
+ }
|
|
|
Sym(ref a0sym) if a0sym == "let*" => {
|
|
|
- // TODO let should be restored to the first purpose
|
|
|
- // and the new let* without an env creation should be availaable
|
|
|
- // env = env_new(Some(env.clone()));
|
|
|
+ env = env_new(Some(env.clone()));
|
|
|
let (a1, a2) = (l[1].clone(), l[2].clone());
|
|
|
match a1 {
|
|
|
List(ref binds, _) | Vector(ref binds, _) => {
|