summaryrefslogtreecommitdiff
path: root/intellect-framework-from-internet/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp
diff options
context:
space:
mode:
authorolpc user <olpc@xo-5d-f7-86.localdomain>2020-01-10 14:56:27 -0800
committerolpc user <olpc@xo-5d-f7-86.localdomain>2020-01-10 14:56:27 -0800
commit26c980d302adce8e3d802cb8db8ab1c69d58ce1a (patch)
treee296225f17370c9e472660396b3a51539f76ff28 /intellect-framework-from-internet/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp
parent2e01fed206e46a669ba56f57b4b943cfe661a0f1 (diff)
parentc8bb547bea279af2bb48c13260f98aa8add07131 (diff)
downloadstandingwithresilience-26c980d302adce8e3d802cb8db8ab1c69d58ce1a.tar.gz
standingwithresilience-26c980d302adce8e3d802cb8db8ab1c69d58ce1a.zip
Merge branch 'intellect-framework-from-internet'
Diffstat (limited to 'intellect-framework-from-internet/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp')
-rw-r--r--intellect-framework-from-internet/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/intellect-framework-from-internet/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp b/intellect-framework-from-internet/starts/meaning-vm/level-2-wip-stmtexprs/statementref.cpp
new file mode 100644
index 0000000..2f23dc8
--- /dev/null
+++ b/intellect-framework-from-internet/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;
+}