|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--org.erights.e.elang.smallcaps.SmallcapsEncoderVisitor
Field Summary | |
private SmallcapsEmitter |
myEmitter
|
private String |
myKind
One of "FOR_VALUE", "FOR_CONTROL", or "FOR_FX_ONLY", as an interned string (so we can test using Java's "=="). |
private SmallcapsVisitorTable |
myVisitors
Corresponding visitors of all different kinds. |
Fields inherited from interface org.erights.e.elang.smallcaps.SmallcapsOps |
ADDR_FRAME, ADDR_FRAME_SLOT, ADDR_LITERAL, ADDR_LOCAL, ADDR_LOCAL_SLOT, ADDR_OUTER_SLOT, OP_ASSIGN, OP_BIND, OP_BIND_SLOT, OP_BRANCH, OP_CALL, OP_CALL_ONLY, OP_CDR_PATT, OP_CHAR, OP_DUP, OP_EJECTOR, OP_EJECTOR_ONLY, OP_END_HANDLER, OP_FALSE, OP_FLOAT64, OP_JUMP, OP_LIST_PATT, OP_NEG_INT, OP_NOUN, OP_NULL, OP_OBJECT, OP_POP, OP_RETURN, OP_ROT, OP_SCOPE, OP_SEND, OP_SEND_ONLY, OP_SLOT, OP_STRING, OP_SWAP, OP_TRUE, OP_TRY, OP_TWINE, OP_UNWIND, OP_WHOLE_NUM |
Constructor Summary | |
(package private) |
SmallcapsEncoderVisitor(SmallcapsEmitter emitter,
String kind,
SmallcapsVisitorTable visitors)
|
Method Summary | |
private void |
branchify()
|
(package private) void |
run(ENode eNode)
|
(package private) void |
run(ENode[] eNodes)
|
Object |
visitAssignExpr(ENode optOriginal,
AtomicExpr lValue,
EExpr rValue)
Sets a variable's value to the value of an rValue expression. |
Object |
visitCallExpr(ENode optOriginal,
EExpr recip,
String verb,
EExpr[] args)
A call expression evaluates the recipient and arguments left to right forValue, then pops all these to perform an immediate call. |
Object |
visitCatchExpr(ENode optOriginal,
EExpr attempt,
Pattern patt,
EExpr catcher)
A try/catch expression. |
Object |
visitCdrPattern(ENode optOriginal,
ListPattern subs,
Pattern rest)
PATT_CDR(numSubs :WholeNum) subs... |
Object |
visitDefineExpr(ENode optOriginal,
Pattern patt,
EExpr rValue)
Evaluates rValue, matches it against patt, and evaluates to the value of rValue. |
Object |
visitEMethod(ENode optOriginal,
String docComment,
String verb,
Pattern[] patterns,
EExpr returnGuard,
EExpr body)
Enabled: "##" docComment "to" verb "(" patterns*, ")" ":" returnGuard "{" body "}". |
Object |
visitEscapeExpr(ENode optOriginal,
Pattern hatchPatt,
EExpr body)
Reify a dynamic extent continuation, sort-of. |
Object |
visitEScript(ENode optOriginal,
EMethodNode[] optMethods,
Matcher optMatcher)
Enabled: "{" methods* matcher? "}"? XXX currently, when a matcher should have been provided to visitObjectExpr, instead an eScript is provided whose optMethods is null. |
Object |
visitFinallyExpr(ENode optOriginal,
EExpr attempt,
EExpr unwinder)
A try/finally expression |
Object |
visitFinalPattern(ENode optOriginal,
String varName,
EExpr valueGuardExpr)
Define final variable whose value is the coercion of the specimen. |
Object |
visitHideExpr(ENode optOriginal,
EExpr body)
Post-transformation, hide has no runtime effect beyond the evaluation of its body, so just generate the body. |
Object |
visitIfExpr(ENode optOriginal,
EExpr test,
EExpr then,
EExpr els)
Evaluates test to a boolean, and then evaluates to the outcome of either then or els, depending. |
Object |
visitIgnorePattern(ENode optOriginal)
Always succeeds, matches specimen, binds nothing. |
Object |
visitListPattern(ENode optOriginal,
Pattern[] subs)
PATT_LIST(numSubs :WholeNum) subs... |
Object |
visitLiteralExpr(ENode optOriginal,
Object value)
A literal expression. |
Object |
visitMatchBindExpr(ENode optOriginal,
EExpr specimen,
Pattern patt)
Matches specimen to pattern and evaluates to a boolean indicating whether it succeeded. |
Object |
visitMatcher(ENode optOriginal,
Pattern pattern,
EExpr body)
Enabled: "match" pattern "{" body "}". |
Object |
visitNounExpr(ENode optOriginal,
String varName)
Accesses the value of a variable. |
Object |
visitObjectExpr(ENode optOriginal,
String docComment,
String optFQN,
EExpr[] auditors,
EScript eScript)
OP_OBJECT(fqn :UTF8, numAuditors :WholeNum, auditors, eScript) |
Object |
visitQuasiLiteralExpr(ENode optOriginal,
int index)
Not Applicable |
Object |
visitQuasiLiteralPatt(ENode optOriginal,
int index)
Not Applicable |
Object |
visitQuasiPatternExpr(ENode optOriginal,
int index)
Not Applicable |
Object |
visitQuasiPatternPatt(ENode optOriginal,
int index)
Not Applicable |
Object |
visitScopeExpr(ENode optOriginal)
Reifies the current scope. |
Object |
visitSendExpr(ENode optOriginal,
EExpr recip,
String verb,
EExpr[] args)
A send expression evaluates the recipient and arguments left to right forValue, then pops all these to perform an eventual send. |
Object |
visitSeqExpr(ENode optOriginal,
EExpr[] subs)
All subexpressions but the last are generated forFxOnly. |
Object |
visitSlotExpr(ENode optOriginal,
AtomicExpr noun)
Obtain the slot holding the value of a variable. |
Object |
visitSuchThatPattern(ENode optOriginal,
Pattern patt,
EExpr test)
PATT_SUCH_THAT patt test PATT_END_SUCH_THAT |
Object |
visitVarPattern(ENode optOriginal,
String varName,
EExpr slotGuardExpr)
Define mutable variable whose slot is slotGuard.makeSlot(specimen, optEjector). |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
private final SmallcapsEmitter myEmitter
private final String myKind
private final SmallcapsVisitorTable myVisitors
Constructor Detail |
SmallcapsEncoderVisitor(SmallcapsEmitter emitter, String kind, SmallcapsVisitorTable visitors)
Method Detail |
void run(ENode eNode)
void run(ENode[] eNodes)
public Object visitHideExpr(ENode optOriginal, EExpr body)
all: this(body)
visitHideExpr
in interface ETreeVisitor
public Object visitSeqExpr(ENode optOriginal, EExpr[] subs)
all: forFxOnly(subs[0]) ... forFxOnly(subs[n-2]) this(subs[n-1])
visitSeqExpr
in interface ETreeVisitor
private void branchify()
public Object visitCallExpr(ENode optOriginal, EExpr recip, String verb, EExpr[] args)
forFxOnly: forValue(recip) forValue(args[0]) ... forValue(args[n-1]) OP_CALL_ONLY(verb :UTF8, arity :WholeNum)If
SmallcapsOps.OP_CALL_ONLY
exits successfully, then the value returned by
the call is ignored and [] (nothing) is pushed.
forValue: forValue(recip) forValue(args[0]) ... forValue(args[n-1]) OP_CALL(verb :UTF8, arity :WholeNum)If
SmallcapsOps.OP_CALL
exits successfully, then [result] (the value
returned by the call) is pushed.
forValue: forValue(recip) forValue(args[0]) ... forValue(args[n-1]) OP_CALL(verb :UTF8, arity :WholeNum) OP_BRANCH
SmallcapsOps.OP_BRANCH
converts a boolean result into a conditional branch.
visitCallExpr
in interface ETreeVisitor
public Object visitSendExpr(ENode optOriginal, EExpr recip, String verb, EExpr[] args)
forFxOnly: forValue(recip) forValue(args[0]) ... forValue(args[n-1]) OP_SEND_ONLY(verb :UTF8, arity :WholeNum)If
SmallcapsOps.OP_SEND_ONLY
exits successfully, then the value returned by
the send is ignored and [] (nothing) is pushed.
forValue: forValue(recip) forValue(args[0]) ... forValue(args[n-1]) OP_SEND(verb :UTF8, arity :WholeNum)If
SmallcapsOps.OP_SEND
exits successfully, then [result] (the value
returned by the send) is pushed.
forValue: forValue(recip) forValue(args[0]) ... forValue(args[n-1]) OP_SEND(verb :UTF8, arity :WholeNum) OP_BRANCH
SmallcapsOps.OP_BRANCH
converts a boolean result into a conditional branch.
visitSendExpr
in interface ETreeVisitor
public Object visitDefineExpr(ENode optOriginal, Pattern patt, EExpr rValue)
forFxOnly: forValue(rValue) forFxOnly(patt)The value pushed by rValue is popped by patt, which either continues executing or reports a problem.
forValue: forValue(rValue) OP_DUP forFxOnly(patt)
SmallcapsOps.OP_DUP
duplicates the top of stack, so that rValue's value is
left pushed if patt exits normally.
forControl: forValue(rValue) OP_DUP forFxOnly(patt) OP_BRANCH
SmallcapsOps.OP_BRANCH
converts a boolean result into a conditional branch.
visitDefineExpr
in interface ETreeVisitor
public Object visitMatchBindExpr(ENode optOriginal, EExpr specimen, Pattern patt)
all: forValue(specimen) this(patt)
XXX How does the ejector know what variables to ruin? I suppose if uninitialized variables are born ruined, then the issue mostly goes away, except that we desire to ruin them with the problem responsible for them not being bound, for diagnostic/debugging purposes.
visitMatchBindExpr
in interface ETreeVisitor
public Object visitIfExpr(ENode optOriginal, EExpr test, EExpr then, EExpr els)
all: OP_EJECTOR_ONLY(elsLabel) forControl(test) OP_END_HANDLER this(then) OP_JUMP(doneLabel) elsLabel: this(els) doneLabel:
SmallcapsOps.OP_EJECTOR_ONLY
pushes [ejector] onto the operand stack and
pushes its handler onto the handler stack. This ejector, if invoked
before it's disabled, will truncate the stacks to their height at the
time the OP_EJECTOR_ONLY was executed (thereby popping itself and its
handler), disables itself, and transfer control to the elsLabel. Note
that the popping of the handler stack may run finally-clauses,
which may themselves exit abruptly, in which case control may never
reach elsLabel.
test is evaluated forControl, so it pops the [ejector] pushed by OP_EJECTOR_ONLY. If the test is true, then it falls through to the OP_END_HANDLER. If the test is false, then it invokes the optEjector. Otherwise, it reports a problem to the top handler on the handler stack.
SmallcapsOps.OP_END_HANDLER
drops the top handler on the handler stack,
which must be the handler pushed by OP_EJECTOR_ONLY. This handler, when
dropped, disables the ejector pushed by OP_EJECTOR_ONLY.
The then-clause is then evaluated so that its outcome is the outcome of the if expression as a whole.
SmallcapsOps.OP_JUMP
just jumps to doneLabel, in which case the
if-expression exits normally.
If the test was false, then the ejector was invoked, transfering control to the els-clause. The else-clause is then evaluated so that its outcome is the outcome of the if expression as a whole.
visitIfExpr
in interface ETreeVisitor
public Object visitEscapeExpr(ENode optOriginal, Pattern hatchPatt, EExpr body)
forFxOnly: OP_EJECTOR_ONLY(doneLabel) forFxOnly(hatchPatt) forFxOnly(body) OP_END_HANDLER doneLabel:The
SmallcapsOps.OP_EJECTOR_ONLY
pushes an ejector which is popped (and
typically bound by) hatchPatt. If this ejector is invoked, stacks are
truncated back to what they were as when the OP_EJECTOR_ONLY was
executed, the ejector is disabled, and control is transfered to
doneLabel:. In the forFxOnly case, the ejector is useful for early exit
but nothing more.
forValue: OP_EJECTOR(doneLabel) forFxOnly(hatchPatt) forValue(body) OP_END_HANDLER doneLabel:
SmallcapsOps.OP_EJECTOR
is like OP_EJECTOR_ONLY, but the ejector it
creates, when its run/0 or run/1 methods are called, also pushes its
argument. (If run/0 is used, a null is pushed.)
forControl: OP_EJECTOR(elsLabel) forFxOnly(hatchPatt) forControl(body) OP_END_HANDLER OP_JUMP(doneLabel) elsLabel: OP_BRANCH doneLabel:Since this case is evaluated forControl, we enter with an optEjector already on the stack -- to be invoked to indicate that the expression as a whole evaluated to false. Let's call this optEjector1. The OP_EJECTOR instruction pushes another one, to be used by the escape expression to exit early with some value. Let's call this ejector2. hatchPatt pops (and typically binds) ejector2. If body evaluates to true, then, since it's evaluated for control, pops optEjector1, falls through to OP_END_HANDLER and then jumps to doneLabel. If body evaluates to false, then it exits according to optEjector1.
If ejector is invoked before it's disabled, it truncates the stacks back to [optEjector1],[], pushes [argument] leaving [optEjector,argument],[], disables itself, and jumps to elsLabel.
SmallcapsOps.OP_BRANCH
pops [optEjector,argument] and converts the truth
value of argument into control flow.
visitEscapeExpr
in interface ETreeVisitor
public Object visitCatchExpr(ENode optOriginal, EExpr attempt, Pattern patt, EExpr catcher)
all: OP_TRY(catchLabel) this(attempt) OP_END_HANDLER OP_JUMP(doneLabel) catchLabel: forFxOnly(patt) this(catcher) doneLabel:
visitCatchExpr
in interface ETreeVisitor
public Object visitFinallyExpr(ENode optOriginal, EExpr attempt, EExpr unwinder)
all: OP_UNWIND(finallyLabel) this(attempt) OP_END_HANDLER XXX punt
visitFinallyExpr
in interface ETreeVisitor
public Object visitLiteralExpr(ENode optOriginal, Object value)
forFxOnly: # nothing
forValue: One of
forControl: forValue OP_BRANCH
XXX Treats Twine like String for now.
visitLiteralExpr
in interface ETreeVisitor
public Object visitScopeExpr(ENode optOriginal)
forFxOnly: # nothing
forValue: OP_SCOPE
forControl: OP_SCOPE OP_BRANCHSince a scope doesn't coerce to a boolean, this will always fail, but we generate it this way so the complaint might be more informative.
visitScopeExpr
in interface ETreeVisitor
public Object visitNounExpr(ENode optOriginal, String varName)
(OP_NOUN+addrMode)(index)
visitNounExpr
in interface ETreeVisitor
public Object visitSlotExpr(ENode optOriginal, AtomicExpr noun)
(OP_SLOT+addrMode)(index)
visitSlotExpr
in interface ETreeVisitor
public Object visitAssignExpr(ENode optOriginal, AtomicExpr lValue, EExpr rValue)
forFxOnly: forValue(rValue) (OP_ASSIGN+addrMode)(index)
forValue: forValue(rValue) OP_DUP (OP_ASSIGN+addrMode)(index)
forControl: forValue(rValue) OP_DUP (OP_ASSIGN+addrMode)(index) OP_BRANCH
visitAssignExpr
in interface ETreeVisitor
public Object visitObjectExpr(ENode optOriginal, String docComment, String optFQN, EExpr[] auditors, EScript eScript)
visitObjectExpr
in interface ETreeVisitor
public Object visitQuasiLiteralExpr(ENode optOriginal, int index)
visitQuasiLiteralExpr
in interface ETreeVisitor
public Object visitQuasiPatternExpr(ENode optOriginal, int index)
visitQuasiPatternExpr
in interface ETreeVisitor
public Object visitIgnorePattern(ENode optOriginal)
forFxOnly: OP_POP
forValue: OP_POP OP_TRUE
forControl: OP_POP OP_POP
visitIgnorePattern
in interface ETreeVisitor
public Object visitFinalPattern(ENode optOriginal, String varName, EExpr valueGuardExpr)
forFxOnly: forValue(valueGuardExpr) OP_SWAP OP_NULL OP_CALL("coerce", 2) (OP_BIND+addrMode)(index)
forControl: forValue(valueGuardExpr) OP_SWAP OP_ROT OP_CALL("coerce", 2) (OP_BIND+addrMode)(index)
forValue: forValue(valueGuardExpr) OP_SWAP OP_EJECTOR_ONLY(elsLabel) OP_CALL("coerce", 2) (OP_BIND+addrMode)(index) OP_END_HANDLER OP_TRUE OP_JUMP(doneLabel) elsLabel: OP_FALSE doneLabel:When valueGuardExpr is the default (":any"), then this simplifies to
forFxOnly: (OP_BIND+addrMode)(index)
forControl: (OP_BIND+addrMode)(index) OP_POP
forValue: (OP_BIND+addrMode)(index) OP_TRUESince the any guard can't fail to match, the pattern cannot generate a false.
visitFinalPattern
in interface ETreeVisitor
public Object visitVarPattern(ENode optOriginal, String varName, EExpr slotGuardExpr)
forFxOnly: forValue(slotGuardExpr) OP_SWAP OP_NULL OP_CALL("makeSlot", 2) (OP_BIND_SLOT+addrMode)(index)
forControl: forValue(slotGuardExpr) OP_SWAP OP_ROT OP_CALL("makeSlot", 2) (OP_BIND_SLOT+addrMode)(index)
forValue: forValue(slotGuardExpr) OP_SWAP OP_EJECTOR_ONLY(elsLabel) OP_CALL("makeSlot", 2) (OP_BIND_SLOT+addrMode)(index) OP_END_HANDLER OP_TRUE OP_JUMP(doneLabel) elsLabel: OP_FALSE doneLabel:
visitVarPattern
in interface ETreeVisitor
public Object visitListPattern(ENode optOriginal, Pattern[] subs)
PATT_LIST(n) pops [optEjector, specimen], coerces the specimen to an EList, and checks that the size is n. If it doesn't coerce of if the size doesn't match, then it escapes according to optEjector. If all this succeeds, then it pushes
[optEjector, specimen[0], ..., optEjector, specimen[n-1]]onto the stack for the subs to consume.
visitListPattern
in interface ETreeVisitor
public Object visitCdrPattern(ENode optOriginal, ListPattern subs, Pattern rest)
PATT_CDR(n) pops [optEjector, specimen], coerces the specimen to an EList, and checks that the size is >= n. If it doesn't coerce of if the size doesn't match, then it escapes according to optEjector. If all this succeeds, then it pushes
[optEjector, specimen[0], ..., optEjector, specimen[n-1], optEjector, specimen(n,specimen.size())]onto the stack for the subs and rest to consume.
visitCdrPattern
in interface ETreeVisitor
public Object visitSuchThatPattern(ENode optOriginal, Pattern patt, EExpr test)
PATT_SUCH_THAT pops [optEjector, specimen] and pushes [optEjector, optEjector, specimen]. patt then consumes the top two. test then pushes the result of the test, leaving [optEjector, successFlag] on the stack for PATT_END_SUCH_THAT to pop. It pops this, coerces the flag to a boolean, and, if false, escapes according to optEjector. If true, then it does nothing further.
visitSuchThatPattern
in interface ETreeVisitor
public Object visitQuasiLiteralPatt(ENode optOriginal, int index)
visitQuasiLiteralPatt
in interface ETreeVisitor
public Object visitQuasiPatternPatt(ENode optOriginal, int index)
visitQuasiPatternPatt
in interface ETreeVisitor
public Object visitEScript(ENode optOriginal, EMethodNode[] optMethods, Matcher optMatcher)
ETreeVisitor
visitEScript
in interface ETreeVisitor
public Object visitEMethod(ENode optOriginal, String docComment, String verb, Pattern[] patterns, EExpr returnGuard, EExpr body)
ETreeVisitor
Defines a method for verb and a number of arguments matching the number of patterns. When the containing object is sent such a message, the arguments are matched against the patterns, and then the body is evaluated. They value of body as coerced by returnGuard is finally revealed.
visitEMethod
in interface ETreeVisitor
public Object visitMatcher(ENode optOriginal, Pattern pattern, EExpr body)
ETreeVisitor
When the incoming message doesn't fit any of the methods, then a pair of the verb and the arguments is matched against patt, then body is evaluated, and it value revealed.
visitMatcher
in interface ETreeVisitor
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |