#include <open-axiom/vm>
#include <iterator>
#include <algorithm>
#include <ostream>
namespace OpenAxiom {
namespace VM {
void Dynamic::Visitor::visit(const NullaryOperator& x) {
visit(as<FunctionBase>(x));
}
void Dynamic::Visitor::visit(const UnaryOperator& x) {
visit(as<FunctionBase>(x));
}
void Dynamic::Visitor::visit(const BinaryOperator& x) {
visit(as<FunctionBase>(x));
}
void FunctionBase::accept(Visitor& v) const { v.visit(*this); }
Environment::Environment() = default;
Environment::~Environment() {
const auto end = dynamic.rend();
for (auto p = dynamic.rbegin(); p != end; ++p)
p->symbol->value = p->value;
}
Environment::Binding*
Environment::lookup(InternedString name) {
for (auto& b : lexical) {
if (b.symbol->name == name)
return &b;
}
return nullptr;
}
Dynamic::~Dynamic() = default;
Symbol::Symbol(InternedString s)
: name(s),
value(),
function(),
properties(),
package(),
attributes()
{ }
void Symbol::accept(Visitor& v) const { v.visit(*this); }
void Binding::accept(Visitor& v) const { v.visit(*this); }
Package::Package(InternedString s)
: name(s)
{ }
Symbol*
Package::make_symbol(InternedString s) {
auto sym = const_cast<Symbol*>(&*symbols.insert(Symbol(s)).first);
sym->package = this;
return sym;
}
Symbol*
Package::find_symbol(InternedString s) {
auto p = symbols.find(Symbol(s));
return p == symbols.end() ? nullptr : const_cast<Symbol*>(&*p);
}
void Package::accept(Visitor& v) const { v.visit(*this); }
Fixnum
count_nodes(Pair p) {
FixnumBits n = 1;
for (; auto q = to_pair_if_can(p->tail); p = q)
++n;
return Fixnum(n);
}
Package*
BasicContext::make_package(InternedString n) {
auto p = &*packages.insert(Package(n)).first;
return const_cast<Package*>(p);
}
Symbol*
BasicContext::make_keyword(InternedString n) {
auto sym = keyword_package()->make_symbol(n);
sym->value = to_value(sym);
sym->attributes = SymbolAttribute::Keyword;
return sym;
}
Pair BasicContext::make_pair(Value h, Value t) {
return conses.make(h, t);
}
const NullaryOperator*
BasicContext::make_operator(Symbol* n, NullaryCode c) {
return setf_symbol_function(n, nullaries.make(n, c));
}
const UnaryOperator*
BasicContext::make_operator(Symbol* n, UnaryCode c) {
return setf_symbol_function(n, unaries.make(n, c));
}
const BinaryOperator*
BasicContext::make_operator(Symbol* n, BinaryCode c) {
return setf_symbol_function(n, binaries.make(n, c));
}
const TernaryOperator*
BasicContext::make_operator(Symbol* n, TernaryCode c) {
return setf_symbol_function(n, ternaries.make(n, c));
}
BasicContext::BasicContext()
: keywords(make_package(intern("KEYWORD"))),
homeless(make_package(nullptr))
{
}
BasicContext::~BasicContext() {
}
}
}