summaryrefslogtreecommitdiff
path: root/sources/ch
diff options
context:
space:
mode:
authorpaltherr <paltherr@epfl.ch>2003-06-16 12:47:57 +0000
committerpaltherr <paltherr@epfl.ch>2003-06-16 12:47:57 +0000
commit44ca12f55bced0a955596402d1bd1ae264358e4b (patch)
treeeea316de82722a014725f4651ac9ed3efa9f8c5c /sources/ch
parentba5d59e9f697fc307140a67d37edbfeb2dc4d795 (diff)
downloadscala-44ca12f55bced0a955596402d1bd1ae264358e4b.tar.gz
scala-44ca12f55bced0a955596402d1bd1ae264358e4b.tar.bz2
scala-44ca12f55bced0a955596402d1bd1ae264358e4b.zip
- Added ch.epfl.lamp.util.Position
- Added ch.epfl.lamp.util.SourceFile
Diffstat (limited to 'sources/ch')
-rw-r--r--sources/ch/epfl/lamp/util/Position.java142
-rw-r--r--sources/ch/epfl/lamp/util/SourceFile.java217
2 files changed, 359 insertions, 0 deletions
diff --git a/sources/ch/epfl/lamp/util/Position.java b/sources/ch/epfl/lamp/util/Position.java
new file mode 100644
index 0000000000..91c9d702a3
--- /dev/null
+++ b/sources/ch/epfl/lamp/util/Position.java
@@ -0,0 +1,142 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package ch.epfl.lamp.util;
+
+public class Position {
+
+ //########################################################################
+ // Public Constants
+
+ /** Number of bits used to encode the file */
+ public static final int FILE_BITS = 6;
+ /** Number of bits used to encode the line number */
+ public static final int LINE_BITS = 16;
+ /** Number of bits used to encode the column number */
+ public static final int COLUMN_BITS = 32 - LINE_BITS - FILE_BITS;
+
+ /** Mask to decode the file */
+ public static final int FILE_MASK = (1 << FILE_BITS) - 1;
+ /** Mask to decode the line number */
+ public static final int LINE_MASK = (1 << LINE_BITS) - 1;
+ /** Mask to decode the column number */
+ public static final int COLUMN_MASK = (1 << COLUMN_BITS) - 1;
+
+ /** The undefined position */
+ public static final int NOPOS = 0;
+
+ /** The first position in a source file */
+ public static final int FIRSTPOS = encode(null, 1, 1);
+
+ //########################################################################
+ // Public Functions
+
+ /** Encodes a position into a single int. */
+ public static int encode(SourceFile file, int line, int column) {
+ int fileId = file == null ? 0 : file.id() & FILE_MASK;
+ if (fileId < 0 || FILE_MASK < fileId) fileId = 0;
+ if (line < 0 || LINE_MASK < line) line = 0;
+ if (column < 0 || COLUMN_MASK < column) column = 0;
+ return (((fileId << LINE_BITS) | line) << COLUMN_BITS) | column;
+ }
+
+ /** Returns the file of the encoded position. */
+ public static SourceFile file(int position) {
+ int fileId = (position >> (COLUMN_BITS + LINE_BITS)) & FILE_MASK;
+ return SourceFile.fromId(fileId);
+ }
+
+ /** Returns the line number of the encoded position. */
+ public static int line(int position) {
+ return (position >> COLUMN_BITS) & LINE_MASK;
+ }
+
+ /** Returns the column number of the encoded position. */
+ public static int column(int position) {
+ return position & COLUMN_MASK;
+ }
+
+ //########################################################################
+ // Private Fields
+
+ /** The position's file */
+ private final SourceFile file;
+
+ /** The position's line number */
+ private final int line;
+
+ /** The position's column number */
+ private final int column;
+
+ //########################################################################
+ // Public Constructors
+
+ /** Initializes a new instance. */
+ public Position(int position) {
+ this(file(position), line(position), column(position));
+ }
+
+ /** Initializes a new instance. */
+ public Position(String source) {
+ this(new SourceFile(source, new byte[0]));
+ }
+
+ /** Initializes a new instance. */
+ public Position(SourceFile file) {
+ this(file, 0, 0);
+ }
+
+ /** Initializes a new instance. */
+ public Position(SourceFile file, int line, int column) {
+ this.file = file;
+ this.line = line;
+ this.column = column;
+ }
+
+ //########################################################################
+ // Public Methods
+
+ /** Returns an int encoding this position. */
+ public int encode() {
+ return encode(file, line, column);
+ }
+
+ /** Returns the file of this position. */
+ public SourceFile file() {
+ return file;
+ }
+
+ /** Returns the line number of this position. */
+ public int line() {
+ return line;
+ }
+
+ /** Returns the column number of this position. */
+ public int column() {
+ return column;
+ }
+
+ /** Returns a string representation of this position. */
+ public String toString() {
+ return file.name() + ":" + line + ":" + column;
+ }
+
+ /** Returns the hash code of this position. */
+ public int hashCode() {
+ return encode();
+ }
+
+ /** Returns true iff the given object represents the same position. */
+ public boolean equals(Object object) {
+ if (!(object instanceof Position)) return false;
+ Position that = (Position)object;
+ return file == that.file && line == that.line && column == that.column;
+ }
+
+ //########################################################################
+}
diff --git a/sources/ch/epfl/lamp/util/SourceFile.java b/sources/ch/epfl/lamp/util/SourceFile.java
new file mode 100644
index 0000000000..44dbf82506
--- /dev/null
+++ b/sources/ch/epfl/lamp/util/SourceFile.java
@@ -0,0 +1,217 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package ch.epfl.lamp.util;
+
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+/**
+ * This class represents a single source file.
+ */
+public class SourceFile {
+
+ //########################################################################
+ // Public Constants
+
+ /** Constants used for source parsing */
+ public static final byte LF = 0x0A;
+ public static final byte FF = 0x0C;
+ public static final byte CR = 0x0D;
+ public static final byte SU = 0x1A;
+
+ //########################################################################
+ // Public Functions
+
+ /** Returns the source file with the given id. */
+ public static SourceFile fromId(int id) {
+ if (id <= 0 || files.size() < id) return UNKNOWN;
+ return (SourceFile)files.get(id - 1);
+ }
+
+ /** Releases all source file. */
+ public static void releaseAll() {
+ files.clear();
+ }
+
+ //########################################################################
+ // Private Variables
+
+ /** The unknown source file */
+ private static final SourceFile UNKNOWN = new SourceFile();
+
+ /** The list containing all source files */
+ private static final ArrayList files = new ArrayList();
+
+ //########################################################################
+ // Private Fields
+
+ /** The name of this source file */
+ private final String name;
+
+ /** The content of source this file */
+ private final byte[] bytes;
+
+ /** The id of this source file */
+ private final int id;
+
+ /** The encoding of this source file or null if unspecified */
+ private String encoding;
+
+ /** The position of the last line returned by getLine */
+ private int lineNumber = 0;
+ private int lineStart = 0;
+ private int lineLength = 0;
+ private int nextIndex = 0;
+
+ //########################################################################
+ // Private Constructors
+
+ /** Initializes a new instance. */
+ private SourceFile() {
+ this.name = "<<unknown source file>>";
+ this.bytes = normalize(new byte[0]);
+ this.id = 0;
+ }
+
+ //########################################################################
+ // Public Constructors
+
+ /** Initializes a new instance. */
+ public SourceFile(String name) throws IOException {
+ this(new File(name));
+ }
+
+ /** Initializes a new instance. */
+ public SourceFile(File name) throws IOException {
+ this(name.toString(), read(name));
+ }
+
+ /** Initializes a new instance. */
+ public SourceFile(String name, InputStream input) throws IOException {
+ this(name, read(name, input));
+ }
+
+ /** Initializes a new instance. */
+ public SourceFile(String name, byte[] bytes) {
+ this.name = name;
+ this.bytes = normalize(bytes);
+ this.id = files.size() + 1;
+ files.add(this);
+ }
+
+ //########################################################################
+ // Public Methods
+
+ /** Returns the name of this source file. */
+ public String name() {
+ return name;
+ }
+
+ /** Returns the content of this source file. */
+ public byte[] bytes() {
+ return bytes;
+ }
+
+ /** Returns the id of this source file. */
+ public int id() {
+ return id;
+ }
+
+ /** Sets the encoding of the file. */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /** Returns the content of the given line. */
+ public String getLine(int line) {
+ int index = lineNumber <= line ? nextIndex : (lineNumber = 0);
+ for (; index < bytes.length && lineNumber < line; lineNumber++) {
+ lineStart = index;
+ for (; index < bytes.length; index++) {
+ if (bytes[index] == CR) break;
+ if (bytes[index] == LF) break;
+ if (bytes[index] == FF) break;
+ }
+ lineLength = index - lineStart;
+ if (index < bytes.length) index++;
+ if (index < bytes.length)
+ if (bytes[index - 1] == CR && bytes[index] == LF) index++;
+ }
+ nextIndex = index;
+ try {
+ return encoding != null ?
+ new String(bytes, lineStart, lineLength, encoding) :
+ new String(bytes, lineStart, lineLength);
+ } catch (UnsupportedEncodingException exception) {
+ throw new Error(exception); // !!! use ApplicationError
+ }
+ }
+
+ /**
+ * Returns an instance of Position representing the given line and
+ * column of this source file.
+ */
+ public Position getPosition(int line, int column) {
+ return new Position(this, line, column);
+ }
+
+ /**
+ * Returns the integer encoding the position of the given line and
+ * column of this source file.
+ */
+ public int getEncodedPosition(int line, int column) {
+ return Position.encode(this, line, column);
+ }
+
+ public String toString() {
+ return name;
+ }
+
+ //########################################################################
+ // Private Methods
+
+ /** Reads the file and returns its content as a byte array. */
+ private static byte[] read(File file) throws IOException {
+ InputStream input = new FileInputStream(file);
+ try {
+ return read(file.toString(), input);
+ } finally {
+ input.close();
+ }
+ }
+
+ /** Reads the InputStream and returns its content as a byte array. */
+ private static byte[] read(String name, InputStream input)
+ throws IOException
+ {
+ try {
+ byte[] bytes = new byte[input.available() + 1];
+ if (input.read(bytes) != bytes.length - 1) throw new IOException();
+ bytes[bytes.length - 1] = SU;
+ return bytes;
+ } catch (IOException exception) {
+ throw new IOException("cannot read '" + name + "'");
+ }
+ }
+
+ /** Ensures that the last byte of the array is SU. */
+ private static byte[] normalize(byte[] input) {
+ if (input.length > 0 && input[input.length - 1] == SU) return input;
+ byte[] bytes = new byte[input.length + 1];
+ System.arraycopy(input, 0, bytes, 0, input.length);
+ bytes[input.length] = SU;
+ return bytes;
+ }
+
+ //########################################################################
+}