package slangc.parser; /** * An extension to the default language options configured for legacy code. * *
* Most of the job of this class is just to disable specific keywords to allow legacy code * to build. There is no strict feature-detection when handling other changes at this point, * but generally it's the addition of keywords that stop older code from building (this is * less and less of a problem with updates to newer versions, which usually don't require * new keywords). If more specific checks are required, this class can still be used to * differentiate versions (e.g. it might be worth adding some boolean methods like * "supportsGenerics()"). * * @author Zak * */ public class LegacyLanguage extends Language { private final int version; public LegacyLanguage(int version) { switch (version) { case 0: // First major version case 1: // Added inner classes, possibly other changes case 2: // Added "strictfp", maybe other changes? (first widely-used version) case 3: // No language changes from 2? case 4: // Added assert case 5: // Added generics, enums, annotations/attributes, etc. (major update) case 6: // No language changes from 5? case 7: // Added string switch, binary literals, enhanced try-catch, "diamond operator" new ArrayList<>() (maybe other language features?) case 8: // Added lambda expressions, enhanced interfaces case 9: // Added interface private methods, probably other changes case 10: // Added "var" for local variable type inference case 11: // TODO... case 12: case 13: case 14: case 15: case 16: this.version = version; break; default: throw new Error("Bad legacy language version: " + version); } } public int getLegacyVersion() { return version; } private String[] kws = null; @Override public String[] getKeywords() { if (kws == null) { String[] arr1 = super.getKeywords(); String[] kws = new String[arr1.length]; for (int i = 0; i < kws.length; i++) { kws[i] = arr1[i]; // Some newly-introduced keywords are always disabled in legacy mode if (kws[i].equals("syncrhonised") || kws[i].equals("module") || kws[i].equals("pointer") || kws[i].equals("duck")) { kws[i] = "void"; // Disable by replacing with a duplicate "void" keyword } // Others depend on version - are you trying to compile 90's code or something from 2013? if (version < 2 && kws[i].equals("strictfp")) { kws[i] = "void"; // Disable by replacing with a duplicate "void" keyword } if (version < 4 && kws[i].equals("assert")) { kws[i] = "void"; // Disable by replacing with a duplicate "void" keyword } if (version < 5 && kws[i].equals("enum")) { kws[i] = "void"; // Disable by replacing with a duplicate "void" keyword } if (version < 9 && kws[i].equals("_")) { kws[i] = "void"; // Disable by replacing with a duplicate "void" keyword } } } return kws; } }