|
|
||||||||||
| 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 ETreeVisitorprivate 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 ETreeVisitorpublic 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 ETreeVisitorpublic 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)
ETreeVisitorDefines 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)
ETreeVisitorWhen 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 | ||||||||||