all repos — xyw @ 9946127dcf38323a0e0fc8c6d53eab4a7d6faa22

A minimal virtual machine and assembler for terminals.

Tested on macOS, fixed compilation errors and portability issues
h3rald h3rald@h3rald.com
Fri, 31 Jul 2026 10:07:55 +0200
commit

9946127dcf38323a0e0fc8c6d53eab4a7d6faa22

parent

abc5d001d81783a64f0f15b13a9d486bd62748a2

7 files changed, 55 insertions(+), 17 deletions(-)

jump to
M .conver/draft.txt.conver/draft.txt

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

+3301
M CHANGELOG.mdCHANGELOG.md

@@ -1,5 +1,11 @@

## Changelog +### v330-1 — 2026-07-31 + +#### Fixes + +- Fixed portability issues on macOS. + ### v320-1 — 2026-07-30 #### New Features
M MakefileMakefile

@@ -1,6 +1,6 @@

CC = gcc -CFLAGS = -Wall -Wextra -g -Os -ffunction-sections -fdata-sections -LDFLAGS = -Wl,--gc-sections -s +CFLAGS = -Wall -Wextra -g -Os +LDFLAGS = -Wl SOURCES = xyw.c xywasm.c xywrun.c devices/system.c devices/terminal.c devices/clock.c devices/file.c devices/beeper.c OBJS = xyw.o xywasm.o xywrun.o devices/system.o devices/terminal.o devices/clock.o devices/file.o devices/beeper.o
M devices/clock.cdevices/clock.c

@@ -162,8 +162,26 @@ if (ms > 0)

Sleep(ms); } #else + // clock_nanosleep(TIMER_ABSTIME) isn't implemented on Darwin, + // so compute the remaining time and use relative nanosleep there. +#ifdef __APPLE__ + { + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + long long ns = (clock_timer_target.tv_sec - now.tv_sec) * 1000000000LL + + (clock_timer_target.tv_nsec - now.tv_nsec); + if (ns > 0) + { + struct timespec req; + req.tv_sec = ns / 1000000000LL; + req.tv_nsec = ns % 1000000000LL; + nanosleep(&req, NULL); + } + } +#else // Use clock_nanosleep with absolute target time for precision clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &clock_timer_target, NULL); +#endif #endif // After sleep, update timer state clock_get_timer_value();
M test.shtest.sh

@@ -99,11 +99,27 @@

need_file "$EXAMPLES_DIR/$img_basename" local run_log="$TMPDIR/run.${img_basename}.log" - #if ! (cd "$EXAMPLES_DIR" && "$xyw_bin" "$img_basename" "${run_args[@]}" </dev/null >"$out_file" 2>"$run_log"); then - if ! (cd "$EXAMPLES_DIR" && "$xyw_bin" "$img_basename" "${run_args[@]}" >"$out_file" 2>"$run_log"); then - dump_file_if_exists "Runtime stderr" "$run_log" - dump_file_if_exists "Runtime stdout" "$out_file" - fail "Execution failed for $img_basename" + + if ((${#run_args[@]})); then + if ! ( + cd "$EXAMPLES_DIR" && + "$xyw_bin" "$img_basename" "${run_args[@]}" \ + >"$out_file" 2>"$run_log" + ); then + dump_file_if_exists "Runtime stderr" "$run_log" + dump_file_if_exists "Runtime stdout" "$out_file" + fail "Execution failed for $img_basename" + fi + else + if ! ( + cd "$EXAMPLES_DIR" && + "$xyw_bin" "$img_basename" \ + >"$out_file" 2>"$run_log" + ); then + dump_file_if_exists "Runtime stderr" "$run_log" + dump_file_if_exists "Runtime stdout" "$out_file" + fail "Execution failed for $img_basename" + fi fi }

@@ -210,8 +226,12 @@ img_basename="$(assemble_in_examples_dir "$XYW_BIN" "$src_basename")"

local raw_out="$TMPDIR/${src_basename%.xyw}.raw" local norm_out="$TMPDIR/${src_basename%.xyw}.norm" - - run_image_capture_stdout "$XYW_BIN" "$img_basename" "$raw_out" "${run_args[@]}" + + if ((${#run_args[@]})); then + run_image_capture_stdout "$XYW_BIN" "$img_basename" "$raw_out" "${run_args[@]}" + else + run_image_capture_stdout "$XYW_BIN" "$img_basename" "$raw_out" + fi normalize_crlf "$raw_out" "$norm_out" "$assert_fn" "$norm_out" "${assert_args[@]}"
M xyw.hxyw.h

@@ -1,7 +1,7 @@

#ifndef XYW_H #define XYW_H -#define XYW_VERSION 0x3201 +#define XYW_VERSION 0x3301 // Registers and memory #define XYW_MODE_X 0x80
M xywasm.cxywasm.c

@@ -336,13 +336,6 @@ ptr += 2;

bytes_written += 2; } -// Encode a push instruction -static inline void push(xyw_word val) -{ - (val > 0xff) ? append(PSH | XYW_MODE_W) : append(PSH); - append(val); -} - // Store macro definition in dictionary static int macro(xyw_context *ctx, char *name, char *contents) {