summaryrefslogtreecommitdiff
path: root/starts/meaning-vm/level-0
diff options
context:
space:
mode:
Diffstat (limited to 'starts/meaning-vm/level-0')
-rw-r--r--starts/meaning-vm/level-0/baseref.hpp4
-rw-r--r--starts/meaning-vm/level-0/concept.cpp1
-rw-r--r--starts/meaning-vm/level-0/memorystore.cpp94
-rw-r--r--starts/meaning-vm/level-0/memorystore.hpp37
-rw-r--r--starts/meaning-vm/level-0/ref.cpp4
5 files changed, 114 insertions, 26 deletions
diff --git a/starts/meaning-vm/level-0/baseref.hpp b/starts/meaning-vm/level-0/baseref.hpp
index fbb7a28..69880c8 100644
--- a/starts/meaning-vm/level-0/baseref.hpp
+++ b/starts/meaning-vm/level-0/baseref.hpp
@@ -57,7 +57,7 @@ public:
template <typename T>
T& vget(ref const & type) const { return p->vget<T>(type.p); }
template <typename T>
- void vset(ref const & type, T const & v) { p->set(type.p, level0::alloc(v)); }
+ void vset(ref const & type, T const & v) { p->set(type.p, level0::alloc(self, v)); }
template <typename T>
T& val() { return p->val<T>(); }
@@ -100,7 +100,7 @@ private:
bool operator!=(mutit const & other) const { return self.it != other.it; }
val & operator*() { return *(val*)&self.it.operator*(); }
- val & operator->() { return *(val*)&self.it.operator->(); }
+ val * operator->() { return (val*)self.it.operator->(); }
private:
It it;
diff --git a/starts/meaning-vm/level-0/concept.cpp b/starts/meaning-vm/level-0/concept.cpp
index 9bb772d..0661edd 100644
--- a/starts/meaning-vm/level-0/concept.cpp
+++ b/starts/meaning-vm/level-0/concept.cpp
@@ -12,6 +12,7 @@ concept* concept::id()
void concept::link(concept* type, concept* target)
{
+ if (type == 0 || target == 0) { throw null_reference(); }
links.insert({type, target});
}
diff --git a/starts/meaning-vm/level-0/memorystore.cpp b/starts/meaning-vm/level-0/memorystore.cpp
index adae8b2..61f8ec0 100644
--- a/starts/meaning-vm/level-0/memorystore.cpp
+++ b/starts/meaning-vm/level-0/memorystore.cpp
@@ -8,21 +8,66 @@
namespace intellect {
namespace level0 {
-static auto & concepts()
+static auto & index()
{
- static std::unordered_set<ref, std::hash<concept*>> concepts;
- return concepts;
+ static std::unordered_set<ref, std::hash<concept*>> index;
+ return index;
}
-ref alloc(std::any data) {
+
+namespace concepts {
+ ref allocator() { static ref ret = new concept(); return ret; };
+ ref allocates() { static ref ret = new concept(); return ret; };
+ ref allocations() { static ref ret = new concept(); return ret; };
+ ref level0allocations() { static ref ret = new concept(); return ret; };
+}
+
+struct init { init()
+{
+ concepts::allocator().link(concepts::allocator(), concepts::level0allocations());
+ concepts::level0allocations().link(concepts::allocates(), concepts::allocator());
+ index().insert(concepts::allocator());
+
+ concepts::allocates().link(concepts::allocator(), concepts::level0allocations());
+ concepts::level0allocations().link(concepts::allocates(), concepts::allocates());
+ index().insert(concepts::allocates());
+
+ concepts::allocations().link(concepts::allocator(), concepts::level0allocations());
+ concepts::level0allocations().link(concepts::allocates(), concepts::allocations());
+ index().insert(concepts::allocations());
+
+ concepts::level0allocations().link(concepts::allocator(), concepts::level0allocations());
+ concepts::level0allocations().link(concepts::allocates(), concepts::level0allocations());
+ index().insert(concepts::level0allocations());
+} } _init;
+
+ref alloc(ref source, std::any data)
+{
concept * r = new concept();
r->data = data;
- concepts().insert(r);
+ alloc((ref)r, source);
+ index().insert(r);
return r;
}
-static concept* referenced(ref r) {
- for (ref r2 : concepts()) {
+void alloc(ref r, ref source)
+{
+ r.link(concepts::allocator(), source);
+ source.link(concepts::allocates(), r);
+}
+
+void realloc(ref r, ref newsource)
+{
+ ref oldsource = r.get(concepts::allocator());
+ alloc(r, newsource);
+ dealloc(r, oldsource);
+}
+
+static concept* referenced(ref r, ref source) {
+ for (ref r2 : index()) {
+ if (r2 == source) {
+ continue;
+ }
if (r2 == r) {
continue;
}
@@ -38,28 +83,33 @@ static concept* referenced(ref r) {
return 0;
}
-void dealloc(ref r) {
- concept * referenced = intellect::level0::referenced(r);
- if (referenced) {
- throw still_referenced_by(r, referenced);
+void dealloc(ref r, ref source) {
+ auto it = index().find(r);
+ if (it == index().end()) { throw no_such_concept(r); }
+
+ source.unlink(concepts::allocates(), r);
+ r.unlink(concepts::allocator(), source);
+ if (r.linked(concepts::allocator())) { return; }
+
+ index().erase(it);
+
+ auto ours = r.getAll(concepts::allocates());
+ for (auto allocation : ours) {
+ dealloc(allocation, r);
}
- for (
- auto it = concepts().begin();
- it != concepts().end();
- ++ it)
- {
- if (*it == r) {
- concepts().erase(it);
- delete (concept*)r;
- return;
+
+ for (auto ghost : ours) {
+ concept * referenced = intellect::level0::referenced(ghost, source);
+ if (referenced) {
+ throw still_referenced_by(ghost, referenced);
}
}
- throw no_such_concept(r);
+ delete (concept*)r;
}
std::size_t allocated()
{
- return concepts().size();
+ return index().size();
}
}
diff --git a/starts/meaning-vm/level-0/memorystore.hpp b/starts/meaning-vm/level-0/memorystore.hpp
index 7843513..eff4235 100644
--- a/starts/meaning-vm/level-0/memorystore.hpp
+++ b/starts/meaning-vm/level-0/memorystore.hpp
@@ -7,8 +7,41 @@
namespace intellect {
namespace level0 {
-ref alloc(std::any data = {});
-void dealloc(ref);
+// self-reference loops are real.
+//
+// one person can feel urgent about issue A, and act on this urgency to engage
+// another person around B, who acts in a different way to someone else, eventually
+// cycling back to stress that stimulates the original person to feel more urgent
+// about issue A.
+// human behavior can make arbitrary positive or negative feedback loops.
+//
+// here in memory allocation, i've designed a system intended to reduce such loops
+// by encouraging my usage to be a certain way, but it still readily provides for
+// them.
+//
+// in process expansion / simple thought, we also have the issue of recursion.
+// if we trust a task to complete, and it ends up triggering itself in a subcontext,
+// we could wait forever.
+//
+// the solution to many of these things is to recognize repetition in systems.
+// we also become skeptical as things continue constantly. we expect to develop
+// some level of understanding that they will shrink, or we stop them and try
+// something else.
+
+namespace concepts {
+
+extern ref allocator(); // link shows what is holding something alive
+extern ref allocates(); // link shows what is being held alive
+
+extern ref allocations(); // to use as a basic allocator for simple things
+extern ref level0allocations(); // allocator for concepts internal to level0
+
+}
+
+ref alloc(ref allocator, std::any data = {}); // new concept
+void alloc(ref allocated, ref allocator); // extra ownership for concept
+void realloc(ref allocated, ref allocator); // move ownership for concept to allocator
+void dealloc(ref allocated, ref allocator); // remove ownership for concept
std::size_t allocated();
}
diff --git a/starts/meaning-vm/level-0/ref.cpp b/starts/meaning-vm/level-0/ref.cpp
index d4758bd..87e911a 100644
--- a/starts/meaning-vm/level-0/ref.cpp
+++ b/starts/meaning-vm/level-0/ref.cpp
@@ -1,10 +1,12 @@
#include "ref.hpp"
#include "concept.hpp"
#include "errors.hpp"
+#include "memorystore.hpp"
#include <ostream>
using namespace intellect::level0;
+using namespace concepts;
std::string ref::dump(ref skipmarkertype, ref skipmarkertarget)
{
@@ -13,10 +15,12 @@ std::string ref::dump(ref skipmarkertype, ref skipmarkertarget)
}
std::string ret = std::to_string((unsigned long)ptr()) + ":\n";
for (auto & link : self.links()) {
+ if (link.first.linked(allocator(), level0allocations())) { continue; }
ret += " " + std::to_string((unsigned long)link.first.ptr()) + ": " + std::to_string((unsigned long)link.second.ptr()) + "\n";
}
self.link(skipmarkertype, skipmarkertarget);
for (auto & link : self.links()) {
+ if (link.first.linked(allocator(), level0allocations())) { continue; }
if (link.first == skipmarkertype && link.second == skipmarkertarget) {
continue;
}