From 33259a6291be67fdc2545024f8fd5ff9603fd8dd Mon Sep 17 00:00:00 2001 From: dos-reis Date: Tue, 16 Sep 2014 18:58:40 +0000 Subject: Add more functionalities to the VM. --- src/rt/Lisp.cc | 40 ++++++++++++++++++++++++++----- src/rt/vm.cc | 75 +++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 92 insertions(+), 23 deletions(-) (limited to 'src/rt') 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 + struct NamedConstant { + const char* const name; + const T value; + }; + } + + constexpr NamedConstant 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(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(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(&*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(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() { -- cgit v1.2.3