Fix operator priorities, fix parsing debugger bug

This commit is contained in:
Lior Halphon 2020-04-09 14:21:07 +03:00
parent 92d6cc6394
commit a9cd3f2c11

View File

@ -334,7 +334,7 @@ static value_t bank(value_t a, value_t b) {return (value_t) {true, a.value, b.va
static struct { static struct {
const char *string; const char *string;
char priority; int8_t priority;
value_t (*operator)(value_t, value_t); value_t (*operator)(value_t, value_t);
value_t (*lvalue_operator)(GB_gameboy_t *, lvalue_t, uint16_t); value_t (*lvalue_operator)(GB_gameboy_t *, lvalue_t, uint16_t);
} operators[] = } operators[] =
@ -352,15 +352,15 @@ static struct {
{"&", 1, and}, {"&", 1, and},
{"^", 1, xor}, {"^", 1, xor},
{"<<", 2, shleft}, {"<<", 2, shleft},
{"<=", -1, lower_equals}, {"<=", 3, lower_equals},
{"<", -1, lower}, {"<", 3, lower},
{">>", 2, shright}, {">>", 2, shright},
{">=", -1, greater_equals}, {">=", 3, greater_equals},
{">", -1, greater}, {">", 3, greater},
{"==", -1, equals}, {"==", 3, equals},
{"=", -2, NULL, assign}, {"=", -1, NULL, assign},
{"!=", -1, different}, {"!=", 3, different},
{":", 3, bank}, {":", 4, bank},
}; };
value_t debugger_evaluate(GB_gameboy_t *gb, const char *string, value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
@ -388,8 +388,8 @@ static lvalue_t debugger_evaluate_lvalue(GB_gameboy_t *gb, const char *string,
} }
if (string[0] == '(' && string[length - 1] == ')') { if (string[0] == '(' && string[length - 1] == ')') {
// Attempt to strip parentheses // Attempt to strip parentheses
signed int depth = 0; signed depth = 0;
for (int i = 0; i < length; i++) { for (unsigned i = 0; i < length; i++) {
if (string[i] == '(') depth++; if (string[i] == '(') depth++;
if (depth == 0) { if (depth == 0) {
// First and last are not matching // First and last are not matching
@ -402,8 +402,8 @@ static lvalue_t debugger_evaluate_lvalue(GB_gameboy_t *gb, const char *string,
} }
else if (string[0] == '[' && string[length - 1] == ']') { else if (string[0] == '[' && string[length - 1] == ']') {
// Attempt to strip square parentheses (memory dereference) // Attempt to strip square parentheses (memory dereference)
signed int depth = 0; signed depth = 0;
for (int i = 0; i < length; i++) { for (unsigned i = 0; i < length; i++) {
if (string[i] == '[') depth++; if (string[i] == '[') depth++;
if (depth == 0) { if (depth == 0) {
// First and last are not matching // First and last are not matching
@ -418,8 +418,8 @@ static lvalue_t debugger_evaluate_lvalue(GB_gameboy_t *gb, const char *string,
} }
else if (string[0] == '{' && string[length - 1] == '}') { else if (string[0] == '{' && string[length - 1] == '}') {
// Attempt to strip curly parentheses (memory dereference) // Attempt to strip curly parentheses (memory dereference)
signed int depth = 0; signed depth = 0;
for (int i = 0; i < length; i++) { for (unsigned i = 0; i < length; i++) {
if (string[i] == '{') depth++; if (string[i] == '{') depth++;
if (depth == 0) { if (depth == 0) {
// First and last are not matching // First and last are not matching
@ -495,8 +495,8 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
} }
if (string[0] == '(' && string[length - 1] == ')') { if (string[0] == '(' && string[length - 1] == ')') {
// Attempt to strip parentheses // Attempt to strip parentheses
signed int depth = 0; signed depth = 0;
for (int i = 0; i < length; i++) { for (unsigned i = 0; i < length; i++) {
if (string[i] == '(') depth++; if (string[i] == '(') depth++;
if (depth == 0) { if (depth == 0) {
// First and last are not matching // First and last are not matching
@ -512,8 +512,8 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
} }
else if (string[0] == '[' && string[length - 1] == ']') { else if (string[0] == '[' && string[length - 1] == ']') {
// Attempt to strip square parentheses (memory dereference) // Attempt to strip square parentheses (memory dereference)
signed int depth = 0; signed depth = 0;
for (int i = 0; i < length; i++) { for (unsigned i = 0; i < length; i++) {
if (string[i] == '[') depth++; if (string[i] == '[') depth++;
if (depth == 0) { if (depth == 0) {
// First and last are not matching // First and last are not matching
@ -539,8 +539,8 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
} }
else if (string[0] == '{' && string[length - 1] == '}') { else if (string[0] == '{' && string[length - 1] == '}') {
// Attempt to strip curly parentheses (memory dereference) // Attempt to strip curly parentheses (memory dereference)
signed int depth = 0; signed depth = 0;
for (int i = 0; i < length; i++) { for (unsigned i = 0; i < length; i++) {
if (string[i] == '{') depth++; if (string[i] == '{') depth++;
if (depth == 0) { if (depth == 0) {
// First and last are not matching // First and last are not matching
@ -565,7 +565,7 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
} }
} }
// Search for lowest priority operator // Search for lowest priority operator
signed int depth = 0; signed depth = 0;
unsigned operator_index = -1; unsigned operator_index = -1;
unsigned operator_pos = 0; unsigned operator_pos = 0;
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
@ -574,15 +574,15 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
else if (string[i] == '[') depth++; else if (string[i] == '[') depth++;
else if (string[i] == ']') depth--; else if (string[i] == ']') depth--;
else if (depth == 0) { else if (depth == 0) {
for (int j = 0; j < sizeof(operators) / sizeof(operators[0]); j++) { for (unsigned j = 0; j < sizeof(operators) / sizeof(operators[0]); j++) {
if (strlen(operators[j].string) > length - i) continue; // Operator too big. unsigned operator_length = strlen(operators[j].string);
// Priority higher than what we already have. if (operator_length > length - i) continue; // Operator too long
unsigned long operator_length = strlen(operators[j].string);
if (memcmp(string + i, operators[j].string, operator_length) == 0) { if (memcmp(string + i, operators[j].string, operator_length) == 0) {
if (operator_index != -1 && operators[operator_index].priority < operators[j].priority) { if (operator_index != -1 && operators[operator_index].priority < operators[j].priority) {
/* for supporting = vs ==, etc*/ /* for supporting = vs ==, etc*/
i += operator_length - 1; i += operator_length - 1;
continue; break;
} }
// Found an operator! // Found an operator!
operator_pos = i; operator_pos = i;
@ -669,7 +669,7 @@ value_t debugger_evaluate(GB_gameboy_t *gb, const char *string,
} }
char *end; char *end;
int base = 10; unsigned base = 10;
if (string[0] == '$') { if (string[0] == '$') {
string++; string++;
base = 16; base = 16;