From: Aaron Taylor Date: Sun, 7 Jul 2019 11:43:30 +0000 (-0700) Subject: Added final tests. All VVhitespace commands now have a basic test. X-Git-Url: http://git.subgeniuskitty.com/vvhitespace/.git/commitdiff_plain/a2664738ebe0f2129ca4b547ec977ea0ce1d6e4d Added final tests. All VVhitespace commands now have a basic test. --- diff --git a/tests/5003_io_input_character.pvvs b/tests/5003_io_input_character.pvvs new file mode 100644 index 0000000..cc40b04 --- /dev/null +++ b/tests/5003_io_input_character.pvvs @@ -0,0 +1,8 @@ +# This test verifies the input/output IMP input character. + +SSSTN | ST: Push +1 +TNTS | IO: Input character +SSSTN | ST: Push +1 +TTT | HP: Load +TNSS | IO: Output character +NNN | FC: Terminate program diff --git a/tests/5004_io_input_digit.pvvs b/tests/5004_io_input_digit.pvvs new file mode 100644 index 0000000..53d48bf --- /dev/null +++ b/tests/5004_io_input_digit.pvvs @@ -0,0 +1,8 @@ +# This test verifies the input/output IMP input digit. + +SSSTN | ST: Push +1 +TNTT | IO: Input digit +SSSTN | ST: Push +1 +TTT | HP: Load +TNST | IO: Output digit +NNN | FC: Terminate program diff --git a/vv_interpreter.c b/vv_interpreter.c index be52497..ca2f772 100644 --- a/vv_interpreter.c +++ b/vv_interpreter.c @@ -11,6 +11,7 @@ #include #include #include +#include #define VERSION 1 @@ -46,11 +47,38 @@ stdin_empty(void) return 1; } +void +set_terminal_mode(void) +{ + struct termios options; + tcgetattr(STDIN_FILENO, &options); + /* Create a cbreak-like environment through the following options. */ + options.c_lflag &= ~ECHO; /* Disable echoing of input characters. */ + options.c_lflag &= ~ICANON; /* Disable cooked/line-oriented mode. */ + options.c_cc[VMIN] = 1; + options.c_cc[VTIME] = 0; + tcsetattr(STDIN_FILENO, TCSANOW, &options); +} + +void +unset_terminal_mode(void) +{ + struct termios options; + tcgetattr(STDIN_FILENO, &options); + /* Undo the changes made in set_terminal_mode(). */ + options.c_lflag |= ECHO; /* Enable echoing of input characters. */ + options.c_lflag |= ICANON; /* Enable cooked/line-oriented mode. */ + options.c_cc[VMIN] = 1; /* Default value from /usr/src/sys/sys/ttydefaults.h */ + options.c_cc[VTIME] = 0; /* Default value from /usr/src/sys/sys/ttydefaults.h */ + tcsetattr(STDIN_FILENO, TCSANOW, &options); +} + void ws_die(size_t * pc, char * msg) { printf("SIM_ERROR @ PC %lu: %s\n", *pc, msg); fflush(stdout); + unset_terminal_mode(); exit(EXIT_FAILURE); } @@ -223,6 +251,7 @@ process_imp_flowcontrol(uint8_t * code, size_t * pc, int32_t ** sp, uint32_t * l case '\n': /* Technically another LF is required but we ignore it. */ fflush(stdout); + unset_terminal_mode(); exit(EXIT_SUCCESS); case ' ': { @@ -325,7 +354,7 @@ process_imp_io(uint8_t * code, size_t * pc, int32_t ** sp, int32_t ** hp) char c = getchar(); switch (next_code_byte(code,pc)) { case '\t': /* Input digit */ c -= '0'; /* fallthrough */ - case ' ' : /* Input character */ *(*hp + *((*sp)--)) = c; break; + case ' ' : /* Input character */ *(*hp + *(--(*sp))) = c; break; default : ws_die(pc, "malformed input IMP"); break; } } @@ -402,13 +431,14 @@ main(int argc, char ** argv) /* * Main Loop */ - + set_terminal_mode(); size_t pc = 0; /* Virtual program counter. Operates in the ws_code_space[] address space. */ while (1) { if (pc >= ws_code_size) { fprintf(stderr, "SIM_ERROR: PC Overrun\n Requested PC: %lu\n Max Address: %lu\n", pc, ws_code_size-1); exit(EXIT_FAILURE); + unset_terminal_mode(); } // TODO: Have the SIGTERM signal handler and normal term point return the value // on TOS so I can do rudimentary automated tests. @@ -450,4 +480,5 @@ main(int argc, char ** argv) printf("Program executed.\n"); exit(EXIT_SUCCESS); + unset_terminal_mode(); } diff --git a/vv_test.py b/vv_test.py index 829e891..2cdadd9 100755 --- a/vv_test.py +++ b/vv_test.py @@ -14,32 +14,35 @@ path_to_tests = './tests/' src_extension = '.pvvs' tests = [ - ['0001_push_printchar_exit', 'A'], - ['1001_stack_push', 'A'], - ['1002_stack_dup', 'AA'], - ['1003_stack_swap', 'AB'], - ['1004_stack_drop', 'A'], - ['2001_arithmetic_addition', 'B'], - ['2002_arithmetic_subtraction', 'A'], - ['2003_arithmetic_multiplication', 'B'], - ['2004_arithmetic_division', 'A'], - ['2005_arithmetic_remainder', 'A'], - ['3001_heap', 'BCA'], - ['4001_flowcontrol_exit', ''], - ['4002_flowcontrol_unconditional_jump_to_label', 'A'], - ['4003_flowcontrol_jump_if_tos_is_zero', 'A'], - ['4004_flowcontrol_jump_if_tos_is_negative', 'A'], - ['4005_flowcontrol_jump_to_subroutine', 'A'], - ['4006_flowcontrol_return_from_subroutine', 'A'], - ['5001_io_output_character', 'A'], - ['5002_io_output_digit', '2'], + # Format: ['filename_without_extension', 'string for stdin', 'string for expected stdout'] + ['0001_push_printchar_exit', '', 'A'], + ['1001_stack_push', '', 'A'], + ['1002_stack_dup', '', 'AA'], + ['1003_stack_swap', '', 'AB'], + ['1004_stack_drop', '', 'A'], + ['2001_arithmetic_addition', '', 'B'], + ['2002_arithmetic_subtraction', '', 'A'], + ['2003_arithmetic_multiplication', '', 'B'], + ['2004_arithmetic_division', '', 'A'], + ['2005_arithmetic_remainder', '', 'A'], + ['3001_heap', '', 'BCA'], + ['4001_flowcontrol_exit', '', ''], + ['4002_flowcontrol_unconditional_jump_to_label', '', 'A'], + ['4003_flowcontrol_jump_if_tos_is_zero', '', 'A'], + ['4004_flowcontrol_jump_if_tos_is_negative', '', 'A'], + ['4005_flowcontrol_jump_to_subroutine', '', 'A'], + ['4006_flowcontrol_return_from_subroutine', '', 'A'], + ['5001_io_output_character', '', 'A'], + ['5002_io_output_digit', '', '2'], + ['5003_io_input_character', 'A', 'A'], + ['5004_io_input_digit', '1', '1'], ] for test in tests: # TODO: Catch stderr subprocess.run([compiler_path, '-i', path_to_tests + test[0] + src_extension, '-o', temp_file]) - result = subprocess.run([interpreter_path, '-i', temp_file], stdout=subprocess.PIPE) - if result.stdout.decode('utf-8') != test[1]: + result = subprocess.run([interpreter_path, '-i', temp_file], stdout=subprocess.PIPE, input=test[1].encode('utf-8')) + if result.stdout.decode('utf-8') != test[2]: print('\n' + test[0]) else: print('.', end='', flush=True)