From 9a14918abec434d8463e07635daef380ad630649 Mon Sep 17 00:00:00 2001 From: olpc user Date: Sun, 24 Nov 2019 13:22:55 -0800 Subject: breaking into levels --- starts/meaning-vm/level-0/common.hpp | 14 +++++ starts/meaning-vm/level-0/concept.cpp | 94 +++++++++++++++++++++++++++++++ starts/meaning-vm/level-0/concept.hpp | 38 +++++++++++++ starts/meaning-vm/level-0/errors.hpp | 77 +++++++++++++++++++++++++ starts/meaning-vm/level-0/level-0.hpp | 9 +++ starts/meaning-vm/level-0/memorystore.cpp | 59 +++++++++++++++++++ starts/meaning-vm/level-0/memorystore.hpp | 13 +++++ starts/meaning-vm/level-0/ref.cpp | 34 +++++++++++ starts/meaning-vm/level-0/ref.hpp | 26 +++++++++ starts/meaning-vm/level-0/value.hpp | 25 ++++++++ starts/meaning-vm/level-0/vref.hpp | 31 ++++++++++ 11 files changed, 420 insertions(+) create mode 100644 starts/meaning-vm/level-0/common.hpp create mode 100644 starts/meaning-vm/level-0/concept.cpp create mode 100644 starts/meaning-vm/level-0/concept.hpp create mode 100644 starts/meaning-vm/level-0/errors.hpp create mode 100644 starts/meaning-vm/level-0/level-0.hpp create mode 100644 starts/meaning-vm/level-0/memorystore.cpp create mode 100644 starts/meaning-vm/level-0/memorystore.hpp create mode 100644 starts/meaning-vm/level-0/ref.cpp create mode 100644 starts/meaning-vm/level-0/ref.hpp create mode 100644 starts/meaning-vm/level-0/value.hpp create mode 100644 starts/meaning-vm/level-0/vref.hpp (limited to 'starts/meaning-vm/level-0') diff --git a/starts/meaning-vm/level-0/common.hpp b/starts/meaning-vm/level-0/common.hpp new file mode 100644 index 0000000..4c36a04 --- /dev/null +++ b/starts/meaning-vm/level-0/common.hpp @@ -0,0 +1,14 @@ +#pragma once + +#define self (*this) + +namespace intellect { +namespace level0 { + +struct concept; +struct ref; +template struct value; +template struct vref; + +} +} diff --git a/starts/meaning-vm/level-0/concept.cpp b/starts/meaning-vm/level-0/concept.cpp new file mode 100644 index 0000000..579cca8 --- /dev/null +++ b/starts/meaning-vm/level-0/concept.cpp @@ -0,0 +1,94 @@ +#include "concept.hpp" +#include "errors.hpp" + +using namespace intellect::level0; + +#define selfref const_cast(&self) + +ref concept::id() +{ + return this; +} + +void concept::link(ref const & type, ref const & target) +{ + links.insert({type.ptr, target.ptr}); +} + +void concept::unlink(ref const & type, ref const & target) +{ + auto ls = links.equal_range(type); + for (auto l = ls.first; l != ls.second; ++ l) { + if (l->second == target) { + links.erase(l); + return; + } + } + throw no_such_link_type_target(selfref, type, target); +} + +void concept::unlink(ref const & type) +{ + auto ls = links.equal_range(type); + if (ls.first == ls.second) { + throw no_such_link_type(selfref, type); + } + auto mid = ls.first; + ++ mid; + if (mid != ls.second) { + throw link_type_not_unique(selfref, type); + } + links.erase(ls.first); +} + +bool concept::linked(ref const & type) const +{ + return links.count(type.ptr) > 0; +} + +bool concept::linked(ref const & type, ref const & target) const +{ + for (ref const & t : getAll(type)) { + if (t == target) { + return true; + } + } + return false; +} + +concept::array concept::getAll(ref const & type) const +{ + array ret; + for ( + auto range = links.equal_range(type); + range.first != range.second; + ++ range.first + ) { + ret.emplace_back(range.first->second); + } + return ret; +} + +ref concept::get(ref const & type) const +{ + auto result = links.equal_range(type.ptr); + if (result.first == result.second) { + throw no_such_link_type(selfref, type); + } + auto test = result.first; + ++ test; + if (test != result.second) { + throw link_type_not_unique(selfref, type); + } + return result.first->second; +} + +void concept::set(ref const & type, ref const & target) +{ + if (linked(type)) { + throw link_type_not_unique(selfref, type); + } + link(type, target); +} + + diff --git a/starts/meaning-vm/level-0/concept.hpp b/starts/meaning-vm/level-0/concept.hpp new file mode 100644 index 0000000..dc3221b --- /dev/null +++ b/starts/meaning-vm/level-0/concept.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include "common.hpp" +#include "ref.hpp" + +#include +#include + +namespace intellect { +namespace level0 { + +struct concept +{ + // a concept is made of concept-typed links to other concepts + std::multimap links; + using array = std::vector; + + ref id(); + + void link(ref const & type, ref const & target); + void unlink(ref const & type, ref const & target); + void unlink(ref const & type); + + bool linked(ref const & type) const; + bool linked(ref const & type, ref const & target) const; + + array getAll(ref const & type) const; + + // get and set enforce that only 1 link of a given type is present + ref get(ref const & type) const; + void set(ref const & type, ref const & target); + + template + vref vget(ref const & type) const { return get(type); } +}; + +} +} diff --git a/starts/meaning-vm/level-0/errors.hpp b/starts/meaning-vm/level-0/errors.hpp new file mode 100644 index 0000000..c052c69 --- /dev/null +++ b/starts/meaning-vm/level-0/errors.hpp @@ -0,0 +1,77 @@ +#pragma once +#include "ref.hpp" + +#include + +namespace intellect { +namespace level0 { + +struct no_such_link_type : public std::out_of_range +{ + no_such_link_type(ref source, ref type) + : std::out_of_range("no such concept link type"), + source(source), + type(type) + { } + + ref const source; + ref const type; +}; + +struct no_such_link_type_target : public std::out_of_range +{ + no_such_link_type_target(ref source, ref type, ref target) + : std::out_of_range("no such concept link type and target"), + source(source), + type(type), + target(type) + { } + + ref const source; + ref const type; + ref const target; +}; + +struct link_type_not_unique : public std::invalid_argument +{ + link_type_not_unique(ref source, ref type) + : std::invalid_argument("more than one such concept link type"), + source(source), + type(type) + { } + + ref const source; + ref const type; +}; + +struct still_referenced_by : public std::invalid_argument +{ + still_referenced_by(ref topic, ref referrer) + : std::invalid_argument("concept is still referenced"), + topic(topic), + referrer(referrer) + { } + + ref const topic; + ref const referrer; +}; + +struct no_such_concept : public std::invalid_argument +{ + no_such_concept(ref topic) + : std::invalid_argument("no such concept reference"), + topic(topic) + { } + + ref const topic; +}; + +struct null_reference : public std::invalid_argument +{ + null_reference() + : std::invalid_argument("null reference") + { } +}; + +} +} diff --git a/starts/meaning-vm/level-0/level-0.hpp b/starts/meaning-vm/level-0/level-0.hpp new file mode 100644 index 0000000..b44b6e0 --- /dev/null +++ b/starts/meaning-vm/level-0/level-0.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "common.hpp" +#include "concept.hpp" +#include "errors.hpp" +#include "memorystore.hpp" +#include "ref.hpp" +#include "value.hpp" +#include "vref.hpp" diff --git a/starts/meaning-vm/level-0/memorystore.cpp b/starts/meaning-vm/level-0/memorystore.cpp new file mode 100644 index 0000000..6cf71df --- /dev/null +++ b/starts/meaning-vm/level-0/memorystore.cpp @@ -0,0 +1,59 @@ +#include "memorystore.hpp" +#include "concept.hpp" +#include "errors.hpp" + +#include + +namespace intellect { +namespace level0 { + +static auto & concepts() +{ + static std::unordered_set> concepts; + return concepts; +} + +ref alloc(concept * moved) { + ref r = moved ? moved : new concept(); + concepts().insert(r); + return r; +} + +static concept* referenced(ref r) { + for (ref r2 : concepts()) { + if (r2 == r) { + continue; + } + for (auto & l : r2->links) { + if (ref(l.first) == r) { + return r2.ptr; + } + if (ref(l.second) == r) { + return r2.ptr; + } + } + } + return 0; +} + +void dealloc(ref r) { + concept * referenced = intellect::level0::referenced(r); + if (referenced) { + throw still_referenced_by(r, referenced); + } + for ( + auto it = concepts().begin(); + it != concepts().end(); + ++ it) + { + if (ref(*it) == r) { + concepts().erase(it); + delete r.ptr; + return; + } + } + throw no_such_concept(r); +} + +} +} diff --git a/starts/meaning-vm/level-0/memorystore.hpp b/starts/meaning-vm/level-0/memorystore.hpp new file mode 100644 index 0000000..4e0a2bd --- /dev/null +++ b/starts/meaning-vm/level-0/memorystore.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "common.hpp" +#include "ref.hpp" + +namespace intellect { +namespace level0 { + +ref alloc(concept * moved = 0); +void dealloc(ref); + +} +} diff --git a/starts/meaning-vm/level-0/ref.cpp b/starts/meaning-vm/level-0/ref.cpp new file mode 100644 index 0000000..7e10528 --- /dev/null +++ b/starts/meaning-vm/level-0/ref.cpp @@ -0,0 +1,34 @@ +#include "ref.hpp" +#include "concept.hpp" +#include "errors.hpp" + +#include + +using namespace intellect::level0; + +ref::ref(concept *p) +: ptr(p) +{ + if (p == 0) { + throw null_reference(); + } +} + +std::string ref::dump(ref skipmarkertype, ref skipmarkertarget) const +{ + if (self->linked(skipmarkertype, skipmarkertarget)) { + return {}; + } + std::string ret = std::to_string((unsigned long)ptr) + ":\n"; + for (auto & link : self->links) { + 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 == skipmarkertype && link.second == skipmarkertype) { + continue; + } + ret += link.second.dump(skipmarkertype, skipmarkertarget); + } + return ret; +} diff --git a/starts/meaning-vm/level-0/ref.hpp b/starts/meaning-vm/level-0/ref.hpp new file mode 100644 index 0000000..951676b --- /dev/null +++ b/starts/meaning-vm/level-0/ref.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include "common.hpp" + +#include + +namespace intellect { +namespace level0 { + +struct ref +{ + ref(concept *p); + operator concept*() const { return ptr; } + concept* operator->() const { return ptr; } + bool operator==(ref const & other) const { return self.ptr == other.ptr; } + bool operator!=(ref const & other) const { return self.ptr != other.ptr; } + bool operator<(ref const & other) const { return self.ptr < other.ptr; } + concept & deref() { return *ptr; } + + std::string dump(ref skipmarkertype, ref skipmarkertarget) const; + + concept * const ptr; +}; + +} +} diff --git a/starts/meaning-vm/level-0/value.hpp b/starts/meaning-vm/level-0/value.hpp new file mode 100644 index 0000000..ff704bf --- /dev/null +++ b/starts/meaning-vm/level-0/value.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include "common.hpp" + +#include "concept.hpp" + +namespace intellect { +namespace level0 { + +template +struct value : public concept +{ + value(T const & val) : data(val) { } + + value(value const & val) = default; + + operator T&() { return data; } + operator T const &() const { return data; } + + T data; +}; + + +} +} diff --git a/starts/meaning-vm/level-0/vref.hpp b/starts/meaning-vm/level-0/vref.hpp new file mode 100644 index 0000000..7fe2045 --- /dev/null +++ b/starts/meaning-vm/level-0/vref.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "common.hpp" +#include "memorystore.hpp" +#include "ref.hpp" +#include "value.hpp" + +namespace intellect { +namespace level0 { + +template +struct vref +{ + vref(value *p) : ptr(p) { } + value* operator->() { return ptr; } + operator T const &() const { return *ptr; } + + vref(T const & val) : ptr(alloc(new value(val))) { } + + vref(ref const & other) : ptr(static_cast*>(other.ptr)) { } + operator ref() { return ptr; } + + // for use by containers + bool operator<(vref const & other) const { return self.ptr < other.ptr; } + + value * const ptr; +}; + + +} +} -- cgit v1.2.3