aboutsummaryrefslogtreecommitdiff
path: root/src/include
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/include
parent0401fe922d9155e62de78e37d2153986522e38e9 (diff)
downloadopen-axiom-33259a6291be67fdc2545024f8fd5ff9603fd8dd.tar.gz
Add more functionalities to the VM.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/Lisp.H26
-rw-r--r--src/include/sexpr.H37
-rw-r--r--src/include/vm.H117
3 files changed, 127 insertions, 53 deletions
diff --git a/src/include/Lisp.H b/src/include/Lisp.H
index 724ab54b..119d07f8 100644
--- a/src/include/Lisp.H
+++ b/src/include/Lisp.H
@@ -47,21 +47,21 @@
namespace std {
template<>
- struct hash<OpenAxiom::VM::Scope> {
+ struct hash<OpenAxiom::VM::Package> {
hash<OpenAxiom::VM::String>::result_type
- operator()(const OpenAxiom::VM::Scope& s) const {
- return h(s.name());
+ operator()(const OpenAxiom::VM::Package& s) const {
+ return h(s.name);
}
hash<OpenAxiom::VM::String> h;
};
template<>
- struct equal_to<OpenAxiom::VM::Scope> {
- using arg_type = OpenAxiom::VM::Scope;
+ struct equal_to<OpenAxiom::VM::Package> {
+ using arg_type = OpenAxiom::VM::Package;
bool operator()(const arg_type& x, const arg_type& y) const {
- return p(x.name(), y.name());
+ constexpr equal_to<OpenAxiom::VM::String> eq { };
+ return eq(x.name, y.name);
}
- equal_to<OpenAxiom::VM::String> p;
};
}
@@ -79,24 +79,20 @@ namespace OpenAxiom {
explicit IntegerOverflow(const std::string&);
};
- // -- Environments.
- using Environment = std::map<Symbol*, Value>;
-
// -- Anchor maps
using AnchorTable = std::map<Ordinal, Value>;
// -- Evaluator --
struct Evaluator : VM::BasicContext {
Evaluator();
- Scope* keyword_namespace() { return &keys; }
- Scope* active_namespace() { return ns; }
+ Package* core_package() { return core; }
+ Package* current_package() { return ns; }
Value toplevel_form(const Sexpr::Syntax*);
Value make_value(const Sexpr::Syntax*);
Environment* global_environment();
private:
- Scope keys;
- std::unordered_set<Scope> packages;
- Scope* ns;
+ Package* core;
+ Package* ns;
std::list<Environment> env_stack;
AnchorTable anchor_map;
};
diff --git a/src/include/sexpr.H b/src/include/sexpr.H
index 84513a8b..d3dafcb7 100644
--- a/src/include/sexpr.H
+++ b/src/include/sexpr.H
@@ -139,10 +139,10 @@ namespace OpenAxiom {
// ------------------
struct SymbolSyntax : AtomSyntax {
enum Kind {
- uninterned, // uninterned symbol
- ordinary, // an interned symbol
- absolute, // case-sensitive symbol
- keyword // a keyword symbol
+ ordinary = 0x0, // an interned symbol
+ uninterned = 0x1, // uninterned symbol
+ absolute = 0x2, // case-sensitive symbol
+ keyword = 0x4, // a keyword symbol
};
SymbolSyntax(const Lexeme&, Kind);
Kind kind() const { return sort; }
@@ -188,6 +188,17 @@ namespace OpenAxiom {
const Syntax* const form;
};
+ template<typename T>
+ struct binary_form : Syntax {
+ const Syntax* first() const { return rep.first; }
+ const Syntax* second() const { return rep.second; }
+ void accept(Visitor&) const;
+ protected:
+ binary_form(const Syntax* f, const Syntax* s) : rep(f, s) { }
+ private:
+ std::pair<const Syntax*, const Syntax*> rep;
+ };
+
// -----------------
// -- QuoteSyntax --
// -----------------
@@ -240,16 +251,16 @@ namespace OpenAxiom {
// -- Include --
// -------------
// Conditional inclusion syntax object
- struct Include : unary_form<Include> {
- explicit Include(const Syntax*);
+ struct Include : binary_form<Include> {
+ Include(const Syntax*, const Syntax*);
};
// -------------
// -- Exclude --
// -------------
// Conditional exclusion syntax object
- struct Exclude : unary_form<Exclude> {
- explicit Exclude(const Syntax*);
+ struct Exclude : binary_form<Exclude> {
+ Exclude(const Syntax*, const Syntax*);
};
// ----------------
@@ -322,6 +333,12 @@ namespace OpenAxiom {
v.visit(static_cast<const T&>(*this));
}
+ template<typename T>
+ void
+ binary_form<T>::accept(Visitor& v) const {
+ v.visit(static_cast<const T&>(*this));
+ }
+
// ---------------
// -- Allocator --
// ---------------
@@ -342,8 +359,8 @@ namespace OpenAxiom {
const Eval* make_eval(const Syntax*);
const Splice* make_splice(const Syntax*);
const Function* make_function(const Syntax*);
- const Include* make_include(const Syntax*);
- const Exclude* make_exclude(const Syntax*);
+ const Include* make_include(const Syntax*, const Syntax*);
+ const Exclude* make_exclude(const Syntax*, const Syntax*);
const ListSyntax* make_list(const std::vector<const Syntax*>&, bool = false);
const VectorSyntax* make_vector(const std::vector<const Syntax*>&);
diff --git a/src/include/vm.H b/src/include/vm.H
index c66a2e02..9337955b 100644
--- a/src/include/vm.H
+++ b/src/include/vm.H
@@ -41,8 +41,8 @@
#include <open-axiom/string-pool>
#include <stdint.h>
#include <utility>
-#include <map>
#include <set>
+#include <vector>
#include <type_traits>
#define internal_type struct alignas(16)
@@ -163,6 +163,14 @@ namespace OpenAxiom {
t = 0x10, // distinguished T value
};
+ constexpr bool to_bool(Value v) {
+ return v != Value::nil;
+ }
+
+ constexpr Value to_value(bool b) {
+ return b ? Value::t : Value::nil;
+ }
+
template<typename>
struct ValueTrait {
};
@@ -208,11 +216,18 @@ namespace OpenAxiom {
return is<Dynamic>(v) ? to_dynamic(v) : nullptr;
}
- inline Value from_dynamic(const Dynamic* o) {
+ template<typename T>
+ using IfDynamic = typename
+ std::enable_if<std::is_base_of<Dynamic, T>::value, Value>::type;
+
+ template<typename T>
+ inline IfDynamic<T> to_value(const T* o) {
return Value(ValueBits(o) | ValueTrait<Dynamic>::tag);
}
- struct Scope;
+ // -- Callable --
+ struct Callable : Dynamic {
+ };
// -------------
// -- Fixnum ---
@@ -351,13 +366,27 @@ namespace OpenAxiom {
const Type* type;
};
+ struct Package;
+
+ enum class SymbolAttribute {
+ None = 0x0, // No particular attribute.
+ Constant = 0x1, // Symbol defined constant.
+ SpecialBinding = 0x2, // Symbol declared special.
+ Keyword = 0x4, // A keyword symbol.
+ SpecialConstant = Constant | SpecialBinding,
+ };
+
// ------------
// -- Symbol --
// ------------
- struct Symbol : Dynamic, std::pair<String, Scope*> {
- Symbol(String, Scope*);
- String name() const { return first; }
- Scope* scope() const { return second; }
+ struct Symbol : Dynamic {
+ const InternedString name;
+ Value value;
+ const Callable* function;
+ Pair properties;
+ Package* package;
+ SymbolAttribute attributes;
+ explicit Symbol(InternedString);
};
inline Symbol* to_symbol_if_can(Value v) {
@@ -368,29 +397,53 @@ namespace OpenAxiom {
return to_symbol_if_can(v) != nullptr;
}
- inline Value from_symbol(const Symbol* s) {
- return from_dynamic(s);
+ struct CmpByName {
+ template<typename T>
+ bool operator()(const T& x, const T& y) const {
+ return std::less<String>()(x.name, y.name);
+ }
+ };
+
+ template<typename T>
+ inline const T* setf_symbol_function(Symbol* sym, const T* fun) {
+ sym->function = fun;
+ return fun;
}
+
+ // -- Environments.
+ struct Environment {
+ struct Binding {
+ Symbol* symbol;
+ Value value;
+ };
- // -----------
- // -- Scope --
- // -----------
- struct Scope : Dynamic, private std::map<Symbol*, Value> {
- explicit Scope(InternedString n) : id(n) { }
- InternedString name() const { return id; }
- Value* lookup(Symbol*) const;
- Value* define(Symbol*, Value);
+ Environment();
+ ~Environment();
+
+ void bind(Symbol*, Value);
private:
- const InternedString id;
+ std::vector<Binding> lexical;
+ std::vector<Binding> dynamic;
+ };
+
+ // -------------
+ // -- Package --
+ // -------------
+ struct Package : Dynamic {
+ const InternedString name;
+ std::set<Symbol, CmpByName> symbols;
+
+ explicit Package(InternedString);
+ Symbol* make_symbol(InternedString);
};
// --------------
// -- Function --
// --------------
- struct FunctionBase : Dynamic {
- const Symbol name;
+ struct FunctionBase : Callable {
+ const Symbol* name;
Value type;
- FunctionBase(Symbol n, Value t = Value::nil)
+ FunctionBase(const Symbol* n, Value t = Value::nil)
: name(n), type(t) { }
};
@@ -407,7 +460,9 @@ namespace OpenAxiom {
template<typename Code>
struct BuiltinFunction : FunctionBase {
Code code;
- BuiltinFunction(Symbol n, Code c) : FunctionBase(n), code(c) { }
+ BuiltinFunction(const Symbol* n, Code c)
+ : FunctionBase(n), code(c)
+ { }
};
using NullaryOperator = BuiltinFunction<NullaryCode>;
@@ -423,20 +478,26 @@ namespace OpenAxiom {
BasicContext();
~BasicContext();
+ Package* make_package(InternedString);
+ Symbol* make_keyword(InternedString);
Pair make_pair(Value, Value);
- const Symbol* make_symbol(String, Scope*);
- const NullaryOperator* make_operator(Symbol, NullaryCode);
- const UnaryOperator* make_operator(Symbol, UnaryCode);
- const BinaryOperator* make_operator(Symbol, BinaryCode);
- const TernaryOperator* make_operator(Symbol, TernaryCode);
+ const NullaryOperator* make_operator(Symbol*, NullaryCode);
+ const UnaryOperator* make_operator(Symbol*, UnaryCode);
+ const BinaryOperator* make_operator(Symbol*, BinaryCode);
+ const TernaryOperator* make_operator(Symbol*, TernaryCode);
+
+ Package* keyword_package() const { return keywords; }
+ Package* homeless_package() const { return homeless; }
protected:
- std::set<Symbol> syms;
+ std::set<Package, CmpByName> packages;
Memory::Factory<ConsCell> conses;
Memory::Factory<NullaryOperator> nullaries;
Memory::Factory<UnaryOperator> unaries;
Memory::Factory<BinaryOperator> binaries;
Memory::Factory<TernaryOperator> ternaries;
+ Package* keywords;
+ Package* homeless;
};
};
}