mirror of
https://github.com/peklaiho/madlisp.git
synced 2024-11-23 05:45:06 +00:00
Optimization: read symbol name to variable in eval
This commit is contained in:
parent
d6127e6821
commit
a86fd77b45
@ -44,7 +44,9 @@ class Evaller
|
|||||||
|
|
||||||
// Handle special forms
|
// Handle special forms
|
||||||
if ($ast->get(0) instanceof Symbol) {
|
if ($ast->get(0) instanceof Symbol) {
|
||||||
if ($ast->get(0)->getName() == 'and') {
|
$symbolName = $ast->get(0)->getName();
|
||||||
|
|
||||||
|
if ($symbolName == 'and') {
|
||||||
if ($ast->count() == 1) {
|
if ($ast->count() == 1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -58,7 +60,7 @@ class Evaller
|
|||||||
|
|
||||||
$ast = $ast->get($ast->count() - 1);
|
$ast = $ast->get($ast->count() - 1);
|
||||||
continue; // tco
|
continue; // tco
|
||||||
} elseif ($ast->get(0)->getName() == 'case') {
|
} elseif ($symbolName == 'case') {
|
||||||
if ($ast->count() < 2) {
|
if ($ast->count() < 2) {
|
||||||
throw new MadLispException("case requires at least 1 argument");
|
throw new MadLispException("case requires at least 1 argument");
|
||||||
}
|
}
|
||||||
@ -78,7 +80,7 @@ class Evaller
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} elseif ($ast->get(0)->getName() == 'def') {
|
} elseif ($symbolName == 'def') {
|
||||||
if ($ast->count() != 3) {
|
if ($ast->count() != 3) {
|
||||||
throw new MadLispException("def requires exactly 2 arguments");
|
throw new MadLispException("def requires exactly 2 arguments");
|
||||||
}
|
}
|
||||||
@ -97,7 +99,7 @@ class Evaller
|
|||||||
|
|
||||||
$value = $this->eval($ast->get(2), $env);
|
$value = $this->eval($ast->get(2), $env);
|
||||||
return $env->set($name, $value);
|
return $env->set($name, $value);
|
||||||
} elseif ($ast->get(0)->getName() == 'do') {
|
} elseif ($symbolName == 'do') {
|
||||||
if ($ast->count() == 1) {
|
if ($ast->count() == 1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -108,7 +110,7 @@ class Evaller
|
|||||||
|
|
||||||
$ast = $ast->get($ast->count() - 1);
|
$ast = $ast->get($ast->count() - 1);
|
||||||
continue; // tco
|
continue; // tco
|
||||||
} elseif ($ast->get(0)->getName() == 'env') {
|
} elseif ($symbolName == 'env') {
|
||||||
if ($ast->count() >= 2) {
|
if ($ast->count() >= 2) {
|
||||||
if (!($ast->get(1) instanceof Symbol)) {
|
if (!($ast->get(1) instanceof Symbol)) {
|
||||||
throw new MadLispException("first argument to env is not symbol");
|
throw new MadLispException("first argument to env is not symbol");
|
||||||
@ -118,14 +120,14 @@ class Evaller
|
|||||||
} else {
|
} else {
|
||||||
return $env;
|
return $env;
|
||||||
}
|
}
|
||||||
} elseif ($ast->get(0)->getName() == 'eval') {
|
} elseif ($symbolName == 'eval') {
|
||||||
if ($ast->count() == 1) {
|
if ($ast->count() == 1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ast = $this->eval($ast->get(1), $env);
|
$ast = $this->eval($ast->get(1), $env);
|
||||||
continue; // tco
|
continue; // tco
|
||||||
} elseif ($ast->get(0)->getName() == 'fn') {
|
} elseif ($symbolName == 'fn') {
|
||||||
if ($ast->count() != 3) {
|
if ($ast->count() != 3) {
|
||||||
throw new MadLispException("fn requires exactly 2 arguments");
|
throw new MadLispException("fn requires exactly 2 arguments");
|
||||||
}
|
}
|
||||||
@ -152,7 +154,7 @@ class Evaller
|
|||||||
};
|
};
|
||||||
|
|
||||||
return new UserFunc($closure, $ast->get(2), $env, $bindings);
|
return new UserFunc($closure, $ast->get(2), $env, $bindings);
|
||||||
} elseif ($ast->get(0)->getName() == 'if') {
|
} elseif ($symbolName == 'if') {
|
||||||
if ($ast->count() < 3 || $ast->count() > 4) {
|
if ($ast->count() < 3 || $ast->count() > 4) {
|
||||||
throw new MadLispException("if requires 2 or 3 arguments");
|
throw new MadLispException("if requires 2 or 3 arguments");
|
||||||
}
|
}
|
||||||
@ -168,7 +170,7 @@ class Evaller
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} elseif ($ast->get(0)->getName() == 'let') {
|
} elseif ($symbolName == 'let') {
|
||||||
if ($ast->count() != 3) {
|
if ($ast->count() != 3) {
|
||||||
throw new MadLispException("let requires exactly 2 arguments");
|
throw new MadLispException("let requires exactly 2 arguments");
|
||||||
}
|
}
|
||||||
@ -199,7 +201,7 @@ class Evaller
|
|||||||
$ast = $ast->get(2);
|
$ast = $ast->get(2);
|
||||||
$env = $newEnv;
|
$env = $newEnv;
|
||||||
continue; // tco
|
continue; // tco
|
||||||
} elseif ($ast->get(0)->getName() == 'load') {
|
} elseif ($symbolName == 'load') {
|
||||||
// Load is here because we want to load into
|
// Load is here because we want to load into
|
||||||
// current $env which is hard otherwise.
|
// current $env which is hard otherwise.
|
||||||
|
|
||||||
@ -244,7 +246,7 @@ class Evaller
|
|||||||
$rootEnv->set('__DIR__', $prevDir);
|
$rootEnv->set('__DIR__', $prevDir);
|
||||||
|
|
||||||
continue; // tco
|
continue; // tco
|
||||||
} elseif ($ast->get(0)->getName() == 'or') {
|
} elseif ($symbolName == 'or') {
|
||||||
if ($ast->count() == 1) {
|
if ($ast->count() == 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -258,7 +260,7 @@ class Evaller
|
|||||||
|
|
||||||
$ast = $ast->get($ast->count() - 1);
|
$ast = $ast->get($ast->count() - 1);
|
||||||
continue; // tco
|
continue; // tco
|
||||||
} elseif ($ast->get(0)->getName() == 'quote') {
|
} elseif ($symbolName == 'quote') {
|
||||||
if ($ast->count() != 2) {
|
if ($ast->count() != 2) {
|
||||||
throw new MadLispException("quote requires exactly 1 argument");
|
throw new MadLispException("quote requires exactly 1 argument");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user