Initial commit of main compiler sources (or should I say ... SAUCES!)
This commit is contained in:
79
slangc/sdk/ArgsLoader.sauce
Normal file
79
slangc/sdk/ArgsLoader.sauce
Normal file
@@ -0,0 +1,79 @@
|
||||
package slangc.sdk;
|
||||
|
||||
import slangc.parser.Source;
|
||||
|
||||
public class ArgsLoader {
|
||||
|
||||
public static String[] remove(String[] array, int index) {
|
||||
if (index < 0 || index >= array.length) {
|
||||
return array;
|
||||
}
|
||||
if (array.length == 1) {
|
||||
return new String[0];
|
||||
}
|
||||
String[] a = new String[array.length - 1];
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
if (i < index) {
|
||||
a[i] = array[i];
|
||||
} else {
|
||||
a[i] = array[i + 1];
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static String[] insert(String[] array, int index, String[] values) {
|
||||
String[] a = new String[array.length + values.length];
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
if (i < index) {
|
||||
a[i] = array[i];
|
||||
} else if (i < index + values.length) {
|
||||
a[i] = values[i - index];
|
||||
} else {
|
||||
a[i] = array[i - values.length];
|
||||
}
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
public static String[] loadArgs(Source source) {
|
||||
int i = 0;
|
||||
int lastStart = -1;
|
||||
int count = 0;
|
||||
String[] result = new String[0];
|
||||
|
||||
while (source.isIndexWithinBounds(i)) {
|
||||
int c = source.getCharacter(i);
|
||||
String str = String.construct(new int[]{c});
|
||||
//Log.line("Reading new character '" + str + "'");
|
||||
if (c == '\n' || c == ' ' || c == '\r' || c == '\f' || c == '\t' || c == '\n') {
|
||||
//Log.line("Is separator");
|
||||
if (lastStart >= 0) {
|
||||
result = innerAppend(result, source, lastStart, count);
|
||||
//Log.line("Loaded arg '" + result[result.length-1] + "'");
|
||||
}
|
||||
lastStart = -1;
|
||||
count = 0;
|
||||
} else {
|
||||
//Log.line("Is not separator");
|
||||
if (lastStart < 0) {
|
||||
lastStart = i;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
i = source.getNextIndex(i);
|
||||
}
|
||||
|
||||
result = innerAppend(result, source, lastStart, count);
|
||||
//Log.line("Loaded arg '" + result[result.length-1] + "'");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String[] innerAppend(String[] result, Source source, int lastStart, int count) {
|
||||
if (count > 0) {
|
||||
result = insert(result, result.length, new String[] {source.getString(lastStart, count)});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
482
slangc/sdk/CompilerMain.sauce
Normal file
482
slangc/sdk/CompilerMain.sauce
Normal file
@@ -0,0 +1,482 @@
|
||||
package slangc.sdk;
|
||||
|
||||
import slangc.streams.FileInput;
|
||||
import slangc.streams.File;
|
||||
import slangc.streams.LogWriter;
|
||||
import slangc.streams.VFS;
|
||||
import slangc.streams.SimpleVFS;
|
||||
import slangc.api.BytecodeTarget;
|
||||
import slangc.api.CompilerWorld;
|
||||
import slangc.api.Reporter;
|
||||
import slangc.api.TypeOption;
|
||||
import slangc.parser.Annotation;
|
||||
import slangc.parser.Branch;
|
||||
import slangc.parser.CleopatraModeLanguage;
|
||||
import slangc.parser.LegacyLanguage;
|
||||
import slangc.parser.Node;
|
||||
import slangc.parser.Token;
|
||||
|
||||
public class CompilerMain {
|
||||
public static int a(int i) {
|
||||
Log.line("" + i);
|
||||
return i;
|
||||
}
|
||||
public static void b(int a, int b) {
|
||||
Log.line(a + " " + b);
|
||||
}
|
||||
|
||||
public static void usage(String[] args, int argi, String message) {
|
||||
Log.line("USAGE:\n\tTODO...\n" + message);
|
||||
if (message != null) {
|
||||
throw new Error("TODO: Safe exit"); //System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void doAddSource(CompilerWorld world, File file, boolean isReference) throws Error {
|
||||
recursiveAddSource(world, null, file, isReference);
|
||||
}
|
||||
|
||||
private static byte[] getFileBytes(File f) throws Error {
|
||||
FileInput in = f.openInput();
|
||||
byte[] out = new byte[(int) f.size()];
|
||||
in.readBuffer(out, 0, out.length);
|
||||
in.close();
|
||||
return out;
|
||||
}
|
||||
|
||||
private static void recursiveAddSource(CompilerWorld world, String packagename, File file, boolean isReference) throws Error {
|
||||
File[] subs = file.list();
|
||||
if (subs == null) {
|
||||
//Log.line(" > Processing " + (isReference ? "referenced" : "included") + " file " + file.path());
|
||||
if (world.matchesIgnorePattern(file.name())) {
|
||||
//Log.line("Ignoring '" + file.path() + "'...");
|
||||
} else if (world.matchesDataPattern(file.name())) {
|
||||
//Log.line("Adding data file '" + file.path() + "'...");
|
||||
if (!isReference) world.addDataFile(packagename, file.name(), getFileBytes(file), null, null);
|
||||
} else if (world.matchesSourcePattern(file.name())) {
|
||||
//Log.line("Adding source file '" + file.path() + "'...");
|
||||
world.addSource(/*new SimpleSource(file)*/ new UnicodeSource(file), isReference);
|
||||
} else {
|
||||
throw new Error("Unrecognised file extension for '" + file.path() + "'");
|
||||
//Log.line("Ignoring " + file.path() + "...");
|
||||
}
|
||||
} else {
|
||||
if (packagename == null) {
|
||||
packagename = ""; // This should be used for default/outer directory
|
||||
} else if (packagename.equals("")) {
|
||||
packagename = file.name();
|
||||
} else {
|
||||
packagename = packagename + "." + file.name();
|
||||
}
|
||||
//Log.line("Scanning directory '" + file.path() + "' (as package " + packagename + ")...");
|
||||
for (int i = 0; i < subs.length; i++) {
|
||||
recursiveAddSource(world, packagename, subs[i], isReference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Log.line("Zak's Burrito Compiler, build #13-ish");
|
||||
//Log.line("Hello, ٣١٤١٥=" + ٣١٤١٥);
|
||||
int i = 0;
|
||||
|
||||
VFS vfs = new SimpleVFS();
|
||||
|
||||
CompilerWorld world = new CompilerWorld();
|
||||
world.addSourcePattern("*.sauce");
|
||||
|
||||
/*
|
||||
world.addIgnorePattern("*.foo");
|
||||
world.addDataPattern("bar");
|
||||
*/
|
||||
|
||||
/*for (i = 0; i < args.length; i++) {
|
||||
Log.line("Arg #" + i + " is '" + args[i] + "'");
|
||||
}
|
||||
i = 0;*/
|
||||
|
||||
boolean doingSomething = false;
|
||||
Reporter reporter = null;
|
||||
//Log.line("Doing args...");
|
||||
//Log.startTracing();
|
||||
try {
|
||||
while (i < args.length) {
|
||||
//Log.line("Handling Arg #" + i + " is '" + args[i] + "'");
|
||||
/* If it's a "-b" flag, then we translate it into corresponding "-a" and "-r" flags. */
|
||||
|
||||
if (args[i].startsWith("-b")) {
|
||||
if (args[i].intsLength() > 2) {
|
||||
String path = args[i].sub(2);
|
||||
args = ArgsLoader.remove(args, i);
|
||||
args = ArgsLoader.insert(args, i, new String[] {"-a", path + "/compiler.wrap", "-r", path});
|
||||
} else {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i + 1, "Expecting filename following -a flag");
|
||||
return;
|
||||
}
|
||||
String path = args[i+1];
|
||||
args = ArgsLoader.remove(args, i);
|
||||
args = ArgsLoader.remove(args, i);
|
||||
args = ArgsLoader.insert(args, i, new String[] {"-a", path + "/compiler.wrap", "-r", path});
|
||||
}
|
||||
/*for (int x = 0; x < args.length; x++) {
|
||||
Log.line("Arg #" + x + " = '" + args[x] + "'");
|
||||
}
|
||||
System.exit(-1);*/
|
||||
}
|
||||
/* If it's a "-a" flag, then we want to load the arguments from a file, insert them in the array,
|
||||
* then continue processing!
|
||||
*/
|
||||
if (args[i].startsWith("-a")) {
|
||||
if (args[i].intsLength() > 2) {
|
||||
Log.line("NOTE: Loading compiler arguments from " + args[i].sub(2));
|
||||
String[] newArgs = ArgsLoader.loadArgs(new UnicodeSource(vfs.file(args[i].sub(2))));
|
||||
args = ArgsLoader.remove(args, i);
|
||||
args = ArgsLoader.insert(args, i, newArgs);
|
||||
} else {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i + 1, "Expecting filename following -a flag");
|
||||
return;
|
||||
}
|
||||
Log.line("NOTE: Loading compiler arguments from " + args[i+1]);
|
||||
String[] newArgs = ArgsLoader.loadArgs(new UnicodeSource(vfs.file(args[i+1])));
|
||||
args = ArgsLoader.remove(args, i);
|
||||
args = ArgsLoader.remove(args, i);
|
||||
args = ArgsLoader.insert(args, i, newArgs);
|
||||
}
|
||||
/*for (int x = 0; x < args.length; x++) {
|
||||
Log.line("Arg #" + x + " = '" + args[x] + "'");
|
||||
}
|
||||
System.exit(-1);*/
|
||||
}
|
||||
|
||||
//Log.line("Handling Arg #" + i + " is '" + args[i] + "'");
|
||||
if (args[i].equals("--provides-version")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected name and version following --provides-version");
|
||||
return;
|
||||
}
|
||||
world.addProvidesVersion(args[i + 1], args[i + 2]);
|
||||
i += 2;
|
||||
} else if (args[i].equals("--depends-version")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected name and version following --depends-version");
|
||||
return;
|
||||
}
|
||||
world.addDependsVersion(args[i + 1], args[i + 2]);
|
||||
i += 2;
|
||||
} else if (args[i].equals("--source-pattern")) {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expected source pattern following --source-pattern (e.g. \"*.slang\" - probably with the quotes)");
|
||||
return;
|
||||
}
|
||||
world.addSourcePattern(args[i + 1]);
|
||||
i += 1;
|
||||
} else if (args[i].equals("--ignore-pattern")) {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expected ignore pattern following --ignore-pattern (e.g. \"*.project\" - probably with the quotes)");
|
||||
return;
|
||||
}
|
||||
world.addIgnorePattern(args[i + 1]);
|
||||
i += 1;
|
||||
} else if (args[i].equals("--data-pattern")) {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expected source pattern following --data-pattern (e.g. \"*.png\" - probably with the quotes)");
|
||||
return;
|
||||
}
|
||||
world.addDataPattern(args[i + 1]);
|
||||
i += 1;
|
||||
} else if (args[i].equals("--global-import")) {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expected package name following --global-import");
|
||||
return;
|
||||
}
|
||||
world.addGlobalImport(args[i + 1]);
|
||||
i += 1;
|
||||
} else if (args[i].equals("--alias-type")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected alias and target type names following --alias-type");
|
||||
return;
|
||||
}
|
||||
world.addAliasType(args[i + 1], args[i + 2]);
|
||||
i += 2;
|
||||
} else if (args[i].equals("--alias-package")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected alias and target package names following --alias-package");
|
||||
return;
|
||||
}
|
||||
world.addAliasPackage(args[i + 1], args[i + 2]);
|
||||
i += 2;
|
||||
} else if (args[i].equals("--main")) {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expected type name following --main");
|
||||
return;
|
||||
}
|
||||
world.addMainType(args[i + 1]);
|
||||
i += 1;
|
||||
} else if (args[i].equals("--special-type-format")) {
|
||||
if (i + 3 >= args.length) {
|
||||
usage(args, i, "Expected kind name, type name and runtime-specific format string following --special-type-format");
|
||||
return;
|
||||
}
|
||||
TypeOption.Kind k;
|
||||
k = (TypeOption.Kind) TypeOption.Kind.lookup(TypeOption.Kind.class, args[i + 1]);
|
||||
if (k == null) {
|
||||
usage(args, i+1, "Invalid kind name");
|
||||
return;
|
||||
}
|
||||
world.addSpecialType(k, args[i + 2], args[i + 3]);
|
||||
i += 3;
|
||||
} else if (args[i].equals("--special-type")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected kind name and type name following --special-type");
|
||||
return;
|
||||
}
|
||||
TypeOption.Kind k;
|
||||
try {
|
||||
k = (TypeOption.Kind) TypeOption.Kind.lookup(TypeOption.Kind.class, args[i + 1]);
|
||||
} catch(Error e) {
|
||||
e.log();
|
||||
Log.line("Name of VOID is '" + TypeOption.Kind.VOID.name() + "'");
|
||||
usage(args, i+1, "Invalid kind name");
|
||||
return;
|
||||
}
|
||||
world.addSpecialType(k, args[i + 2], null);
|
||||
i += 2;
|
||||
} else if (args[i].equals("--builtin-type")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected kind name and type name following --builtin-type");
|
||||
return;
|
||||
}
|
||||
TypeOption.Kind k;
|
||||
try {
|
||||
k = (TypeOption.Kind) TypeOption.Kind.lookup(TypeOption.Kind.class, args[i + 1]);
|
||||
} catch(Error e) {
|
||||
usage(args, i+1, "Invalid kind name");
|
||||
return;
|
||||
}
|
||||
world.addBuiltinType(k, args[i + 2], null);
|
||||
i += 2;
|
||||
} else if (args[i].equals("--meta")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected key and typeName following --meta");
|
||||
return;
|
||||
}
|
||||
world.addMeta(false, args[i + 1], args[i + 2]);
|
||||
i += 2;
|
||||
} else if (args[i].equals("--important-meta")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expected key and typeName following --important-meta");
|
||||
return;
|
||||
}
|
||||
world.addMeta(true, args[i + 1], args[i + 2]);
|
||||
i += 2;
|
||||
} else if (args[i].startsWith("-r")) {
|
||||
if (args[i].ints().length > 2) {
|
||||
doAddSource(world, vfs.file(args[i].sub(2)), true);
|
||||
doingSomething = true;
|
||||
} else {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
usage(args, i, "Expecting filename following -r flag");
|
||||
return;
|
||||
}
|
||||
doAddSource(world, vfs.file(args[i]), true);
|
||||
doingSomething = true;
|
||||
}
|
||||
} else if (args[i].startsWith("-o")) {
|
||||
if (args[i].ints().length > 2) {
|
||||
world.setTarget(new BytecodeTarget(new SimpleBytecodeOutput(vfs.file(args[i].sub(2)).openOutput())));
|
||||
//doingSomething = true;
|
||||
} else {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
usage(args, i, "Expecting filename following -o flag");
|
||||
return;
|
||||
}
|
||||
world.setTarget(new BytecodeTarget(new SimpleBytecodeOutput(vfs.file(args[i]).openOutput())));
|
||||
//doingSomething = true;
|
||||
}
|
||||
} else if (args[i].equals("--compliments-to-the-chef") || args[i].equals("--gluten-free")) {
|
||||
Log.line("**************************************************");
|
||||
String start = "* Salt Sprinkling Mode ";
|
||||
boolean merciless = args[i].equals("--gluten-free");
|
||||
CleopatraModeLanguage herMajesty = new CleopatraModeLanguage(!merciless);
|
||||
herMajesty.addMedu(CleopatraModeLanguage.Medu.NUBIAN);
|
||||
herMajesty.addMedu(CleopatraModeLanguage.Medu.COPTIC);
|
||||
world.setLanguage(herMajesty);
|
||||
Log.line(start + (merciless ? " TURBO *" : "ACTIVATED *"));
|
||||
Log.line("**************************************************");
|
||||
//herMajesty.printTable(System.err);
|
||||
//return;
|
||||
} else if (args[i].equals("-ll0")) {
|
||||
world.setLanguage(new LegacyLanguage(0));
|
||||
} else if (args[i].equals("-ll1")) {
|
||||
world.setLanguage(new LegacyLanguage(1));
|
||||
} else if (args[i].equals("-ll2")) {
|
||||
world.setLanguage(new LegacyLanguage(2));
|
||||
} else if (args[i].equals("-ll3")) {
|
||||
world.setLanguage(new LegacyLanguage(3));
|
||||
} else if (args[i].equals("-ll4")) {
|
||||
world.setLanguage(new LegacyLanguage(4));
|
||||
} else if (args[i].equals("-ll5")) {
|
||||
world.setLanguage(new LegacyLanguage(5));
|
||||
} else if (args[i].equals("-ll6")) {
|
||||
world.setLanguage(new LegacyLanguage(6));
|
||||
} else if (args[i].equals("-ll7")) {
|
||||
world.setLanguage(new LegacyLanguage(7));
|
||||
} else if (args[i].equals("-ll8")) {
|
||||
world.setLanguage(new LegacyLanguage(8));
|
||||
} else if (args[i].equals("-ll9")) {
|
||||
world.setLanguage(new LegacyLanguage(9));
|
||||
} else if (args[i].equals("-ll10")) {
|
||||
world.setLanguage(new LegacyLanguage(10));
|
||||
} else if (args[i].equals("-ll11")) {
|
||||
world.setLanguage(new LegacyLanguage(11));
|
||||
} else if (args[i].equals("-ll12")) {
|
||||
world.setLanguage(new LegacyLanguage(12));
|
||||
} else if (args[i].equals("-ll13")) {
|
||||
world.setLanguage(new LegacyLanguage(13));
|
||||
} else if (args[i].equals("-ll14")) {
|
||||
world.setLanguage(new LegacyLanguage(14));
|
||||
} else if (args[i].equals("-ll15")) {
|
||||
world.setLanguage(new LegacyLanguage(15));
|
||||
} else if (args[i].equals("-ll16")) {
|
||||
world.setLanguage(new LegacyLanguage(16));
|
||||
} else if (args[i].equals("--language-forget")) {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expecting setting name following --language-forget");
|
||||
return;
|
||||
}
|
||||
if (!world.getLanguage().applySetting(args[i+1], null, true, false)) {
|
||||
usage(args, i+1, "Invalid setting");
|
||||
return;
|
||||
}
|
||||
i += 1;
|
||||
} /*else if (args[i].equals("--language-set")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expecting setting name and value following --language-set");
|
||||
return;
|
||||
}
|
||||
if (!world.getLanguage().applySetting(args[i+1], args[i+2], false, false)) {
|
||||
usage(args, i+2, "Invalid setting");
|
||||
return;
|
||||
}
|
||||
i += 2;
|
||||
}*/ else if (args[i].equals("--language-add")) {
|
||||
if (i + 2 >= args.length) {
|
||||
usage(args, i, "Expecting setting name and value following --language-append");
|
||||
return;
|
||||
}
|
||||
if (!world.getLanguage().applySetting(args[i+1], args[i+2], false, true)) {
|
||||
usage(args, i+2, "Invalid setting");
|
||||
return;
|
||||
}
|
||||
i += 2;
|
||||
} else if (args[i].equals("--array-length-name")) {
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expecting setting name following --array-length-name");
|
||||
return;
|
||||
}
|
||||
world.addArrayLengthName(args[i+1]);
|
||||
i += 1;
|
||||
} else if (args[i].equals("--errors-brief")) {
|
||||
world.setErrorVerbosity(0);
|
||||
} else if (args[i].equals("--errors-nice")) {
|
||||
world.setErrorVerbosity(2);
|
||||
} else if (args[i].equals("--errors-ast")) {
|
||||
world.setErrorVerbosity(5);
|
||||
} else if (args[i].equals("--errors-full-ast")) {
|
||||
world.setErrorVerbosity(10);
|
||||
} else if (args[i].equals("--cache-dir")) {
|
||||
//Log.line("WTF...");
|
||||
if (i + 1 >= args.length) {
|
||||
usage(args, i, "Expecting directory path following --cache-dir");
|
||||
return;
|
||||
}
|
||||
//Log.line("Trying to set cache manager...");
|
||||
world.setCacheManager(new SimpleCacheManager(vfs.file(args[i+1])));
|
||||
//Log.line("Done.");
|
||||
i += 1;
|
||||
} else {
|
||||
Log.line("Adding regular sources '" + args[i] + "'");
|
||||
doAddSource(world, vfs.file(args[i]), false);
|
||||
doingSomething = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!doingSomething) {
|
||||
usage(args, i, "Expecting something to do! Try listing some source files?");
|
||||
}
|
||||
|
||||
if (reporter == null) {
|
||||
reporter = new SimpleReporter();
|
||||
}
|
||||
world.setReporter(reporter);
|
||||
if (world.build()) {
|
||||
Log.line("Compilation completed.");
|
||||
} else {
|
||||
Log.line("Compilation terminated without finishing.");
|
||||
}
|
||||
} catch (Error e) {
|
||||
e.log();
|
||||
// TODO: Is more reporting needed here?
|
||||
}
|
||||
//SimpleSource src = new SimpleSource("package x.y\nimport z.*; import foo.bar.Baz;\npublic final enum X extends a.B, C{X,Y,private static Z,;} class Foo extends Bar {\nvoid x(int a){{}}\nint a = 1, b;\npublic Foo(int... nums){}}\n/* comment 1 */\n// comment 2\nclass Documented {\n/* look, an array of arrays: */\nint[][] arrz = null;\nDocumented(){if(true){return 1;}else{return;}int x = add(1,z().foo[1].mul(2,3)), y = (z).foo();n();x++; x *= 2; x = 1 + 2 * -3 + new fencom.Object;\nx = \"foo bar\";\n}\n}\n");//int add(int x, int y){\nreturn x + y;\n}
|
||||
/*Scan scan = new Scan(new Language(), src);
|
||||
int n = scan.scanPedantic();
|
||||
Log.line("Scanned " + n + " tokens:");
|
||||
for (int i = 0; i < scan.countTokens(); i++) {
|
||||
Log.line(" > " + scan.getToken(i));
|
||||
}
|
||||
Parse p = new Parse();
|
||||
Node u = p.parseUnit(scan);
|
||||
Log.line("Finished parsing!");
|
||||
// Was just for testing order of operations: b(a(1), a(2));
|
||||
dump(System.out, u);
|
||||
*/
|
||||
}
|
||||
@SuppressWarnings("unused")
|
||||
private static void dump(LogWriter out, Node n) {
|
||||
dump(out, n, "", " ");
|
||||
}
|
||||
|
||||
private static void dump(LogWriter out, Node n, String curindent, String subindent) {
|
||||
if (n instanceof Branch) {
|
||||
dumpBranch(out, (Branch) n, curindent, subindent);
|
||||
} else if (n instanceof Token) {
|
||||
dumpToken(out, (Token) n, curindent, subindent);
|
||||
} else if (n instanceof Annotation) {
|
||||
dumpAnnotation(out, (Annotation) n, curindent, subindent);
|
||||
} else if (n == null) {
|
||||
out.println(curindent + "-! UH-OH !- null");
|
||||
} else {
|
||||
out.println(curindent + "-! TO-DO !- code to dump " + n);
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpAnnotations(LogWriter out, Node n, String curindent, String subindent) {
|
||||
for (int i = 0; i < n.countAnnotations(); i++) {
|
||||
dump(out, n.getAnnotation(i), curindent + subindent, subindent);
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpBranch(LogWriter out, Branch b, String curindent, String subindent) {
|
||||
out.println(curindent + "-> " + b.getNodeType());
|
||||
dumpAnnotations(out, b, curindent, subindent);
|
||||
for (int i = 0; i < b.countSubnodes(); i++) {
|
||||
dump(out, b.getSubnode(i), curindent + subindent, subindent);
|
||||
}
|
||||
}
|
||||
|
||||
private static void dumpToken(LogWriter out, Token t, String curindent, String subindent) {
|
||||
out.println(curindent + "-. " + t);
|
||||
dumpAnnotations(out, t, curindent, subindent);
|
||||
}
|
||||
|
||||
private static void dumpAnnotation(LogWriter out, Annotation a, String curindent, String subindent) {
|
||||
out.println(curindent + "-+ " + a);
|
||||
dumpAnnotations(out, a, curindent, subindent);
|
||||
}
|
||||
}
|
54
slangc/sdk/SimpleBytecodeOutput.sauce
Normal file
54
slangc/sdk/SimpleBytecodeOutput.sauce
Normal file
@@ -0,0 +1,54 @@
|
||||
package slangc.sdk;
|
||||
|
||||
import slang.streams.SyncOutput;
|
||||
import slangc.streams.ArrayOutput;
|
||||
import slangc.streams.FileOutput;
|
||||
import slangc.api.BytecodeOutput;
|
||||
|
||||
public class SimpleBytecodeOutput extends BytecodeOutput {
|
||||
private SyncOutput<byte> out;
|
||||
|
||||
public SimpleBytecodeOutput() {
|
||||
this.out = new ArrayOutput();
|
||||
}
|
||||
|
||||
public SimpleBytecodeOutput(FileOutput out) {
|
||||
//try {
|
||||
this.out = out; //new FileOutput(outname);
|
||||
//} catch (Error e) {
|
||||
// throw new Error("Couldn't open output stream", e);
|
||||
//}
|
||||
}
|
||||
|
||||
public SimpleBytecodeOutput(SyncOutput<byte> out) {
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processByte(byte b) {
|
||||
//byte[] buf = new byte[1];
|
||||
//int tmp = b + 0;
|
||||
//buf[0] = (byte) tmp; // TODO: More thorough type-checking??
|
||||
try {
|
||||
if (out.writeBuffer(new byte[]{b}, 0, 1) != 1) {
|
||||
throw new Error("Failed to write byte to output stream");
|
||||
}
|
||||
} catch (Error e) {
|
||||
throw new Error("Couldn't write to output stream", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endOfFile() {
|
||||
try {
|
||||
out.close();
|
||||
} catch (Error e) {
|
||||
throw new Error("Couldn't close output stream", e);
|
||||
}
|
||||
out = null;
|
||||
}
|
||||
|
||||
public SyncOutput<byte> getOut() {
|
||||
return out;
|
||||
}
|
||||
}
|
34
slangc/sdk/SimpleCacheManager.sauce
Normal file
34
slangc/sdk/SimpleCacheManager.sauce
Normal file
@@ -0,0 +1,34 @@
|
||||
package slangc.sdk;
|
||||
|
||||
import slangc.api.CacheManager;
|
||||
import slangc.streams.File;
|
||||
import slang.streams.SyncInput;
|
||||
import slang.streams.SyncOutput;
|
||||
|
||||
public class SimpleCacheManager extends CacheManager {
|
||||
public File outerDir;
|
||||
|
||||
public SimpleCacheManager(File outerDir) {
|
||||
this.outerDir = outerDir;
|
||||
}
|
||||
|
||||
public boolean looksReady(String cacheName) {
|
||||
return ((int)outerDir.getVFS().size(outerDir.path() + "/" + cacheName)) > 0;
|
||||
}
|
||||
|
||||
public SyncInput<byte> getInput(String cacheName) {
|
||||
if (looksReady(cacheName)) {
|
||||
//Log.line("I'm gonna fuckin try it");
|
||||
return outerDir.getVFS().openInput(outerDir.path() + "/" + cacheName);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public SyncOutput<byte> getOutput(String cacheName) {
|
||||
if (looksReady(cacheName)) {
|
||||
return null;
|
||||
}
|
||||
return outerDir.getVFS().openOutput(outerDir.path() + "/" + cacheName);
|
||||
}
|
||||
}
|
16
slangc/sdk/SimpleReporter.sauce
Normal file
16
slangc/sdk/SimpleReporter.sauce
Normal file
@@ -0,0 +1,16 @@
|
||||
package slangc.sdk;
|
||||
|
||||
import slangc.api.NullReporter;
|
||||
|
||||
public class SimpleReporter extends NullReporter {
|
||||
|
||||
public SimpleReporter() {
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void note(String topic, String text) {
|
||||
Log.line(topic + ": " + text);
|
||||
}
|
||||
|
||||
}
|
54
slangc/sdk/SimpleSource.sauce
Normal file
54
slangc/sdk/SimpleSource.sauce
Normal file
@@ -0,0 +1,54 @@
|
||||
package slangc.sdk;
|
||||
|
||||
import slangc.streams.FileInput;
|
||||
import slangc.streams.File;
|
||||
import slangc.parser.Source;
|
||||
|
||||
public class SimpleSource extends Source {
|
||||
byte[] source;
|
||||
|
||||
public SimpleSource(File file) throws Error {
|
||||
this(file.path(), file);
|
||||
}
|
||||
|
||||
public SimpleSource(String filename, File file) throws Error {
|
||||
super(filename);
|
||||
FileInput is = file.openInput();
|
||||
byte[] fileData = new byte[(int) file.size()];
|
||||
/*int i =*/ is.read(fileData);
|
||||
//System.out.println("Read " + i + " bytes from " + file);
|
||||
is.close();
|
||||
this.source = String.construct(fileData);
|
||||
//sourceFile = this.source.replace("\r\n", "\n");
|
||||
//System.out.println("GOT:\n" + sourceFile);
|
||||
}
|
||||
|
||||
public SimpleSource(String filename, String source) {
|
||||
super(filename);
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public SimpleSource(String source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexLength() {
|
||||
return source.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacter(int index) {
|
||||
if (isIndexWithinBounds(index)) {
|
||||
return (int) source[index]; //.charAt(index);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNextIndex(int currentIndex) {
|
||||
// TODO Auto-generated method stub
|
||||
return currentIndex + 1;
|
||||
}
|
||||
}
|
5
slangc/sdk/UnicodeCharacter.sauce
Normal file
5
slangc/sdk/UnicodeCharacter.sauce
Normal file
@@ -0,0 +1,5 @@
|
||||
package slangc.sdk;
|
||||
|
||||
public class UnicodeCharacter {
|
||||
|
||||
}
|
97
slangc/sdk/UnicodeSource.sauce
Normal file
97
slangc/sdk/UnicodeSource.sauce
Normal file
@@ -0,0 +1,97 @@
|
||||
package slangc.sdk;
|
||||
|
||||
import slangc.streams.FileInput;
|
||||
import slangc.streams.File;
|
||||
import slangc.parser.Source;
|
||||
|
||||
public class UnicodeSource extends Source {
|
||||
int[] source;
|
||||
|
||||
public UnicodeSource(File file) throws Error {
|
||||
this(file.path(), file);
|
||||
}
|
||||
|
||||
public UnicodeSource(String filename, File file) throws Error {
|
||||
super(filename);
|
||||
FileInput is = file.openInput();
|
||||
byte[] fileData = new byte[(int) file.size()];
|
||||
int ln = is.read(fileData);
|
||||
//System.out.println("Read " + i + " bytes from " + file);
|
||||
is.close();
|
||||
// This is a lot easier in Slang since the String class handles both 8-bit and 32-bit conversions naturally:
|
||||
//Log.line("About to construct...");
|
||||
String strsource = String.construct(fileData); // This will assume a standard 8-bit encoding (compressed characters)
|
||||
//Log.line("Done constructing!");
|
||||
source = strsource.ints(); // This will assume a standard 32-bit encoding (one value per character)
|
||||
//String strsource = new String(fileData, "UTF-8");
|
||||
//int ncp = strsource.codePointCount(0, strsource.length());
|
||||
//source = new int[ncp];
|
||||
//int cpi = 0;
|
||||
//int i = 0;
|
||||
//while (i < strsource.length()) {
|
||||
// if (cpi >= ncp) {
|
||||
// throw new Error("Unicode error: Number of characters (at least " + cpi + ") is greater than number of expected characters ("+ncp+")");
|
||||
// }
|
||||
// int cp = strsource.codePointAt(i);
|
||||
// int cpl = Character.toChars(cp).length;
|
||||
// source[cpi] = cp;
|
||||
// i += cpl;
|
||||
// cpi++;
|
||||
//}
|
||||
//source = this.source.replace("\r\n", "\n");
|
||||
//System.out.println("GOT:\n" + source);
|
||||
}
|
||||
|
||||
public UnicodeSource(String filename, int[] source) {
|
||||
super(filename);
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public UnicodeSource(int[] source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIndexLength() {
|
||||
return source.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCharacter(int index) {
|
||||
if (isIndexWithinBounds(index)) {
|
||||
return source[index];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
int lastidx = 0;
|
||||
int lastlen = 0;
|
||||
String laststr = null;
|
||||
public String getString(int index, int len) {
|
||||
if (index == lastidx && len == lastlen) {
|
||||
return laststr;
|
||||
} else {
|
||||
lastidx = index;
|
||||
lastlen = len;
|
||||
laststr = super.getString(index, len);
|
||||
return laststr;
|
||||
}
|
||||
}*/
|
||||
|
||||
public String getString(int index, int len) {
|
||||
if (index + len > source.length) {
|
||||
return super.getString(index, len);
|
||||
}
|
||||
int[] vals = new int[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
vals[i] = source[index+i];
|
||||
}
|
||||
return String.construct(vals);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNextIndex(int currentIndex) {
|
||||
return currentIndex + 1;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user