sm64coopdx/data/dynos_bin_utils.cpp

158 lines
3.3 KiB
C++
Raw Normal View History

2022-04-02 02:19:26 +02:00
#include "dynos.cpp.h"
///////////////////////
// Recursive Descent //
///////////////////////
static char* sRdString = NULL;
static bool sRdError = false;
static s64 ParseExpression();
static void ParseWhitespace() {
while (*sRdString == ' ' || *sRdString == '\t' || *sRdString == '\r' || *sRdString == '\n') {
sRdString++;
}
}
static s64 ParseNumeric() {
String numeric = "";
char* c = sRdString;
// check for hex
if (*c == '0' && *(c+1) == 'x') {
numeric.Add(*c);
c++;
numeric.Add(*c);
c++;
}
// continue adding to string
while (*c >= '0' && *c <= '9') {
numeric.Add(*c);
c++;
}
// advance parsing
sRdString = c;
ParseWhitespace();
// parse
return numeric.ParseInt();
}
static s64 ParseFactor() {
char* c = sRdString;
// check for unary op
if (*c == '-') {
sRdString++;
ParseWhitespace();
s64 f1 = ParseFactor();
return -f1;
} else if (*c == '+') {
sRdString++;
ParseWhitespace();
s64 f1 = ParseFactor();
return +f1;
} else if (*c == '!') {
sRdString++;
ParseWhitespace();
s64 f1 = ParseFactor();
return !f1;
} else if (*c == '~') {
sRdString++;
ParseWhitespace();
s64 f1 = ParseFactor();
return ~f1;
}
// check for numeric
if (*c >= '0' && *c <= '9') {
return ParseNumeric();
// check for sub expression
} else if (*c >= '(') {
sRdString++;
ParseWhitespace();
s64 e1 = ParseExpression();
if (*sRdString == ')') {
sRdString++;
ParseWhitespace();
return e1;
}
}
sRdError = true;
return 0;
}
static s64 ParseTerm() {
s64 f1 = ParseFactor();
if (*sRdString == '*') {
sRdString++;
ParseWhitespace();
s64 f2 = ParseFactor();
return f1 * f2;
} else if (*sRdString == '/') {
sRdString++;
ParseWhitespace();
s64 f2 = ParseFactor();
return f1 / f2;
} else if (*sRdString == '%') {
sRdString++;
ParseWhitespace();
s64 f2 = ParseFactor();
return f1 % f2;
}
return f1;
}
static s64 ParseAddSubExpression() {
s64 t1 = ParseTerm();
if (*sRdString == '+') {
sRdString++;
ParseWhitespace();
s64 t2 = ParseTerm();
return t1 + t2;
} else if (*sRdString == '+') {
sRdString++;
ParseWhitespace();
s64 t2 = ParseTerm();
return t1 - t2;
}
return t1;
}
static s64 ParseExpression() {
s64 e1 = ParseAddSubExpression();
if (*sRdString == '<' && *(sRdString + 1) == '<') {
sRdString += 2;
ParseWhitespace();
s64 e2 = ParseAddSubExpression();
return e1 << e2;
} else if (*sRdString == '>' && *(sRdString + 1) == '>') {
sRdString += 2;
ParseWhitespace();
s64 e2 = ParseAddSubExpression();
return e1 >> e2;
}
return e1;
}
s64 DynOS_RecursiveDescent_Parse(const char* expr, bool* success) {
sRdString = (char*)expr;
sRdError = false;
s64 value = ParseExpression();
sRdString = NULL;
*success = !sRdError;
//Print(">>> PARSING %s == %d :: %u", expr, value, *success);
return value;
}