[e-cvs] cvs commit: e/src/jsrc/org/erights/e/meta/java/lang CharacterSugar.java
markm@eros.cs.jhu.edu
markm@eros.cs.jhu.edu
Mon, 16 Jul 2001 06:42:48 -0400
markm 01/07/16 06:42:48
Modified: doc/elang/collect index.html tables.html
doc/elang/io text-file-io.html
src/esrc/scripts eBrowser.e
src/jsrc/org/erights/e/elib/base TextWriter.java
src/jsrc/org/erights/e/elib/tables Twine.java
src/jsrc/org/erights/e/meta/java/io BufferedReaderSugar.java
src/jsrc/org/erights/e/meta/java/lang CharacterSugar.java
Log:
updoc driven progress
Revision Changes Path
1.24 +2 -2 e/doc/elang/collect/index.html
Index: index.html
===================================================================
RCS file: /cvs/e/doc/elang/collect/index.html,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- index.html 2001/05/07 08:29:24 1.23
+++ index.html 2001/07/16 10:42:48 1.24
@@ -83,7 +83,7 @@
<pre>? def erightsDir := <file:/erights.org>
# value: <file:/erights.org/>
-? erightsDir["Setup.bat"] length
+? erightsDir["Setup.bat"] length()
# value: 359
</pre>
</blockquote>
@@ -94,7 +94,7 @@
<p>
<blockquote>
<pre>? for name => file in erightsDir {
-> println(`$name is ${file length} bytes`)
+> println(`$name is ${file length()} bytes`)
> }
bin is 0 bytes
Setup.bat is 359 bytes
1.31 +49 -48 e/doc/elang/collect/tables.html
Index: tables.html
===================================================================
RCS file: /cvs/e/doc/elang/collect/tables.html,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- tables.html 2001/05/07 08:29:24 1.30
+++ tables.html 2001/07/16 10:42:48 1.31
@@ -333,61 +333,60 @@
<p>Here's the color spectrum according to a silly mnemonic many of us learned
in grade school, represented as an ConstList:</p>
<p>
- <blockquote>
+ <blockquote>
<pre>? def spectrum := <b>[</b>"red", "orange", "yellow", "green",
> "blue", "indigo", "violet"<b>]</b>
-# value: [red, orange, yellow, green, blue, indigo, violet] </pre>
+# value: ["red", "orange", "yellow", "green", "blue", "indigo", "violet"] </pre>
</blockquote>
We can look up the value at a particular index using the familiar indexing
notation:
- <blockquote>
+ <blockquote>
<pre>
? spectrum<b>[</b>2<b>]
-</b># value: yellow </pre>
+</b># value: "yellow" </pre>
</blockquote>
<p>We can extract sub-lists, or <i>runs</i>, by using parens and providing
a start position and a stop position:</p>
<p>
- <blockquote>
+ <blockquote>
<pre>? spectrum(1, 3)
-# value: [orange, yellow]
-</pre>
+# value: ["orange", "yellow"]</pre>
</blockquote>
<p>This extracts the run from the start position, including the start position,
up to <i>but not including</i> the stop position. The stop position is
the first position after the run.</p>
<p>We can loop through the spectrum using the <a href="../blocks/forExpr.html">for
loop</a>: </p>
- <blockquote>
+ <blockquote>
<pre>
-? def mnemonic := ""
-# value:
-
+? var mnemonic := ""
+# value: ""
+
? <b>for</b> color <b>in</b> spectrum {
> mnemonic <b>+=</b> color[0]
> }
? mnemonic
-# value: roygbiv
+# value: "roygbiv"
</pre>
</blockquote>
<p>What about the "<code>+=</code>" to accumulate the mnemonic?
ELists can be concatenated with "+". Here's the spectrum rotated:</p>
- <blockquote>
- <pre>? spectrum(3, spectrum size) <b>+</b> spectrum(0, 3)
-# value: [green, blue, indigo, violet, red, orange, yellow]</pre>
+ <blockquote>
+ <pre>? spectrum(3, spectrum size()) <b>+</b> spectrum(0, 3)
+# value: ["green", "blue", "indigo", "violet", "red", "orange", "yellow"]</pre>
</blockquote>
<p><code>spectrum(0, 3)</code> requests the run from 0 inclusive to 3 exclusive.
<code>spectrum(3, spectrum size)</code> requests the run from 3 inclusive
to the end.</p>
<p>The values in an EList can be any object, including itself:</p>
<p>
- <blockquote>
+ <blockquote>
<pre>? def infinitree := ["left", infinitree, "rt"]
-# value: [left, ***CYCLE***, rt]
+# value: ["left", ***CYCLE***, "rt"]
? infinitree[1][1][1][0]
-# value: left </pre>
+# value: "left" </pre>
</blockquote>
<p>Although this is implemented as a cyclic data structure, it represents
an infinite repeating data structure:</p>
@@ -403,35 +402,37 @@
we modify this list, its state will <i>diverge</i> from spectrum's, so
that's how we ask for it:</p>
<p>
- <blockquote>
- <pre>? def flextrum := spectrum <b>diverge</b>
-# value: [red, orange, yellow, green, blue, indigo, violet] diverge
+ <blockquote>
+ <pre>? def flextrum := spectrum <b>diverge</b>()
+# value: ["red", "orange", "yellow", "green", "blue", "indigo", "violet"] diverge
</pre>
</blockquote>
<p>We can then assign to individual elements</p>
<p>
- <blockquote>
+ <blockquote>
<pre>? flextrum<b>[</b>1<b>] :=</b> "burnt-orange"
-
+# value: "burnt-orange"
+
? flextrum
-# value: [red, burnt-orange, yellow, green, blue, indigo, violet] diverge
+# value: ["red", "burnt-orange", "yellow", "green", "blue", "indigo", "violet"] diverge
</pre>
</blockquote>
<p>or to runs</p>
<p>
- <blockquote>
+ <blockquote>
<pre>? flextrum<b>(</b>3,6<b>) :=</b> ["cyan", "sky-blue"]
-
+# value ["cyan", "sky-blue"]
+
? flextrum
-# value: [red, burnt-orange, yellow, cyan, sky-blue, violet] diverge</pre>
+# value: ["red", "burnt-orange", "yellow", "cyan", "sky-blue", "violet"] diverge</pre>
</blockquote>
<p>Notice that the size of the run replaced can differ from the size of
the run replacing it. The rest of the list slides over to accommodate.
A <i>read-only</i> facet of a list allows one to observe the current state
of the list, but not to change it.</p>
- <blockquote>
- <pre>? def rainbow := flextrum <b>readOnly</b>
-# value: [red, burnt-orange, yellow, cyan, sky-blue, violet] diverge readOnly
+ <blockquote>
+ <pre>? def rainbow := flextrum <b>readOnly</b>()
+# value: ["red", "burnt-orange", "yellow", "cyan", "sky-blue", "violet"] diverge readOnly
? rainbow[2] := "light yellow"
# problem: <NoSuchMethodException: put/2>
@@ -442,7 +443,7 @@
one, or we can take a <i>snapshot</i>.</p>
<p>
<blockquote>
- <pre>? def colors := flextrum <b>snapshot</b>
+ <pre>? def colors := flextrum <b>snapshot</b>()
# value: [red, burnt-orange, yellow, cyan, sky-blue, violet]
? flextrum(1,1) := ["mauve"]
@@ -473,9 +474,9 @@
<p>
<blockquote>
<pre>? def parentMapM := ["MarkM" <b>=></b> ["Ann", "Bernie"],
-> "Jeff" <b>=></b> ["Ann", "Bernie"],
-> "Ann" <b>=></b> ["Grina", "Isaac"],
-> "Max" <b>=></b> ["Lisa", "Jeff"]]</pre>
+> "Jeff" <b>=></b> ["Ann", "Bernie"],
+> "Ann" <b>=></b> ["Grina", "Isaac"],
+> "Max" <b>=></b> ["Lisa", "Jeff"]]</pre>
</blockquote>
<p>Notice that a two-element EList is a natural way to write a pair.</p>
<p>Of course, we can look up someone's parents </p>
@@ -502,10 +503,10 @@
<blockquote>
<pre>
? def parentMapT := ["Terry" => ["Betty", "Bill"],
-> "Cindy" => ["Betty", "Bill"],
-> "Everett" => ["Betty", "Bill"],
-> "Angie" => ["Cindy", "Louis"],
-> "Mandy" => ["Cindy", "Louis"]]</pre>
+> "Cindy" => ["Betty", "Bill"],
+> "Everett" => ["Betty", "Bill"],
+> "Angie" => ["Cindy", "Louis"],
+> "Mandy" => ["Cindy", "Louis"]]</pre>
</blockquote>
For example, let's say <code>parentMapT</code> represents another family,
and we wish to combine the families
@@ -513,7 +514,7 @@
<pre>
? def parentMapMT := parentMapT <b>|</b> parentMapM
-? (parentMapM <b>&</b> parentMapT) size
+? (parentMapM <b>&</b> parentMapT) size()
# value: 0</pre>
</blockquote>
<p>The "<code>|</code>" operator brings about a union of the families
@@ -560,8 +561,8 @@
<p>
<blockquote>
<pre>? def CapLanguages := ["E" => null,
-> "Joule" => null,
-> "Trusty Scheme" => null]
+> "Joule" => null,
+> "Trusty Scheme" => null]
# value: [E => null, Trusty Scheme => null, Joule => null]
</pre>
</blockquote>
@@ -569,7 +570,7 @@
to write. This convenience</p>
<p>
<blockquote>
- <pre>? def CapLanguages := ["E", "Joule", "Trusty Scheme"] <b>asKeys</b>
+ <pre>? def CapLanguages := ["E", "Joule", "Trusty Scheme"] <b>asKeys</b>()
# value: [E => null, Trusty Scheme => null, Joule => null]
</pre>
</blockquote>
@@ -581,10 +582,10 @@
Open-Source systems.</p>
<p>
<blockquote>
- <pre>? def CapOSs := ["Hydra", "KeyKOS", "EROS"] asKeys
+ <pre>? def CapOSs := ["Hydra", "KeyKOS", "EROS"] asKeys()
# value: [Hydra => null, EROS => null, KeyKOS => null]
-? def OpenSource := ["Linux", "Netscape", "Apache", "E", "EROS"] asKeys
+? def OpenSource := ["Linux", "Netscape", "Apache", "E", "EROS"] asKeys()
# value: [E => null, EROS => null, Apache => null,
# Linux => null, Netscape => null]
@@ -592,7 +593,7 @@
# value: [Hydra => null, E => null, Joule => null,
# Trusty Scheme => null, EROS => null, KeyKOS => null]
-? def OpenCaps := CapSystems <b>&</b> OpenSource
+? def OpenCaps := CapSystems <b>&</b> OpenSource
# value: [E => null, EROS => null]
? def ClosedCaps := CapSystems <b>-</b> OpenSource
@@ -603,15 +604,15 @@
<p>Since we know we're only interested in the keys, by asking for a list
of the keys:</p>
<blockquote>
- <pre>? OpenCaps <b>getKeys</b>
+ <pre>? OpenCaps <b>getKeys</b>()
# value: [E, EROS]
</pre>
</blockquote>
<p>we see the list of all open-source capability systems known to this author.
But beware, the EMap is not the terrain.</p>
<h3>Changing EMaps</h3>
- <p>EMaps respond to <code>diverge</code>, <code>snapshot</code>, and <code>readOnly</code>
- in exactly the same way ELists do.</p>
+ <p>EMaps respond to <code>diverge()</code>, <code>snapshot()</code>, and
+ <code>readOnly()</code> in exactly the same way ELists do.</p>
<!-- #EndEditable --></TD>
<TD WIDTH="10%"> </TD>
</TR>
1.5 +173 -141 e/doc/elang/io/text-file-io.html
Index: text-file-io.html
===================================================================
RCS file: /cvs/e/doc/elang/io/text-file-io.html,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- text-file-io.html 2001/07/16 03:28:30 1.4
+++ text-file-io.html 2001/07/16 10:42:48 1.5
@@ -46,15 +46,38 @@
</TR>
</TABLE>
<hr>
- <!-- #BeginEditable "LongBody" -->
- <p>As explained in <a href="uri-exprs.html"><i>URI Expressions</i></a>,
- the value of a "file:" URI expression is a java.io.File object.
- Such a file object doesn't necessarily represent a file that already exists
- on your file system. It might represent an existing directory, an existing
- "normal" file (a non-directory), or it might represent a file
- that doesn't yet exist -- a potential file or directory. You can test
- which as follows:</p>
- <blockquote>
+ <!-- #BeginEditable "LongBody" -->
+ <h2>Pay no attention to the man behind the curtain.</h2>
+ <p>(The following lines of code set up your file system so that this test
+ will succeed. It fetches the text of the Jabberwock poem <a href="http://www.erights.org/elang/intro/jabberwocky.txt">from
+ the web</a> and places it into your "<code>c:/jabbertest/</code>"
+ directory, which it creates if needed. It also ensures deletes any files
+ or directories named "<code>jabberwocky2.txt</code>" or "<code>a</code>"
+ in that directory if such exists, since the following test cases make
+ use of their absence.)</p>
+ <p>
+ <blockquote>
+ <pre>? def poem := <http://www.erights.org/elang/intro/jabberwocky.txt>
+# value: <http://www.erights.org/elang/intro/jabberwocky.txt>
+
+? <file:c:/jabbertest> mkdirs(); null
+? <file:c:/jabbertest/jabberwocky.txt> setText(poem getText())
+? <file:c:/jabbertest/jabberwocky2.txt> delete(); null
+? <file:c:/jabbertest/a/b/c> delete(); null
+? <file:c:/jabbertest/a/b> delete(); null
+? <file:c:/jabbertest/a> delete(); null
+</pre>
+ </blockquote>
+ <hr>
+ <h1>"<file:...>" URI Expressions</h1>
+ <p>As explained in <a href="uri-exprs.html"><i>URI Expressions</i></a>,
+ the value of a "<code><file:...></code>" URI expression
+ is a <code>java.io.File</code> object. Such a file object doesn't necessarily
+ represent a file that already exists on your file system. It might represent
+ an existing directory, an existing "normal" file (a non-directory),
+ or it might represent a file that doesn't yet exist -- a potential file
+ or directory. You can test which as follows:</p>
+ <blockquote>
<pre>? def j1 := <file:c:/jabbertest/jabberwocky.txt>
# value: <file:c:/jabbertest/jabberwocky.txt>
@@ -67,13 +90,19 @@
? j1 <b>isDirectory</b>()
# value: false</pre>
</blockquote>
- <p>Not surprisingly, the jabberwocky.txt file we created earlier exists,
- and is a normal file, and therefore is not a directory.
- <blockquote>
+ <p>Not surprisingly, the jabberwocky.txt file we created earlier exists,
+ and is a normal file, and therefore is not a directory.
+ <blockquote>
<pre>? def j2 := <c:/jabbertest/jabberwocky2.txt>
-# value: <file:c:/jabbertest/jabberwocky2.txt>
-
-? j2 exists()
+# value: <file:c:/jabbertest/jabberwocky2.txt></pre>
+ </blockquote>
+ The URI here shows an allowable shorthand. For the convenience of MSWindows
+ users, if the URI begins with a single letter followed by a colon, then
+ a preceding "<code>file:</code>" is assumed. (On MSWindows this
+ single letter is known as the <i>drive letter</i>, and names approximately
+ a mounted volume.)
+ <blockquote>
+ <pre>? j2 exists()
# value: false
? j2 isNormal()
@@ -82,9 +111,9 @@
? j2 isDirectory()
# value: false</pre>
</blockquote>
- <p>On the other hand, "jabberwocky2.txt" does not yet exist, and
+ <p>On the other hand, "jabberwocky2.txt" does not yet exist, and
is therefore neither normal nor a directory.</p>
- <blockquote>
+ <blockquote>
<pre>? def desk := <c:/windows/desktop>
# value: <file:c:/windows/desktop/>
@@ -97,17 +126,17 @@
? desk isDirectory()
# value: true</pre>
</blockquote>
- <p>"desk" now represents our Windows Desktop which, as you can
+ <p>"desk" now represents our Windows Desktop which, as you can
see, is a directory.</p>
<blockquote>
<pre>? desk <b>getCanonicalPath</b>()
# value: "C:/WINDOWS/Desktop/"
</pre>
</blockquote>
- <p>To aid portability, E enables (and encourages) you to deal with Files
- using "/" as the path separator character. But you can use "getCanonicalPath"
- when you want to see what the path-name of the file looks like to your
- operating system.
+ <p>To aid portability, E enables (and encourages) you to deal with Files
+ using "/" as the path separator character. But you can use "getCanonicalPath"
+ when you want to see what the path-name of the file looks like to your
+ operating system.
<blockquote>
<pre>? desk <b>getName</b>()
# value: "desktop"
@@ -130,10 +159,10 @@
<b>renameTo</b>(file) all behave just as in Java, and operate on both
normal files and directories. See the javadoc-umentation.</p>
<h2><a name="ReadingText"></a>Reading Text</h2>
- <p>As we saw in the Jabberwocky example, if you use a normal File as the
- collection of a for loop, E assumes the file is a text file, and treats
+ <p>As we saw in the Jabberwocky example, if you use a normal File as the
+ collection of a for loop, E assumes the file is a text file, and treats
it as a collection of lines.</p>
- <blockquote>
+ <blockquote>
<pre>? var size := 0
# value: 0
@@ -144,11 +173,11 @@
? size
# value: 270</pre>
</blockquote>
- <p>To aid portability, each of these lines ends with a newline character,
- '\n', independent of how newlines are actually represented on the current
- platform. On Windows newlines are represented with a pair of characters,
- so the above size is smaller than the Windows file size.
- <blockquote>
+ <p>To aid portability, each of these lines ends with a newline character,
+ '\n', independent of how newlines are actually represented on the current
+ platform. On Windows newlines are represented with a pair of characters,
+ so the above size is smaller than the Windows file size.
+ <blockquote>
<pre>? <c:/jabbertest/jabberwocky.txt> <b></b>getText() size()
# value: 270</pre>
</blockquote>
@@ -156,11 +185,11 @@
using "<code>getText()</code>". As you might be able to guess
from the agreement on size, <code>getText()</code> also turns platform-specific
newlines into newline characters.</p>
- <p>When you don't want to read the whole file at once, you instead open
+ <p>When you don't want to read the whole file at once, you instead open
a text reading stream on the File using "textReader":</p>
<blockquote>
<pre>? def reader := <c:/jabbertest/jabberwocky.txt> <b>textReader</b>()
-# value: <BufferedReader>
+# value: <TextReader>
? reader <b>readChar</b>()
# value: '\''
@@ -174,30 +203,30 @@
? reader <b>readString</b>(1000) size()
# value: 232</pre>
</blockquote>
- <p>"readChar" returns the next character. "readLine"
- reads a line of text, but, following Java conventions, without the terminating
- newline. "readString(num)" will read num characters, and return
- them as a String. However, if there aren't num character left before the
- end of file, it will return the rest of the characters and leave the stream
- at end of file.
- <blockquote>
+ <p>"readChar" returns the next character. "readLine"
+ reads a line of text, but, following Java conventions, without the terminating
+ newline. "readString(num)" will read num characters, and return
+ them as a String. However, if there aren't num character left before the
+ end of file, it will return the rest of the characters and leave the stream
+ at end of file.
+ <blockquote>
<pre>? reader readChar() == null
# value: true</pre>
</blockquote>
- <p>When the stream is at end of file, the above read-requests all return
+ <p>When the stream is at end of file, the above read-requests all return
null.</p>
<blockquote>
<pre>? reader <b>close</b>()
? reader readChar()
# problem: <IOException: Stream closed></pre>
</blockquote>
- <p>When you're done with a stream, you should always be sure to close it.
- That's fine for interactive use, but how can you be sure your program
- will close the stream when an I/O error might throw you out of your function
+ <p>When you're done with a stream, you should always be sure to close it.
+ That's fine for interactive use, but how can you be sure your program
+ will close the stream when an I/O error might throw you out of your function
before you get to your close message? By using try/finally:</p>
<blockquote>
<pre>? def reader := <c:/jabbertest/jabberwocky.txt> textReader()
-# value: <BufferedReader>
+# value: <TextReader>
? var size := 0
# value: 0
@@ -212,13 +241,13 @@
> }
# value: 261</pre>
</blockquote>
- <p>This loop uses a reader to loop through the file one line at a time.
- The "finally" clause will be sure we close the stream no matter
- how we exit the try block. If, for example, "reader readLine"
- throws an IOException (always a possibility), the stream will still be
+ <p>This loop uses a reader to loop through the file one line at a time.
+ The "finally" clause will be sure we close the stream no matter
+ how we exit the try block. If, for example, "reader readLine"
+ throws an IOException (always a possibility), the stream will still be
closed.</p>
- <p>Notice that the cumulative size is smaller than before. This is because
- "readLine" produces lines <i>not</i> terminated by any form
+ <p>Notice that the cumulative size is smaller than before. This is because
+ "readLine" produces lines <i>not</i> terminated by any form
of newline.</p>
<blockquote>
<pre>? <c:/jabbertest/jabberwocky2.txt> exists()
@@ -228,22 +257,24 @@
# problem: <FileNotFoundException: c:\jabbertest\jabberwocky2.txt \
# (The system cannot find the file specified)></pre>
</blockquote>
- <p>Not surprisingly, you can't open a text Reader on a file that doesn't
- exist. However...
+ <p>(Note that the above example doesn't yet pass as an Updoc test case due
+ to the <i><a href="../tools/updoc.html#continuation-bug">line continuation
+ bug</a></i>.)
+ <p>Not surprisingly, you can't open a text Reader on a file that doesn't
+ exist. However...
<h2><a name="WritingText"></a>Writing Text</h2>
- <blockquote>
+ <blockquote>
<pre>? def writer := <c:/jabbertest/jabberwocky2.txt> <b>textWriter</b>()
# value: <TextWriter>
? <c:/jabbertest/jabberwocky2.txt> exists()
# value: true</pre>
</blockquote>
- <p>... you can open a TextWriter, which also causes the file to be created
- if needed. You then fill the file with content by writing to the TextWriter,
- and then closing it. For example, to copy the contents of
-<c:/jabbertest/jabberwocky.txt>
+ <p>... you can open a TextWriter, which also causes the file to be created
+ if needed. You then fill the file with content by writing to the TextWriter,
+ and then closing it. For example, to copy the contents of <c:/jabbertest/jabberwocky.txt>
into <c:/jabbertest/jabberwock2.txt>:</p>
- <blockquote>
+ <blockquote>
<pre>? try {
> for line in <c:/jabbertest/jabberwocky.txt> {
> writer <b>print</b>(line)
@@ -252,7 +283,7 @@
> writer close()
> }</pre>
</blockquote>
- <p>Once again, we use a try/finally expression to ensure that the Writer
+ <p>Once again, we use a try/finally expression to ensure that the Writer
gets closed no matter how we leave the expression.</p>
<p>"print(object)" prints the stringified form of the object to
the Writer. The stringified form of a String is the String itself. The
@@ -260,23 +291,23 @@
". <font color="#ff0000">(*** No longer quite true. Need to explain
about the quoted form.)</font> For example, the stringified form of a
number is just its decimal representation:</p>
- <blockquote>
+ <blockquote>
<pre>? 2 + 3
# value: 5
? 2 / 3
# value: 0.6666666666666666</pre>
</blockquote>
- <p>This is the form that would get written to a file if these values were
+ <p>This is the form that would get written to a file if these values were
used as the argument of a "print" message.</p>
- <blockquote>
+ <blockquote>
<pre>? <c:/jabbertest/jabberwocky2.txt> getText() size()
# value: 270</pre>
</blockquote>
<p>As we see from the size, our file-copy code copied the whole file.</p>
- <p>We can turn the above pattern into a useful little function for copying
+ <p>We can turn the above pattern into a useful little function for copying
text files:</p>
- <blockquote>
+ <blockquote>
<pre>? def textFileCopy(srcFile, destFile) {
> def writer := destFile textWriter()
> try {
@@ -289,28 +320,28 @@
> }
# value: <textFileCopy></pre>
</blockquote>
- <p>Using this function, we can copy files simply:
- <blockquote>
+ <p>Using this function, we can copy files simply:
+ <blockquote>
<pre>? textFileCopy(<c:/jabbertest/jabberwocky.txt>,
> <c:/jabbertest/jabberwocky2.txt>)</pre>
</blockquote>
- <p>Your interactive command-line interpreter already has an TextWriter that's
- always open, called "stdout", that displays text on your command
+ <p>Your interactive command-line interpreter already has an TextWriter that's
+ always open, called "stdout", that displays text on your command
line interpreter window:</p>
- <blockquote>
+ <blockquote>
<pre>? stdout
# value: <TextWriter>
? stdout <b>println</b>(2/3)
0.6666666666666666</pre>
</blockquote>
- <p>TextWriters also respond to a "println" message, which is just
- like "print", except that it also provides a newline on the
- end. Similarly, there is also a "lnPrint" message that provides
- a newline on the beginning. If we wanted to write a text-copy function
- that worked on already open streams, rather than opening and closing them
+ <p>TextWriters also respond to a "println" message, which is just
+ like "print", except that it also provides a newline on the
+ end. Similarly, there is also a "lnPrint" message that provides
+ a newline on the beginning. If we wanted to write a text-copy function
+ that worked on already open streams, rather than opening and closing them
ourselves, we might write:</p>
- <blockquote>
+ <blockquote>
<pre>? def textStreamCopy(reader, writer) {
> while ((def line := reader readLine()) != null) {
> writer println(line)
@@ -319,7 +350,7 @@
# value: <textStreamCopy>
? def reader := <c:/jabbertest/jabberwocky.txt> textReader()
-# value: <BufferedReader>
+# value: <TextReader>
? try {
> textStreamCopy(reader, stdout)
@@ -337,14 +368,14 @@
Beware the Jubjub bird and shun
The frumious bandersnatch."</pre>
</blockquote>
- <p>We print to the writer using "println" above, since "reader
+ <p>We print to the writer using "println" above, since "reader
readLine" returns a line without the terminal newline.</p>
<p>If we replace the line containing "stdout" above with</p>
- <blockquote>
+ <blockquote>
<pre>> textStreamCopy(reader, stdout <b>indent</b>("..."))</pre>
</blockquote>
<p>and do the above sequence again, we get</p>
- <blockquote>
+ <blockquote>
<pre>Twas Brillig and the Slithy Toves
...Did gyre and gimbal in the wabe
...All mimsy were the borogroves
@@ -357,10 +388,10 @@
...The frumious bandersnatch."
...</pre>
</blockquote>
- <p>When you send the "indent(prefix)" message to an TextWriter,
- it returns a new TextWriter that writes to the same destination, but adding
- the extra prefix after every newline.
- <blockquote>
+ <p>When you send the "indent(prefix)" message to an TextWriter,
+ it returns a new TextWriter that writes to the same destination, but adding
+ the extra prefix after every newline.
+ <blockquote>
<pre>? stdout indent("...") <b>lnPrint</b>(<c:/jabbertest/jabberwocky.txt> getText())
...Twas Brillig and the Slithy Toves
@@ -375,18 +406,18 @@
...The frumious bandersnatch."
...</pre>
</blockquote>
- <p>Finally, there are also global "print" and "println"
- functions that send the corresponding message to stdout and also return
+ <p>Finally, there are also global "print" and "println"
+ functions that send the corresponding message to stdout and also return
their argument.</p>
- <blockquote>
+ <blockquote>
<pre>? <b>println</b>(2/3)
0.6666666666666666
# value: 0.6666666666666666</pre>
</blockquote>
<h2><a name="Directories"></a>Directories</h2>
- <p>As we saw in the original Jabberwocky example, if you use a for-loop
- to iterate a File object that is a directory, the loop variable gets bound
- to each File (normal file or directory) in this directory. With this piece
+ <p>As we saw in the original Jabberwocky example, if you use a for-loop
+ to iterate a File object that is a directory, the loop variable gets bound
+ to each File (normal file or directory) in this directory. With this piece
of information, we can now write our first non-trivial useful program:</p>
<blockquote>
<pre>? def writeDirMap(filedir, writer) {
@@ -406,21 +437,21 @@
> }
# value: <writeDirMap></pre>
</blockquote>
- <p>"writeDirMap" is a recursive function only meant to be called
- from "dirMapper". "filedir" is a File object that
- may represent either a normal file or a directory. writeMapDir uses "lnPrint"
- to print the local-name part of filedir onto writer, preceded by a newline.
- If filedir is a normal file, we're done. If it's a directory, then we
- suffix the name with a "/", so someone looking at the output
- can tell it's a directory, and then call ourselves recursively with each
- File (normal file or directory) in this directory. In this recursive call,
- we pass a new TextWriter, "nested" which is just like "writer",
- except that it has an extra prefix string consisting of a number of spaces
- equal to our local name, followed by a "/". As you'll see, this
- results in outline-style output in which it's easy to figure out what's
- under what. This prefix string gets output after the newline written by
- the call to "lnPrint" in the nested call to "writeDirMap".
- <blockquote>
+ <p>"writeDirMap" is a recursive function only meant to be called
+ from "dirMapper". "filedir" is a File object that
+ may represent either a normal file or a directory. writeMapDir uses "lnPrint"
+ to print the local-name part of filedir onto writer, preceded by a newline.
+ If filedir is a normal file, we're done. If it's a directory, then we
+ suffix the name with a "/", so someone looking at the output
+ can tell it's a directory, and then call ourselves recursively with each
+ File (normal file or directory) in this directory. In this recursive call,
+ we pass a new TextWriter, "nested" which is just like "writer",
+ except that it has an extra prefix string consisting of a number of spaces
+ equal to our local name, followed by a "/". As you'll see, this
+ results in outline-style output in which it's easy to figure out what's
+ under what. This prefix string gets output after the newline written by
+ the call to "lnPrint" in the nested call to "writeDirMap".
+ <blockquote>
<pre>? def dirMapper(filedir, destFile) {
> def writer := destFile textWriter()
> try {
@@ -432,17 +463,17 @@
> }
# value: <dirMapper></pre>
</blockquote>
- <p>Just wraps the top-level call to "writeDirMap" with the opening
- of a Writer onto destFile, and the insertion of the last newline. We can
- call "dirMapper" to get a useful textual roadmap to a portion
- of our directory hierarchy. For example, when I map out my Windows Start
- Menu:
- <blockquote>
+ <p>Just wraps the top-level call to "writeDirMap" with the opening
+ of a Writer onto destFile, and the insertion of the last newline. We can
+ call "dirMapper" to get a useful textual roadmap to a portion
+ of our directory hierarchy. For example, when I map out my Windows Start
+ Menu:
+ <blockquote>
<pre>? dirMapper(<file: "/Windows/Start Menu">,
> <file:/startMenuMap.txt>)</pre>
</blockquote>
<pre>The beginning of my resulting file looks like</pre>
- <blockquote>
+ <blockquote>
<pre>Start Menu/
/ebash.pif
/Programs/
@@ -456,62 +487,63 @@
/ /Internet Mail.lnk
/ /Microsoft NetMeeting.lnk</pre>
</blockquote>
- <p>Yours, of course, will differ in the details. If you map your
-<file:/>
- instead, go out and get a cup of java. It'll take a while. (My little
- laptop has over 53,000 files and directories on it, each of which produces
+ <p>Yours, of course, will differ in the details. If you map your <file:/>
+ instead, go out and get a cup of java. It'll take a while. (My little
+ laptop has over 53,000 files and directories on it, each of which produces
a line in the map file.)</p>
- <p>We've seen how to create new normal files -- by opening up a textWriter.
+ <p>We've seen how to create new normal files -- by opening up a textWriter.
How do we create directories? With "mkdir" or "mkdirs":</p>
- <blockquote>
- <pre>? def abc := <c:/a/b/c>
-# value: <file:c:/a/b/c>
+ <blockquote>
+ <pre>? def abc := <c:/jabbertest/a/b/c>
+# value: <file:c:/jabbertest/a/b/c>
? abc exists()
# value: false</pre>
</blockquote>
- <p>At this point, <file:/a/b/c> is neither a directory nor a normal file.
- <blockquote>
+ <p>At this point, <file:/jabbertest/a/b/c> is neither a directory
+ nor a normal file.
+ <blockquote>
<pre>? abc <b>mkdirs</b>()
# value: true</pre>
</blockquote>
- <p>If <file:/a/b> already existed, and was a directory, then "<code>mkdir</code>"
- would have been adequate. However, if <file:/a/b> didn't exist,
- "mkdir" would have failed. "<code>mkdirs</code>",
- on the other hand, creates the parent directories as necessary in order
- to create <file:/a/b/c> as a directory.
- <blockquote>
+ <p>If <code><file:/jabbertest/a/b></code> already existed, and was
+ a directory, then "<code>mkdir</code>" would have been adequate.
+ However, if <code><file:/jabbertest/a/b></code> didn't exist, "<code>mkdir</code>"
+ would have failed. "<code>mkdirs</code>", on the other hand,
+ creates the parent directories as necessary in order to create <code><file:/jabbertest/a/b/c></code>
+ as a directory.
+ <blockquote>
<pre>? abc exists()
# value: true</pre>
<pre>? abc isDirectory()
# value: true
? abc
-# value: <file:c:/a/b/c/></pre>
+# value: <file:c:/jabbertest/a/b/c/></pre>
</blockquote>
- <p>abc now prints out with a terminal slash to indicate that it represents
+ <p>abc now prints out with a terminal slash to indicate that it represents
a directory.</p>
<blockquote>
- <pre>? def ab := <c:/a/b>
-# value: <file:c:/a/b/>
+ <pre>? def ab := <c:/jabbertest/a/b>
+# value: <file:c:/jabbertest/a/b/>
? ab<b>[</b>"c"<b>]</b>
-# value: <file:c:/a/b/c/>
+# value: <file:c:/jabbertest/a/b/c/>
? ab[".."]
# problem: <SecurityException: ".." not allowed: ..></pre>
</blockquote>
- <p>Directories are collections, mapping from local file names to the contained
- Files (normal files or directories). We've already seen that directories
- support the for-loop the way would expect such a collection to. In addition,
- we can use the square-bracket indexing operator to get a File of a given
- name within a directory. However, we can only descend the directory hierarchy.
- For reasons explained in <i>Capability Programming Patterns</i> E disallows
- the use of ".." to navigate upwards.
+ <p>Directories are collections, mapping from local file names to the contained
+ Files (normal files or directories). We've already seen that directories
+ support the for-loop the way would expect such a collection to. In addition,
+ we can use the square-bracket indexing operator to get a File of a given
+ name within a directory. However, we can only descend the directory hierarchy.
+ For reasons explained in <i>Capability Programming Patterns</i> E disallows
+ the use of ".." to navigate upwards.
<h2><a name="URLs"></a>URLs</h2>
<p><font color="#ff0000">*** to be written</font></p>
- <p>
- <P ALIGN="left">
+ <p>
+ <P ALIGN="left">
<!-- #EndEditable --></TD>
<TD WIDTH="10%"> </TD>
</TR>
1.24 +2 -2 e/src/esrc/scripts/eBrowser.e
Index: eBrowser.e
===================================================================
RCS file: /cvs/e/src/esrc/scripts/eBrowser.e,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- eBrowser.e 2001/07/14 12:57:20 1.23
+++ eBrowser.e 2001/07/16 10:42:48 1.24
@@ -432,13 +432,13 @@
def runner() {
E call(target, operation, [])
}
- uiTools newToolButton(uri, tipText ,runner)
+ uiTools newToolButton(uri, tipText, runner)
}
def addMenuItem(menu, name, operation, target) :any {
def runner() {
E call(target, operation, [])
}
- uiTools addMenuItem(menu, name,runner)
+ uiTools addMenuItem(menu, name, runner)
}
def icons__uriGetter {
to get(name) :any {
1.28 +7 -0 e/src/jsrc/org/erights/e/elib/base/TextWriter.java
Index: TextWriter.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/base/TextWriter.java,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -r1.27 -r1.28
--- TextWriter.java 2001/04/08 21:15:12 1.27
+++ TextWriter.java 2001/07/16 10:42:48 1.28
@@ -325,4 +325,11 @@
off = nl + 1;
}
}
+
+ /**
+ * A TextWriter prints itself on a TextWriter as <TextWriter>.
+ */
+ public void printOn(TextWriter out) throws IOException {
+ out.print("<TextWriter>");
+ }
}
1.12 +6 -2 e/src/jsrc/org/erights/e/elib/tables/Twine.java
Index: Twine.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/elib/tables/Twine.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Twine.java 2001/07/14 12:57:24 1.11
+++ Twine.java 2001/07/16 10:42:48 1.12
@@ -217,13 +217,16 @@
/**
* Return a new Twine that represents a concatenation of the parts of
- * these this and other. The last part of this may be merged with the
- * first part of other.
+ * this and other. <p>
+ *
+ * The last part of this may be merged with the first part of other.
*/
public ConstList add(Object other) {
Twine otherTwine;
if (other instanceof Twine) {
otherTwine = (Twine)other;
+ } else if (other instanceof Character) {
+ otherTwine = Twine.fromString(other.toString());
} else {
otherTwine = Twine.fromString(E.toString(other));
}
@@ -291,6 +294,7 @@
for (int p2 = 0; p2 < len; p2++) {
char c = charAt(p2);
String newStr = null;
+ //XXX Redundant with CharacterSugar.escaped(c).
switch(c) {
case '\b': { newStr = "\\b"; break; }
case '\t': { newStr = "\\t"; break; }
1.13 +9 -0 e/src/jsrc/org/erights/e/meta/java/io/BufferedReaderSugar.java
Index: BufferedReaderSugar.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/meta/java/io/BufferedReaderSugar.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -r1.12 -r1.13
--- BufferedReaderSugar.java 2001/03/20 03:18:25 1.12
+++ BufferedReaderSugar.java 2001/07/16 10:42:48 1.13
@@ -22,6 +22,7 @@
import java.io.BufferedReader;
import java.io.IOException;
import org.erights.e.elib.base.SourceSpan;
+import org.erights.e.elib.base.TextWriter;
import org.erights.e.elib.tables.AssocFunc;
import org.erights.e.elib.tables.FlexList;
import org.erights.e.elib.tables.Twine;
@@ -115,5 +116,13 @@
} finally {
self.close();
}
+ }
+
+ /**
+ * A BufferedReader prints as <TextReader>
+ */
+ static public void printOn(BufferedReader self, TextWriter out)
+ throws IOException {
+ out.print("<TextReader>");
}
}
1.11 +50 -0 e/src/jsrc/org/erights/e/meta/java/lang/CharacterSugar.java
Index: CharacterSugar.java
===================================================================
RCS file: /cvs/e/src/jsrc/org/erights/e/meta/java/lang/CharacterSugar.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- CharacterSugar.java 2001/03/28 22:30:50 1.10
+++ CharacterSugar.java 2001/07/16 10:42:48 1.11
@@ -18,6 +18,10 @@
Contributor(s): ______________________________________.
*/
+
+import java.io.IOException;
+import org.erights.e.elib.base.TextWriter;
+
/**
* A sweetener defining extra messages that may be e-sent to characters.
*
@@ -106,5 +110,51 @@
*/
static public char max(char self, char other) {
return (char)Math.max((int)self, (int)other);
+ }
+
+ /**
+ * Unlike Java's Writer.print(char), E's chars print by printing
+ * their quoted form. <p>
+ *
+ * If you want to contribute the character itself to a TextWriter,
+ * print it by doing <code>out print(""+c)</code>
+ */
+ static public void printOn(char self, TextWriter out)
+ throws IOException {
+ out.print("'", escaped(self), "'");
+ }
+
+ /**
+ * Just the part of a character's quoted form that encodes the
+ * character. <p>
+ *
+ * In other words, everything except the enclosing quote signs.
+ * This is equally useful for composing a quoted character or a
+ * quoted string.
+ */
+ static public String escaped(char self) {
+ StringBuffer buf = new StringBuffer();
+ //XXX Redundant with the inner loop of Twine.quote()
+ switch(self) {
+ case '\b': { buf.append("\\b"); break; }
+ case '\t': { buf.append("\\t"); break; }
+ case '\n': { buf.append("\\n\\\n"); break; }
+ case '\f': { buf.append("\\f"); break; }
+ case '\r': { buf.append("\\r"); break; }
+ case '\"': { buf.append("\\\""); break; }
+ case '\'': { buf.append("\\\'"); break; }
+ case '\\': { buf.append("\\\\"); break; }
+ default: {
+ if (self < 32 && self > 255) {
+ String num = "0000" + Integer.toHexString(self);
+ int len = num.length();
+ num = num.substring(len - 4, len);
+ buf.append("\\u" + num);
+ } else {
+ buf.append(self);
+ }
+ }
+ }
+ return buf.toString();
}
}