diff options
-rw-r--r-- | src/cli/runtime/LineNumberingTextReader.cs | 57 | ||||
-rw-r--r-- | src/cli/runtime/RT.cs | 55 | ||||
-rw-r--r-- | src/org/clojure/runtime/LineNumberingPushbackReader.java | 27 | ||||
-rw-r--r-- | src/org/clojure/runtime/RT.java | 433 |
4 files changed, 384 insertions, 188 deletions
diff --git a/src/cli/runtime/LineNumberingTextReader.cs b/src/cli/runtime/LineNumberingTextReader.cs new file mode 100644 index 00000000..5238c6e8 --- /dev/null +++ b/src/cli/runtime/LineNumberingTextReader.cs @@ -0,0 +1,57 @@ +/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
+ * which can be found in the file CPL.TXT at the root of this distribution.
+ * By using this software in any fashion, you are agreeing to be bound by
+ * the terms of this license.
+ * You must not remove this notice, or any other, from this software.
+ **/
+
+using System;
+using System.IO;
+
+namespace org.clojure.runtime
+ {
+
+
+public class LineNumberingTextReader : TextReader, IDisposable
+ {
+ TextReader impl;
+ int line = 0;
+
+ public LineNumberingTextReader(TextReader r){
+ this.impl = r;
+ }
+
+ public int getLineNumber(){
+ return line;
+ }
+
+ override public int Read(){
+ int ret = impl.Read();
+ if(ret == '\n')
+ ++line;
+ return ret;
+ }
+
+ override public int Peek(){
+ return impl.Peek();
+ }
+
+ public override void Close()
+ {
+ base.Close();
+ impl.Close();
+ }
+
+ void IDisposable.Dispose()
+ {
+ base.Dispose();
+ impl.Dispose();
+ }
+
+ }
+
+
+ }
diff --git a/src/cli/runtime/RT.cs b/src/cli/runtime/RT.cs index 51d40809..ef60aa77 100644 --- a/src/cli/runtime/RT.cs +++ b/src/cli/runtime/RT.cs @@ -12,6 +12,7 @@ using System;
using System.Collections;
+using System.IO;
namespace org.clojure.runtime
{
@@ -22,6 +23,15 @@ public class RT public static Symbol T = Symbol.intern("t");
public static Object[] EMPTY_ARRAY = new Object[0];
+
+ static public readonly Object[] chars;
+
+ static RT(){
+ chars = new Object[256];
+ for(int i=0;i<chars.Length;i++)
+ chars[i] = (char)i;
+ }
+
static public Object eq(Object arg1, Object arg2) {
return (arg1 == arg2)?T:null;
}
@@ -80,7 +90,9 @@ public class RT static public Object box(char x)
{
- return x;
+ if (x < chars.Length)
+ return chars[x];
+ return x;
}
static public Object box(bool x)
@@ -239,6 +251,45 @@ static public int boundedLength(Cons list, int limit) return i;
}
+
+///////////////////////////////// reader support ////////////////////////////////
+
+static Object readRet(int ret){
+ if(ret == -1)
+ return null;
+ return box((char) ret);
+}
+
+static public Object readChar(TextReader r) {
+ int ret = r.Read();
+ return readRet(ret);
+}
+
+static public Object peekChar(TextReader r) {
+ return readRet(r.Peek());
+}
+
+static public int getLineNumber(TextReader r)
+ {
+ if (r is LineNumberingTextReader)
+ return ((LineNumberingTextReader)r).getLineNumber();
+ return 0;
+ }
+
+static public TextReader getLineNumberingReader(TextReader r)
+ {
+ if (isLineNumberingReader(r))
+ return r;
+ return new LineNumberingTextReader(r);
+ }
+
+static public bool isLineNumberingReader(TextReader r)
+ {
+ return r is LineNumberingTextReader;
+ }
+
+/*-------------------------------- values --------------*/
+
static public Object setValues(ThreadLocalData tld, Object arg1)
{
if(tld == null)
@@ -296,7 +347,7 @@ static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Ob }
static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4,
- Object arg5, Cons args) /*throws Exception*/
+ Object arg5, Cons args) /**/
{
if(tld == null)
tld = ThreadLocalData.get();
diff --git a/src/org/clojure/runtime/LineNumberingPushbackReader.java b/src/org/clojure/runtime/LineNumberingPushbackReader.java new file mode 100644 index 00000000..a3a10e1a --- /dev/null +++ b/src/org/clojure/runtime/LineNumberingPushbackReader.java @@ -0,0 +1,27 @@ +/**
+ * Copyright (c) Rich Hickey. All rights reserved.
+ * The use and distribution terms for this software are covered by the
+ * Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
+ * which can be found in the file CPL.TXT at the root of this distribution.
+ * By using this software in any fashion, you are agreeing to be bound by
+ * the terms of this license.
+ * You must not remove this notice, or any other, from this software.
+ */
+
+package org.clojure.runtime;
+
+import java.io.PushbackReader;
+import java.io.Reader;
+import java.io.LineNumberReader;
+
+
+public class LineNumberingPushbackReader extends PushbackReader {
+
+public LineNumberingPushbackReader(Reader r){
+ super(new LineNumberReader(r));
+}
+
+public int getLineNumber(){
+ return ((LineNumberReader)in).getLineNumber();
+}
+}
diff --git a/src/org/clojure/runtime/RT.java b/src/org/clojure/runtime/RT.java index e68d4d70..c10fcbf9 100644 --- a/src/org/clojure/runtime/RT.java +++ b/src/org/clojure/runtime/RT.java @@ -13,11 +13,21 @@ package org.clojure.runtime; import java.util.Iterator; +import java.io.Reader; +import java.io.PushbackReader; public class RT{ - static public Symbol T = Symbol.intern("t"); + static public Symbol T = Symbol.intern("t"); static public final Object[] EMPTY_ARRAY = new Object[]{}; + static public final Character[] chars; + + static { + chars = new Character[256]; + for(int i=0;i<chars.length;i++) + chars[i] = new Character((char)i); + } + static public Object eq(Object arg1, Object arg2) { return (arg1 == arg2)?Boolean.TRUE:null; @@ -25,47 +35,47 @@ public class RT{ static public Object eql(Object arg1, Object arg2) { if(arg1 == arg2) - return Boolean.TRUE; + return Boolean.TRUE; if(arg1 == null || arg2 == null) - return null; + return null; if(arg1 instanceof Num && arg1.getClass() == arg2.getClass() && arg1.equals(arg2)) - return Boolean.TRUE; + return Boolean.TRUE; if(arg1.getClass() == Character.class && arg2.getClass() == Character.class && arg1.equals(arg2)) - return Boolean.TRUE; + return Boolean.TRUE; return null; } static public Object equal(Object arg1, Object arg2) { if(arg1 == null) - return arg2 == null ? Boolean.TRUE : null; + return arg2 == null ? Boolean.TRUE : null; else if(arg2 == null) return null; - return (eql(arg1,arg2) != null - || (arg1.getClass() == Cons.class - && arg2.getClass() == Cons.class - && equal(((Cons)arg1).first,((Cons)arg2).first)!=null - && equal(((Cons)arg1).rest,((Cons)arg2).rest)!=null)) - ?Boolean.TRUE:null; - } + return (eql(arg1,arg2) != null + || (arg1.getClass() == Cons.class + && arg2.getClass() == Cons.class + && equal(((Cons)arg1).first,((Cons)arg2).first)!=null + && equal(((Cons)arg1).rest,((Cons)arg2).rest)!=null)) + ?Boolean.TRUE:null; + } static public Iter iter(Object coll) - { - if(coll == null || coll instanceof Iter) - return (Iter) coll; - else if(coll instanceof Iterator) - { - Iterator i = (Iterator) coll; - if(i.hasNext()) - return new IteratorIter(i); - return null; - } - else - throw new IllegalArgumentException("Don't know how to create Iter from arg"); - } + { + if(coll == null || coll instanceof Iter) + return (Iter) coll; + else if(coll instanceof Iterator) + { + Iterator i = (Iterator) coll; + if(i.hasNext()) + return new IteratorIter(i); + return null; + } + else + throw new IllegalArgumentException("Don't know how to create Iter from arg"); + } /************************ Boxing/casts *******************************/ static public Object box(Object x) @@ -75,6 +85,8 @@ static public Object box(Object x) static public Character box(char x) { + if(x < chars.length) + return chars[x]; return new Character(x); } @@ -84,140 +96,140 @@ static public Boolean box(boolean x) } static public Byte box(byte x) - { - return new Byte(x); - } + { + return new Byte(x); + } static public Short box(short x) - { - return new Short(x); - } + { + return new Short(x); + } static public Integer box(int x) - { - return new Integer(x); - } + { + return new Integer(x); + } static public Long box(long x) - { - return new Long(x); - } + { + return new Long(x); + } static public Float box(float x) - { - return new Float(x); - } + { + return new Float(x); + } static public Double box(double x) - { - return new Double(x); - } + { + return new Double(x); + } static public char charCast(Object x) - { - if(x instanceof Character) - return ((Character)x).charValue(); - return (char) ((Number)x).intValue(); - } + { + if(x instanceof Character) + return ((Character)x).charValue(); + return (char) ((Number)x).intValue(); + } static public boolean booleanCast(Object x) - { - if(x instanceof Boolean) - return ((Boolean)x).booleanValue(); - return x != null; - } + { + if(x instanceof Boolean) + return ((Boolean)x).booleanValue(); + return x != null; + } static public byte byteCast(Object x) - { - return ((Number)x).byteValue(); - } + { + return ((Number)x).byteValue(); + } static public short shortCast(Object x) - { - return ((Number)x).shortValue(); - } + { + return ((Number)x).shortValue(); + } static public int intCast(Object x) - { - return ((Number)x).intValue(); - } + { + return ((Number)x).intValue(); + } static public long longCast(Object x) - { - return ((Number)x).longValue(); - } + { + return ((Number)x).longValue(); + } static public float floatCast(Object x) - { - return ((Number)x).floatValue(); - } + { + return ((Number)x).floatValue(); + } static public double doubleCast(Object x) - { - return ((Number)x).doubleValue(); - } + { + return ((Number)x).doubleValue(); + } /******************************************* list support ********************************/ static public Cons cons(Object x, Cons y) - { - return new Cons(x, y); - } + { + return new Cons(x, y); + } static public Cons list() - { - return null; - } + { + return null; + } static public Cons list(Object arg1) - { - return cons(arg1, null); - } + { + return cons(arg1, null); + } static public Cons list(Object arg1, Object arg2) - { - return listStar(arg1, arg2, null); - } + { + return listStar(arg1, arg2, null); + } static public Cons list(Object arg1, Object arg2, Object arg3) - { - return listStar(arg1, arg2, arg3, null); - } + { + return listStar(arg1, arg2, arg3, null); + } static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4) - { - return listStar(arg1, arg2, arg3, arg4, null); - } + { + return listStar(arg1, arg2, arg3, arg4, null); + } static public Cons list(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) - { - return listStar(arg1, arg2, arg3, arg4, arg5, null); - } + { + return listStar(arg1, arg2, arg3, arg4, arg5, null); + } static public Cons listStar(Object arg1, Cons rest) - { - return cons(arg1, rest); - } + { + return cons(arg1, rest); + } static public Cons listStar(Object arg1, Object arg2, Cons rest) - { - return cons(arg1, cons(arg2, rest)); - } + { + return cons(arg1, cons(arg2, rest)); + } static public Cons listStar(Object arg1, Object arg2, Object arg3, Cons rest) - { - return cons(arg1, cons(arg2, cons(arg3, rest))); - } + { + return cons(arg1, cons(arg2, cons(arg3, rest))); + } static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, Cons rest) - { - return cons(arg1, cons(arg2, cons(arg3, cons(arg4, rest)))); - } + { + return cons(arg1, cons(arg2, cons(arg3, cons(arg4, rest)))); + } static public Cons listStar(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons rest) - { - return cons(arg1, cons(arg2, cons(arg3, cons(arg4, cons(arg5, rest))))); - } + { + return cons(arg1, cons(arg2, cons(arg3, cons(arg4, cons(arg5, rest))))); + } static public Cons arrayToList(Object[] a){ Cons ret = null; @@ -227,99 +239,148 @@ static public Cons arrayToList(Object[] a){ } static public int length(Cons list) - { - int i = 0; - for(Cons c = list; c != null; c = c.rest) - { - i++; - } - return i; - } + { + int i = 0; + for(Cons c = list; c != null; c = c.rest) + { + i++; + } + return i; + } static public int boundedLength(Cons list, int limit) - { - int i = 0; - for(Cons c = list; c != null && i <= limit; c = c.rest) - { - i++; - } - return i; - } + { + int i = 0; + for(Cons c = list; c != null && i <= limit; c = c.rest) + { + i++; + } + return i; + } + + +///////////////////////////////// reader support //////////////////////////////// + +static Object readRet(int ret){ + if(ret == -1) + return null; + return box((char) ret); +} + +static public Object readChar(Reader r) throws Exception { + int ret = r.read(); + return readRet(ret); +} + +static public Object peekChar(Reader r) throws Exception { + int ret; + if(r instanceof PushbackReader) + { + ret = r.read(); + ((PushbackReader) r).unread(ret); + } + else + { + r.mark(1); + ret = r.read(); + r.reset(); + } + + return readRet(ret); +} + +static public int getLineNumber(Reader r){ + if(r instanceof LineNumberingPushbackReader) + return ((LineNumberingPushbackReader)r).getLineNumber(); + return 0; +} + +static public Reader getLineNumberingReader(Reader r) { + if(isLineNumberingReader(r)) + return r; + return new LineNumberingPushbackReader(r); +} + +static public boolean isLineNumberingReader(Reader r) { + return r instanceof LineNumberingPushbackReader; +} + +///////////////////////////////// values ////////////////////////// static public Object setValues(ThreadLocalData tld, Object arg1) - { - if(tld == null) - tld = ThreadLocalData.get(); - tld.mvCount = 1; - tld.mvArray[0] = arg1; - return arg1; - } + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 1; + tld.mvArray[0] = arg1; + return arg1; + } static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2) - { - if(tld == null) - tld = ThreadLocalData.get(); - tld.mvCount = 2; - tld.mvArray[0] = arg1; - tld.mvArray[1] = arg2; - return arg1; - } + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 2; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + return arg1; + } static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3) - { - if(tld == null) - tld = ThreadLocalData.get(); - tld.mvCount = 3; - tld.mvArray[0] = arg1; - tld.mvArray[1] = arg2; - tld.mvArray[2] = arg3; - return arg1; - } + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 3; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + return arg1; + } static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4) - { - if(tld == null) - tld = ThreadLocalData.get(); - tld.mvCount = 4; - tld.mvArray[0] = arg1; - tld.mvArray[1] = arg2; - tld.mvArray[2] = arg3; - tld.mvArray[3] = arg4; - return arg1; - } + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 4; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + tld.mvArray[3] = arg4; + return arg1; + } static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) - { - if(tld == null) - tld = ThreadLocalData.get(); - tld.mvCount = 5; - tld.mvArray[0] = arg1; - tld.mvArray[1] = arg2; - tld.mvArray[2] = arg3; - tld.mvArray[3] = arg4; - tld.mvArray[4] = arg5; - return arg1; - } + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 5; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + tld.mvArray[3] = arg4; + tld.mvArray[4] = arg5; + return arg1; + } static public Object setValues(ThreadLocalData tld, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Cons args) throws Exception - { - if(tld == null) - tld = ThreadLocalData.get(); - tld.mvCount = 5; - tld.mvArray[0] = arg1; - tld.mvArray[1] = arg2; - tld.mvArray[2] = arg3; - tld.mvArray[3] = arg4; - tld.mvArray[4] = arg5; - for(int i = 5; args != null && i < ThreadLocalData.MULTIPLE_VALUES_LIMIT; i++, args = args.rest) - { - tld.mvArray[i] = args.first; - } - if(args != null) - throw new IllegalArgumentException("Too many arguments to values (> ThreadLocalData.MULTIPLE_VALUES_LIMIT)"); - return arg1; - } + { + if(tld == null) + tld = ThreadLocalData.get(); + tld.mvCount = 5; + tld.mvArray[0] = arg1; + tld.mvArray[1] = arg2; + tld.mvArray[2] = arg3; + tld.mvArray[3] = arg4; + tld.mvArray[4] = arg5; + for(int i = 5; args != null && i < ThreadLocalData.MULTIPLE_VALUES_LIMIT; i++, args = args.rest) + { + tld.mvArray[i] = args.first; + } + if(args != null) + throw new IllegalArgumentException("Too many arguments to values (> ThreadLocalData.MULTIPLE_VALUES_LIMIT)"); + return arg1; + } } |