Operations on numbers in CLI debugger

This commit is contained in:
Jeffrey Pfau 2014-07-12 04:04:15 -07:00
parent 5b7a551ed8
commit 903f384e05
1 changed files with 123 additions and 19 deletions

View File

@ -287,6 +287,39 @@ enum _DVParseState {
PARSE_EXPECT_SUFFIX, PARSE_EXPECT_SUFFIX,
}; };
enum Operation {
ASSIGN,
ADD,
SUBTRACT,
MULTIPLY,
DIVIDE
};
static uint32_t _performOperation(enum Operation operation, uint32_t current, uint32_t next) {
switch (operation) {
case ASSIGN:
current = next;
break;
case ADD:
current += next;
break;
case SUBTRACT:
current -= next;
break;
case MULTIPLY:
current *= next;
break;
case DIVIDE:
if (next != 0) {
current /= next;
} else {
return 0;
}
break;
}
return current;
}
static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* string, size_t length) { static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* string, size_t length) {
if (!string || length < 1) { if (!string || length < 1) {
return 0; return 0;
@ -295,6 +328,9 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
enum _DVParseState state = PARSE_ROOT; enum _DVParseState state = PARSE_ROOT;
struct DebugVector dvTemp = { .type = INT_TYPE }; struct DebugVector dvTemp = { .type = INT_TYPE };
uint32_t current = 0; uint32_t current = 0;
uint32_t next = 0;
enum Operation operation = ASSIGN;
while (length > 0 && string[0] && string[0] != ' ' && state != PARSE_ERROR) { while (length > 0 && string[0] && string[0] != ' ' && state != PARSE_ERROR) {
char token = string[0]; char token = string[0];
@ -325,14 +361,14 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case '8': case '8':
case '9': case '9':
state = PARSE_EXPECT_DECIMAL; state = PARSE_EXPECT_DECIMAL;
current = token - '0'; next = token - '0';
break; break;
case '0': case '0':
state = PARSE_EXPECT_PREFIX; state = PARSE_EXPECT_PREFIX;
break; break;
case '$': case '$':
state = PARSE_EXPECT_HEX; state = PARSE_EXPECT_HEX;
current = 0; next = 0;
break; break;
default: default:
state = PARSE_ERROR; state = PARSE_ERROR;
@ -342,7 +378,7 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case PARSE_EXPECT_LR: case PARSE_EXPECT_LR:
switch (token) { switch (token) {
case 'r': case 'r':
current = debugger->d.cpu->gprs[ARM_LR]; next = debugger->d.cpu->gprs[ARM_LR];
state = PARSE_EXPECT_SUFFIX; state = PARSE_EXPECT_SUFFIX;
break; break;
default: default:
@ -353,7 +389,7 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case PARSE_EXPECT_PC: case PARSE_EXPECT_PC:
switch (token) { switch (token) {
case 'c': case 'c':
current = debugger->d.cpu->gprs[ARM_PC]; next = debugger->d.cpu->gprs[ARM_PC];
state = PARSE_EXPECT_SUFFIX; state = PARSE_EXPECT_SUFFIX;
break; break;
default: default:
@ -364,7 +400,7 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case PARSE_EXPECT_SP: case PARSE_EXPECT_SP:
switch (token) { switch (token) {
case 'p': case 'p':
current = debugger->d.cpu->gprs[ARM_SP]; next = debugger->d.cpu->gprs[ARM_SP];
state = PARSE_EXPECT_SUFFIX; state = PARSE_EXPECT_SUFFIX;
break; break;
default: default:
@ -383,7 +419,7 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case '7': case '7':
case '8': case '8':
case '9': case '9':
current = debugger->d.cpu->gprs[token - '0']; next = debugger->d.cpu->gprs[token - '0'];
state = PARSE_EXPECT_SUFFIX; state = PARSE_EXPECT_SUFFIX;
break; break;
case '1': case '1':
@ -402,7 +438,7 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case '3': case '3':
case '4': case '4':
case '5': case '5':
current = debugger->d.cpu->gprs[token - '0' + 10]; next = debugger->d.cpu->gprs[token - '0' + 10];
state = PARSE_EXPECT_SUFFIX; state = PARSE_EXPECT_SUFFIX;
break; break;
default: default:
@ -423,8 +459,32 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case '8': case '8':
case '9': case '9':
// TODO: handle overflow // TODO: handle overflow
current *= 10; next *= 10;
current += token - '0'; next += token - '0';
break;
case '+':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = ADD;
break;
case '-':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = SUBTRACT;
break;
case '*':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = MULTIPLY;
break;
case '/':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = DIVIDE;
break; break;
default: default:
state = PARSE_ERROR; state = PARSE_ERROR;
@ -443,8 +503,8 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case '8': case '8':
case '9': case '9':
// TODO: handle overflow // TODO: handle overflow
current *= 16; next *= 16;
current += token - '0'; next += token - '0';
break; break;
case 'A': case 'A':
case 'B': case 'B':
@ -453,8 +513,8 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case 'E': case 'E':
case 'F': case 'F':
// TODO: handle overflow // TODO: handle overflow
current *= 16; next *= 16;
current += token - 'A' + 10; next += token - 'A' + 10;
break; break;
case 'a': case 'a':
case 'b': case 'b':
@ -463,8 +523,32 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
case 'e': case 'e':
case 'f': case 'f':
// TODO: handle overflow // TODO: handle overflow
current *= 16; next *= 16;
current += token - 'a' + 10; next += token - 'a' + 10;
break;
case '+':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = ADD;
break;
case '-':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = SUBTRACT;
break;
case '*':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = MULTIPLY;
break;
case '/':
current = _performOperation(operation, current, next);
next = 0;
state = PARSE_ROOT;
operation = DIVIDE;
break; break;
default: default:
state = PARSE_ERROR; state = PARSE_ERROR;
@ -475,7 +559,7 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
switch (token) { switch (token) {
case 'X': case 'X':
case 'x': case 'x':
current = 0; next = 0;
state = PARSE_EXPECT_HEX; state = PARSE_EXPECT_HEX;
break; break;
default: default:
@ -484,8 +568,26 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
} }
break; break;
case PARSE_EXPECT_SUFFIX: case PARSE_EXPECT_SUFFIX:
// TODO current = _performOperation(operation, current, next);
state = PARSE_ERROR; next = 0;
state = PARSE_ROOT;
switch (token) {
case '+':
operation = ADD;
break;
case '-':
operation = SUBTRACT;
break;
case '*':
operation = MULTIPLY;
break;
case '/':
operation = DIVIDE;
break;
default:
state = PARSE_ERROR;
break;
}
break; break;
case PARSE_ERROR: case PARSE_ERROR:
// This shouldn't be reached // This shouldn't be reached
@ -493,8 +595,10 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
} }
} }
current = _performOperation(operation, current, next);
struct DebugVector* dv = malloc(sizeof(struct DebugVector)); struct DebugVector* dv = malloc(sizeof(struct DebugVector));
if (state == PARSE_ERROR) { if (state == PARSE_ERROR || state == PARSE_ROOT) {
dv->type = ERROR_TYPE; dv->type = ERROR_TYPE;
dv->next = 0; dv->next = 0;
} else { } else {