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() + "\")"; } }