all repos — xyw @ 13b16677dbafd92d9695aa0708ac30383cad92a8

A minimal virtual machine and assembler for terminals.

Predicates are now always pushing a single byte to the stack as result.
h3rald h3rald@h3rald.com
Tue, 21 Jul 2026 14:42:55 +0200
commit

13b16677dbafd92d9695aa0708ac30383cad92a8

parent

056b9f31c880e4e748d4aeda893322b597bb4422

3 files changed, 15 insertions(+), 16 deletions(-)

jump to
M examples/factorial16.xywexamples/factorial16.xyw

@@ -13,9 +13,8 @@ ; Save argument to both registers

POPxyw .label fact.loop ; Need to work with 16-bit comparisons - ; but JCN only works with 8-bit values, so remove high byte first - PSHyw $0000 EQUw LBYTE fact.end0 JCNw - PSHyw $0001 EQUw LBYTE fact.end1 JCNw + PSHyw $0000 EQUw fact.end0 JCNw + PSHyw $0001 EQUw fact.end1 JCNw ; Decrement y and multiply DECyw PSHxw PSHyw MULxw POPxw fact.loop JMPw
M examples/lib/putdw.xywexamples/lib/putdw.xyw

@@ -6,7 +6,7 @@ .label putdw

POPxw ; If value is less than 10, print single digit ; Push 16-bit literal as two bytes (high, low), then compare - PSHxw $000A LTHw LBYTE putdw.single JCNw + PSHxw $000A LTHw putdw.single JCNw ; Divide by 10, stack becomes [remainder, quotient] with quotient on top PSHxw $000A DIVw ; Call PUTDw recursively with quotient (on top, consumed by POPxw)
M xywrun.cxywrun.c

@@ -288,14 +288,14 @@ // clang-format off

//// Operations that support stack and all registers #define OPC_SR2(opc, body) { \ - case opc: { const int w=0, rx=0, ry=0; xyw_byte b = us_pop(); xyw_byte a = us_pop(); body; (void)(rx); (void)(ry); } break; \ - case XYW_MODE_X|opc: { const int w=0, rx=1, ry=0; xyw_byte b = *x; xyw_byte a = us_pop(); body; (void)(rx); (void)(ry); } break; \ - case XYW_MODE_Y|opc: { const int w=0, rx=0, ry=1; xyw_byte b = *y; xyw_byte a = us_pop(); body; (void)(rx); (void)(ry); } break; \ - case XYW_MODE_X|XYW_MODE_Y|opc: { const int w=0, rx=1, ry=1; xyw_byte a = *x; xyw_byte b = *y; body; (void)(rx); (void)(ry); } break; \ - case XYW_MODE_W|opc: { const int w=1, rx=0, ry=0; xyw_word b = us_popw(); xyw_word a = us_popw(); body; (void)(rx); (void)(ry); } break; \ - case XYW_MODE_X|XYW_MODE_W|opc: { const int w=1, rx=1, ry=0; xyw_word b = *xw; xyw_word a = us_popw(); body; (void)(rx); (void)(ry); } break; \ - case XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=0, ry=1; xyw_word b = *yw; xyw_word a = us_popw(); body; (void)(rx); (void)(ry); } break; \ - case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=1, ry=1; xyw_word a = *xw; xyw_word b = *yw; body; (void)(rx); (void)(ry); } break; \ + case opc: { const int w=0, rx=0, ry=0; xyw_byte b = us_pop(); xyw_byte a = us_pop(); body; (void)(rx); (void)(ry); (void)(w);} break; \ + case XYW_MODE_X|opc: { const int w=0, rx=1, ry=0; xyw_byte b = *x; xyw_byte a = us_pop(); body; (void)(rx); (void)(ry); (void)(w); } break; \ + case XYW_MODE_Y|opc: { const int w=0, rx=0, ry=1; xyw_byte b = *y; xyw_byte a = us_pop(); body; (void)(rx); (void)(ry); (void)(w); } break; \ + case XYW_MODE_X|XYW_MODE_Y|opc: { const int w=0, rx=1, ry=1; xyw_byte a = *x; xyw_byte b = *y; body; (void)(rx); (void)(ry); (void)(w); } break; \ + case XYW_MODE_W|opc: { const int w=1, rx=0, ry=0; xyw_word b = us_popw(); xyw_word a = us_popw(); body; (void)(rx); (void)(ry); (void)(w); } break; \ + case XYW_MODE_X|XYW_MODE_W|opc: { const int w=1, rx=1, ry=0; xyw_word b = *xw; xyw_word a = us_popw(); body; (void)(rx); (void)(ry); (void)(w); } break; \ + case XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=0, ry=1; xyw_word b = *yw; xyw_word a = us_popw(); body; (void)(rx); (void)(ry); (void)(w); } break; \ + case XYW_MODE_X|XYW_MODE_Y|XYW_MODE_W|opc: { const int w=1, rx=1, ry=1; xyw_word a = *xw; xyw_word b = *yw; body; (void)(rx); (void)(ry); (void)(w); } break; \ } //// Operations that support stack and one register

@@ -487,10 +487,10 @@ /* ADD */ OPC_SR2(0x0C, PUSH(a + b));

/* SUB */ OPC_SR2(0x0D, PUSH(a - b)); /* MUL */ OPC_SR2(0x0E, PUSH(a * b)); /* DIV */ OPC_SR2(0x0F, if (b) { PUSH(a % b); PUSH(a / b); } else { xyw_memory[SYSTEM_ERROR] = XYW_ERROR_DIVISION_BY_ZERO; } ); - /* EQU */ OPC_SR2(0x10, PUSH(a == b)); - /* NEQ */ OPC_SR2(0x11, PUSH(a != b)); - /* GTH */ OPC_SR2(0x12, PUSH(a > b)); - /* LTH */ OPC_SR2(0x13, PUSH(a < b)); + /* EQU */ OPC_SR2(0x10, us_push(a == b)); + /* NEQ */ OPC_SR2(0x11, us_push(a != b)); + /* GTH */ OPC_SR2(0x12, us_push(a > b)); + /* LTH */ OPC_SR2(0x13, us_push(a < b)); /* NOT */ OPC_SR1(0x14, , SET(~ARG)); /* NOT */ OPC_SR1r(0x14, SET(~ARGX); SET(~ARGY); ); /* AND */ OPC_SR2(0x15, PUSH(a & b));