[e-cvs] cvs commit: e/src/jsrc/org/erights/e/elang/visitors BindFramesVisitor.java
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Thu, 8 Nov 2001 23:47:35 -0500
markm 01/11/08 23:47:35
Added: src/jsrc notes.txt
src/jsrc/org/erights/e/elang/evm EImplByRelay.java
EMethodNode.java FrameFinalNounExpr.java
FrameSlotNounExpr.java LiteralNounExpr.java
LiteralSlotNounExpr.java LocalFinalNounExpr.java
LocalSlotNounExpr.java NounPattern.java
OuterNounExpr.java
src/jsrc/org/erights/e/elang/interp Loader.java
src/jsrc/org/erights/e/elang/scope EvalContext.java
InnerScope.java OuterScope.java ScopeMap.java
src/jsrc/org/erights/e/elang/visitors BindFramesVisitor.java
Log:
forgot these from Dean
Revision Changes Path
1.1 e/src/jsrc/notes.txt
Index: notes.txt
===================================================================
TODO:
. todos
. parse emakers and launched files as a single Sequence expression
. copy nodes for lazy outer resolution
. discuss protected vs. package
. send coding conventions
. send agorics open systems papers
DONE:
. check out notes.txt
. rename FrameVarNounExpr.java LocalVarNounExpr.java
. rename Frames to Fields
. rename FrameVarNounExpr.java LocalVarNounExpr.java
. track the number of active outers
. implement getSlot and put for Scopes
. top-level locals
. clean up mutable scopes
. arrange so that locals don't need to grow
. bindSlot
. move LoaderScope, PackageScope, and UnsafeLoaderScope into a separate hierarchy
. get mutable scopes working
. send notes.txt to markm
. copy nodes for scopeMap, source positions,
NOTES:
. New locals are introduced by the top of the world, method, matcher, loop
. staticScope is called in computeStaticScope, EBuilder, and eval()
. IgnorePattern should not be a kernel type; it's just a degenerate case of FinalPattern.
. mutable scopes are only when interacting with the user
. command line
. elmer
. updoc
. never for a lazy evaluation
- each top level expression in an emaker evaluates separately
- semanticaly complicted an unnecessary
. emakers see top level expressions within the emaker as outers.
.? should top-level defs in an emaker shadow outers (e.g., println)
. yes
. they should be outers though, just with a different offset
. The bindings go into each ENode
Optimizations:
. universal constants should be defined in a singleton
. have Slot types for common scalars
. have a special range of variables or supporting FinalNoun types for scalars
. make override fillInStackTrace in Ejector
. linearly search for eq classnames in HONORARY
. separate selfless and non-selfless classes in const and equalizer
. Ejection should be a runtime exception, and the Ejector does not need asSafe
Starting it:
simple.e makeprettydean.e eChat.e
Interp VTable
Reference:
<import: foo> => import__uriGetter get("foo")
Charlie 408 248-4604
clandau@macslab.com
don lavoie
703-791-0152
final normal form vs slot normal form
gc:
? force full gc required?
? is conservative allowed?
loops:
? termination
? contour
architecture:
? flat closures vs. display lists
. use flat closures
? debugging?
? antlr
kernel E:
? move to slot normal form
? preserve hide
? no embedded defs or vars
? list expansion
? what do you have to know to understand the java mapping
?! kernel E is the contract between unprivileged computation
and the virtual machine
DONE:
x Scopes must respond to getValue(String)
x make universal constants into universal nouns and don't have
them in the eval context
x have a UniversalNoun and a LazyNoun that when asked for the
copy with source positions, returns a new, no longer lazy
UniversalNoun
x remove lamport stuff out of the universal scope
x Loading an emaker is an eval.
x compute the maximum allocated # of locals for each stack frame
x rename VarNounExprs to SlotNounExprs, and then add a VarNounExpr set that
store there as Finals do. (for single closure vars)
x scope objects should have a Bindings and an EvalContext that has values for
the specified bindings
x add a contour boundary in the scope map. Have the with() operation
fail with AlreadyDefined
- for outers, the slot must be reassignable. Therefore, make each
OuterNounExpr point directly at its slot object. Then the slot
is "compiled in" to the code.
- when asked for a slot by name, the global slot should return one that
indirects through the OuterNounExpr
x eval is sent to a kernel tree. It assign-transforms the tree and then
subEvals it.
. ParseNode
ENode
EExpr
Pattern
EScript
EMethod
Matcher
MethodNode
EMethodNode
1.3 +0 -39 e/src/jsrc/org/erights/e/elang/evm/EImplByRelay.java
1.23 +50 -142 e/src/jsrc/org/erights/e/elang/evm/EMethodNode.java
1.1 e/src/jsrc/org/erights/e/elang/evm/FrameFinalNounExpr.java
Index: FrameFinalNounExpr.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.scope.EvalContext;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.slot.FinalSlotMaker;
import org.erights.e.elib.slot.Slot;
import java.io.IOException;
/**
* What an object expression evaluates to.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class FrameFinalNounExpr extends NounExpr {
private int myIndex;
FrameFinalNounExpr(String name, int index) {
super(name);
myIndex = index;
}
/**
*
*/
public Slot getSlot(EvalContext ctx) {
return FinalSlotMaker.THE_ONE.makeSlot(ctx.field(myIndex), null);
}
/**
*
*/
/*package*/ Object subEval(EvalContext ctx, boolean forValue) {
return ctx.field(myIndex);
}
/**
*
*/
public void subPrintOn(TextWriter out, int priority) throws IOException {
super.subPrintOn(out, priority);
out.print("$ff", new Integer(myIndex));
}
/**
* The miranda printOn will call this. Also, it may be called by normal
* non-E cognizant java code. This provides a default EImpl behavior,
* unless overridden by a printOn method written in E.
*/
public String toString() {
return ""+myIndex;
}
/**
* Return the kind of object that should be stored in a frame, assuming
* an accessor of the same type as the receiver.
*/
public Object getRepresentation(EvalContext ctx) {
return ctx.field(myIndex);
}
/**
*
*/
public NounExpr asFieldAt(int index) {
return new FrameFinalNounExpr(name(), index);
}
/**
*
*/
public void initFinal(EvalContext ctx, Object value) {
ctx.initField(myIndex, value);
}
}
1.1 e/src/jsrc/org/erights/e/elang/evm/FrameSlotNounExpr.java
Index: FrameSlotNounExpr.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.scope.EvalContext;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.slot.Slot;
import java.io.IOException;
/**
* What an object expression evaluates to.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class FrameSlotNounExpr extends NounExpr {
private int myIndex;
FrameSlotNounExpr(String name, int index) {
super(name);
myIndex = index;
}
/**
*
*/
public boolean isFinal() {
return false;
}
/**
*
*/
public Slot getSlot(EvalContext ctx) {
return (Slot) ctx.field(myIndex);
}
/**
*
*/
public NounExpr asFieldAt(int index) {
return new FrameSlotNounExpr(name(), index);
}
/**
*
*/
public void subPrintOn(TextWriter out, int priority) throws IOException {
super.subPrintOn(out, priority);
out.print("$fv", new Integer(myIndex));
}
/**
* The miranda printOn will call this. Also, it may be called by normal
* non-E cognizant java code. This provides a default EImpl behavior,
* unless overridden by a printOn method written in E.
*/
public String toString() {
return ""+myIndex;
}
/**
*
*/
public void initSlot(EvalContext ctx, Slot slot) {
ctx.initField(myIndex, slot);
}
}
1.1 e/src/jsrc/org/erights/e/elang/evm/LiteralNounExpr.java
Index: LiteralNounExpr.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.scope.EvalContext;
import org.erights.e.elib.slot.FinalSlotMaker;
import org.erights.e.elib.slot.Slot;
import org.erights.e.elib.util.AlreadyDefinedException;
/**
* A noun-expr for compile-time literals, particularly universal constants.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class LiteralNounExpr extends NounExpr {
private Object myValue;
public LiteralNounExpr(String name, Object value) {
super(name);
myValue = value;
}
public boolean isOuter() {
return true;
}
/**
*
*/
public Slot getSlot(EvalContext ctx) {
return FinalSlotMaker.THE_ONE.makeSlot(myValue, null);
}
/**
*
*/
/*package*/ Object subEval(EvalContext ctx, boolean forValue) {
return myValue;
}
/**
* The miranda printOn will call this. Also, it may be called by normal
* non-E cognizant java code. This provides a default EImpl behavior,
* unless overridden by a printOn method written in E.
*/
public String toString() {
return ""+myValue;
}
/**
*
*/
public NounExpr asFieldAt(int index) {
return new FrameFinalNounExpr(name(), index);
}
/**
*
*/
public void initFinal(EvalContext ctx, Object value) {
throw new AlreadyDefinedException("Cannot redefine a universal constant" + name());
}
}
1.1 e/src/jsrc/org/erights/e/elang/evm/LiteralSlotNounExpr.java
Index: LiteralSlotNounExpr.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.scope.EvalContext;
import org.erights.e.elib.slot.Slot;
import org.erights.e.elib.util.AlreadyDefinedException;
/**
* What an object expression evaluates to.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class LiteralSlotNounExpr extends NounExpr {
private Slot mySlot;
public LiteralSlotNounExpr(String name, Slot slot) {
super(name);
mySlot = slot;
}
public boolean isOuter() {
return true;
}
/**
*
*/
public Slot getSlot(EvalContext ctx) {
return mySlot;
}
/**
*
*/
/*package*/ Object subEval(EvalContext ctx, boolean forValue) {
return mySlot.getValue();
}
/**
* The miranda printOn will call this. Also, it may be called by normal
* non-E cognizant java code. This provides a default EImpl behavior,
* unless overridden by a printOn method written in E.
*/
public String toString() {
return ""+mySlot;
}
/**
*
*/
public NounExpr asFieldAt(int index) {
return this;
}
/**
*
*/
public void initFinal(EvalContext ctx, Object value) {
throw new AlreadyDefinedException("Cannot redefine a universal constant" + name());
}
}
1.1 e/src/jsrc/org/erights/e/elang/evm/LocalFinalNounExpr.java
Index: LocalFinalNounExpr.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.scope.EvalContext;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.slot.FinalSlotMaker;
import org.erights.e.elib.slot.Slot;
import java.io.IOException;
/**
* What an object expression evaluates to.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class LocalFinalNounExpr extends NounExpr {
private int myIndex;
public LocalFinalNounExpr(String name, int index) {
super(name);
myIndex = index;
}
/**
*
*/
public Slot getSlot(EvalContext ctx) {
return FinalSlotMaker.THE_ONE.makeSlot(ctx.local(myIndex), null);
}
/**
*
*/
/*package*/ Object subEval(EvalContext ctx, boolean forValue) {
return ctx.local(myIndex);
}
/**
* Return the kind of object that should be stored in a frame, assuming
* an accessor of the same type as the receiver.
*/
public Object getRepresentation(EvalContext ctx) {
return ctx.local(myIndex);
}
/**
*
*/
public NounExpr asFieldAt(int index) {
return new FrameFinalNounExpr(name(), index);
}
/**
*
*/
public void subPrintOn(TextWriter out, int priority) throws IOException {
super.subPrintOn(out, priority);
out.print("$lf", new Integer(myIndex));
}
/**
* The miranda printOn will call this. Also, it may be called by normal
* non-E cognizant java code. This provides a default EImpl behavior,
* unless overridden by a printOn method written in E.
*/
public String toString() {
return ""+myIndex;
}
/**
*
*/
public void initFinal(EvalContext ctx, Object value) {
ctx.initLocal(myIndex, value);
}
}
1.1 e/src/jsrc/org/erights/e/elang/evm/LocalSlotNounExpr.java
Index: LocalSlotNounExpr.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.scope.EvalContext;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.slot.Slot;
import java.io.IOException;
/**
* What an object expression evaluates to.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class LocalSlotNounExpr extends NounExpr {
private int myIndex;
public LocalSlotNounExpr(String name, int index) {
super(name);
myIndex = index;
}
/**
*
*/
public boolean isFinal() {
return false;
}
/**
*
*/
public Slot getSlot(EvalContext ctx) {
return (Slot) ctx.local(myIndex);
}
/**
*
*/
public NounExpr asFieldAt(int index) {
return new FrameSlotNounExpr(name(), index);
}
/**
*
*/
public void initSlot(EvalContext ctx, Slot slot) {
//System.out.println("Initing: " + name() + " at" + myIndex);
ctx.initLocal(myIndex, slot);
}
/**
*
*/
public void subPrintOn(TextWriter out, int priority) throws IOException {
super.subPrintOn(out, priority);
out.print("$lv", new Integer(myIndex));
}
/**
* The miranda printOn will call this. Also, it may be called by normal
* non-E cognizant java code. This provides a default EImpl behavior,
* unless overridden by a printOn method written in E.
*/
public String toString() {
return ""+myIndex;
}
}
1.1 e/src/jsrc/org/erights/e/elang/evm/NounPattern.java
Index: NounPattern.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.interp.ScopeSetup;
import org.erights.e.elang.visitors.ETreeVisitor;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.ref.Ref;
import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.tables.FlexMap;
import java.io.IOException;
import java.util.Set;
/**
* BNF: Identifier ':' expr <p>
*
* The identifier on the left is the defining occurrence of a variable
* name. The expression on the right is a "value guard expression". The
* object it evaluates to will be treated as a ValueGuard, and asked to make a
* value initialized from a specimen, as if: <p><pre>
*
* def value := valueGuard coerce(specimen, XXX)
*
* <p></pre>This value is then defined as the value for a variable of this name
* in the scope starting immediately after this name. <p>
*
* But wait! That scope includes the value guard expression?!? As with the
* def-expression, this circularity is indeed allowed and correct in the
* user-level language, but the kernel-level language (ie, the parse node
* FinalPattern) imposes a well-formedness criterea that allows us to
* evaluate in the wrong order without effect. A circular user-level
* final-pattern must be translated into a well-formed kernel-level
* FinalPattern. <p>
*
* @see org.erights.e.elang.evm.DefineExpr
* @see org.erights.e.elang.evm.FinalPattern
* @see org.erights.e.elang.evm.VarPattern
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
abstract public class NounPattern extends Pattern {
/**
* A set of all the variable names that may not be shadowed (ie,
* redefined)
*/
static public final Set NonShadowable = ScopeSetup.nonShadowable();
private String myVarName;
/**
* If 'varName' would shadow a non-shadowable, throw a (XXX to be
* defined) exception instead. <p>
*
* If the FinalPattern would not be well-formed, throw a (XXX to be
* defined) exception instead. <p>
*/
protected NounPattern(String varName) {
myVarName = varName;
// NOTE non-shadowable variables seem like a bad idea....
if (NonShadowable.contains(myVarName)) {
throw new RuntimeException("can't redefine " + myVarName);
}
}
/**
*
*/
protected void ensureWellFormed(EExpr guardExpr) {
StaticScope smScope = guardExpr.staticScope();
if (smScope.namesUsed().maps(myVarName)) {
throw new RuntimeException
("kernel definer cycle not allowed: " + myVarName);
}
if (smScope.namesOut().maps(myVarName)) {
throw new RuntimeException
("kernel definer shadow not allowed: " + myVarName);
}
}
abstract public NounExpr getNoun();
/**
*
*/
abstract public Object welcome(ETreeVisitor visitor);
/**
* A Definer will never return null for this. It is named
* 'optName' because it is polymorphic with IgnorePattern
*/
public String optName() { return myVarName; }
/**
*
*/
protected abstract EExpr guardExpr();
/**
*
*/
/*package*/ StaticScope computeStaticScope() {
FlexMap namesOut = FlexMap.fromTypes(String.class, Void.class);
namesOut.put(myVarName, null);
StaticScope result = StaticScope.scopeDefine(namesOut.snapshot());
result = result.add(guardExpr().staticScope());
return result;
}
/**
*
*/
public boolean matchBind(Object[] args,
Object specimen,
FlexList bindings)
{
NounPattern other;
try {
other = (NounPattern)Ref.resolution(specimen);
} catch (ClassCastException cce) {
//using a try/catch since success is typical and we have
//to pay for the test in the cast anyway
return false;
}
if (other.getClass() != getClass()) {
return false;
}
return matchBind(getNoun(),
args,
other.getNoun(),
bindings)
&& matchBind(guardExpr(),
args,
other.guardExpr(),
bindings);
}
/**
*
*/
public void subPrintOn(TextWriter out, int priority) throws IOException {
getNoun().subPrintOn(out, priority);
out.print(" :");
guardExpr().subPrintOn(out, PR_ORDER);
}
}
1.1 e/src/jsrc/org/erights/e/elang/evm/OuterNounExpr.java
Index: OuterNounExpr.java
===================================================================
package org.erights.e.elang.evm;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.scope.EvalContext;
import org.erights.e.elib.eio.TextWriter;
import org.erights.e.elib.slot.Slot;
import java.io.IOException;
/**
* What an object expression evaluates to.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class OuterNounExpr extends NounExpr {
private int myIndex;
public OuterNounExpr(String name, int index) {
super(name);
myIndex = index;
}
/**
*
*/
public boolean isOuter() {
return true;
}
/**
*
*/
public Slot getSlot(EvalContext ctx) {
return ctx.outer(myIndex);
}
public int getIndex() {
return myIndex;
}
/**
*
*/
/*package*/ Object subEval(EvalContext ctx, boolean forValue) {
return getSlot(ctx).getValue();
}
/**
* Return the kind of object that should be stored in a frame, assuming
* an accessor of the same type as the receiver.
*/
public Object getRepresentation(EvalContext ctx) {
return ctx.outer(myIndex);
}
/**
*
*/
public void subPrintOn(TextWriter out, int priority) throws IOException {
super.subPrintOn(out, priority);
out.print("$o", new Integer(myIndex));
}
/**
* The miranda printOn will call this. Also, it may be called by normal
* non-E cognizant java code. This provides a default EImpl behavior,
* unless overridden by a printOn method written in E.
*/
public String toString() {
return ""+myIndex;
}
/**
*
*/
public void initSlot(EvalContext ctx, Slot slot) {
ctx.initOuter(myIndex, slot);
}
}
1.1 e/src/jsrc/org/erights/e/elang/interp/Loader.java
Index: Loader.java
===================================================================
package org.erights.e.elang.interp;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elib.eio.EPrintable;
import org.erights.e.elib.eio.TextWriter;
import java.io.IOException;
/**
* Provides access to the java fully-qualified class namespace as a scope
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
/*package*/ abstract public class Loader implements EPrintable {
abstract public Object get(String name);
/**
*
*/
public void printOn(TextWriter out) throws IOException {
out.print("<import:*>");
}
}
1.1 e/src/jsrc/org/erights/e/elang/scope/EvalContext.java
Index: EvalContext.java
===================================================================
package org.erights.e.elang.scope;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elib.slot.Slot;
/**
* Instances maintain the outer, object-frame, and local nouns during
* the evaluation of an E expression. <p>
*
* Three groups of variables comprise the execution state of the
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class EvalContext {
static private final int LOCAL_COUNT = 64;
static private Object[] NO_FIELDS = {};
// Idealy, this should cache no-longer-used local arrays.
private Object[] myLocals;
private Object[] myFields;
private OuterScope myOuters;
static public EvalContext make(int localCount, Object[] fields, OuterScope outers) {
return new EvalContext(new Object[localCount], fields, outers);
}
static public EvalContext make(int localCount, OuterScope outers) {
return new EvalContext(new Object[localCount], NO_FIELDS, outers);
}
private EvalContext(Object[] locals, Object[] fields, OuterScope outers) {
myLocals = locals;
myFields = fields;
myOuters = outers;
}
/**
* returns a new Scope that inherits from this one.
* This new Scope has an empty set of locals.
*/
public EvalContext extended(int localCount) {
if (0 == localCount) {
return this;
}
int len = myLocals.length;
int newLen = len + localCount;
Object[] newLocals = new Object[newLen];
System.arraycopy(myLocals, 0, newLocals, 0, len);
return new EvalContext(newLocals, myFields, myOuters);
}
public Object local(int index) {
return myLocals[index];
}
public Object field(int index) {
return myFields[index];
}
public Slot outer(int index) {
return myOuters.getIndex(index);
}
public OuterScope outers() { return myOuters; }
public void initLocal(int index, Object value) {
if (index >= myLocals.length) {
System.err.println("Assign: " + index + " within: " + myLocals.length);
}
myLocals[index] = value;
}
public void initField(int index, Object value) {
myFields[index] = value;
}
public void initOuter(int index, Slot value) {
myOuters.initIndex(index, value);
}
}
1.1 e/src/jsrc/org/erights/e/elang/scope/InnerScope.java
Index: InnerScope.java
===================================================================
package org.erights.e.elang.scope;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.evm.NounExpr;
import org.erights.e.elib.slot.Slot;
import org.erights.e.elib.util.AlreadyDefinedException;
/**
* The implementation of E's interactive top-level lexical scope.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class InnerScope extends Scope {
protected EvalContext myEvalContext;
/**
*
*/
public InnerScope(ScopeMap scopeMap, EvalContext ctx) {
super(scopeMap);
myEvalContext = ctx;
}
public NounExpr reserveOuter(String name) {
return myEvalContext.outers().reserveOuter(name);
}
public Slot getSlot(String name) {
return myScopeMap.getNoun(name).getSlot(myEvalContext);
}
/**
*
*/
public void bindOuter(String name, Slot slot)
throws AlreadyDefinedException
{
myEvalContext.outers().bindOuter(name, slot);
}
public Scope sprout() {
throw new RuntimeException("TODO unimplemented");
}
public EvalContext newContext(int numLocals) {
// TODO should this eliminate all the current locals?
return myEvalContext.extended(numLocals);
}
}
1.1 e/src/jsrc/org/erights/e/elang/scope/OuterScope.java
Index: OuterScope.java
===================================================================
package org.erights.e.elang.scope;
/*
The contents of this file are subject to the Electric Communities E Open
Source Code License Version 1.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License
at http://www.communities.com/EL/.
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is the Distributed E Language Implementation, released
July 20, 1998.
The Initial Developer of the Original Code is Electric Communities.
Copyright (C) 1998 Electric Communities. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.evm.NounExpr;
import org.erights.e.elang.evm.OuterNounExpr;
import org.erights.e.elib.slot.Slot;
import org.erights.e.elib.tables.ConstMap;
import org.erights.e.elib.util.AlreadyDefinedException;
/**
* The normal implementation of an E lexical scope.
*
* @author <a href="mailto:markm@erights.org">Mark S. Miller</a>
*/
public class OuterScope extends Scope {
private Slot[] myOuters;
private int myNextOuter;
private boolean myIsMutable;
static public OuterScope make(ScopeMap map, Slot[] outers, int nextOuter) {
return new OuterScope(map, outers, nextOuter, false);
}
static public OuterScope make(ScopeMap map,
Slot[] outers,
int nextOuter,
boolean isMutable)
{
return new OuterScope(map, outers, nextOuter, isMutable);
}
/**
*
*/
private OuterScope(ScopeMap map,
Slot[] outers,
int nextOuter,
boolean isMutable)
{
super(map);
myOuters = outers;
myNextOuter = nextOuter;
myIsMutable = isMutable;
}
/*package*/ Slot getIndex(int index) {
return myOuters[index];
}
/*package*/ void initIndex(int index, Slot value) {
myOuters[index] = value;
}
// TODO make this less exposed
public NounExpr reserveOuter(String name) {
// sort of like myScope = myScope.bindOuter(varName, null);
if (myIsMutable && myScopeMap.contains(name)) {
return myScopeMap.getNoun(name);
}
NounExpr noun = new OuterNounExpr(name, nextIndex());
myScopeMap = myScopeMap.with(name, noun);
return noun;
}
private int nextIndex() {
// NOTE that the new slot is null
if (myNextOuter >= myOuters.length) {
int len = myOuters.length;
int newLen = Math.max(len + 32, myNextOuter + 1);
// System.err.println("Allocated locals: " + len + " to " + newLen);
Slot[] newOuters = new Slot[newLen];
System.arraycopy(myOuters, 0, newOuters, 0, len);
myOuters = newOuters;
}
return myNextOuter++;
}
/**
* Sprouted scopes are never mutable.
*/
public Scope sprout() {
return new OuterScope(myScopeMap, (Slot[]) myOuters.clone(), myNextOuter, false);
}
public ConstMap locals() { throw new RuntimeException("TODO unimplemented"); }
public Slot getSlot(String name) {
OuterNounExpr noun = (OuterNounExpr) myScopeMap.getNoun(name);
return myOuters[noun.getIndex()];
}
/**
*
*/
public void bindOuter(String name, Slot slot)
throws AlreadyDefinedException
{
OuterNounExpr noun = (OuterNounExpr) reserveOuter(name);
myOuters[noun.getIndex()] = slot;
}
public EvalContext newContext(int numLocals) {
return EvalContext.make(numLocals, this);
}
}
1.1 e/src/jsrc/org/erights/e/elang/scope/ScopeMap.java
Index: ScopeMap.java
===================================================================
package org.erights.e.elang.scope;
/*
The contents of this file are subject to the Improvements to the
Distributed E Language Implementation License Version 1.0 (the
"License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.erights.org/mmlicense.html
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
The Original Code is the Improvements to the Distributed E Language
Implementation, released May 27, 1999.
The Initial Developer of the Original Code is Dean Tribble.
Copyright (C) 2001 Dean Tribble. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.evm.NounExpr;
import org.erights.e.elib.util.AlreadyDefinedException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
*
*
*/
public abstract class ScopeMap {
static public final ScopeMap EMPTY = new ScopeMapBase(new HashMap());
static public ScopeMap make(Map initial) {
return new ScopeMapBase(initial);
}
abstract public NounExpr getNoun(String name);
abstract public boolean contains(String name);
abstract public int count();
public ScopeMap with(String varName, NounExpr noun) {
assertShadowable(varName);
return new ScopeMapLink(varName, noun, this);
}
/*
* Return the set of all names mapped by the receiver.
*/
abstract public Set namesSet();
/*
* Make a new contour within the receiver.
*/
public ScopeMap nested() {
return new ContourBoundary(this);
}
/*
* Throw an exception is the varName may not be shadowed, either
* because it is a special name or because it is already defined
* in the innermost contour.
*/
abstract public void assertShadowable(String varName);
}
/**
*
*/
class ContourBoundary extends ScopeMap {
private ScopeMap myNext;
public ContourBoundary(ScopeMap outer) {
myNext = outer;
}
public int count() { return myNext.count(); }
public NounExpr getNoun(String name) {
return myNext.getNoun(name);
}
public boolean contains(String name) {
return myNext.contains(name);
}
public Set namesSet() {
return myNext.namesSet();
}
public void assertShadowable(String varName) {
// Do nothing; we are at the end of the contour
}
/*
* There is no need for two contiguous boundaries, so just return self.
*/
public ScopeMap nested() {
return this;
}
}
/**
*
*
*/
class ScopeMapLink extends ScopeMap {
private ScopeMap myNext;
private final String myName;
private final NounExpr myNoun;
public ScopeMapLink(String name, NounExpr noun, ScopeMap others) {
myNext = others;
myName = name;
myNoun = noun;
}
public int count() { return myNext.count() + 1; }
public NounExpr getNoun(String name) {
// TODO markm are we guaranteed that the names are canonical?
return myName.equals(name) ? myNoun : myNext.getNoun(name);
}
public boolean contains(String name) {
// TODO markm are we guaranteed that the names are canonical?
return myName.equals(name) || myNext.contains(name);
}
public Set namesSet() {
Set res = myNext.namesSet();
res.add(myName);
return res;
}
public void assertShadowable(String name) {
// TODO markm are we guaranteed that the names are canonical?
if (myName.equals(name)) {
throw new AlreadyDefinedException(name + " already in scope");
}
myNext.assertShadowable(name);
}
}
class ScopeMapBase extends ScopeMap {
private final Map myBindings;
public ScopeMapBase(Map bindings) {
myBindings = bindings;
}
public int count() { return myBindings.size(); }
public NounExpr getNoun(String name) {
NounExpr optRes = (NounExpr) myBindings.get(name);
if (optRes == null) {
throw new UndefinedVariableException(name + " not in scope");
}
return optRes;
}
public boolean contains(String name) {
return myBindings.containsKey(name);
}
public Set namesSet() {
return myBindings.keySet();
}
public void assertShadowable(String name) {
if (contains(name)) {
throw new AlreadyDefinedException(name + " already in scope");
}
}
}
1.1 e/src/jsrc/org/erights/e/elang/visitors/BindFramesVisitor.java
Index: BindFramesVisitor.java
===================================================================
package org.erights.e.elang.visitors;
/*
The contents of this file are subject to the Improvements to the
Distributed E Language Implementation License Version 1.0 (the
"License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.erights.org/mmlicense.html
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and limitations
under the License.
The Original Code is the Improvements to the Distributed E Language
Implementation, released May 27, 1999.
The Initial Developer of the Original Code is Dean Tribble.
Copyright (C) 2001 Dean Tribble. All Rights Reserved.
Contributor(s): ______________________________________.
*/
import org.erights.e.elang.evm.EExpr;
import org.erights.e.elang.evm.EMethod;
import org.erights.e.elang.evm.ENode;
import org.erights.e.elang.evm.EScript;
import org.erights.e.elang.evm.FinalPattern;
import org.erights.e.elang.evm.LocalFinalNounExpr;
import org.erights.e.elang.evm.LocalSlotNounExpr;
import org.erights.e.elang.evm.MatchBindExpr;
import org.erights.e.elang.evm.Matcher;
import org.erights.e.elang.evm.NounExpr;
import org.erights.e.elang.evm.ObjectExpr;
import org.erights.e.elang.evm.Pattern;
import org.erights.e.elang.evm.StaticScope;
import org.erights.e.elang.evm.VarPattern;
import org.erights.e.elang.scope.Scope;
import org.erights.e.elang.scope.ScopeMap;
import org.erights.e.elib.tables.ConstMap;
import java.util.ArrayList;
import java.util.HashMap;
abstract public class BindFramesVisitor extends CopyVisitor {
static private final NounExpr[] NOUN_PROTO = {};
protected ScopeMap myBindings;
protected int[] myMaxLocalsCell;
static public BindFramesVisitor make(Scope scope) {
return new BindOuterVisitor(scope);
}
protected BindFramesVisitor(ScopeMap bindings, int[] localsCell) {
myBindings = bindings;
myMaxLocalsCell = localsCell;
}
public ScopeMap scopeMap() { return myBindings; }
/*
* Set the scope map of the new node to the scope map visible from
* that location.
*/
public ENode xformNode(ENode eNode) {
ENode res = super.xformNode(eNode);
res.setScopeMap(myBindings);
return res;
}
/**
*
*/
protected BindFramesVisitor nestLocals() {
// NOTE the int cell is initialized by Java to 0. This is a cell to
// accumulate the max locals for any part of the nested method or
// matcher.
return new BindNestedVisitor(myBindings.nested(), 0, new int[1]);
}
/**
* Return a BindFramesVisitor for inside a method: it will start
* assigning locals from 0 again, and access locals bound outside
* itself from frame fields instead.
*/
private CopyVisitor nestObject(ScopeMap newBindings) {
return new BindNestedVisitor(newBindings.nested(), 0, myMaxLocalsCell);
}
public int maxLocals() { return myMaxLocalsCell[0]; }
/***************************** Names *************************/
/**
*
*/
public Object visitNounExpr(String varName) {
// Make a copy of the noun so we can track source positions
// and keep the scopeMap for debugging
return myBindings.getNoun(varName).copy();
}
/**
*
*/
public Object visitFinalPattern(String varName,
EExpr valueGuardExpr)
{
return new FinalPattern(varName,
newFinal(varName),
xformEExpr(valueGuardExpr));
}
/**
*
*/
public Object visitVarPattern(String varName,
EExpr slotGuardExpr)
{
return new VarPattern(varName,
newVar(varName),
xformEExpr(slotGuardExpr));
}
abstract protected NounExpr newFinal(String varName);
abstract protected NounExpr newVar(String varName);
/**
*
*/
public Object visitObjectExpr(String docComment,
String optFQN,
NounExpr[] auditors,
EScript eScript)
{
// TODO markm can worry about auditors
StaticScope ss = eScript.staticScope();
String[] used = (String[]) ss.namesUsed().getKeys(String.class);
HashMap newBindings = new HashMap(used.length);
ArrayList fields = new ArrayList(used.length);
for (int i = 0, max = used.length; i < max; i++) {
NounExpr noun = myBindings.getNoun(used[i]);
if (noun.isOuter()) {
newBindings.put(noun.name(), noun);
} else {
NounExpr newNoun = noun.asFieldAt(fields.size());
fields.add(noun);
newBindings.put(newNoun.name(), newNoun);
}
}
ScopeMap inner = ScopeMap.make(newBindings);
CopyVisitor nested = nestObject(inner);
return new ObjectExpr(docComment,
optFQN,
(NounExpr[]) xformEExprs(auditors),
nested.xformEScript(eScript),
(NounExpr[]) fields.toArray(NOUN_PROTO));
}
/**
*
*/
public Object visitMatchBindExpr(EExpr specimen, Pattern patt) {
Pattern xpat = xformPattern(patt);
ConstMap out = xpat.staticScope().namesOut();
String[] boundNames = (String[]) out.getKeys(String.class);
int boundCount = boundNames.length;
NounExpr[] bound = new NounExpr[boundCount];
for (int i = 0; i < boundCount; i++) {
// myBindings must include the bindings from the pattern
bound[i] = myBindings.getNoun(boundNames[i]);
}
return new MatchBindExpr(xformEExpr(specimen), xpat, bound);
}
/**************************** EExprs **************************/
/**
* Eliminate the HideExpr, while preserving its scope boundary.
*/
public Object visitHideExpr(EExpr body) {
return body.welcome(nest());
}
/***************************** Other **************************/
/**
*
*/
public Object visitEMethod(String docComment,
String verb,
Pattern[] patterns,
EExpr returnGuard,
EExpr body)
{
// NOTE the acces to maxLocals is after the visitor is used on
// the other children.
BindFramesVisitor t = nestLocals();
return new EMethod(docComment,
verb,
t.xformPatterns(patterns),
t.xformEExpr(returnGuard),
t.xformEExpr(body),
t.maxLocals());
}
/**
*
*/
public Object visitMatcher(Pattern patt,
EExpr body)
{
BindFramesVisitor t = nestLocals();
return new Matcher(t.xformPattern(patt),
t.xformEExpr(body),
t.maxLocals());
}
/**************************** Internal ************************/
}
class BindNestedVisitor extends BindFramesVisitor {
protected int myNextLocal;
public BindNestedVisitor(ScopeMap bindings, int localN, int[] localsCell) {
super(bindings, localsCell);
myNextLocal = localN;
}
protected CopyVisitor nest() {
ScopeMap newContour = myBindings.nested();
return new BindNestedVisitor(newContour, myNextLocal, myMaxLocalsCell);
}
protected NounExpr newFinal(String varName) {
NounExpr noun = new LocalFinalNounExpr(varName, nextLocal());
myBindings = myBindings.with(varName, noun);
return noun;
}
protected NounExpr newVar(String varName) {
NounExpr noun = new LocalSlotNounExpr(varName, nextLocal());
myBindings = myBindings.with(varName, noun);
return noun;
}
private int nextLocal() {
int index = myNextLocal;
myNextLocal++;
myMaxLocalsCell[0] = Math.max(myNextLocal, myMaxLocalsCell[0]);
return index;
}
}
class BindOuterVisitor extends BindFramesVisitor {
private Scope myScope;
protected BindOuterVisitor(Scope scope) {
super(scope.scopeMap(), new int[1]);
myScope = scope;
}
/**
*
*/
protected CopyVisitor nest() {
return new BindNestedVisitor(myBindings.nested(), 0, myMaxLocalsCell);
}
protected NounExpr newFinal(String varName) {
return newVar(varName);
}
protected NounExpr newVar(String varName) {
NounExpr noun = myScope.reserveOuter(varName);
myBindings = myScope.scopeMap();
return noun;
}
}