2015-03-27 09:04:35 +11:00
|
|
|
#include "Environment.h"
|
|
|
|
|
#include "Types.h"
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
2015-03-27 11:03:28 +11:00
|
|
|
malEnv::malEnv(malEnvPtr outer)
|
|
|
|
|
: m_outer(outer)
|
|
|
|
|
{
|
|
|
|
|
TRACE_ENV("Creating malEnv %p, outer=%p\n", this, m_outer.ptr());
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-27 12:52:07 +11:00
|
|
|
malEnv::malEnv(malEnvPtr outer, const StringVec& bindings,
|
|
|
|
|
malValueIter argsBegin, malValueIter argsEnd)
|
|
|
|
|
: m_outer(outer)
|
|
|
|
|
{
|
|
|
|
|
TRACE_ENV("Creating malEnv %p, outer=%p\n", this, m_outer.ptr());
|
|
|
|
|
int n = bindings.size();
|
|
|
|
|
auto it = argsBegin;
|
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
|
if (bindings[i] == "&") {
|
2015-03-28 22:54:26 +11:00
|
|
|
MAL_CHECK(i == n - 2, "There must be one parameter after the &");
|
2015-03-27 12:52:07 +11:00
|
|
|
|
|
|
|
|
set(bindings[n-1], mal::list(it, argsEnd));
|
|
|
|
|
return;
|
|
|
|
|
}
|
2015-03-28 22:54:26 +11:00
|
|
|
MAL_CHECK(it != argsEnd, "Not enough parameters");
|
2015-03-27 12:52:07 +11:00
|
|
|
set(bindings[i], *it);
|
|
|
|
|
++it;
|
|
|
|
|
}
|
2015-03-28 22:54:26 +11:00
|
|
|
MAL_CHECK(it == argsEnd, "Too many parameters");
|
2015-03-27 12:52:07 +11:00
|
|
|
}
|
|
|
|
|
|
2015-03-27 11:03:28 +11:00
|
|
|
malEnv::~malEnv()
|
|
|
|
|
{
|
|
|
|
|
TRACE_ENV("Destroying malEnv %p, outer=%p\n", this, m_outer.ptr());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
malEnvPtr malEnv::find(const String& symbol)
|
|
|
|
|
{
|
|
|
|
|
for (malEnvPtr env = this; env; env = env->m_outer) {
|
|
|
|
|
if (env->m_map.find(symbol) != env->m_map.end()) {
|
|
|
|
|
return env;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2015-03-27 09:04:35 +11:00
|
|
|
malValuePtr malEnv::get(const String& symbol)
|
|
|
|
|
{
|
2015-03-27 11:03:28 +11:00
|
|
|
for (malEnvPtr env = this; env; env = env->m_outer) {
|
|
|
|
|
auto it = env->m_map.find(symbol);
|
|
|
|
|
if (it != env->m_map.end()) {
|
|
|
|
|
return it->second;
|
|
|
|
|
}
|
2015-03-27 09:04:35 +11:00
|
|
|
}
|
2015-03-28 22:54:26 +11:00
|
|
|
MAL_FAIL("'%s' not found", symbol.c_str());
|
2015-03-27 09:04:35 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
malValuePtr malEnv::set(const String& symbol, malValuePtr value)
|
|
|
|
|
{
|
|
|
|
|
m_map[symbol] = value;
|
|
|
|
|
return value;
|
|
|
|
|
}
|
2015-03-27 16:07:46 +11:00
|
|
|
|
|
|
|
|
malEnvPtr malEnv::getRoot()
|
|
|
|
|
{
|
|
|
|
|
// Work our way down the the global environment.
|
|
|
|
|
for (malEnvPtr env = this; ; env = env->m_outer) {
|
|
|
|
|
if (!env->m_outer) {
|
|
|
|
|
return env;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|