mirror of
https://github.com/kanaka/mal.git
synced 2024-11-11 00:52:44 +03:00
54 lines
1.2 KiB
D
54 lines
1.2 KiB
D
import types;
|
|
|
|
class Env {
|
|
Env outer;
|
|
MalType[MalSymbol] data;
|
|
|
|
this(Env outer_v, MalType[] binds = [], MalType[] exprs = [])
|
|
{
|
|
outer = outer_v;
|
|
foreach (int i, MalType b; binds)
|
|
{
|
|
auto arg_name = verify_cast!MalSymbol(b);
|
|
if (arg_name.name == "&")
|
|
{
|
|
auto rest_arg_name = verify_cast!MalSymbol(binds[i + 1]);
|
|
auto rest_exprs = new MalList(exprs[i..$]);
|
|
set(rest_arg_name, rest_exprs);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
set(arg_name, exprs[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
MalType set(MalSymbol key, MalType val)
|
|
{
|
|
data[key] = val;
|
|
return val;
|
|
}
|
|
|
|
Env find(MalSymbol key)
|
|
{
|
|
auto val = (key in data);
|
|
if (val !is null) {
|
|
return this;
|
|
} else if (outer is null) {
|
|
return null;
|
|
} else {
|
|
return outer.find(key);
|
|
}
|
|
}
|
|
|
|
MalType get(MalSymbol key)
|
|
{
|
|
auto found = find(key);
|
|
if (found is null) {
|
|
throw new Exception("'" ~ key.print(true) ~ "' not found");
|
|
}
|
|
return found.data[key];
|
|
}
|
|
}
|