|
@@ -74,87 +74,157 @@ QVector<Token> lex(const QString& code) {
|
|
|
QVector<QVector<Instruction>> parse(const QString& code, const QVector<Token>& tokens, QVector<ParseError>& errors) {
|
|
QVector<QVector<Instruction>> parse(const QString& code, const QVector<Token>& tokens, QVector<ParseError>& errors) {
|
|
|
size_t i = 0;
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
|
|
+ auto skipToEol = [&tokens, &i](){
|
|
|
|
|
+ while(i < tokens.size() && tokens[i].tokenType != TokenTypeEOL) {
|
|
|
|
|
+ ++i;
|
|
|
|
|
+ }
|
|
|
|
|
+ ++i;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
while(i < tokens.size()) {
|
|
while(i < tokens.size()) {
|
|
|
if(tokens[i].tokenType != TokenTypeWord) {
|
|
if(tokens[i].tokenType != TokenTypeWord) {
|
|
|
errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction"));
|
|
errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction"));
|
|
|
//lets fast forward to next line
|
|
//lets fast forward to next line
|
|
|
- while(i < tokens.size() && tokens[i].tokenType != TokenTypeEOL) {
|
|
|
|
|
- ++i;
|
|
|
|
|
- }
|
|
|
|
|
- ++i;
|
|
|
|
|
|
|
+ skipToEol();
|
|
|
continue;
|
|
continue;
|
|
|
}
|
|
}
|
|
|
else {
|
|
else {
|
|
|
- QString word = code.mid(tokens[i].begin, tokens[i].end - tokens[i].begin).toUpper();
|
|
|
|
|
|
|
+ auto getTokenText = [&](size_t k){
|
|
|
|
|
+ return code.mid(tokens[k].begin, tokens[k].end - tokens[k].begin).toUpper();
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ QString word = getTokenText(i);
|
|
|
|
|
|
|
|
if(word.compare("CREATE", Qt::CaseInsensitive)) {
|
|
if(word.compare("CREATE", Qt::CaseInsensitive)) {
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "MOVE", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("MOVE", Qt::CaseInsensitive)) {
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "DIE", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("DIE", Qt::CaseInsensitive)) {
|
|
|
|
|
+ if(i + 1 >= tokens.size() || tokens[i + 1].tokenType != TokenTypeEOL) {
|
|
|
|
|
+ errors += ParseError(tokens[i - 1].line, tokens[i - 1].column, QObject::tr("error"));
|
|
|
|
|
+ }
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "TRANS", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("TRANS", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "RTRANS", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("RTRANS", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "TURN", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("TURN", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "JUMP", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("JUMP", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "AJUMP", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("AJUMP", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "BJUMP", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("BJUMP", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "TURN", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("TURN", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "SCAN", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("SCAN", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "FARSCAN", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("FARSCAN", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "SET", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("SET", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "ADD", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("ADD", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "SUB", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("SUB", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "MUL", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("MUL", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "DIV", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("DIV", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "MOD", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("MOD", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "MIN", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("MIN", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "MAX", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("MAX", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "RANDOM", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("RANDOM", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "IF", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("IF", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "IFN", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("IFN", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "IFG", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("IFG", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "IFL", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("IFL", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "IFGE", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("IFGE", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "IFLE", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("IFLE", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "INIT", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("INIT", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "BREAK", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("BREAK", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "RESUME", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("RESUME", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "SLEEP", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("SLEEP", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- else if(word.compare( "QUIT", Qt::CaseInsensitive)) {
|
|
|
|
|
|
|
+ else if(word.compare("QUIT", Qt::CaseInsensitive)) {
|
|
|
|
|
+
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
else {
|
|
else {
|
|
|
errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction"));
|
|
errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction"));
|
|
|
|
|
+ skipToEol();
|
|
|
}
|
|
}
|
|
|
- ++i;
|
|
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|