Parse expressions in a separate function

This commit is contained in:
Jeffrey Pfau 2014-07-12 14:50:09 -07:00
parent f74815988b
commit f71edb1684
1 changed files with 43 additions and 24 deletions

View File

@ -295,46 +295,46 @@ enum Operation {
DIVIDE DIVIDE
}; };
static uint32_t _performOperation(enum Operation operation, uint32_t current, uint32_t next) { static void _performOperation(enum Operation operation, uint32_t next, struct DebugVector* dv) {
switch (operation) { switch (operation) {
case ASSIGN: case ASSIGN:
current = next; dv->intValue = next;
break; break;
case ADD: case ADD:
current += next; dv->intValue += next;
break; break;
case SUBTRACT: case SUBTRACT:
current -= next; dv->intValue -= next;
break; break;
case MULTIPLY: case MULTIPLY:
current *= next; dv->intValue *= next;
break; break;
case DIVIDE: case DIVIDE:
if (next != 0) { if (next != 0) {
current /= next; dv->intValue /= next;
} else { } else {
return 0; dv->type = ERROR_TYPE;
return;
} }
break; break;
} }
return current;
} }
static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* string, size_t length) { static size_t _parseExpression(struct CLIDebugger* debugger, const char* string, size_t length, struct DebugVector* dv) {
if (!string || length < 1) { if (!string || length < 1) {
return 0; return 0;
} }
enum _DVParseState state = PARSE_ROOT;
struct DebugVector dvTemp = { .type = INT_TYPE };
uint32_t current = 0;
uint32_t next = 0; uint32_t next = 0;
size_t adjusted = 0;
enum _DVParseState state = PARSE_ROOT;
enum Operation operation = ASSIGN; 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];
++string; ++string;
++adjusted;
--length; --length;
switch (state) { switch (state) {
case PARSE_ROOT: case PARSE_ROOT:
@ -463,25 +463,25 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
next += token - '0'; next += token - '0';
break; break;
case '+': case '+':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = ADD; operation = ADD;
break; break;
case '-': case '-':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = SUBTRACT; operation = SUBTRACT;
break; break;
case '*': case '*':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = MULTIPLY; operation = MULTIPLY;
break; break;
case '/': case '/':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = DIVIDE; operation = DIVIDE;
@ -527,25 +527,25 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
next += token - 'a' + 10; next += token - 'a' + 10;
break; break;
case '+': case '+':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = ADD; operation = ADD;
break; break;
case '-': case '-':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = SUBTRACT; operation = SUBTRACT;
break; break;
case '*': case '*':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = MULTIPLY; operation = MULTIPLY;
break; break;
case '/': case '/':
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
operation = DIVIDE; operation = DIVIDE;
@ -568,7 +568,7 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
} }
break; break;
case PARSE_EXPECT_SUFFIX: case PARSE_EXPECT_SUFFIX:
current = _performOperation(operation, current, next); _performOperation(operation, next, dv);
next = 0; next = 0;
state = PARSE_ROOT; state = PARSE_ROOT;
switch (token) { switch (token) {
@ -595,14 +595,33 @@ static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* st
} }
} }
current = _performOperation(operation, current, next); if (state == PARSE_ERROR) {
dv->type = ERROR_TYPE;
} else {
_performOperation(operation, next, dv);
}
return adjusted;
}
static struct DebugVector* _DVParse(struct CLIDebugger* debugger, const char* string, size_t length) {
if (!string || length < 1) {
return 0;
}
struct DebugVector dvTemp = { .type = INT_TYPE };
size_t adjusted = _parseExpression(debugger, string, length, &dvTemp);
if (adjusted > length) {
dvTemp.type = ERROR_TYPE;
}
length -= adjusted;
string += adjusted;
struct DebugVector* dv = malloc(sizeof(struct DebugVector)); struct DebugVector* dv = malloc(sizeof(struct DebugVector));
if (state == PARSE_ERROR || state == PARSE_ROOT) { if (dvTemp.type == ERROR_TYPE) {
dv->type = ERROR_TYPE; dv->type = ERROR_TYPE;
dv->next = 0; dv->next = 0;
} else { } else {
dvTemp.intValue = current;
*dv = dvTemp; *dv = dvTemp;
if (string[0] == ' ') { if (string[0] == ' ') {
dv->next = _DVParse(debugger, string + 1, length - 1); dv->next = _DVParse(debugger, string + 1, length - 1);