#include "KSGSLeser.h" #include #include "../Error/Error.h" #include "KSGSCompile.h" #include "../Befehl/KSGSKlasse.h" #include "../Klassen/KSGSTyp.h" #include "../Funktionen/KSGSCallback.h" #include "../Main/KSGScriptObj.h" using namespace KSGScript; void KSGScript::removeLehr(Text* txt) { if (!txt->getLength()) return; while (txt->getLength() && (*txt[0] == ' ' || *txt[0] == '\n' || *txt[0] == '\r' || *txt[0] == '\t')) txt->remove(0); while (txt->getLength() && (txt->getText()[txt->getLength() - 1] == ' ' || txt->getText()[txt->getLength() - 1] == '\n' || txt->getText()[txt->getLength() - 1] == '\r' || txt->getText()[txt->getLength() - 1] == '\t')) txt->remove(txt->getLength() - 1); } void KSGScript::removeKlammer(Text* txt) { if (!txt->getLength()) return; removeLehr(txt); while (*txt[0] == '(' && txt->getText()[txt->getLength() - 1] == ')') { int count = 0; for (int i = 0; i < txt->getLength(); i++) { if (txt->getText()[i] == '(') count++; if (txt->getText()[i] == ')') count--; if (!count && i != txt->getLength() - 1) return; } txt->remove(0); txt->remove(txt->getLength() - 1); removeLehr(txt); if (!txt->getLength()) return; } } int KSGScript::hatOperator(Text* txt) { if (txt->hat("+=")) return KSGS_O_PLUSSET; if (txt->hat("-=")) return KSGS_O_MINUSSET; if (txt->hat("*=")) return KSGS_O_MAHLSET; if (txt->hat("/=")) return KSGS_O_GETEILTSET; if (txt->hat("&=")) return KSGS_O_UNDSET; if (txt->hat("|=")) return KSGS_O_ODERSET; if (txt->hat("==")) return KSGS_O_GLEICH; if (txt->hat("<=")) return KSGS_O_KLEINERGLEICH; if (txt->hat(">=")) return KSGS_O_GREATERGLEICH; if (txt->hat("!=")) return KSGS_O_UNGLEICH; if (txt->hat("||")) return KSGS_O_ODER; if (txt->hat("&&")) return KSGS_O_UND; if (txt->hat("++")) return KSGS_O_PLUS1; if (txt->hat("--")) return KSGS_O_MINUS1; if (txt->hat("<<")) return KSGS_O_NACHLINKS; if (txt->hat(">>")) return KSGS_O_NACHRECHTS; if (txt->hat("=")) return KSGS_O_SET; if (txt->hat("<")) return KSGS_O_KLEINER; if (txt->hat(">")) return KSGS_O_GREATER; if (txt->hat("|")) return KSGS_O_BITODER; if (txt->hat("&")) return KSGS_O_BITUND; if (txt->hat("+")) return KSGS_O_PLUS; if (txt->hat("-")) return KSGS_O_MINUS; if (txt->hat("*")) return KSGS_O_MAHL; if (txt->hat("/")) return KSGS_O_GETEILT; if (txt->hat("%")) return KSGS_O_REST; if (txt->hat("!")) return KSGS_O_NICHT; if (txt->hat("~")) return KSGS_O_BITNICHT; return -1; } int KSGScript::getOperatorPos(Text* txt, int* len) { *len = 2; if (txt->hat("+=")) return txt->positionVon("+="); if (txt->hat("-=")) return txt->positionVon("-="); if (txt->hat("*=")) return txt->positionVon("*="); if (txt->hat("/=")) return txt->positionVon("/="); if (txt->hat("&=")) return txt->positionVon("&="); if (txt->hat("|=")) return txt->positionVon("|="); if (txt->hat("==")) return txt->positionVon("=="); if (txt->hat("<=")) return txt->positionVon("<="); if (txt->hat(">=")) return txt->positionVon(">="); if (txt->hat("!=")) return txt->positionVon("!="); if (txt->hat("||")) return txt->positionVon("||"); if (txt->hat("&&")) return txt->positionVon("&&"); if (txt->hat("++")) return txt->positionVon("++"); if (txt->hat("--")) return txt->positionVon("--"); if (txt->hat("<<")) return txt->positionVon("<<"); if (txt->hat(">>")) return txt->positionVon(">>"); *len = 1; if (txt->hat("=")) return txt->positionVon("="); if (txt->hat("<")) return txt->positionVon("<"); if (txt->hat(">")) return txt->positionVon(">"); if (txt->hat("|")) return txt->positionVon("|"); if (txt->hat("&")) return txt->positionVon("&"); if (txt->hat("+")) return txt->positionVon("+"); if (txt->hat("-")) return txt->positionVon("-"); if (txt->hat("*")) return txt->positionVon("*"); if (txt->hat("/")) return txt->positionVon("/"); if (txt->hat("%")) return txt->positionVon("%"); if (txt->hat("!")) return txt->positionVon("!"); if (txt->hat("~")) return txt->positionVon("~"); *len = 0; return -1; } // Lese Strukturen KSGSLeseBefehl::~KSGSLeseBefehl() { int anz = listA.getEintragAnzahl(); for (int i = 0; i < anz; i++) delete listA.get(i); anz = listB.getEintragAnzahl(); for (int i = 0; i < anz; i++) delete listB.get(i); } void KSGSLeseFunktion::release() { if (!--ref) delete this; } KSGSLeseFunktion::~KSGSLeseFunktion() { int anz3 = parameter.getEintragAnzahl(); for (int k = 0; k < anz3; k++) delete parameter.get(k); anz3 = befehle.getEintragAnzahl(); for (int k = 0; k < anz3; k++) delete befehle.get(k); } void KSGSLeseKlasse::release() { if (!--ref) delete this; } KSGSLeseKlasse::~KSGSLeseKlasse() { int anz2 = variablen.getEintragAnzahl(); for (int j = 0; j < anz2; j++) delete variablen.get(j); anz2 = funktionen.getEintragAnzahl(); for (int j = 0; j < anz2; j++) funktionen.get(j)->release(); } KSGSLeseScript::~KSGSLeseScript() { int anz = variablen.getEintragAnzahl(); for (int i = 0; i < anz; i++) delete variablen.get(i); anz = funktionen.getEintragAnzahl(); for (int i = 0; i < anz; i++) funktionen.get(i)->release(); anz = klassen.getEintragAnzahl(); for (int i = 0; i < anz; i++) klassen.get(i)->release(); } // Inhalt der KSGSLeser klasse aus KSGSLeser.h // Konstruktor KSGSLeser::KSGSLeser(Reader* reader, KSGScriptProcessor* zObj, Text fileName) : KSGSLeser() { this->zObj = zObj; d = reader; this->fileName = fileName; } // Destruktor KSGSLeser::~KSGSLeser() { delete dat; } // protected KSGSLeser::KSGSLeser() : ReferenceCounter() { errorIgnore = 0; this->zObj = 0; d = 0; dat = 0; zeile = 0; mainFuncId = -1; mausFuncId = -1; tastaturFuncId = -1; tickFuncId = -1; renderFuncId = -1; } void KSGSLeser::handleError(int beginn, int ende) {} void KSGSLeser::handleKommentar(int beginn, int ende) {} void KSGSLeser::handleString(int beginn, int ende) {} // Script Laden bool KSGSLeser::ladeDatei() { bool ok = 1; zeile = 1; while (!d->istEnde()) { bool br = 0; int id = leseNext(); switch (id) { case -1: // Ende der Datei break; case 1: // Klasse if (1) { KSGSLeseKlasse* k = leseKlasse(); if (!k) { error(6, { "Klasse", fileName }, zObj); br = 1; } else dat->klassen.add(k); } break; case 2: // funktion if (1) { KSGSLeseFunktion* f = leseFunktion(); if (!f) { error(6, { "Funktion", fileName }, zObj); br = 1; } else dat->funktionen.add(f); } break; case 3: // Variable if (1) { KSGSLeseVariable* v = leseVariable(); if (!v) { error(6, { "Variable", fileName }, zObj); br = 1; } else dat->variablen.add(v); } break; case 12: // lesen if (1) { if (!leseBis('(')) { error(6, { "Lade Anweisung", fileName }, zObj); br = 1; break; } d->setLPosition(d->getLPosition() + 1, 0); if (!leseBis('"')) { error(6, { "Lade Anweisung", fileName }, zObj); br = 1; break; } d->setLPosition(d->getLPosition() + 1, 0); __int64 end = nextPosOf('"', 0); if (end < 0) { error(6, { "Lade Anweisung", fileName }, zObj); br = 1; break; } char* datei = new char[(int)(end - d->getLPosition()) + 1]; datei[end - d->getLPosition()] = 0; d->lese(datei, (int)(end - d->getLPosition())); Text* dPf = zObj->convertPfad(datei); delete[] datei; if (!leseBis(')')) { error(6, { "Lade Anweisung", fileName }, zObj); br = 1; break; } d->setLPosition(d->getLPosition() + 1, 0); Text pf = fileName; fileName.setText(dPf); Datei* dat = new Datei(); dat->setDatei(fileName); if (!dat->open(Datei::Style::lesen)) { dat->release(); error(4, { fileName }, zObj); br = 1; fileName.setText(pf); break; } Reader* tmp = d; d = dat; if (!ladeDatei()) { d = tmp; error(6, { "Lade Anweisung", fileName }, zObj); br = 1; fileName.setText(pf); break; } dat->close(); dat->release(); d = tmp; fileName.setText(pf); } break; default: // Fehler error(5, { fileName, Text() += zeile }, zObj); br = 1; break; } if (id == -1) break; if (br) { ok = 0; break; } } d = 0; return ok; } bool KSGSLeser::leseBis(char c) { __int64 pos = d->getLPosition(); int tmpZ = zeile; char byte = 0; bool kommentar = 0; int kBeg = 0; bool slash = 0; bool gefunden = 0; bool inString = 0; bool inChar = 0; int sBeg = 0; while (!d->istEnde()) { d->lese(&byte, 1); if (byte == '\n') { zeile++; if (kommentar) handleKommentar(kBeg, (int)d->getLPosition()); kommentar = 0; continue; } if (byte == '"' && !inChar && !kommentar) { if (inString) handleString(sBeg, (int)d->getLPosition()); inString = !inString; sBeg = (int)d->getLPosition() - 1; } if (byte == '\'' && !inString && !kommentar) { if (inChar) handleString(sBeg, (int)d->getLPosition()); inChar = !inChar; sBeg = (int)d->getLPosition() - 1; } if (byte == '#') { kBeg = (int)d->getLPosition() - 1; kommentar = 1; continue; } if (byte == '/') { if (slash) { kBeg = (int)d->getLPosition() - 2; kommentar = 1; slash = 0; } else slash = 1; continue; } else slash = 0; if (byte == c && !kommentar) { gefunden = 1; break; } } if (d->istEnde() && !gefunden) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); d->setLPosition(pos, 0); zeile = tmpZ; return 0; } d->setLPosition(d->getLPosition() - 1, 0); return 1; } __int64 KSGSLeser::nextPosOf(char c, char c2) { __int64 pos = d->getLPosition(); char byte = 0; bool kommentar = 0; int kBeg = 0; bool slash = 0; int count = 0; bool gefunden = 0; bool inString = 0; bool inChar = 0; int sBeg = 0; while (!d->istEnde()) { d->lese(&byte, 1); if (byte == '\n') { if (kommentar) handleKommentar(kBeg, (int)d->getLPosition()); kommentar = 0; continue; } if (byte == '"' && !inChar && !kommentar) { if (inString) handleString(sBeg, (int)d->getLPosition()); inString = !inString; sBeg = (int)d->getLPosition() - 1; } if (byte == '\'' && !inString && !kommentar) { if (inChar) handleString(sBeg, (int)d->getLPosition()); inChar = !inChar; sBeg = (int)d->getLPosition() - 1; } if (byte == '#') { kBeg = (int)d->getLPosition() - 1; kommentar = 1; continue; } if (byte == '/') { if (slash) { kBeg = (int)d->getLPosition() - 2; kommentar = 1; slash = 0; } else slash = 1; continue; } else slash = 0; if (!kommentar) { if (byte == c2) { count++; continue; } if (byte == c) { if (!count) { gefunden = 1; break; } count--; continue; } } } if (d->istEnde() && !gefunden) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); d->setLPosition(pos, 0); return -1; } __int64 ret = d->getLPosition() - 1; d->setLPosition(pos, 0); return ret; } bool KSGSLeser::leseBisText() { __int64 pos = d->getLPosition(); char c = 0; bool kommentar = 0; int kBeg = 0; bool slash = 0; bool gefunden = 0; bool inString = 0; bool inChar = 0; int sBeg = 0; while (!d->istEnde()) { d->lese(&c, 1); if (c == '\n') { zeile++; if (kommentar) handleKommentar(kBeg, (int)d->getLPosition()); kommentar = 0; continue; } if (c == '"' && !inChar && !kommentar) { if (inString) handleString(sBeg, (int)d->getLPosition()); inString = !inString; sBeg = (int)d->getLPosition() - 1; } if (c == '\'' && !inString && !kommentar) { if (inChar) handleString(sBeg, (int)d->getLPosition()); inChar = !inChar; sBeg = (int)d->getLPosition() - 1; } if (c == '#') { kBeg = (int)d->getLPosition() - 1; kommentar = 1; continue; } if (c == '/') { if (slash) { kBeg = (int)d->getLPosition() - 2; kommentar = 1; slash = 0; } else slash = 1; continue; } else slash = 0; if (!istLehr(c) && !kommentar) { gefunden = 1; break; } } if (d->istEnde() && !gefunden) { d->setLPosition(pos, 0); return 0; } d->setLPosition(d->getLPosition() - 1, 0); return 1; } int KSGSLeser::leseNext() { if (!leseBisText()) return -1; __int64 pos = d->getLPosition(); int ret = 0; Text txt = ""; char byte[] = { 0, 0 }; d->lese(byte, 1); while (!istTrenner(byte[0]) && !d->istEnde()) { txt.append(byte); d->lese(byte, 1); } if (d->istEnde() || !txt.getLength()) { d->setLPosition(pos, 0); return -1; } if (txt.istGleich("class")) ret = 1; if (txt.istGleich("func")) ret = 2; if (txt.istGleich("var")) ret = 3; if (txt.istGleich("public")) ret = 4; if (txt.istGleich("private")) ret = 5; if (txt.istGleich("if")) ret = 6; if (txt.istGleich("for")) ret = 7; if (txt.istGleich("while")) ret = 8; if (txt.istGleich("return")) ret = 9; if (txt.istGleich("break")) ret = 10; if (txt.istGleich("continue")) ret = 11; if (txt.istGleich("lesen")) ret = 12; d->setLPosition(pos, 0); return ret; } bool KSGSLeser::istTrenner(char c) { return !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == 'ä' || c == 'ö' || c == 'ü' || c == 'Ä' || c == 'Ö' || c == 'Ü' || c == 'ß'); } bool KSGSLeser::istLehr(char c) { return c == ' ' || c == '\n' || c == '\r' || c == '\t'; } KSGSLeseKlasse* KSGSLeser::leseKlasse() { KSGSLeseKlasse* ret = new KSGSLeseKlasse(); ret->debug.datei.setText(fileName); ret->debug.zeile = zeile; d->setLPosition(d->getLPosition() + 5, 0); // 'class' überspringen if (!leseBisText()) // Bis zum beginn des Klassennamens lesen { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); ret->release(); return 0; } char byte[] = { 0, 0 }; // Klassenname lesen d->lese(byte, 1); while (!istTrenner(*byte)) { ret->name.append(byte); d->lese(byte, 1); } if (!leseBis('{')) // Bis zum beginn der Klasse lesen { ret->release(); return 0; } d->setLPosition(d->getLPosition() + 1, 0); bool sichtbar = 0; __int64 ende = nextPosOf('}', '{'); // Ende der Klasse if (ende < 0) { ret->release(); return 0; } while (d->getLPosition() < ende) // Inhalt der Klasse lesen { int id = leseNext(); if (id == -1) break; switch (id) { case 2: // Funktion if (1) { KSGSLeseFunktion* f = leseFunktion(); if (!f) { ret->release(); return 0; } ret->funktionen.add(f); ret->fSichtbar.add(sichtbar); } break; case 3: // Variable if (1) { KSGSLeseVariable* v = leseVariable(); if (!v) { ret->release(); return 0; } ret->variablen.add(v); ret->vSichtbar.add(sichtbar); } break; case 4: // public sichtbar = 1; d->setLPosition(d->getLPosition() + 6, 0); if (!leseBis(':')) { ret->release(); return 0; } d->setLPosition(d->getLPosition() + 1, 0); break; case 5: // private sichtbar = 0; d->setLPosition(d->getLPosition() + 7, 0); if (!leseBis(':')) { ret->release(); return 0; } d->setLPosition(d->getLPosition() + 1, 0); break; default: ret->release(); return 0; } } if (d->getLPosition() > ende) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); ret->release(); return 0; } d->setLPosition(ende + 1, 0); if (!leseBis(';')) // ';' Nach einer Klasse überlesen { ret->release(); return 0; } d->setLPosition(d->getLPosition() + 1, 0); return ret; } KSGSLeseFunktion* KSGSLeser::leseFunktion() { KSGSLeseFunktion* ret = new KSGSLeseFunktion(); ret->debug.datei.setText(fileName); ret->debug.zeile = zeile; d->setLPosition(d->getLPosition() + 4, 0); // 'func' überspringen if (!leseBisText()) { ret->release(); return 0; } char byte[] = { 0, 0 }; // Rückgabetyp der Funktion lesen d->lese(byte, 1); while (!istTrenner(*byte)) { ret->typ.append(byte); d->lese(byte, 1); } d->setLPosition(d->getLPosition() - 1, 0); if (!leseBisText()) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); ret->release(); return 0; } d->lese(byte, 1); // Name der Funktion lesen while (!istTrenner(*byte)) { ret->name.append(byte); d->lese(byte, 1); } d->setLPosition(d->getLPosition() - 1, 0); if (!leseBis('(')) // Parameterbeginn { ret->release(); return 0; } d->setLPosition(d->getLPosition() + 1, 0); __int64 paramEnde = nextPosOf(')', '('); if (paramEnde < 0) { ret->release(); return 0; } while (d->getLPosition() < paramEnde) { KSGSLeseVariable* param = leseVariable(1); // Übergabeparameter einlesen if (!param) break; ret->parameter.add(param); } d->setLPosition(paramEnde + 1, 0); if (!leseBis('{')) // Funktionsrumpf beginn { ret->release(); return 0; } d->setLPosition(d->getLPosition() + 1, 0); __int64 funkEnde = nextPosOf('}', '{'); // Ende der Funktion if (funkEnde < 0) { ret->release(); return 0; } while (d->getLPosition() < funkEnde) { KSGSLeseBefehl* bef = leseBefehl(); // Befehle einlesen if (!bef) break; else ret->befehle.add(bef); if (!leseBisText()) { ret->release(); return 0; } } d->setLPosition(funkEnde + 1, 0); // '}' am ende der Funktion überlesen return ret; } KSGSLeseVariable* KSGSLeser::leseVariable(bool param) { KSGSLeseVariable* ret = new KSGSLeseVariable(); ret->debug.datei.setText(fileName); ret->debug.zeile = zeile; if (!param) d->setLPosition(d->getLPosition() + 3, 0); // 'var' überspringen __int64 endPos = 0; if (param) { endPos = nextPosOf(')', 0); if (endPos < 0) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); delete ret; return 0; } } if (!leseBisText()) { delete ret; return 0; } if (param && d->getLPosition() >= endPos) { delete ret; return 0; } char byte[] = { 0, 0 }; // Variablentyp lesen d->lese(byte, 1); while (!istTrenner(*byte)) { ret->typ.append(byte); d->lese(byte, 1); } d->setLPosition(d->getLPosition() - 1, 0); if (!leseBisText()) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); delete ret; return 0; } d->lese(byte, 1); // Variablenname lesen while (!istTrenner(*byte)) { ret->name.append(byte); d->lese(byte, 1); } d->setLPosition(d->getLPosition() - 1, 0); __int64 ende = nextPosOf(';', 0); if (ende < 0) { delete ret; return 0; } if (param) { errorIgnore = 1; __int64 tmp = nextPosOf(',', 0); errorIgnore = 0; if (tmp >= 0 && tmp < endPos) ende = tmp; else ende = endPos; } errorIgnore = 1; __int64 gleich = nextPosOf('=', 0); errorIgnore = 0; if (gleich < ende && gleich >= 0) // prüfen ob die variable gesetzt wird { if (!leseBis('=')) { delete ret; return 0; } d->setLPosition(d->getLPosition() + 1, 0); } if (leseBisText()) { if (d->getLPosition() < ende) { while (d->getLPosition() < ende) // Wert der Variable lesen { d->lese(byte, 1); ret->wert.append(byte); } } } while (istLehr(ret->wert.getText()[ret->wert.getLength() - 1]) && ret->wert.getLength() > 0) { if (ret->wert.getText()[ret->wert.getLength() - 1] == '\n') zeile++; if (!(ret->wert.getLength() - 1)) { ret->wert.setText(""); break; } ret->wert.setText(ret->wert.getText(), ret->wert.getLength() - 1); } if (d->getLPosition() > ende) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); delete ret; return 0; } d->setLPosition(ende + 1, 0); // ';' oder bei param ')' oder ',' am Ende überlesen return ret; } KSGSLeseBefehl* KSGSLeser::leseBefehl() { __int64 fEnde = nextPosOf('}', '{'); if (fEnde < 0) return 0; int typ = leseNext(); if (typ < 0) return 0; KSGSLeseBefehl* ret = new KSGSLeseBefehl(); ret->debug.datei.setText(fileName); ret->debug.zeile = zeile; ret->typ = typ; switch (typ) { case 0: case 3: // var if (1) { __int64 endPos = nextPosOf(';', 0); if (endPos < 0) { delete ret; return 0; } int len = (int)(endPos - d->getLPosition()); if (len) { char* txt = new char[len + 1]; txt[len] = 0; d->lese(txt, len); ret->befehl = txt; delete[] txt; } d->setLPosition(endPos + 1, 0); } break; case 6: // if if (1) { if (!leseBis('(')) { delete ret; return 0; } d->setLPosition(d->getLPosition() + 1, 0); __int64 endPos = nextPosOf(')', '('); if (endPos < 0) { delete ret; return 0; } int len = (int)(endPos - d->getLPosition()); if (len) { char* txt = new char[len + 1]; txt[len] = 0; d->lese(txt, len); ret->befehl = txt; delete[] txt; } d->setLPosition(endPos + 1, 0); if (!leseBis('{')) { delete ret; return 0; } d->setLPosition(d->getLPosition() + 1, 0); endPos = nextPosOf('}', '{'); if (endPos < 0) { delete ret; return 0; } while (d->getLPosition() < endPos) { KSGSLeseBefehl* tmp = leseBefehl(); if (!tmp) break; else ret->listA.add(tmp); } d->setLPosition(endPos + 1, 0); int tmpZ = zeile; if (!leseBisText()) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); delete ret; return 0; } char* el = new char[5]; if (d->getLPosition() + 4 <= fEnde) d->lese(el, 4); else el[0] = 0; el[4] = 0; if (Text("else").istGleich(el)) { if (!leseBis('{')) { delete ret; return 0; } d->setLPosition(d->getLPosition() + 1, 0); endPos = nextPosOf('}', '{'); if (endPos < 0) { delete ret; return 0; } while (d->getLPosition() < endPos) { KSGSLeseBefehl* tmp = leseBefehl(); if (!tmp) break; else ret->listB.add(tmp); } d->setLPosition(endPos + 1, 0); } else { d->setLPosition(endPos + 1, 0); zeile = tmpZ; } delete[] el; } break; case 7: // for case 8: // while if (1) { if (!leseBis('(')) { delete ret; return 0; } d->setLPosition(d->getLPosition() + 1, 0); __int64 endPos = nextPosOf(')', '('); if (endPos < 0) { delete ret; return 0; } int len = (int)(endPos - d->getLPosition()); if (len) { char* txt = new char[len + 1]; txt[len] = 0; d->lese(txt, len); ret->befehl = txt; delete[] txt; } d->setLPosition(endPos + 1, 0); if (!leseBis('{')) { delete ret; return 0; } d->setLPosition(d->getLPosition() + 1, 0); endPos = nextPosOf('}', '{'); if (endPos < 0) { delete ret; return 0; } while (d->getLPosition() < endPos) { KSGSLeseBefehl* tmp = leseBefehl(); if (!tmp) break; else ret->listA.add(tmp); } d->setLPosition(endPos + 1, 0); } break; case 9: // return if (1) { __int64 endPos = nextPosOf(';', 0); if (endPos < 0) { delete ret; return 0; } int len = (int)(endPos - d->getLPosition()); if (len) { char* txt = new char[len + 1]; txt[len] = 0; d->lese(txt, len); ret->befehl = txt; delete[] txt; } d->setLPosition(endPos + 1, 0); } break; case 10: // break case 11: // continue if (1) { __int64 endPos = nextPosOf(';', 0); if (endPos < 0) { delete ret; return 0; } d->setLPosition(endPos + 1, 0); } break; default: handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); delete ret; return 0; } if (d->getLPosition() > fEnde) { handleError((int)d->getLPosition() - 1, (int)d->getLPosition()); delete ret; return 0; } ret->befehl.ersetzen("->", "."); return ret; } // Script Compilieren bool KSGSLeser::compileKlasse(KSGSLeseKlasse* zLK, KSGSCompKlassTable* zKT) { if (!zKT->hat(zLK->name)) { error(10, {}, zObj); return 0; } KSGSCompileKlasse* k = zKT->get(zLK->name); int lFAnz = zLK->funktionen.getEintragAnzahl(); for (int i = 0; i < lFAnz; i++) { if (!compileFunktion(zLK->funktionen.get(i), zKT, &k->funcs, 1 + !zLK->fSichtbar.get(i))) return 0; } k->vars.addVariable("this", new KSGSCompileVariable(k->id, 2)); int lVAnz = zLK->variablen.getEintragAnzahl(); for (int i = 0; i < lVAnz; i++) { auto tmp = zKT->get(zLK->variablen.get(i)->typ); if (!tmp) { error(11, { zLK->debug.datei, Text() += zLK->debug.zeile, zLK->variablen.get(i)->typ, zLK->variablen.get(i)->name }, zObj); return 0; } if (!k->vars.addVariable(zLK->variablen.get(i)->name, new KSGSCompileVariable(tmp->id, 1 + !zLK->vSichtbar.get(i)))) { error(9, { zLK->variablen.get(i)->debug.datei, Text() += zLK->variablen.get(i)->debug.zeile, zLK->variablen.get(i)->name }, zObj); return 0; } } return 1; } bool KSGSLeser::compileFunktion(KSGSLeseFunktion* zLF, KSGSCompKlassTable* zKT, KSGSCompFuncTable* zFT, int s) { KSGSCompileFunktion* f = new KSGSCompileFunktion(zKT->get(zLF->typ)->id, s, {}); int anz = zLF->parameter.getEintragAnzahl(); for (int j = 0; j < anz; j++) { auto tmp = zKT->get(zLF->parameter.get(j)->typ); if (tmp) f->parameterTyp.add(tmp->id); else { error(11, { zLF->debug.datei, Text() += zLF->debug.zeile, zLF->parameter.get(j)->typ, zLF->parameter.get(j)->name }, zObj); return 0; } } if (!zFT->addFunktion(zLF->name, f)) { error(8, { zLF->debug.datei, Text() += zLF->debug.zeile, zLF->name }, zObj); return 0; } return 1; } KSGSVariableDef* KSGSLeser::compileVariable(KSGSLeseVariable* zLV, KSGSCompKlassTable* zKT, int id) { if (!zKT->hat(zLV->typ)) { error(11, { zLV->debug.datei, Text() += zLV->debug.zeile, zLV->typ, zLV->name }, zObj); return 0; } KSGSVariableDef* ret = new KSGSVariableDef(); ret->id = id; ret->sichtbar = 0; ret->typId = zKT->get(zLV->typ)->id; ret->wert.setText(zLV->wert); return ret; } KSGSKlasse* KSGSLeser::buildKlasse(KSGSLeseKlasse* zLK, KSGSCompKlassTable* zKT, KSGSCompFuncTable* zFT, KSGSCompVarTable* zVT) { if (!zKT->hat(zLK->name)) { error(10, {}, zObj); return 0; } KSGSKlasse* ret = new KSGSKlasse(zKT->get(zLK->name)->id); int anz = zLK->funktionen.getEintragAnzahl(); for (int i = 0; i < anz; i++) { KSGSFunktion* f = buildFunktion(zLK->funktionen.get(i), zKT, zFT, zVT, zLK->name); if (!f) { ret->release(); return 0; } ret->addFunktion(f); } anz = zLK->variablen.getEintragAnzahl(); for (int i = 0; i < anz; i++) { KSGSVariableDef* v = compileVariable(zLK->variablen.get(i), zKT, i); if (!v) { ret->release(); return 0; } v->sichtbar = 1 + !zLK->vSichtbar.get(i); ret->addVariable(v); } return ret; } KSGSFunktion* KSGSLeser::buildFunktion(KSGSLeseFunktion* zLF, KSGSCompKlassTable* zKT, KSGSCompFuncTable* zFT, KSGSCompVarTable* zVT, const char* klassName) { KSGSCompFuncTable* ft = zFT; if (klassName) ft = &zKT->get(klassName)->funcs; if (!ft->hat(zLF->name)) { error(10, {}, zObj); return 0; } KSGSFunktion* ret = new KSGSFunktion(ft->get(zLF->name)->id, ft->get(zLF->name)->sichtbar, zKT->get(zLF->typ)->id); ret->setName(zLF->name); int anz = zLF->parameter.getEintragAnzahl(); for (int i = 0; i < anz; i++) { KSGSVariableDef* v = compileVariable(zLF->parameter.get(i), zKT, i); if (!v) { ret->release(); return 0; } v->sichtbar = 3; ret->addParameter(v); auto tmp = zKT->get(zLF->parameter.get(i)->typ); if (!tmp) { error(11, { zLF->debug.datei, Text() += zLF->debug.zeile, zLF->parameter.get(i)->typ, zLF->parameter.get(i)->name }, zObj); return 0; } ft->get(zLF->name)->vars.addVariable(zLF->parameter.get(i)->name, new KSGSCompileVariable(tmp->id, 3)); } anz = zLF->befehle.getEintragAnzahl(); for (int i = 0; i < anz; i++) { KSGSBefehl* b = buildBefehl(zLF->befehle.get(i), zKT, zFT, zVT, klassName, zLF->name); if (!b) { ret->release(); return 0; } ret->addBefehl(b); } return ret; } KSGSBefehl* KSGSLeser::buildBefehl(KSGSLeseBefehl* zLB, KSGSCompKlassTable* zKT, KSGSCompFuncTable* zFT, KSGSCompVarTable* zVT, const char* klassName, const char* funktionName) { KSGSBefehl* ret = 0; zLB->befehl.setSuchGrenzen('(', ')'); removeKlammer(&zLB->befehl); switch (zLB->typ) { case 0: // call oder operator if (1) { if (hatOperator(&zLB->befehl) >= 0) ret = new KSGSOperatorBefehl(zObj, zLB, zKT, zFT, zVT, klassName, funktionName); else ret = new KSGSCallBefehl(zObj, zLB, zKT, zFT, zVT, klassName, funktionName); } break; case 3: // var ret = new KSGSVariableBefehl(zObj, zLB, zKT, zFT, zVT, klassName, funktionName); break; case 6: // if ret = new KSGSIfBefehl(zObj, zLB, zKT, zFT, zVT, klassName, funktionName); break; case 7: // for ret = new KSGSForBefehl(zObj, zLB, zKT, zFT, zVT, klassName, funktionName); break; case 8: // while ret = new KSGSWhileBefehl(zObj, zLB, zKT, zFT, zVT, klassName, funktionName); break; case 9: // return ret = new KSGSReturnBefehl(zObj, zLB, zKT, zFT, zVT, klassName, funktionName); break; case 10: // break ret = new KSGSBreakBefehl(zLB, zKT, zFT, zVT, klassName, funktionName); break; case 11: // continue ret = new KSGSContinueBefehl(zLB, zKT, zFT, zVT, klassName, funktionName); break; } if (!ret) error(13, { zLB->debug.datei, Text() += zLB->debug.zeile, zLB->befehl }, zObj); if (ret && ret->hatFehler()) ret = (KSGSBefehl*)ret->release(); return ret; } // nicht constant bool KSGSLeser::laden() { delete dat; dat = new KSGSLeseScript(); bool ok = ladeDatei(); return ok; } bool KSGSLeser::compile(RCArray< KSGSKlasse >* klassen, RCArray< KSGSFunktion >* funktionen, Array< KSGSVariableDef* >* variablen) { // Klassen Tabelle KSGSCompKlassTable* klassT = new KSGSCompKlassTable(); int kAnz = dat->klassen.getEintragAnzahl(); for (int i = 0; i < kAnz; i++) { if (!klassT->addKlasse(dat->klassen.get(i)->name, new KSGSCompileKlasse())) { error(7, { dat->klassen.get(i)->debug.datei, Text() += dat->klassen.get(i)->debug.zeile, dat->klassen.get(i)->name }, zObj); klassT->release(); return 0; } } // Funktions Tabelle KSGSCompFuncTable* funcT = new KSGSCompFuncTable(); funcT->addFunktion("Rückruf", new KSGSCompileFunktion(KSGS_VOID, 0, {})); int fAnz = dat->funktionen.getEintragAnzahl(); for (int i = 0; i < fAnz; i++) { if (!compileFunktion(dat->funktionen.get(i), klassT, funcT)) { error(8, { dat->funktionen.get(i)->debug.datei, Text() += dat->funktionen.get(i)->debug.zeile, dat->funktionen.get(i)->name }, zObj); klassT->release(); funcT->release(); return 0; } if (dat->funktionen.get(i)->name.istGleich("start")) mainFuncId = funcT->get("start")->id; if (dat->funktionen.get(i)->name.istGleich("maus")) mausFuncId = funcT->get("maus")->id; if (dat->funktionen.get(i)->name.istGleich("tastatur")) tastaturFuncId = funcT->get("tastatur")->id; if (dat->funktionen.get(i)->name.istGleich("tick")) tickFuncId = funcT->get("tick")->id; if (dat->funktionen.get(i)->name.istGleich("render")) renderFuncId = funcT->get("render")->id; } // Variablen Tabelle KSGSCompVarTable* varT = new KSGSCompVarTable(); int vAnz = dat->variablen.getEintragAnzahl(); for (int i = 0; i < vAnz; i++) { auto tmp = klassT->get(dat->variablen.get(i)->typ); if (!tmp) { error(11, { dat->variablen.get(i)->debug.datei, Text() += dat->variablen.get(i)->debug.zeile, dat->variablen.get(i)->typ, dat->variablen.get(i)->name }, zObj); return 0; } if (!varT->addVariable(dat->variablen.get(i)->name, new KSGSCompileVariable(klassT->get(dat->variablen.get(i)->typ)->id, 0))) { error(9, { dat->variablen.get(i)->debug.datei, Text() += dat->variablen.get(i)->debug.zeile, dat->variablen.get(i)->name }, zObj); klassT->release(); funcT->release(); varT->release(); return 0; } } for (int i = 0; i < kAnz; i++) { if (!compileKlasse(dat->klassen.get(i), klassT)) { klassT->release(); funcT->release(); varT->release(); return 0; } } for (int i = 0; i < vAnz; i++) { KSGSVariableDef* k = compileVariable(dat->variablen.get(i), klassT, i); if (!k) { int anz = variablen->getEintragAnzahl(); for (int i = 0; i < anz; i++) delete variablen->get(i); variablen->leeren(); klassT->release(); funcT->release(); varT->release(); return 0; } variablen->add(k); } for (int i = 0; i < kAnz; i++) { KSGSKlasse* k = buildKlasse(dat->klassen.get(i), klassT, funcT, varT); if (!k) { klassen->leeren(); variablen->leeren(); klassT->release(); funcT->release(); varT->release(); return 0; } klassen->add(k); } funktionen->add(new KSGSCallbackFunktion()); for (int i = 0; i < fAnz; i++) { KSGSFunktion* f = buildFunktion(dat->funktionen.get(i), klassT, funcT, varT); if (!f) { klassen->leeren(); funktionen->leeren(); variablen->leeren(); klassT->release(); funcT->release(); varT->release(); return 0; } funktionen->add(f); } klassT->release(); funcT->release(); varT->release(); return 1; } // constant int KSGSLeser::getMainFuncId() const { return mainFuncId; } int KSGSLeser::getMausFuncId() const { return mausFuncId; } int KSGSLeser::getTastaturFuncId() const { return tastaturFuncId; } int KSGSLeser::getTickFuncId() const { return tickFuncId; } int KSGSLeser::getRenderFuncId() const { return renderFuncId; }