diff --git a/CMakeLists.txt b/CMakeLists.txt index 0383cff..b8ce13d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(fun VERSION 0.37.11 LANGUAGES C) +project(fun VERSION 0.37.12 LANGUAGES C) set(CMAKE_C_STANDARD 99) set(CMAKE_C_STANDARD_REQUIRED ON) diff --git a/examples/random_number_example.fun b/examples/random_number_example.fun index 031d0dd..9ad5213 100755 --- a/examples/random_number_example.fun +++ b/examples/random_number_example.fun @@ -17,12 +17,17 @@ * hex-encoded as a string of length 2*len (since each byte -> two hex chars). */ +#include + print("--- random_number(len) demo ---") len_bytes = 16 hexstr = random_number(len_bytes) print("Requested bytes: " + to_string(len_bytes)) print("Hex string: " + hexstr) +print("Hex bytes array: " + to_string(hex_to_bytes(hexstr))) +echo("Hex dump to bytes: ") +print(hex_to_bytes(hexstr)) print("Hex length (should be 2*bytes = 32): " + to_string(len(hexstr))) // Zero length returns empty string @@ -36,7 +41,9 @@ print("32 bytes -> " + to_string(len(hex64)) + " hex chars") /* Possible output: --- random_number(len) demo --- Requested bytes: 16 -Hex string: d5f12eb93b71e78cc803aa802e76e3b4 +Hex string: 8497373c7fb52c6cb7f1e1fda5bb6a60 +Hex bytes array: [array n=16] +Hex dump to bytes: [132, 151, 55, 60, 127, 181, 44, 108, 183, 241, 225, 253, 165, 187, 106, 96] Hex length (should be 2*bytes = 32): 32 Empty (0 bytes) -> length: 0 value: 32 bytes -> 64 hex chars diff --git a/src/vm.c b/src/vm.c index d7fb110..dd96216 100644 --- a/src/vm.c +++ b/src/vm.c @@ -269,6 +269,8 @@ void vm_clear_output(VM *vm) { free_value(vm->output[i]); } vm->output_count = 0; + // reset partial flags + for (int i = 0; i < OUTPUT_SIZE; ++i) vm->output_is_partial[i] = 0; } void vm_free(VM *vm) { @@ -420,6 +422,7 @@ void vm_init(VM *vm) { vm->sp = -1; vm->fp = -1; vm->output_count = 0; + for (int i = 0; i < OUTPUT_SIZE; ++i) vm->output_is_partial[i] = 0; vm->instr_count = 0; vm->exit_code = 0; vm->trace_enabled = 0; @@ -475,6 +478,12 @@ static void vm_pop_frame(VM *vm) { void vm_print_output(VM *vm) { for (int i = 0; i < vm->output_count; ++i) { print_value(&vm->output[i]); + if (!vm->output_is_partial[i]) { + printf("\n"); + } + } + /* If the last item was partial (from echo), terminate the line for cleanliness */ + if (vm->output_count > 0 && vm->output_is_partial[vm->output_count - 1]) { printf("\n"); } } diff --git a/src/vm.h b/src/vm.h index a69b0a4..6ee2f7f 100644 --- a/src/vm.h +++ b/src/vm.h @@ -72,6 +72,7 @@ struct VM { Value output[OUTPUT_SIZE]; // store printed values int output_count; + int output_is_partial[OUTPUT_SIZE]; // 1 when the corresponding output entry should not end with newline (echo) long long instr_count; // executed instructions in the last vm_run diff --git a/src/vm/echo.c b/src/vm/echo.c index 626bd7d..0a18101 100644 --- a/src/vm/echo.c +++ b/src/vm/echo.c @@ -1,12 +1,22 @@ /** * Implements OP_ECHO: print top-of-stack value without trailing newline. - * Does not store into VM output buffer; writes directly to stdout and flushes. + * Now stores the value into the VM's output buffer and marks it as partial, + * so the CLI can render echo output together with following print output. */ case OP_ECHO: { Value v = pop_value(vm); - print_value(&v); - fflush(stdout); + Value snap = deep_copy_value(&v); free_value(v); + if (vm->output_count < OUTPUT_SIZE) { + int idx = vm->output_count; + vm->output[idx] = snap; + vm->output_is_partial[idx] = 1; // ECHO does not end the line + vm->output_count++; + } else { + free_value(snap); + fprintf(stderr, "Runtime error: output buffer overflow\n"); + exit(1); + } break; } diff --git a/src/vm/print.c b/src/vm/print.c index aee24f9..a50de0f 100644 --- a/src/vm/print.c +++ b/src/vm/print.c @@ -32,7 +32,10 @@ case OP_PRINT: { Value snap = deep_copy_value(&v); free_value(v); if (vm->output_count < OUTPUT_SIZE) { - vm->output[vm->output_count++] = snap; + int idx = vm->output_count; + vm->output[idx] = snap; + vm->output_is_partial[idx] = 0; // PRINT terminates the line + vm->output_count++; } else { free_value(snap); fprintf(stderr, "Runtime error: output buffer overflow\n");