aboutsummaryrefslogtreecommitdiff
path: root/src/rt
diff options
context:
space:
mode:
authordos-reis <gdr@axiomatics.org>2014-09-16 18:58:40 +0000
committerdos-reis <gdr@axiomatics.org>2014-09-16 18:58:40 +0000
commit33259a6291be67fdc2545024f8fd5ff9603fd8dd (patch)
treefec669b435ffe2508ed89097b9948d1ec548cffd /src/rt
parent0401fe922d9155e62de78e37d2153986522e38e9 (diff)
downloadopen-axiom-33259a6291be67fdc2545024f8fd5ff9603fd8dd.tar.gz
Add more functionalities to the VM.
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/Lisp.cc40
-rw-r--r--src/rt/vm.cc75
2 files changed, 92 insertions, 23 deletions
diff --git a/src/rt/Lisp.cc b/src/rt/Lisp.cc
index f87db63c..fd1f5289 100644
--- a/src/rt/Lisp.cc
+++ b/src/rt/Lisp.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2013, Gabriel Dos Reis.
+// Copyright (C) 2013-2014, Gabriel Dos Reis.
// All rights reserved.
// Written by Gabriel Dos Reis.
//
@@ -37,6 +37,30 @@
namespace OpenAxiom {
namespace Lisp {
+ namespace {
+ template<typename T>
+ struct NamedConstant {
+ const char* const name;
+ const T value;
+ };
+ }
+
+ constexpr NamedConstant<Value> value_constants[] = {
+ { "NIL", Value::nil },
+ { "T", Value::t },
+ { "MOST-NEGATIVE-FIXNUM", from_fixnum(Fixnum::minimum) },
+ { "MOST-POSITIVE-FIXNUM", from_fixnum(Fixnum::maximum) },
+ };
+
+ static void define_special_value_constants(Evaluator* ctx) {
+ auto core = ctx->core_package();
+ for (auto& x : value_constants) {
+ auto sym = core->make_symbol(ctx->intern(x.name));
+ sym->value = x.value;
+ sym->attributes = SymbolAttribute::SpecialConstant;
+ }
+ }
+
Unimplemented::Unimplemented(const std::string& s)
: BasicError(s)
{ }
@@ -134,13 +158,13 @@ namespace OpenAxiom {
auto s = ctx->intern(x.lexeme().begin(), x.lexeme().size());
switch (x.kind()) {
case Sexpr::SymbolSyntax::uninterned:
- return from_symbol(ctx->make_symbol(s, nullptr));
+ return to_value(ctx->homeless_package()->make_symbol(s));
case Sexpr::SymbolSyntax::keyword:
- return from_symbol(ctx->make_symbol(s, ctx->keyword_namespace()));
+ return to_value(ctx->make_keyword(s));
default:
- return from_symbol(ctx->make_symbol(s, ctx->active_namespace()));
+ return to_value(ctx->current_package()->make_symbol(s));
}
}
@@ -199,7 +223,11 @@ namespace OpenAxiom {
return v;
}
- Evaluator::Evaluator() : keys(intern("KEYWORD")), ns() {
+ Evaluator::Evaluator()
+ : core(make_package(intern("AxiomCore"))),
+ ns(core)
+ {
+ define_special_value_constants(this);
env_stack.push_back(Environment{ });
}
@@ -242,7 +270,7 @@ namespace OpenAxiom {
static void format(const Symbol* s, std::ostream& os) {
// FIXME: Handle escapes.
- auto n = s->name();
+ auto n = s->name;
std::copy(n->begin(), n->end(), std::ostream_iterator<char>(os));
}
diff --git a/src/rt/vm.cc b/src/rt/vm.cc
index a0f4f2e3..7f5cd5fc 100644
--- a/src/rt/vm.cc
+++ b/src/rt/vm.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2013, Gabriel Dos Reis.
+// Copyright (C) 2011-2014, Gabriel Dos Reis.
// All rights reserved.
// Written by Gabriel Dos Reis.
//
@@ -36,12 +36,41 @@
namespace OpenAxiom {
namespace VM {
+ // -- Environement
+ Environment::Environment() = default;
+
+ Environment::~Environment() {
+ // Restore value of special variables bound in this environment.
+ const auto end = dynamic.rend();
+ for (auto p = dynamic.rbegin(); p != end; ++p)
+ p->symbol->value = p->value;
+ }
+
+ // -- Dynamic
Dynamic::~Dynamic() { }
- Symbol::Symbol(String n, Scope* s)
- : std::pair<String, Scope*>(n, s)
+ // -- Symbol
+ Symbol::Symbol(InternedString s)
+ : name(s),
+ value(),
+ function(),
+ properties(),
+ package(),
+ attributes()
{ }
+ // -- Package
+ 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;
+ }
+
Fixnum
count_nodes(Pair p) {
FixnumBits n = 1;
@@ -51,36 +80,48 @@ namespace OpenAxiom {
}
// -- BasicContext --
- Pair BasicContext::make_pair(Value h, Value t) {
- return conses.make(h, t);
+ 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;
}
- const Symbol*
- BasicContext::make_symbol(String n, Scope* s) {
- return &*syms.insert({ n, s }).first;
+ Pair BasicContext::make_pair(Value h, Value t) {
+ return conses.make(h, t);
}
const NullaryOperator*
- BasicContext::make_operator(Symbol n, NullaryCode c) {
- return nullaries.make(n, c);
+ 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 unaries.make(n, c);
+ 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 binaries.make(n, c);
+ 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 ternaries.make(n, c);
+ BasicContext::make_operator(Symbol* n, TernaryCode c) {
+ return setf_symbol_function(n, ternaries.make(n, c));
}
- BasicContext::BasicContext() {
+ BasicContext::BasicContext()
+ : keywords(make_package(intern("KEYWORD"))),
+ homeless(make_package(nullptr))
+ {
}
BasicContext::~BasicContext() {