135 lines
3.3 KiB
Plaintext
135 lines
3.3 KiB
Plaintext
|
package slangc.parser;
|
||
|
|
||
|
//import slang.data.Map;
|
||
|
import slang.data.Mappable;
|
||
|
import slang.vm.Ankh;
|
||
|
|
||
|
/**
|
||
|
* The sourceFile class is a simple abstraction over a sourceFile file, suitable for easily writing a
|
||
|
* scanner on top of. The main differences between this and just using a stream or array or string
|
||
|
* are that it's easier to handle different encodings and access mechanisms this way.
|
||
|
*
|
||
|
* @author Zak
|
||
|
*
|
||
|
*/
|
||
|
public abstract class Source {
|
||
|
private final SourceEncoding encoding;
|
||
|
private final String filename;
|
||
|
|
||
|
public Source(SourceEncoding encoding, String filename) {
|
||
|
this.encoding = encoding;
|
||
|
this.filename = filename;
|
||
|
}
|
||
|
|
||
|
public Source(String filename) {
|
||
|
this(new SourceEncoding(), filename);
|
||
|
}
|
||
|
|
||
|
public Source() {
|
||
|
this("");
|
||
|
}
|
||
|
|
||
|
public SourceEncoding getEncoding() {
|
||
|
return encoding;
|
||
|
}
|
||
|
|
||
|
public String getFilename() {
|
||
|
return filename;
|
||
|
}
|
||
|
|
||
|
public abstract int getIndexLength();
|
||
|
|
||
|
public final boolean isIndexWithinBounds(int index) {
|
||
|
return index >= 0 && index < getIndexLength();
|
||
|
}
|
||
|
|
||
|
public abstract int getCharacter(int index);
|
||
|
|
||
|
public abstract int getNextIndex(int currentIndex);
|
||
|
|
||
|
public String getString(int index, int maximumLength) {
|
||
|
String result = "";
|
||
|
|
||
|
for (int i = 0; i < maximumLength; i++) {
|
||
|
if (isIndexWithinBounds(index)) {
|
||
|
result += getEncoding().getString(getCharacter(index));
|
||
|
index = getNextIndex(index);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
private String[][] matchCache = null;
|
||
|
private int[] matchCheck = new int[1];
|
||
|
private int lastidx = -1;
|
||
|
private int lastch = 0;
|
||
|
|
||
|
public boolean matches(int index, String value) {
|
||
|
if (index != lastidx) {
|
||
|
lastidx = index;
|
||
|
lastch = getCharacter(index);
|
||
|
}
|
||
|
Ankh.stringToArray(value, "COMPAT32", matchCheck);
|
||
|
if (matchCheck[0] != lastch) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if (matchCache == null) {
|
||
|
matchCache = new String[getIndexLength()][];
|
||
|
}
|
||
|
if (matchCache[index] == null) {
|
||
|
matchCache[index] = new String[100];
|
||
|
}
|
||
|
int len = value.intsLength();
|
||
|
String s = matchCache[index][len];
|
||
|
if (s == null) {
|
||
|
s = getString(index, len);
|
||
|
matchCache[index][len] = s;
|
||
|
}
|
||
|
return s == value;
|
||
|
//return getString(index, value.intsLength()) == value;
|
||
|
}
|
||
|
|
||
|
public boolean matches(int index, String[] values) {
|
||
|
for (int i = 0; i < values.length; i++) {
|
||
|
if (matches(index, values[i])) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public String match(int index, String[] values) {
|
||
|
for (int i = 0; i < values.length; i++) {
|
||
|
if (matches(index, values[i])) {
|
||
|
return values[i];
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public boolean matches(int index, String[][] values) {
|
||
|
for (int i = 0; i < values.length; i++) {
|
||
|
if (matches(index, values[i][0])) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
public String match(int index, String[][] values) {
|
||
|
for (int i = 0; i < values.length; i++) {
|
||
|
if (matches(index, values[i][0])) {
|
||
|
return values[i][1];
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String toString() {
|
||
|
return Type.of(this).getTypeName() + "(\"" + getFilename() + "\")";
|
||
|
}
|
||
|
}
|