From d0e4d44e783862137f1de034ad958d24afa56dcd Mon Sep 17 00:00:00 2001 From: Michael Kohn Date: Sat, 19 Oct 2024 09:40:05 -0500 Subject: [PATCH] More cleanup in eval_expression(). --- common/Var.h | 10 +- common/eval_expression.cpp | 109 ++++++++------------ common/eval_expression.h | 47 +++++++-- tests/unit/eval_expression_ex/unit_test.cpp | 32 ++++++ 4 files changed, 121 insertions(+), 77 deletions(-) diff --git a/common/Var.h b/common/Var.h index 9d656e52..4e0fb43e 100644 --- a/common/Var.h +++ b/common/Var.h @@ -28,7 +28,7 @@ class Var { } - Var(Var &v) + Var(const Var &v) { type = v.type; value_int = v.value_int; @@ -38,6 +38,14 @@ class Var { } + Var & operator= (const Var &s) + { + type = s.type; + value_int = s.value_int; + + return *this; + } + template TYPE get_data() { diff --git a/common/eval_expression.cpp b/common/eval_expression.cpp index a93fc01a..f26ceeb8 100644 --- a/common/eval_expression.cpp +++ b/common/eval_expression.cpp @@ -18,33 +18,19 @@ #include "common/Operator.h" #include "common/tokens.h" -#define PRINT_STACK() \ -{ \ - int i; \ - for (i = 0; i < var_stack_ptr; i++) printf("%d) %lx <-\n", i, var_stack[i].value_int); \ -} - int EvalExpression::run( AsmContext *asm_context, Var &var, - Operator &last_operator) + Operator &last_oper) { char token[TOKENLEN]; int token_type; - Var var_stack[3]; - int var_stack_ptr = 1; + VarStack var_stack; Operator oper; int last_token_was_op = -1; -#ifdef DEBUG -printf("Enter eval_expression, var=%d/%f/%d\n", - var.get_int32(), - var.get_float(), - var.get_type()); -#endif - - oper = last_operator; - var_stack[0] = var; + oper = last_oper; + var_stack.push(var); while (true) { @@ -55,7 +41,7 @@ printf("eval_expression> token=%s var_stack_ptr=%d\n", token, var_stack_ptr); #endif // Issue 15: Return an error if a stack is full with no operator. - if (var_stack_ptr == 3 && oper.is_unset()) + if (var_stack.size() == 3 && oper.is_unset()) { return -1; } @@ -75,22 +61,23 @@ printf("eval_expression> token=%s var_stack_ptr=%d\n", token, var_stack_ptr); { if (last_token_was_op == 0 && oper.is_set()) { - last_operator.execute( - var_stack[var_stack_ptr - 2], - var_stack[var_stack_ptr - 1]); + last_oper.execute( + var_stack.get_second(), + var_stack.get_last()); - var_stack_ptr--; + var_stack.pop(); oper.reset(); - var = var_stack[var_stack_ptr - 1]; + var = var_stack.pop(); + tokens_push(asm_context, token, token_type); return 0; } - if (oper.is_unset() && var_stack_ptr == 2) + if (oper.is_unset() && var_stack.size() == 2) { // This is probably the x(r12) case.. so this is actually okay. - var = var_stack[var_stack_ptr - 1]; + var = var_stack.pop(); tokens_push(asm_context, token, token_type); return 0; } @@ -111,12 +98,12 @@ printf("eval_expression> token=%s var_stack_ptr=%d\n", token, var_stack_ptr); printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&paren_var), var_get_type(&paren_var)); #endif - var_stack[var_stack_ptr++] = paren_var; + var_stack.push(paren_var); token_type = tokens_get(asm_context, token, TOKENLEN); - // FIXME: if (IS_NOT_TOKEN(token, ')') - if (!(token[0] == ')' && token[1] == 0)) + //if (!(token[0] == ')' && token[1] == 0)) + if (IS_NOT_TOKEN(token, ')')) { print_error(asm_context, "No matching ')'"); return -1; @@ -143,13 +130,11 @@ printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&pa if (token_type == TOKEN_EOL) { - //asm_context->tokens.line++; tokens_push(asm_context, token, token_type); break; } -//printf("** token=%s %s\n", token, oper.to_string()); - bool do_minus = false; + //bool do_minus = false; #if 0 if (oper.is_set() && IS_TOKEN(token, '-')) @@ -164,29 +149,24 @@ printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&pa { last_token_was_op = 0; - if (var_stack_ptr == 3) + if (var_stack.size() == 3) { print_error_unexp(asm_context, token); return -1; } -//printf("var_stack_ptr=%d\n", var_stack_ptr); - - var_stack[var_stack_ptr].set_int(token); - if (do_minus) { var_stack[var_stack_ptr].negative(); } - - var_stack_ptr++; + var_stack.push_int(token); } else if (token_type == TOKEN_FLOAT) { - if (var_stack_ptr == 3) + if (var_stack.size() == 3) { print_error_unexp(asm_context, token); return -1; } - var_stack[var_stack_ptr++].set_float(token); + var_stack.push_float(token); } else if (token_type == TOKEN_SYMBOL) @@ -212,13 +192,13 @@ printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&pa return -1; } - if (var_stack_ptr == 3) + if (var_stack.size() == 3) { print_error_unexp(asm_context, token); return -1; } - var_stack[var_stack_ptr++].set_int(num); + var_stack.push_int(num); oper = operator_prev; last_token_was_op = 0; @@ -226,8 +206,7 @@ printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&pa continue; } - // Stack pointer probably shouldn't be less than 2. - if (var_stack_ptr == 0) + if (var_stack.is_empty()) { printf("Error: Unexpected operator '%s' at %s:%d\n", token, @@ -236,30 +215,30 @@ printf("Paren got back %d/%f/%d\n", var_get_int32(&paren_var), var_get_float(&pa return -1; } -#ifdef DEBUG -printf("TOKEN %s: precedence %d %d\n", token, last_operator.precedence, oper.precedence); -#endif - - if (last_operator.is_unset()) + if (last_oper.is_unset()) { - last_operator = oper; + last_oper = oper; } else - if (last_operator.precedence > oper.precedence) + if (last_oper.precedence > oper.precedence) { - if (run(asm_context, var_stack[var_stack_ptr - 1], oper) == -1) + Var var = var_stack.pop(); + + if (run(asm_context, var, oper) == -1) { return -1; } + + var_stack.push(var); } else { - last_operator.execute( - var_stack[var_stack_ptr - 2], - var_stack[var_stack_ptr - 1]); + last_oper.execute( + var_stack.get_second(), + var_stack.get_last()); - var_stack_ptr--; - last_operator = oper; + var_stack.pop(); + last_oper = oper; } } else @@ -273,20 +252,20 @@ printf("TOKEN %s: precedence %d %d\n", token, last_operator.precedence, oper.pre } #ifdef DEBUG -printf("going to leave operation=%d\n", last_operator.operation); +printf("going to leave operation=%d\n", last_oper.operation); PRINT_STACK() #endif - if (last_operator.is_set()) + if (last_oper.is_set()) { - last_operator.execute( - var_stack[var_stack_ptr - 2], - var_stack[var_stack_ptr - 1]); + last_oper.execute( + var_stack.get_second(), + var_stack.get_last()); - var_stack_ptr--; + var_stack.pop(); } - var = var_stack[var_stack_ptr - 1]; + var = var_stack.pop(); return 0; } diff --git a/common/eval_expression.h b/common/eval_expression.h index 0da7492b..532201a0 100644 --- a/common/eval_expression.h +++ b/common/eval_expression.h @@ -45,7 +45,29 @@ class EvalExpression return 0; } - int size() { return ptr; } + int push_int(uint64_t value) + { + Var var; + var.set_int(value); + return push(var); + } + + int push_int(const char *token) + { + Var var; + var.set_int(token); + return push(var); + } + + int push_float(const char *token) + { + Var var; + var.set_float(token); + return push(var); + } + + int size() { return ptr; } + bool is_empty() { return ptr == 0; } int pop_first() { @@ -61,36 +83,39 @@ class EvalExpression return 0; } - int pop() + Var pop() { assert(ptr > 0); - - ptr--; - - return 0; + return stack[--ptr]; } Var &get_first() { assert(ptr >= 1); - return stack[0]; } Var &get_second() { assert(ptr >= 2); - return stack[ptr - 2]; } - Var &get_bottom() + Var &get_last() { - assert(ptr >= 3); - + assert(ptr >= 1); return stack[ptr - 1]; } + void dump() + { + printf("-- var_stack %d --\n", ptr); + for (int n = 0; n < ptr; n++) + { + printf(" %d) %ld\n", n, stack[n].get_int64()); + } + } + Var stack[3]; int ptr; }; diff --git a/tests/unit/eval_expression_ex/unit_test.cpp b/tests/unit/eval_expression_ex/unit_test.cpp index 2f507268..d6f52b8e 100644 --- a/tests/unit/eval_expression_ex/unit_test.cpp +++ b/tests/unit/eval_expression_ex/unit_test.cpp @@ -9,6 +9,29 @@ int errors = 0; +int get_int(const char *expression) +{ + AsmContext asm_context; + Var var; + + printf("Testing: %s\n", expression); + + tokens_open_buffer(&asm_context, expression); + tokens_reset(&asm_context); + + int ret = eval_expression(&asm_context, var); + int num = var.get_int32(); + + if (ret != 0) + { + printf("FAILED. (error evaluating)\n"); + } + + tokens_close(&asm_context); + + return num; +} + void test_int(const char *expression, int answer) { AsmContext asm_context; @@ -104,6 +127,14 @@ int main(int argc, char *argv[]) { printf("eval_expression() test\n"); + if (argc >= 2) + { + int n = get_int(argv[1]); + printf("Answer: %d\n", n); + exit(0); + } + + test_int("-6", -6); //test_int("6 + -5", 1); //test_int("6 + -5 + -3", -2); @@ -120,6 +151,7 @@ int main(int argc, char *argv[]) test_int("(106 - 100) / 2 - 2", 1); test_int("6 / 2 - 2", 1); test_int("6 * 2 - 2", 10); + test_int("8 * 4 / 2", 16); test_int64("0xffffffff+1", 0x100000000); test_int64("~0", -1); test_int64("1 - ~0", 2);