summaryrefslogtreecommitdiff
path: root/graphics/asymptote/access.cc
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/asymptote/access.cc
Initial commit
Diffstat (limited to 'graphics/asymptote/access.cc')
-rw-r--r--graphics/asymptote/access.cc163
1 files changed, 163 insertions, 0 deletions
diff --git a/graphics/asymptote/access.cc b/graphics/asymptote/access.cc
new file mode 100644
index 0000000000..f71dba71bf
--- /dev/null
+++ b/graphics/asymptote/access.cc
@@ -0,0 +1,163 @@
+/*****
+ * access.cc
+ * Andy Hammerlindl 2003/12/03
+ * Describes an "access," a representation of where a variable will be
+ * stored at runtime, so that read, write, and call instructions can be
+ * made.
+ *****/
+
+#include "access.h"
+#include "frame.h"
+#include "coder.h"
+#include "callable.h"
+
+using vm::item;
+
+namespace trans {
+
+/* access */
+access::~access()
+{}
+
+/* identAccess */
+void identAccess::encode(action act, position pos, coder& e)
+{
+ if (act != CALL) {
+ access::encode(act, pos, e);
+ }
+ // else - do nothing
+}
+
+
+/* bltinAccess */
+static void bltinError(position pos)
+{
+ em.error(pos);
+ em << "built-in functions cannot be modified";
+}
+
+void bltinAccess::encode(action act, position pos, coder &e)
+{
+ switch (act) {
+ case READ:
+ e.encode(inst::constpush,(item)(vm::callable*)new vm::bfunc(f));
+ break;
+ case WRITE:
+ bltinError(pos);
+ break;
+ case CALL:
+ e.encode(inst::builtin, f);
+ break;
+ }
+}
+
+void bltinAccess::encode(action act, position pos, coder &e, frame *)
+{
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+/* callableAccess */
+void callableAccess::encode(action act, position pos, coder &e)
+{
+ switch (act) {
+ case READ:
+ e.encode(inst::constpush, (item)f);
+ break;
+ case WRITE:
+ bltinError(pos);
+ break;
+ case CALL:
+ this->encode(READ, pos, e);
+ e.encode(inst::popcall);
+ break;
+ }
+}
+
+void callableAccess::encode(action act, position pos, coder &e, frame *)
+{
+ e.encode(inst::pop);
+ encode(act, pos, e);
+}
+
+
+/* frameAccess */
+void frameAccess::encode(action act, position pos, coder &e)
+{
+ if (act == READ) {
+ if (!e.encode(f)) {
+ em.compiler(pos);
+ em << "encoding frame out of context";
+ }
+ }
+ else
+ access::encode(act, pos, e);
+}
+
+void frameAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ if (act == READ) {
+ if (!e.encode(f, top)) {
+ em.compiler(pos);
+ em << "encoding frame out of context";
+ }
+ }
+ else
+ access::encode(act, pos, e, top);
+}
+
+/* localAccess */
+static void frameError(position pos) {
+ // A local variable is being used when its frame is not active.
+ em.error(pos);
+ em << "static use of dynamic variable";
+}
+
+void localAccess::encode(action act, position pos, coder &e)
+{
+ // Get the active frame of the virtual machine.
+ frame *active = e.getFrame();
+ if (level == active) {
+ e.encode(act == WRITE ? inst::varsave : inst::varpush,
+ offset);
+ }
+ else if (e.encode(level)) {
+ e.encode(act == WRITE ? inst::fieldsave : inst::fieldpush,
+ offset);
+ }
+ else {
+ frameError(pos);
+ }
+
+ if (act == CALL)
+ e.encode(inst::popcall);
+}
+
+void localAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ if (e.encode(level,top)) {
+ e.encode(act == WRITE ? inst::fieldsave : inst::fieldpush,
+ offset);
+ if (act == CALL)
+ e.encode(inst::popcall);
+ }
+ else {
+ frameError(pos);
+ }
+}
+
+
+void qualifiedAccess::encode(action act, position pos, coder &e)
+{
+ qualifier->encode(READ, pos, e);
+ field->encode(act, pos, e, qualifierLevel);
+}
+
+void qualifiedAccess::encode(action act, position pos, coder &e, frame *top)
+{
+ qualifier->encode(READ, pos, e, top);
+ field->encode(act, pos, e, qualifierLevel);
+}
+
+
+} // namespace trans