all repos — xyw @ c373ff690a595f92dce281c5b11bc9496bf9a86c

A minimal virtual machine and assembler for terminals.

Implemented on_argument support.
h3rald h3rald@h3rald.com
Thu, 05 Feb 2026 11:25:38 +0100
commit

c373ff690a595f92dce281c5b11bc9496bf9a86c

parent

6fc232901e6b09cf345728dbd826968a5ad8562a

8 files changed, 39 insertions(+), 10 deletions(-)

jump to
M examples/devices.abs.xywexamples/devices.abs.xyw

@@ -11,6 +11,7 @@ ;terminal

.macro terminal.input $FF10 .macro terminal.output $FF11 .macro terminal.on_keypress $FF12 +.macro terminal.on_argument $FF14 ;clock .macro clock.year $FF20
M examples/devices.xywexamples/devices.xyw

@@ -11,6 +11,7 @@ ;terminal

.macro terminal.input $10 .macro terminal.output $11 .macro terminal.on_keypress $12 +.macro terminal.on_argument $14 ;clock .macro clock.year $20
A examples/print-args.xyw

@@ -0,0 +1,27 @@

+.include "devices.xyw" + +; Set on_argument event handler +print-args terminal.on_argument STW +; End program +end JMPw + +; on_argument event handler +.label print-args + terminal.input POPx + ; If end of argument, print new line and end + LDBx $1D EQU print-args.end JCNw + LDBx $1E EQU print-args.next JCNw + ; Print typed character + LDBx terminal.output STB + RTS + ; Print argument separator (, ) + .label print-args.next + $2C terminal.output STB + $20 terminal.output STB + RTS + ; Print new line + .label print-args.end + $0A terminal.output STB + RTS + +.label end
M test.shtest.sh

@@ -6,6 +6,7 @@ TEST_CASES=(

"run_test helloworld.xyw assert_output_equals \$'Hello, World!\\n'" "run_test d6.xyw assert_output_in_range 1 6" "run_test on-error.xyw assert_output_equals \$'Error: Division by zero.\\nError: Unknown error.\\n'" + "run_test print-args.xyw assert_output_equals \$'print-args.xim, \\n'" ) ### Helper functions
M xyw.cxyw.c

@@ -31,12 +31,11 @@ }

int main(int argc, char *argv[]) { - (void)argc; xyw_argc = argc; - *xyw_argv = *argv; for (int i = 1; i < argc; i++) { + xyw_argv[i] = argv[i]; if (flag(argv[i], "debug")) { xyw_debug = 1;

@@ -68,6 +67,7 @@ {

printf("Assembled %s to %s\n", input_file, output_file); } } + break; } else if (ext && strcmp(ext, ".xim") == 0) {

@@ -76,11 +76,7 @@ {

fprintf(stderr, "Execution failed for file: %s\n", input_file); return -1; } - } - else - { - fprintf(stderr, "Unsupported file type: %s\n", input_file); - return -1; + break; } } }
M xyw.hxyw.h

@@ -6,7 +6,7 @@ #define XYW_MODE_Y 0x40

#define XYW_MODE_W 0x80 #define XYW_TOTAL_INSTRUCTIONS 0x20 #define XYW_TOTAL_DEVICES 0x10 -#define XYW_ARGUMENT_SEPARATOR 0x0A +#define XYW_ARGUMENT_SEPARATOR 0x1E #define XYW_END_OF_ARGUMENTS 0x1D // clang-format off
M xywasm.cxywasm.c

@@ -750,7 +750,6 @@ {

c = *ctx->sp++; } } - // printf("Char read: '%c' (0x%02X) [Ln %d, Col %d] - Token: %s\n", c, (unsigned char)c, ctx->line, ctx->column, token); // Handle character if (c == '\n') {
M xywrun.cxywrun.c

@@ -317,10 +317,13 @@ return xyw_memory[SYSTEM_ERROR];

} } // Process terminal arguments if not already done - if (!xyw_arguments_processed && XYW_PEEKW(&xyw_memory[TERMINAL_ON_ARGUMENT]) && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) + static int argument_processing_active = 0; + if (!xyw_arguments_processed && !argument_processing_active && XYW_PEEKW(&xyw_memory[TERMINAL_ON_ARGUMENT]) && !(xyw_memory[SYSTEM_STATE] & SYSTEM_STATE_ERROR)) { + argument_processing_active = 1; // Prevent re-entry for (int i = 1; i < xyw_argc; i++) { + xyw_dbg("Processing argument %d of %d: %s\n", i, xyw_argc, xyw_argv[i]); const char *arg = xyw_argv[i]; for (size_t j = 0; arg[j] != '\0'; j++) {

@@ -330,6 +333,7 @@ write(TERMINAL_INPUT, XYW_ARGUMENT_SEPARATOR);

} write(TERMINAL_INPUT, XYW_END_OF_ARGUMENTS); xyw_arguments_processed = 1; + argument_processing_active = 0; } return 0;