diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/asymptote/access.cc |
Initial commit
Diffstat (limited to 'graphics/asymptote/access.cc')
-rw-r--r-- | graphics/asymptote/access.cc | 163 |
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 |