summaryrefslogtreecommitdiff
path: root/starts/meaning-vm
diff options
context:
space:
mode:
Diffstat (limited to 'starts/meaning-vm')
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/baseref.hpp23
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/common.hpp9
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/concepts.hpp26
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/funcs.cpp69
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/funcs.hpp14
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/meaning.hpp42
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/ref.hpp (renamed from starts/meaning-vm/level-2/ref.hpp)0
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp68
-rw-r--r--starts/meaning-vm/level-2-wip-stmtexprs/statementref.hpp31
-rw-r--r--starts/meaning-vm/level-2/common.hpp0
10 files changed, 282 insertions, 0 deletions
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/baseref.hpp b/starts/meaning-vm/level-2-wip-stmtexprs/baseref.hpp
new file mode 100644
index 0000000..84c9c13
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/baseref.hpp
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "common.hpp"
+#include "../level-1/ref.hpp"
+#include "statementref.hpp"
+
+namespace intellect {
+namespace level2 {
+
+template <typename ref>
+struct baseref : public level1::baseref<ref>
+{
+ using level1::baseref<ref>::baseref;
+ baseref(level1::ref other) : level1::baseref<ref>(other.ptr()) { }
+ operator level1::ref() { return ptr(); }
+
+ statementref operator=(ref other) { return assignop(self, other); }
+ statementref operator,(ref other) { return commaop(self, other); }
+ ref operator[](ref other) { return subop(self, other); }
+}
+
+}
+}
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/common.hpp b/starts/meaning-vm/level-2-wip-stmtexprs/common.hpp
new file mode 100644
index 0000000..25c8026
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/common.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+namespace intellect {
+namespace level2 {
+
+struct ref;
+
+}
+}
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/concepts.hpp b/starts/meaning-vm/level-2-wip-stmtexprs/concepts.hpp
new file mode 100644
index 0000000..20c5ad4
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/concepts.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "../level-1/concepts.hpp"
+
+namespace intellect {
+namespace level2 {
+
+namespace concepts {
+
+using namespace level1::concepts;
+
+static decl(variable),
+ decl(expression),
+ decl(assign),
+ decl(comma),
+ decl(subscript),
+ decl(action),
+ decl(statement),
+ decl(left),
+ decl(right),
+ decl(operand);
+
+}
+
+}
+}
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/funcs.cpp b/starts/meaning-vm/level-2-wip-stmtexprs/funcs.cpp
new file mode 100644
index 0000000..d746f13
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/funcs.cpp
@@ -0,0 +1,69 @@
+#include "funcs.hpp"
+
+using namespace intellect;
+using namespace level2;
+using namespace concepts;
+
+static ref refassigned(ref expr)
+{
+ ref lhs = ref.get(left-operand);
+ ref rhs = ref.get(right-operand);
+ if (lhs.isa(link) && lhs.get(link-target) == unknown) {
+ // completes the target of a link, for a[b] = c
+ lhs.unlink(link-target, unknown);
+ lhs.set(link-target, rhs);
+ ref.unlink(right-operand, rhs);
+ ref src = lhs.get(link-source);
+ if (lhs.get(link-type) != unknown && src != unknown) {
+ src.set(lhs.get(link-type), rhs);
+ return src;
+ } else {
+ throw std::logic_error("not sure what to do with incomplete link assignment");
+ }
+ } else if (isanonymous(rhs) && !isanonymous(lhs)) {
+ // assignment of anonymous content to empty named concept
+ ref.unlink(left-operand, lhs);
+ return level1::movetoname(rhs, lhs);
+ } else {
+ throw std::logic_error("unexpected bare assignment");
+ }
+}
+// maybe later we can have ref class itself do operators completely based on its own
+// ref content.
+
+statementref assignop(ref self, ref other)
+{
+ return statementref::makebinary(
+ self, concepts::assign, other,
+ refassigned, refassigned
+ );
+}
+statementref commaop(ref self, ref other)
+{
+ if (self.isa(comma-expression)) {
+ if (other.isa(comma-expression)) {
+ for (auto & l : other.links()) { self.insert(l.first, l.second); }
+ dealloc(other);
+ } else {
+ self.link(topic, other);
+ }
+ return self;
+ } else if (other.isa(comma-expression)) {
+ other.link(topic, self);
+ return other;
+ } else {
+ return statementcallref::makebinary(
+ self, comma, other,
+ [](ref)->ref { return ref; },
+ // um when we pass the comma-expression to
+ // the [] operator that takes a ref
+ // the destructor of statementref will deallocate it.
+ [](ref) { throw std::logic_error("bare comma-expression"); }
+ // something is wrong here. some approach is wrong.
+ // would it be better to have ref itself do it all?
+ );
+ }
+}
+ref subop(ref self, ref other)
+{
+}
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/funcs.hpp b/starts/meaning-vm/level-2-wip-stmtexprs/funcs.hpp
new file mode 100644
index 0000000..6af6ce1
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/funcs.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "common.hpp"
+#include "../level-1/ref.hpp"
+
+namespace intellect {
+namespace level2 {
+
+statementref commaop(ref self, ref other);
+statementref assignop(ref self, ref other);
+ref subop(ref self, ref other);
+
+}
+}
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/meaning.hpp b/starts/meaning-vm/level-2-wip-stmtexprs/meaning.hpp
new file mode 100644
index 0000000..049e7f9
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/meaning.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "ref.hpp"
+#include "../level-1/helpers.hpp"
+
+namespace intellect {
+namespace level2 {
+
+// get a named variable
+ref avariable(ref name);
+
+template <typename... T>
+ref and(T... refs)
+{
+ std::initializer_list<ref> rs = { refs... };
+ decl(and, topic);
+ ref ret = a(and);
+ ref name; int count = 0;
+ for (auto r : rs) {
+ ret.link(topic, r);
+ if (count == 0) {
+ name.ptr() = r.ptr();
+ } else {
+ name.ptr() = (name-and-r).ptr();
+ }
+ ++ count;
+ }
+ if (count == 1) {
+ throw std::invalid_argument("and needs at least two subjects");
+ }
+ // in level-1, we'll want to name anonymous objects after defining them
+ return name = ret;
+}
+
+// make a reference to a link
+ref link(ref sourceref, ref typeref, ref targetref);
+
+// invert a meaning
+ref not(ref whatref);
+
+}
+}
diff --git a/starts/meaning-vm/level-2/ref.hpp b/starts/meaning-vm/level-2-wip-stmtexprs/ref.hpp
index 5b7dc4f..5b7dc4f 100644
--- a/starts/meaning-vm/level-2/ref.hpp
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/ref.hpp
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp b/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp
new file mode 100644
index 0000000..2f23dc8
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp
@@ -0,0 +1,68 @@
+#include "statementref.hpp"
+
+#include "concepts.hpp"
+#include "ref.hpp"
+
+using namespace intellect;
+using namespace level2;
+using namespace concepts;
+
+// so, anonymous-assignment is both a statement and an expression.
+// multiple-member-assignment is only an expression: it is an error to evaluate it
+// the submember operator will be both a statement and an expression, but doesn't need to be held as a ref
+// single-member-assignment is mostly a statement: using it as an expression should be an error.
+
+static statementref makebinary(
+ ref lhs, ref kind, ref rhs,
+ std::function<ref(ref)> expraction,
+ std::function<void(ref)> stmtaction
+)
+{
+ a(statement-expresion, kind-expression);
+ ref r = a(kind-expression);
+ r.set(left-operand, lhs);
+ r.set(right-operand, rhs);
+ r.vset(expression-action, expraction);
+ r.vset(statement-action, stmtaction);
+ return r;
+}
+
+statementref::statementref(ref r)
+: r(r.ptr())
+{
+ if (!r.isa(statement-expression)) {
+ throw std::logic_error("that is not a statement expression");
+ }
+}
+
+static void de(ref & r)
+{
+ ref lhs, rhs, expraction, stmtaction;
+
+ try { lhs = r.get(left-operand); } catch(level0::no_such_link_type&) {}
+ try { rhs = r.get(right-operand); } catch(level0::no_such_link_type&) {}
+
+ expraction = r.get(expression-action);
+ stmtaction = r.get(statement-action);
+ dealloc(r);
+ if (lhs != nothing) { dealloc(lhs); }
+ if (rhs != nothing) { dealloc(rhs); }
+ dealloc(expraction);
+ dealloc(stmtaction);
+ r = 0;
+}
+
+statementref::~statementref()
+{
+ if (r == 0) { return; }
+ r.vget<std::function<void(ref)>>(statement-action)(r);
+ de(r);
+}
+
+statementref::operator ref()
+{
+ if (r == 0) { throw std::logic_error("doubly evaluated expression"); }
+ auto ret = r.vget<std::function<void(ref)>>(expression-action)(r);
+ de(r);
+ return ret;
+}
diff --git a/starts/meaning-vm/level-2-wip-stmtexprs/statementref.hpp b/starts/meaning-vm/level-2-wip-stmtexprs/statementref.hpp
new file mode 100644
index 0000000..502ecf4
--- /dev/null
+++ b/starts/meaning-vm/level-2-wip-stmtexprs/statementref.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "common.hpp"
+#include "../level-0/concept.hpp"
+
+namespace intellect {
+namespace level2 {
+
+// this class is returned by some of the baseref operators.
+// its purpose is to evaluate code when it goes out of
+// scope, so as to facilitate syntactic behavior.
+struct statementref
+{
+ statementref(ref r);
+ statementref(statementref const &) = delete;
+ ~statementref();
+
+ operator ref();
+
+ static statementref makebinary(
+ ref lhs, ref kind, ref rhs,
+ std::function<ref(ref)> expraction = {},
+ std::function<void(ref)> stmtaction = {}
+ );
+
+private:
+ level0::concept * r;
+};
+
+}
+}
diff --git a/starts/meaning-vm/level-2/common.hpp b/starts/meaning-vm/level-2/common.hpp
deleted file mode 100644
index e69de29..0000000
--- a/starts/meaning-vm/level-2/common.hpp
+++ /dev/null