subleq.awk (1264B)
1 #!/sbin/env awk -f 2 # POSIX AWK port of Subleq VM (16-bit variant) 3 # Accepts .dec files as input 4 # Usage: [busybox] awk -f subleq.awk program.dec 5 # Created by Luxferre in 2023, released into public domain 6 7 function L(v) { # cast any value to unsigned 16-bit integer 8 v = int(v) 9 while(v < 0) v += 65536 10 return int(v%65536) 11 } 12 13 function getchar(c, cmd) { # POSIX-compatible getchar emulation with sh read 14 (cmd="c='';IFS= read -r -n 1 -d $'\\0' c;printf '%u' \"'$c\"") | getline c 15 close(cmd) 16 return int(c) 17 } 18 19 BEGIN { 20 for(pc=0;pc<65536;pc++) MEM[pc] = 0 # init the memory array 21 pc = a = b = c = 0 # reset the program counter and other vars 22 } 23 24 # match on any 16-bit signed integer in the .dec file 25 { for(i=1;i<=NF;i++) if($i ~ /^[-0-9][0-9]*$/) MEM[pc++] = L($i) } 26 27 END { # start the actual execution 28 for(pc=0;pc<32768;) { 29 a = MEM[pc++]; b = MEM[pc++]; c = MEM[pc++] # fill the cell addresses 30 # -1 in cell A => input to cell B 31 if(a == 65535) MEM[b] = L(getchar()) 32 # -1 in cell B => output cell A 33 else if(b == 65535) printf("%c", MEM[a]%256) 34 # main OISC logic here 35 else { 36 MEM[b] = L(MEM[b] - MEM[a]) # subtract the first 2 cells and cast 37 if(MEM[b] == 0 || (MEM[b] > 32767)) pc = c # jump if result <=0 38 } 39 } 40 }