slcom/slangc/parser/CleopatraModeLanguage.sauce

258 lines
9.9 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
}
}