|
|
@@ -0,0 +1,160 @@
|
|
|
+#include "parse.h"
|
|
|
+
|
|
|
+#include <QObject>
|
|
|
+
|
|
|
+QVector<Token> lex(const QString& code) {
|
|
|
+ QVector<Token> tokens;
|
|
|
+ size_t i = 0;
|
|
|
+ size_t lineCounter = 0;
|
|
|
+ size_t columnCounter = 0;
|
|
|
+ while(i < code.size()) {
|
|
|
+ if(code[i] == '\n') {
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypeEOL, i, i + 1});
|
|
|
+ ++lineCounter;
|
|
|
+ columnCounter = 0;
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ else if(code[i] == ',') {
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypeComma, i, i + 1});
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ else if(code[i] == '#') {
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypeHash, i, i + 1});
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ else if(code[i] == '%') {
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypePercent, i, i + 1});
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ else if(code[i] == '$') {
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypeDollar, i, i + 1});
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ else if(code[i] == '/' && (i+1) < code.size() && code[i+1] == '/') {
|
|
|
+ size_t s = i + 2;
|
|
|
+ while(s < code.size() && code[s] != '\n') {
|
|
|
+ ++s;
|
|
|
+ }
|
|
|
+ i = s;
|
|
|
+ }
|
|
|
+ else if(code[i].isSpace()) {
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ else if(code[i].isDigit()) {
|
|
|
+ size_t s = i + 1;
|
|
|
+ while(s < code.size() && code[s].isDigit()){
|
|
|
+ ++s;
|
|
|
+ }
|
|
|
+
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypeNumber, i, s});
|
|
|
+ i = s;
|
|
|
+ }
|
|
|
+ else if(code[i].isLetter()) {
|
|
|
+ size_t s = i + 1;
|
|
|
+ while(s < code.size() && code[s].isLetter()){
|
|
|
+ ++s;
|
|
|
+ }
|
|
|
+
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypeWord, i, s});
|
|
|
+ i = s;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ tokens.push_back({lineCounter, columnCounter, TokenTypeError, i, i + 1});
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+
|
|
|
+ ++columnCounter;
|
|
|
+ }
|
|
|
+
|
|
|
+ return tokens;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+QVector<QVector<Instruction>> parse(const QString& code, const QVector<Token>& tokens, QVector<ParseError>& errors) {
|
|
|
+ size_t i = 0;
|
|
|
+
|
|
|
+ while(i < tokens.size()) {
|
|
|
+ if(tokens[i].tokenType != TokenTypeWord) {
|
|
|
+ errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction"));
|
|
|
+ //lets fast forward to next line
|
|
|
+ while(i < tokens.size() && tokens[i].tokenType != TokenTypeEOL) {
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ ++i;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ QString word = code.mid(tokens[i].begin, tokens[i].end - tokens[i].begin).toUpper();
|
|
|
+
|
|
|
+ if(word.compare("CREATE", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "MOVE", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "DIE", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "TRANS", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "RTRANS", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "TURN", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "JUMP", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "AJUMP", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "BJUMP", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "TURN", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "SCAN", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "FARSCAN", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "SET", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "ADD", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "SUB", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "MUL", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "DIV", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "MOD", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "MIN", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "MAX", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "RANDOM", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "IF", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "IFN", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "IFG", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "IFL", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "IFGE", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "IFLE", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "INIT", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "BREAK", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "RESUME", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "SLEEP", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else if(word.compare( "QUIT", Qt::CaseInsensitive)) {
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ errors += ParseError(tokens[i].line, tokens[i].column, QObject::tr("is not a valid Instruction"));
|
|
|
+ }
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|