Browse files

Merge remote branch 'upstream/master'

  • Loading branch information...
2 parents 411f9f3 + 21c8092 commit a90887edf7f39dbad47dadbeafe656f229a38d5d @pavlobaron committed Dec 31, 2010
View
8 build.xml
@@ -155,4 +155,12 @@
</manifest>
</jar>
</target>
+
+
+ <target name="javadoc" description="generate Javadoc documentation">
+ <javadoc destdir="target/doc">
+ <fileset dir="src"><include name="**/*.java"/></fileset>
+ </javadoc>
+ </target>
+
</project>
View
2 erjang_cfg.properties
@@ -6,4 +6,4 @@ erjang.otp.version = R14B
# erjang.debug.inet=true
# erjang.dump_on_exit = true
-erjang.triq.root = c:/Users/pb/code/ex/triq
+erjang.triq.root = c:/Users/pb/code/ex/triq
View
4 src/main/java/erjang/EAtom.java
@@ -222,10 +222,6 @@ public int compareTo(EAtom other) {
return value.compareTo(other.value);
}
- public int compareTo(EObject other) {
- return super.compareTo(other);
- }
-
/* (non-Javadoc)
* @see erjang.EObject#equalsExactly(erjang.EObject)
*/
View
9 src/main/java/erjang/EBigString.java
@@ -183,8 +183,7 @@ public boolean equals(Object obj) {
return false;
}
- return compareTo((EObject) obj) == 0;
-
+ return equalsExactly((EObject) obj);
}
@Override
@@ -357,7 +356,7 @@ int compare_same(EObject rhs) {
return -1; // I AM SHORTER
}
- int cmp = (new ESmall(charAt(i++))).compareTo(seq.head());
+ int cmp = (new ESmall(charAt(i++))).erlangCompareTo(seq.head());
if (cmp != 0)
return cmp;
@@ -367,12 +366,12 @@ int compare_same(EObject rhs) {
continue;
}
- return -res.compareTo(new EBigString(data, i));
+ return -res.erlangCompareTo(new EBigString(data, i));
}
}
- return -rhs.compareTo(this);
+ return -rhs.erlangCompareTo(this);
}
/*
View
4 src/main/java/erjang/ECons.java
@@ -55,7 +55,7 @@ int compare_same(EObject rhs) {
return ths.isNil() ? 0 : 1;
if (ths.isNil()) return -1;
- int cmp1 = ths.head().compareTo(other.head());
+ int cmp1 = ths.head().erlangCompareTo(other.head());
if (cmp1 != 0)
return cmp1;
@@ -64,7 +64,7 @@ int compare_same(EObject rhs) {
EObject otherTail = other.tail();
if (! (thisTail instanceof ECons &&
otherTail instanceof ECons))
- return thisTail.compareTo(otherTail);
+ return thisTail.erlangCompareTo(otherTail);
else {
ths = thisTail.testCons();
other = otherTail.testCons();
View
3 src/main/java/erjang/EDouble.java
@@ -68,8 +68,7 @@ public boolean equals(Object other) {
}
@Override
- public
- boolean equalsExactly(EObject rhs) {
+ public boolean equalsExactly(EObject rhs) {
return rhs.r_equals_exactly(this);
}
View
73 src/main/java/erjang/EObject.java
@@ -23,6 +23,7 @@
import java.io.IOException;
import java.util.List;
import java.util.Set;
+import java.util.Comparator;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
@@ -32,7 +33,34 @@
import erjang.m.ets.ETermPattern;
import erjang.m.java.JavaObject;
-public abstract class EObject implements Comparable<EObject> {
+/** The base class for representing Erlang values.
+ * This class embodíes in particular (the base of) the following concerns:
+ * - Dynamic value kind testing;
+ * - Erlang value ordering (incl. "compare-same") and "exact equality"
+ * (as used in matching).
+ * - The unary and binary operators built into the Erlang language
+ *
+ * Furthermore, the class contains helper methods concerned with:
+ * - building and flattening of lists;
+ * - counting up and down, and integer zero-testing. (TODO: consider these)
+ *
+ * Regarding EObjects and collections:
+ *
+ * Erjang will need to form both hash tables and ordered collections
+ * of EObjects.
+ * For hashing purposes, EObject implements equals() and hashCode().
+ * While EObjects have an ordering (the value ordering defined by Erlang),
+ * it is not total: an integer and its floating-point equivalent are
+ * considered equivalent as far as the ordering is concerned, though
+ * not by equals().
+ * EObject therefore <i>intentionally</i> does not implement Comparable;
+ * instead, use the explicit comparator EObject.ERLANG_ORDERING.
+ * (This is also the reason that its comparison method is called
+ * erlangCompareTo() rather than plain compareTo().)
+ */
+public abstract class EObject {
+ public static final ErlangOrderComparator ERLANG_ORDERING =
+ new ErlangOrderComparator();
public ECons cons(EObject h)
{
@@ -264,18 +292,18 @@ public Type emit_const(MethodVisitor mv) {
public boolean equals(Object other) {
if (other == this) return true;
if (other instanceof EObject) {
- return compareTo((EObject) other) == 0;
+ return equalsExactly((EObject) other);
} else {
return false;
}
}
public boolean equals(EObject other) {
if (other == this) return true;
- return compareTo(other) == 0;
+ return equalsExactly(other);
}
-
- public int compareTo(EObject rhs) {
+
+ public final int erlangCompareTo(EObject rhs) {
if (rhs == this) return 0;
int cmp1 = cmp_order();
int cmp2 = rhs.cmp_order();
@@ -296,8 +324,16 @@ public int compareTo(EObject rhs) {
int r_compare_same(EDouble lhs) { throw new NotImplemented(); }
int r_compare_same(EInternalPID lhs) { throw new NotImplemented(); }
+ /** Erlang "equals exactly", also called "matches" (=:= operator).
+ * Is overridden by some subclasses, inclusing composites.
+ */
public boolean equalsExactly(EObject rhs) {
- return compareTo(rhs) == 0;
+ return erlangCompareTo(rhs) == 0;
+ }
+
+ /** Erlang "compares same" (== operator). */
+ public final boolean erlangEquals(EObject rhs) {
+ return erlangCompareTo(rhs) == 0;
}
boolean r_equals_exactly(ESmall lhs) { return false; }
@@ -335,7 +371,7 @@ public EAtom is_function(EObject arity) {
* @return
*/
public EAtom ge(EObject o2) {
- return ERT.box ( this.compareTo(o2) >= 0 );
+ return ERT.box ( this.erlangCompareTo(o2) >= 0 );
}
@@ -400,27 +436,27 @@ public void encode(EOutputStream eos) {
}
final public boolean is_eq(EObject other) {
- return equals(other);
+ return erlangEquals(other);
}
final public boolean is_eq_exact(EObject other) {
return equalsExactly(other);
}
final public boolean is_ne(EObject other) {
- return !equals(other);
+ return !erlangEquals(other);
}
final public boolean is_ne_exact(EObject other) {
return !equalsExactly(other);
}
final public boolean is_lt(EObject other) {
- return this.compareTo(other) < 0;
+ return this.erlangCompareTo(other) < 0;
}
final public boolean is_ge(EObject other) {
- return this.compareTo(other) >= 0;
+ return this.erlangCompareTo(other) >= 0;
}
/**
@@ -449,5 +485,18 @@ public EObject prepend(ESeq list) {
public ENumber inc() { return ESmall.ONE.add(this); }
public ENumber dec() { return ESmall.MINUS_ONE.add(this); }
public boolean is_zero() { return false; }
-
+
+
+ public static abstract class ValueComparator implements Comparator<EObject> {
+ public abstract int compare(EObject a, EObject b);
+ }
+
+ /** Comparator which doesn't distibguish between integers and floats.
+ * Note: this comparator imposes orderings that are inconsistent with equals.
+ */
+ private static class ErlangOrderComparator extends ValueComparator {
+ public int compare(EObject a, EObject b) {
+ return a.erlangCompareTo(b);
+ }
+ }
}
View
12 src/main/java/erjang/ERT.java
@@ -348,17 +348,19 @@ public static void test_fun(EObject orig, EFun fun) {
static EInteger max_send_time = ERT.box(4294967295L);
static ESmall zero = ERT.box(0);
- public static final <T> boolean gt(Comparable<T> v1, T v2) {
- return v1.compareTo(v2) > 0;
+ public static final boolean gt(EInteger v1, EInteger v2) {
+ return v1.erlangCompareTo(v2) > 0;
}
- public static final <T> boolean lt(Comparable<T> v1, T v2) {
- return v1.compareTo(v2) < 0;
+ public static final boolean lt(EInteger v1, EInteger v2) {
+ return v1.erlangCompareTo(v2) < 0;
}
+/*
public static final <T> boolean le(Comparable<T> v1, T v2) {
- return v1.compareTo(v2) <= 0;
+ return v1.erlangCompareTo(v2) <= 0;
}
+ */
@BIF
public static EObject cancel_timer(EObject ref)
View
8 src/main/java/erjang/EString.java
@@ -184,7 +184,7 @@ public boolean equals(Object obj) {
return false;
}
- return compareTo((EObject) obj) == 0;
+ return equalsExactly((EObject) obj);
}
@@ -391,7 +391,7 @@ int compare_same(EObject rhs) {
return 1; // I AM LONGER
}
- int cmp = (new ESmall(charAt(i++))).compareTo(rseq.head());
+ int cmp = (new ESmall(charAt(i++))).erlangCompareTo(rseq.head());
if (cmp != 0)
return cmp;
@@ -401,12 +401,12 @@ int compare_same(EObject rhs) {
continue;
}
- return -res.compareTo(new EString(data, i));
+ return -res.erlangCompareTo(new EString(data, i));
}
}
- return -rhs.compareTo(this);
+ return -rhs.erlangCompareTo(this);
}
/*
View
2 src/main/java/erjang/ETask.java
@@ -51,7 +51,7 @@
*/
public abstract H self_handle();
- protected Set<EHandle> links = new ConcurrentSkipListSet<EHandle>();
+ protected Set<EHandle> links = new ConcurrentSkipListSet<EHandle>(EObject.ERLANG_ORDERING);
protected Map<ERef,EHandle> monitors = new ConcurrentHashMap<ERef, EHandle>();
public void unlink(EHandle other) throws Pausable {
View
22 src/main/java/erjang/ETuple.java
@@ -67,7 +67,7 @@ int compare_same(EObject rhs) {
return 1;
for (int i = 1; i <= arity(); i++) {
- int cmp = elm(i).compareTo(other.elm(i));
+ int cmp = elm(i).erlangCompareTo(other.elm(i));
if (cmp != 0)
return cmp;
}
@@ -498,26 +498,6 @@ public int hashCode() {
return result;
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof ETuple) {
- ETuple ot = (ETuple) obj;
- if (arity() != ot.arity())
- return false;
- for (int i = 0; i < arity(); i++) {
- if (!elm(i + 1).equals(ot.elm(i + 1)))
- return false;
- }
- return true;
- }
- return false;
- }
-
@Override
public boolean equalsExactly(EObject obj) {
if (obj instanceof ETuple) {
View
2 src/main/java/erjang/beam/CompilerVisitor.java
@@ -2574,7 +2574,7 @@ public int compareTo(Case o) {
return -1;
if (h > ho)
return 1;
- return value().compareTo(o.value());
+ return value().erlangCompareTo(o.value());
}
}
View
8 src/main/java/erjang/beam/interpreter/ops.spec
@@ -147,18 +147,18 @@ is_ne_exact lbl a b:
if (GET(a).equalsExactly(GET(b))) GOTO(lbl);
is_eq lbl a b:
- if (GET(a).compareTo(GET(b)) != 0) GOTO(lbl);
+ if (GET(a).erlangCompareTo(GET(b)) != 0) GOTO(lbl);
is_ne lbl a b:
- if (GET(a).compareTo(GET(b)) == 0) GOTO(lbl);
+ if (GET(a).erlangCompareTo(GET(b)) == 0) GOTO(lbl);
# src1.equals(src2) => GOTO(lbl);
## (src1 instanceof Literal && src2 instanceof Literal && !src1.equals(src2)) => {}
is_lt lbl a b:
- if (GET(a).compareTo(GET(b)) >= 0) GOTO(lbl);
+ if (GET(a).erlangCompareTo(GET(b)) >= 0) GOTO(lbl);
is_ge lbl a b:
- if (GET(a).compareTo(GET(b)) < 0) GOTO(lbl);
+ if (GET(a).erlangCompareTo(GET(b)) < 0) GOTO(lbl);
%class LDS(label:L, dest:D, src:S)
is_function2 lbl subject arity:
View
4 src/main/java/erjang/beam/repr/ModuleRepr.java
@@ -98,7 +98,7 @@ public ETuple toSymbolic() {
public EObject symbolicAttributes() {
// Sort the attributes to make them comparable to beam_disasm's output:
EObject[] attrs = attributes.toArray();
- Arrays.sort(attrs);
+ Arrays.sort(attrs, EObject.ERLANG_ORDERING);
return ESeq.fromArray(attrs);
}
@@ -110,7 +110,7 @@ public ESeq symbolicExportList() {
new ESmall(f.arity),
new ESmall(f.label)));
}
- Collections.sort(symExports);
+ Collections.sort(symExports, EObject.ERLANG_ORDERING);
return ESeq.fromList(symExports);
}
View
40 src/main/java/erjang/m/erlang/ErlBif.java
@@ -773,7 +773,7 @@ static public ENumber div(ENumber n1, int v2) {
if ((n1 = v1.testInteger()) != null &&
(n2 = v2.testInteger()) != null)
{
- if (n2.equals(ESmall.ZERO)) return null;
+ if (n2.erlangEquals(ESmall.ZERO)) return null;
return n1.idiv(n2);
}
return null;
@@ -987,7 +987,7 @@ static public ENumber rem(EObject v1, EObject v2) {
@BIF(name = "rem", type = Type.GUARD)
static public EInteger rem$p(EObject v1, EObject v2) {
- if (v2.equals(ESmall.ZERO) || v1.testInteger()==null || v2.testInteger()==null) {
+ if (v2.erlangEquals(ESmall.ZERO) || v1.testInteger()==null || v2.testInteger()==null) {
return null;
} else {
return v1.irem(v2);
@@ -1046,7 +1046,7 @@ static public ETuple3 now() {
@BIF(name = "==", type = Type.GUARD)
public static final EAtom is_eq$p(EObject a1, EObject a2) {
- return ERT.guard(a1.equals(a2));
+ return ERT.guard(a1.erlangEquals(a2));
}
@BIF(name = "=/=", type = Type.GUARD)
@@ -1135,12 +1135,12 @@ public static final EAtom eqxp(EObject a1, EObject a2) {
@BIF(name = "==", type = Type.GUARD)
public static final EAtom is_eq_op$g(EObject a1, EObject a2) {
- return ERT.guard(a1.equals(a2));
+ return ERT.guard(a1.erlangEquals(a2));
}
@BIF(name = "==")
public static final EAtom is_eq_op(EObject a1, EObject a2) {
- return a1.equals(a2) ? ERT.TRUE : ERT.FALSE;
+ return a1.erlangEquals(a2) ? ERT.TRUE : ERT.FALSE;
}
@BIF(name = "=/=", type = Type.GUARD)
@@ -1150,69 +1150,69 @@ public static final EAtom is_eq_op(EObject a1, EObject a2) {
@BIF(name = ">=", type = Type.GUARD)
public static final EAtom is_ge$g2(EObject a1, EObject a2) {
- return ERT.guard( a1.compareTo(a2) >= 0 );
+ return ERT.guard( a1.erlangCompareTo(a2) >= 0 );
}
@BIF(name = ">", type = Type.GUARD)
public static final EAtom is_gt$g(EObject a1, EObject a2) {
- return ERT.guard( a1.compareTo(a2) > 0 );
+ return ERT.guard( a1.erlangCompareTo(a2) > 0 );
}
@BIF(name = "is_ge", type = Type.GUARD)
public static final EAtom is_ge$g(EObject a1, EObject a2) {
- return ERT.guard(a1.compareTo(a2) >= 0);
+ return ERT.guard(a1.erlangCompareTo(a2) >= 0);
}
@BIF(name = "/=")
public static final EAtom is_ne(EObject a1, EObject a2) {
- boolean eq = a1.equals(a2);
+ boolean eq = a1.erlangEquals(a2);
return ERT.box(!eq);
}
@BIF(name = "/=", type = Type.GUARD)
public static final EAtom is_ne$g(EObject a1, EObject a2) {
- boolean eq = a1.equals(a2);
+ boolean eq = a1.erlangEquals(a2);
return ERT.guard(!eq);
}
@BIF(name = "<", type = Type.GUARD)
public static final EAtom is_lt$g(EObject a1, EObject a2) {
- return ERT.guard(a1.compareTo(a2) < 0);
+ return ERT.guard(a1.erlangCompareTo(a2) < 0);
}
@BIF(name = "=<")
public static final EAtom is_le(EObject a1, EObject a2) {
- return ERT.box(a1.compareTo(a2) <= 0);
+ return ERT.box(a1.erlangCompareTo(a2) <= 0);
}
@BIF(name = "<")
public static final EAtom is_lt(EObject a1, ESmall a2) {
- return ERT.box( a2.compareTo(a1) > 0 );
+ return ERT.box( a2.erlangCompareTo(a1) > 0 );
}
@BIF(name = "<")
public static final EAtom is_lt(ESmall a1, EObject a2) {
- return ERT.box( a1.compareTo(a2) < 0 );
+ return ERT.box( a1.erlangCompareTo(a2) < 0 );
}
@BIF(name = "=<", type = Type.GUARD)
public static final EAtom is_le$g(EObject a1, EObject a2) {
- return ERT.guard(a1.compareTo(a2) <= 0);
+ return ERT.guard(a1.erlangCompareTo(a2) <= 0);
}
@BIF(name = "<")
public static final EAtom is_lt(EObject a1, EObject a2) {
- return ERT.box(a1.compareTo(a2) < 0);
+ return ERT.box(a1.erlangCompareTo(a2) < 0);
}
@BIF(name = ">=")
public static final EAtom is_ge(EObject a1, EObject a2) {
- return ERT.box(a1.compareTo(a2) >= 0);
+ return ERT.box(a1.erlangCompareTo(a2) >= 0);
}
@BIF
public static final EAtom is_eq(EObject a1, EObject a2) {
- return ERT.box(a1.compareTo(a2) == 0);
+ return ERT.box(a1.erlangEquals(a2));
}
@BIF(name = "=:=")
@@ -1511,12 +1511,12 @@ public static EAtom and(EObject o1, EObject e2) {
@BIF(name = "<")
public static EAtom lt(EObject v1, EObject v2) {
- return ERT.box(v1.compareTo(v2) < 0);
+ return ERT.box(v1.erlangCompareTo(v2) < 0);
}
@BIF(name = ">")
public static EAtom gt(EObject v1, EObject v2) {
- return ERT.box(v1.compareTo(v2) > 0);
+ return ERT.box(v1.erlangCompareTo(v2) > 0);
}
@BIF(type = Type.GUARD, name = "or")
View
2 src/main/java/erjang/m/erlang/ErlConvert.java
@@ -178,7 +178,7 @@ public static EInteger list_to_integer(EObject obj) {
// remove leading +
if (!seq.isNil()) {
- if (seq.head().equals(PLUS_SIGN)) {
+ if (seq.head().equalsExactly(PLUS_SIGN)) {
seq = seq.tail().testString();
if (seq == null) {
View
2 src/main/java/erjang/m/erlang/ErlList.java
@@ -49,7 +49,7 @@ public static ECons listDiff(EObject a1, EObject a2) {
for (ESeq cur = l2; !cur.isNil(); cur=cur.tail()) {
EObject elm = cur.head();
for (int i=tmp_start; i<tmp.length; i++) {
- if (tmp[i] != null && tmp[i].equals(elm)) {
+ if (tmp[i] != null && tmp[i].equalsExactly(elm)) {
// Delete element
tmp[i] = null;
View
18 src/main/java/erjang/m/ets/EMatchSpec.java
@@ -198,40 +198,40 @@ public EqualsPattern(EObject term) {
@Override
public boolean match(ECons c, EMatchContext r) {
- return c.compareTo(value) == 0;
+ return c.erlangEquals(value);
}
@Override
public boolean match(ETuple t, EMatchContext r) {
- return t.compareTo(value) == 0;
+ return t.erlangEquals(value);
}
public boolean match(EPID pid, EMatchContext r) {
- return pid.compareTo(value) == 0;
+ return pid.erlangEquals(value);
}
public boolean match(ERef ref, EMatchContext r) {
- return ref.compareTo(value) == 0;
+ return ref.erlangEquals(value);
}
public boolean match(EPort port, EMatchContext r) {
- return port.compareTo(value) == 0;
+ return port.erlangEquals(value);
}
public boolean match(EAtom am, EMatchContext r) {
- return am.compareTo(value) == 0;
+ return am.erlangEquals(value);
}
public boolean match(EFun fu, EMatchContext r) {
- return fu.compareTo(value) == 0;
+ return fu.erlangEquals(value);
}
public boolean match(EBitString bits, EMatchContext r) {
- return bits.compareTo(value) == 0;
+ return bits.erlangEquals(value);
}
public boolean match(ENumber num, EMatchContext r) {
- return num.compareTo(value) == 0;
+ return num.erlangEquals(value);
}
}
View
10 src/main/java/erjang/m/ets/ETableSet.java
@@ -53,11 +53,11 @@
ETableSet(EProc owner, EAtom type, EInteger tid, EAtom aname, EAtom access, int keypos,
boolean write_concurrency, boolean is_named, EInternalPID heirPID, EObject heirData) {
- super(owner, type, tid, aname, access, keypos,
- is_named, heirPID, heirData,
- type == Native.am_set
- ? PersistentHashMap.EMPTY
- : PersistentTreeMap.EMPTY);
+ super(owner, type, tid, aname, access, keypos,
+ is_named, heirPID, heirData,
+ type == Native.am_set
+ ? PersistentHashMap.EMPTY
+ : new PersistentTreeMap(null, EObject.ERLANG_ORDERING));
this.ordered = type != Native.am_set;
}
View
74 src/main/java/erjang/package.html
@@ -0,0 +1,74 @@
+<html>
+<body>
+<p>Central Erjang classes, including representation of data and processes.</p>
+
+<p><i>Developer's note: The contents of this package is rather diverse; it might be a good idea to move data representation classes to <tt>erjang.data</tt> and move some support classes to <tt>erjang.util</tt>.</i>
+
+<h2>Data representation</h2>
+<p>Erlang values are represented in Erjang through the class hierarchy rooted in EObject.
+<br>The class hierarchy is depicted below:
+</p>
+<pre>
+ +-------+
+ |EObject|
+ +-------+
+ ^
+ ______________________________|____________________________
+ | | | | | | | | |
+ | +-----+ | +----+ | +-------------+ | +----------+ |
+ | |EAtom| | |ERef| | |&laquo;EPseudoTerm&raquo;| | |EBitstring| |
+ | +-----+ | +----+ | +-------------+ | +----------+ |
+ | | | | ^ |
++------+ <span style="background: #cfc">+-------+</span> +--------+ <span style="background: #ccf">+---------+</span> | <span style="background: #fcc">+---------+</span>
+|&laquo;EFun&raquo;| <span style="background: #cfc">|&laquo;ECons&raquo;|</span> |&laquo;ETuple&raquo;| <span style="background: #ccf">|&laquo;ENumber&raquo;|</span> +-------+ <span style="background: #fcc">|&laquo;EHandle&raquo;|</span>
++------+ <span style="background: #cfc">+-------+</span> +--------+ <span style="background: #ccf">+---------+</span> |EBinary| <span style="background: #fcc">+---------+</span>
+ ^ <span style="background: #cfc"> ^ </span> ^ <span style="background: #ccf"> ^ </span> +-------+ <span style="background: #fcc"> ^ </span>
+ | <span style="background: #cfc"> | </span> | <span style="background: #ccf"> ___|___ </span> <span style="background: #fcc"> ____|___ </span>
++.......+ <span style="background: #cfc"> | </span> +.......+ <span style="background: #ccf"> | | </span> <span style="background: #fcc"> | | </span>
+:one per: <span style="background: #cfc"> | </span> :one per: <span style="background: #ccf">+----------+ +-------+</span> <span style="background: #fcc">+-------+ +------+</span>
+: arity : <span style="background: #cfc"> | </span> : arity : <span style="background: #ccf">|&laquo;EInteger&raquo;| |EDouble|</span> <span style="background: #fcc">|&laquo;EPort&raquo;| |&laquo;EPID&raquo;|</span>
++.......+ <span style="background: #cfc"> | </span> +.......+ <span style="background: #ccf">+----------+ +-------+</span> <span style="background: #fcc">+-------+ +------+</span>
+<span style="background: #cfc"> ________|________ </span> <span style="background: #ccf"> ^ </span> <span style="background: #fcc"> ^ ^ </span>
+<span style="background: #cfc"> | | | </span> <span style="background: #ccf"> __|____ </span> <span style="background: #fcc"> | _|____________ </span>
+<span style="background: #cfc"> +-----+ +------+ +--------+</span> <span style="background: #ccf"> | | </span> <span style="background: #fcc">+-------------+ | |</span>
+<span style="background: #cfc"> |EPair| |&laquo;ESeq&raquo;| |EBinList|</span> <span style="background: #ccf">+------+ +----+</span> <span style="background: #fcc">|EInternalPort| +------------+ +------------+</span>
+<span style="background: #cfc"> +-----+ +------+ +--------+</span> <span style="background: #ccf">|ESmall| |EBig|</span> <span style="background: #fcc">+-------------+ |EInternalPID| |EExternalPID|</span>
+<span style="background: #cfc"> ^ </span> <span style="background: #ccf">+------+ +----+</span> <span style="background: #fcc"> +------------+ +------------+</span>
+<span style="background: #cfc"> | </span>
+<span style="background: #cfc"> ________|____________________________________________ </span>
+<span style="background: #cfc"> | | | | | | </span>
+<span style="background: #cfc">+----+ +-----+ +-------+ +----------+ +-----------+ +----------+</span>
+<span style="background: #cfc">|ENil| |EList| |EString| |EBigString| |EStringList| |&laquo;ELazySeq&raquo;|</span>
+<span style="background: #cfc">+----+ +-----+ +-------+ +----------+ +-----------+ +----------+</span>
+
+</pre>
+
+<ul>
+ <li>{@link erjang.EAtom} and {@link erjang.ERef} represent Erlang atoms and references, respectively.
+ <li>{@link erjang.ETuple} and {@link erjang.EFun} represent Erlang tuples and function values, respectively; a concrete subclass exists for each arity. Some of these subclasses are created at runtime, but in general, they are generated as needed at runtime.
+ <li>{@link erjang.EBitstring} represents Erlang bit strings. {@link erjang.EBinary} is a specialization for bitstrings ending on byte boundaries. (This subclass relation is just as in Erlang, cf. <tt>erlang:is_bitstring/1</tt> and <tt>erlang:is_binary/1</tt>.)
+ <li>{@link erjang.ECons} represents lists (the name is a bit of a misnomer). There are several list representation classes; see below for details.
+ <li>{@link erjang.ENumber} represents numbers (cf. <tt>erlang:is_number/1</tt>). Floats are represented by {@link erjang.EDouble}. Integers are represented by {@link erjang.ESmall} if they fit into 32 bits, and by {@link erjang.EBig} otherwise.
+ <li>{@link erjang.EHandle} represents handles to active objects (entities with inboxes): processes ({@link erjang.EPID}) and ports ({@link erjang.EPort}). PIDs are represented differently according to whether the process lives at this node ({@link erjang.EInternalPID}) or in a remote node ({@link erjang.EExternalPID}).
+ <li>Finally, {@link erjang.EPseudoTerm} represents an entity which is not an Erlang term but which nevertheless needs to have EObject type. Examples include {@link erjang.EBinMatchState} and {@link erjang.ETailMarker}.
+</ul>
+
+
+<h3>List representation</h3>
+<p>For performance reasons, Erjang has several different list representations.
+<br>The most general representation is using {@link erjang.ENil} and {@link erjang.EPair} &mdash; for the empty list and non-empty lists, respectively.
+
+<p>Furthermore, the following important special cases are accomodated:
+
+<ul>
+ <li>Lists which are known to be pure: {@link erjang.ESeq} and subclasses; {@link erjang.EList} handles the general case.
+ <li>Pure lists of integers in the range [0;2<sup>8</sup>-1] (Ascii/Latin-1 strings; list equivalent of binaries): {@link erjang.EString}
+ <li>Pure lists of integers in the range [0;2<sup>16</sup>-1] (Unicode strings): {@link erjang.EBigString}
+ <li>Lists with a prefix of integers in the range [0;2<sup>8</sup>-1] (I/O-lists): {@link erjang.EBinList}
+ <li>Pure lists with a prefix of integers in the range [0;2<sup>8</sup>-1] (I/O-lists): {@link erjang.EStringList}
+ <li>Internal lazily-generated lists (exception stack traces): {@link erjang.ELazySeq}
+</ul>
+
+
+</body>
+</html>

0 comments on commit a90887e

Please sign in to comment.