summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--starts/meaning-vm/level-0/level-0.hpp1
-rw-r--r--starts/meaning-vm/level-0/ref-mixin.hpp33
-rw-r--r--starts/meaning-vm/level-0/ref.hpp3
-rw-r--r--starts/meaning-vm/level0.cpp18
4 files changed, 45 insertions, 10 deletions
diff --git a/starts/meaning-vm/level-0/level-0.hpp b/starts/meaning-vm/level-0/level-0.hpp
index b44b6e0..10df5b7 100644
--- a/starts/meaning-vm/level-0/level-0.hpp
+++ b/starts/meaning-vm/level-0/level-0.hpp
@@ -5,5 +5,6 @@
#include "errors.hpp"
#include "memorystore.hpp"
#include "ref.hpp"
+#include "ref-mixin.hpp"
#include "value.hpp"
#include "vref.hpp"
diff --git a/starts/meaning-vm/level-0/ref-mixin.hpp b/starts/meaning-vm/level-0/ref-mixin.hpp
new file mode 100644
index 0000000..ba5fe09
--- /dev/null
+++ b/starts/meaning-vm/level-0/ref-mixin.hpp
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <vector>
+
+namespace intellect {
+namespace level0 {
+
+template <typename ref, template<typename> typename vref>
+struct refmixin {
+ using array = std::vector<ref>;
+
+ void link(ref const & type, ref const & target) { ptr()->link(type, target); }
+ void unlink(ref const & type, ref const & target) { ptr()->unlink(type, target); }
+ void unlink(ref const & type) { ptr()->unlink(type); }
+
+ bool linked(ref const & type) const { return ptr()->linked(type); }
+ bool linked(ref const & type, ref const & target) const { return ptr()->linked(type, target); }
+
+ array getAll(ref const & type) const { return conv<array>(ptr()->getAll(type)); }
+
+ ref get(ref const & type) const { return conv<ref>(ptr()->get(type)); }
+ void set(ref const & type, ref const & target) { ptr()->set(type, target); }
+
+ template <typename T>
+ vref<T> vget(ref const & type) const { return conv<vref<T>>(get(type)); }
+
+private:
+ inline concept * ptr() const { return conv<ref*>(this)->ptr; }
+ template <typename OUT, typename IN>
+ static inline OUT conv(IN r) { return *(OUT*)&r; }
+};
+}
+}
diff --git a/starts/meaning-vm/level-0/ref.hpp b/starts/meaning-vm/level-0/ref.hpp
index 951676b..c1fa7fa 100644
--- a/starts/meaning-vm/level-0/ref.hpp
+++ b/starts/meaning-vm/level-0/ref.hpp
@@ -1,13 +1,14 @@
#pragma once
#include "common.hpp"
+#include "ref-mixin.hpp"
#include <string>
namespace intellect {
namespace level0 {
-struct ref
+struct ref : public refmixin<ref, vref>
{
ref(concept *p);
operator concept*() const { return ptr; }
diff --git a/starts/meaning-vm/level0.cpp b/starts/meaning-vm/level0.cpp
index 8cb60f9..a69da91 100644
--- a/starts/meaning-vm/level0.cpp
+++ b/starts/meaning-vm/level0.cpp
@@ -21,22 +21,22 @@ int main()
ref skip = alloc();
- a->link(b, c);
- a->link(d, e);
- e->link(b, a);
- c->link(b, e);
- a->link(numlink, num);
- a->link(codelink, code);
+ a.set(b, c);
+ a.link(d, e);
+ e.link(b, a);
+ c.link(b, e);
+ a.link(numlink, num);
+ a.link(codelink, code);
std::cout << "Num: " << ref(num).dump(skip, skip);
std::cout << "Code: " << ref(code).dump(skip, skip);
std::cout << a.dump(skip, skip);
- std::cout << "Num: " << a->vget<int>(numlink).val() << std::endl;
- std::cout << "Code: "; a->vget<std::function<void()>>(codelink).val()();
+ std::cout << "Num: " << a.vget<int>(numlink).val() << std::endl;
+ std::cout << "Code: "; a.vget<std::function<void()>>(codelink).val()();
std::cout << allocated() << " allocated" << std::endl;
- e->unlink(b, a);
+ e.unlink(b, a);
dealloc(a);
dealloc(c);
dealloc(e);