slcom/slangc/parser/CleopatraModeLanguage.sauce

258 lines
9.9 KiB
Plaintext
Raw Permalink Normal View History

package slangc.parser;
import slang.data.List;
import slangc.streams.LogWriter;
public class CleopatraModeLanguage extends Language {
private Option[] options = new Option[0];
private final boolean enableFallbacks;
public CleopatraModeLanguage(boolean enableFallbacks) {
this.enableFallbacks = enableFallbacks;
}
public static class Option {
public final String language;
public final Key key;
public final String value;
public Option(String language, Key key, String value) {
this.language = language;
this.key = key;
this.value = value;
}
}
public void addOption(Option o) {
Option[] newarr = new Option[options.length + 1];
for (int i = 0; i < newarr.length; i++) {
newarr[i] = (i < options.length ? options[i] : o);
}
options = newarr;
}
public void addOption(String language, Key key, String value) {
addOption(new Option(language, key, value));
}
public void addOption(Medu medu, Key key, String value) {
addOption(""+medu /*.name()*/, key, value);
}
String[] cachedKeywords = null;
@Override
public String[] getKeywords() {
if (cachedKeywords == null) {
cachedKeywords = recalculateKeywords();
}
return cachedKeywords;
}
public String[] recalculateKeywords() {
String[] initial;
if (enableFallbacks) {
initial = super.getKeywords();
} else {
initial = new String[0];
}
String[] result = new String[initial.length + options.length];
for (int i = 0; i < result.length; i++) {
result[i] = (i < initial.length ? initial[i] : options[i - initial.length].value);
}
return result;
}
@Override
public boolean matches(Key key, String str) {
for (int i = 0; i < options.length; i++) {
if (options[i].key == key && options[i].value.equals(str)) {
return true;
}
}
if (enableFallbacks) {
return super.matches(key, str);
} else {
return false;
}
}
public enum Medu {
USERDEFINED,
NETER,
NUBIAN,
COPTIC,
GREEK
}
public void addMedu(Medu m) {
switch (m) {
case Medu.NUBIAN:
addNubian();
break;
case Medu.COPTIC:
addCoptic();
break;
default:
throw new Error("TODO: This medu mode " + m + " is not implemented yet");
}
}
public void printTable(LogWriter out) {
/*
List<String> columns = new List<String>();
for (int i = 0; i < options.length; i++) {
if (!columns.contains(options[i].language)) {
columns.add(options[i].language);
}
}
out.print("[%header,cols=\"1,");
for (int i = 0; i < columns.size(); i++) {
if (i != 0) {
out.print(",");
}
out.print(2);
}
out.println("\"]");
out.println("|===");
out.print("|Keyword Id ");
for (int i = 0; i < columns.size(); i++) {
//if (i != 0) {
// out.print(",");
//}
out.print("|" + columns.get(i) + " ");
}
out.println();
out.println();
for (int i = 0; i < Key.values().length; i++) {
printTableRow(out, columns, Key.values()[i]);
out.println();
}
out.println("|===");
*/
throw new Error("TODO: Printing language tables");
}
public void printTableRow(LogWriter out, List<String> columns, Key key) {
out.print("|" + key + " ");
for (int i = 0; i < columns.count(); i++) {
out.print("| ");
boolean addedOne = false;
for (int j = 0; j < options.length; j++) {
Option o = options[j];
if (o.key == key && o.language.equals(columns.get(i))) {
if (addedOne) {
out.print(", ");
} else {
addedOne = true;
}
out.print("`" + o.value + "`");
}
}
if (addedOne) {
out.print(" ");
}
}
out.println();
}
public void addNubian() {
addOption(Medu.NUBIAN, Key.CLASS, "ⲕⲗⲁⲥⲥ");
addOption(Medu.NUBIAN, Key.PUBLIC, "ⲡⲩⲃⲗⲓⲕ");
// From "An English-Nubian Comparative Dictionary", 1923
// NOTE: There is a small but strong Nubian community on Twitter that can provide more links.
addOption(Medu.NUBIAN, Key.THIS, "ⲉⲓⲛ"); // p.xxxv, p.73 (note: "that" would be ⲙⲁⲛ)
addOption(Medu.NUBIAN, Key.BREAK, "ⲡⲁⲗ"); // p.49
addOption(Medu.NUBIAN, Key.TRUE, "ⲉⲩⲟ"); // ⲡ.48 ("yes", speculative spelling, only phonetics provided)
addOption(Medu.NUBIAN, Key.VOID, "ⲡⲁⲣⲕ"); //ⲡ.50 (a valley or place water goes without releasing)
addOption(Medu.NUBIAN, Key.IF, "ⲡⲉϣϣ"); //ⲡ.51 ("judge")
addOption(Medu.NUBIAN, Key.IF, "ⲟⲛ"); // p.188 (and/if)
addOption(Medu.NUBIAN, Key.STATIC, "ⲡⲓ"); //ⲡ.52 (i.e. to stay, as in the sentence "I'm staying at home")
addOption(Medu.NUBIAN, Key.RETURN, "ⳟⲓⲡⲓⲣⲧ"); //p.60 (repeat or return, NOTE: need to check first character)
addOption(Medu.NUBIAN, Key.THROW, "ⳝⲟⳝ"); //ⲡ.62 (kill/fight/sacrifice)
addOption(Medu.NUBIAN, Key.THROW, "ⲙⲟⲩⲣⲧ"); //ⲡ.125 (warn)
addOption(Medu.NUBIAN, Key.FOR, "ⲕⲉⲗ"); // p.95 (limit or boundary, related to the word used for WHILE)
addOption(Medu.NUBIAN, Key.WHILE, "ⲕⲉⲗⲗ"); //p.95 ("as much as", "sometimes", related to the word used for FOR)
addOption(Medu.NUBIAN, Key.DUCK, "ⲕⲉⲗⲁⲓ"); // p.95 (wild duck, speculative spelling, only phonetics provided)
addOption(Medu.NUBIAN, Key.NULL, "ⲕⲓⳡ"); // p.99 (empty or exhausted, NOTE: need to check last character)
addOption(Medu.NUBIAN, Key.FINAL, "ⲕⲓⲣⲓⳟ"); // p.100 (finished or complete, NOTE: need to check last character)
addOption(Medu.NUBIAN, Key.ABSTRACT, "ⲙⲓⲛⲇⲓ"); // ⲡ.122 (partial, incomplete, NOTE: this seems to be a rarely-used word)
addOption(Medu.NUBIAN, Key.NEW, "ⳟⲁⲓⲉⲣ"); // ⲡ.134 ("bring to life")
addOption(Medu.NUBIAN, Key.INT, "ⲥⲁⲗ"); // p.144 ("word", which fits with an old way of basically saying int - "machine word")
addOption(Medu.NUBIAN, Key.EXTENDS, "ⲥⲉⲩ"); // p.147 ("inherit")
addOption(Medu.NUBIAN, Key.MODULE, "ϣⲟⲗ"); // p.157 (a book or charm)
addOption(Medu.NUBIAN, Key.PRIVATE, "ⲧⲟⲩ"); // p.169 (internals, belly/guts)
addOption(Medu.NUBIAN, Key.THIS, "ⲟⲩⲣ"); // p. 178 ("self")
// p.161 for class/etc.?
// ⲉⲧⲉⲣ for "do"? p.48
}
public void addCoptic() {
// From "Aegyptisches Glossar", 1904
// NOTE: This source was chosen as the primary one because it focuses on words
// present in both Medu Neter and Coptic (also with many connections to Greek, Hebrew,
// Arabic and so on).
addOption(Medu.COPTIC, Key.WHILE, "ⲟⲩⲱϩⲙ"); // p.32, "repeat"/"to repeat"
addOption(Medu.COPTIC, Key.FOR, "ⲟⲩⲱϣ"); // p.32, "search"
// NOTE: See also p.56 for iteration-releated words
addOption(Medu.COPTIC, Key.RETURN, "ⲟⲩⲱϣⲃ"); // p.34, "answer"
addOption(Medu.COPTIC, Key.TRY, "ⲟⲩⲇⲁⲓ"); // p.35, "be safe"
// NOTE: See also p.56 for "witness", p.65 for "harness"
addOption(Medu.COPTIC, Key.THROW, "ⲕⲱ"); // p.90, literally "throw" or "leave"
addOption(Medu.COPTIC, Key.DO, "ⲃⲁⲕ"); // p.39, "work"
addOption(Medu.COPTIC, Key.CATCH, "ⲡⲏⲓ"); // p.41, "escaped" (fits with "catch" because that's why you need to catch it!)
addOption(Medu.COPTIC, Key.FINALLY, "ⲁϩⲟⲩ"); // p.43, "the end"/"the rear" (as in "reaching the end"? literally "ahoy"? The Euros seem to think not)
addOption(Medu.COPTIC, Key.FINALLY, "ⲡⲁϩⲟⲩ"); // Alternative spelling
// See also p.124 for a word for "tail"
addOption(Medu.COPTIC, Key.FINAL, "ⲙⲟⲩⲛⲕ"); // p.51, "complete" (literally "monk")
addOption(Medu.COPTIC, Key.FINAL, "ⲧⲱⲱⲃⲉ"); // p. 155, "seal"
addOption(Medu.COPTIC, Key.SUPER, "ⲡⲧⲁϩ"); // p.45 (Ptah = Phthah, we still use the same word "father" in English)
addOption(Medu.COPTIC, Key.SUPER, "ⲙⲁⲁⲩ"); // p.49, (Maa', from which mother is derived)
addOption(Medu.COPTIC, Key.ELSE, "ⲙ"); // p.46, "Negation of the Imperative" lmao perfect (ⲙ︦? needs line above?)
addOption(Medu.COPTIC, Key.TRUE, "ⲙⲉ"); // p.47, "true"
addOption(Medu.COPTIC, Key.TRUE, "ⲙⲏⲓ"); // Alternative spelling? (or I've interpreted this entry incorrectly...)
addOption(Medu.COPTIC, Key.STATIC, "ⲙⲟⲩⲛ"); // p.50, "stay"
addOption(Medu.COPTIC, Key.NEW, "ⲙⲓⲥⲉ"); // p.55, "give birth", "generate", "form"
addOption(Medu.COPTIC, Key.VOID, "ⲛⲟⲩϥⲉⲛ"); // p.62, spelling assumed based on nearby term. Intended meaning is "never", related to "nether".
addOption(Medu.COPTIC, Key.NULL, "ϣⲱⲩⲉⲓⲧ"); // p.127, "be empty of something"
addOption(Medu.COPTIC, Key.DUCK, ""); // p.70, slight pun (a goose is basically a duck right?)
addOption(Medu.COPTIC, Key.BREAK, "ⲗⲟ"); // p.71, "stop" or "flee"
addOption(Medu.COPTIC, Key.PRIVATE, "ϩⲱⲃⲥ"); // p.82, "conceal" or "dress"
addOption(Medu.COPTIC, Key.SWITCH, "ⲥⲱⲧⲡ"); // p.122, "choose"
addOption(Medu.COPTIC, Key.CASE, "ⲥⲟⲡ"); // p.103, "type of" or "case of" (note, type seems to be "Art" in German?)
addOption(Medu.COPTIC, Key.SHORT, "ϣⲓⲣⲉ"); // p.130, "be small"
addOption(Medu.COPTIC, Key.BYTE, "ϣⲏⲣⲉ"); // p.130, "smaller" (literally same as ϣⲓⲣⲉ except shorter "i" vowel)
addOption(Medu.COPTIC, Key.CLASS, "ⲕⲟⲧ"); // p.135, "circle", "shape", "kind", "essence"
// p.140 for "equip" as extends/implements? 151 for similar
// p.153 for "enter" as main?
// p.33 for "say" as logLine?
// p.45 for "run" ?
// p.58 for "depth" as length?
}
public boolean applySetting(String key, String value, boolean reset, boolean append) {
if (reset && key == "*") {
options = new Option[0];
return true;
} else if (append && value != null && !reset) {
Key k;
try {
k = (Key) Key.lookup(Key.class, key);
} catch (Error e) {
return false;
}
addOption(Medu.USERDEFINED, k, value);
return true;
} else {
return super.applySetting(key, value, reset, append);
}
}
}