about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2025-01-09 20:30:45 -0500
committerelioat <elioat@tilde.institute>2025-01-09 20:30:45 -0500
commit786901f108f50eedde9b8dad9c6d327b108b1276 (patch)
tree922951ec445b373dbe70987097e4988266ca6ced
parent662c3ceae2a4ffc598a8b99690a0cfdc0b4f47a8 (diff)
downloadtour-786901f108f50eedde9b8dad9c6d327b108b1276.tar.gz
*
-rwxr-xr-xawk/retro/retro.awk250
-rwxr-xr-xawk/retro/test.awk52
-rwxr-xr-xawk/retro/vm.awk364
3 files changed, 666 insertions, 0 deletions
diff --git a/awk/retro/retro.awk b/awk/retro/retro.awk
new file mode 100755
index 0000000..2a14ff0
--- /dev/null
+++ b/awk/retro/retro.awk
@@ -0,0 +1,250 @@
+#!/usr/bin/awk -f
+
+# Constants and VM setup
+BEGIN {
+    IMAGE_SIZE = 524288    # Amount of simulated RAM
+    DATA_DEPTH = 8192      # Depth of data stack
+    ADDRESS_DEPTH = 32768  # Depth of the stacks
+    
+    # Initialize stacks
+    data_sp = 0
+    addr_sp = 0
+    
+    # VM state
+    ip = 0
+    
+    # Opcode definitions
+    OP_NOP = 0
+    OP_LIT = 1
+    OP_DUP = 2
+    OP_DROP = 3
+    OP_SWAP = 4
+    OP_PUSH = 5
+    OP_POP = 6
+    OP_JUMP = 7
+    OP_CALL = 8
+    OP_CCALL = 9
+    OP_RETURN = 10
+    OP_EQ = 11
+    OP_NEQ = 12
+    OP_LT = 13
+    OP_GT = 14
+    OP_FETCH = 15
+    OP_STORE = 16
+    OP_ADD = 17
+    OP_SUB = 18
+    OP_MUL = 19
+    OP_DIVMOD = 20
+    OP_AND = 21
+    OP_OR = 22
+    OP_XOR = 23
+    OP_SHIFT = 24
+    OP_ZERO_EXIT = 25
+    OP_HALT = 26
+    
+    # Initialize VM
+    prepare_vm()
+    
+    # Load and run test program
+    load_test_program()
+    execute(0)
+    
+    # Print results
+    print "Stack contents after execution:"
+    print_stack()
+}
+
+# Stack operations
+function stack_push(stack_name, value) {
+    if (stack_name == "data") {
+        data_sp++
+        data_stack[data_sp] = value
+    } else if (stack_name == "addr") {
+        addr_sp++
+        addr_stack[addr_sp] = value
+    }
+}
+
+function stack_pop(stack_name) {
+    if (stack_name == "data") {
+        if (data_sp > 0) {
+            value = data_stack[data_sp]
+            data_sp--
+            return value
+        }
+    } else if (stack_name == "addr") {
+        if (addr_sp > 0) {
+            value = addr_stack[addr_sp]
+            addr_sp--
+            return value
+        }
+    }
+    return 0
+}
+
+function stack_tos(stack_name) {
+    if (stack_name == "data" && data_sp > 0) {
+        return data_stack[data_sp]
+    }
+    return 0
+}
+
+function stack_nos(stack_name) {
+    if (stack_name == "data" && data_sp > 1) {
+        return data_stack[data_sp - 1]
+    }
+    return 0
+}
+
+# Bitwise operations
+function bitwise_and(x, y,    i, result, a, b) {
+    result = 0
+    for (i = 0; i < 32; i++) {
+        a = int(x / (2 ^ i)) % 2
+        b = int(y / (2 ^ i)) % 2
+        if (a == 1 && b == 1)
+            result += 2 ^ i
+    }
+    return result
+}
+
+function bitwise_or(x, y,    i, result, a, b) {
+    result = 0
+    for (i = 0; i < 32; i++) {
+        a = int(x / (2 ^ i)) % 2
+        b = int(y / (2 ^ i)) % 2
+        if (a == 1 || b == 1)
+            result += 2 ^ i
+    }
+    return result
+}
+
+function bitwise_xor(x, y,    i, result, a, b) {
+    result = 0
+    for (i = 0; i < 32; i++) {
+        a = int(x / (2 ^ i)) % 2
+        b = int(y / (2 ^ i)) % 2
+        if (a != b)
+            result += 2 ^ i
+    }
+    return result
+}
+
+# Helper functions
+function abs(x) {
+    return x < 0 ? -x : x
+}
+
+function lshift(x, n) {
+    return int(x * (2 ^ n))
+}
+
+function rshift(x, n) {
+    return int(x / (2 ^ n))
+}
+
+# VM core functions
+function process_opcode(opcode) {
+    if (opcode == OP_NOP) {
+        return
+    }
+    else if (opcode == OP_LIT) {
+        ip++
+        stack_push("data", image[ip])
+    }
+    else if (opcode == OP_DUP) {
+        stack_push("data", stack_tos("data"))
+    }
+    else if (opcode == OP_DROP) {
+        stack_pop("data")
+    }
+    else if (opcode == OP_SWAP) {
+        temp = stack_pop("data")
+        temp2 = stack_pop("data")
+        stack_push("data", temp)
+        stack_push("data", temp2)
+    }
+    else if (opcode == OP_ADD) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", x + y)
+    }
+    else if (opcode == OP_SUB) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", y - x)
+    }
+    else if (opcode == OP_MUL) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", x * y)
+    }
+    else if (opcode == OP_HALT) {
+        ip = IMAGE_SIZE
+    }
+}
+
+function check_stack() {
+    if (data_sp < 0 || addr_sp < 0 || 
+        data_sp > DATA_DEPTH || addr_sp > ADDRESS_DEPTH) {
+        ip = 0
+        data_sp = 0
+        addr_sp = 0
+    }
+}
+
+function process_packed_opcodes(packed) {
+    ops[0] = bitwise_and(packed, 255)
+    ops[1] = bitwise_and(rshift(packed, 8), 255)
+    ops[2] = bitwise_and(rshift(packed, 16), 255)
+    ops[3] = bitwise_and(rshift(packed, 24), 255)
+    
+    for (i = 0; i < 4; i++) {
+        if (ops[i] != 0) {
+            process_opcode(ops[i])
+        }
+    }
+}
+
+function execute(offset) {
+    addr_sp = 1
+    ip = offset
+    
+    while (ip < IMAGE_SIZE) {
+        opcode = image[ip]
+        process_packed_opcodes(opcode)
+        
+        if (addr_sp == 0)
+            ip = IMAGE_SIZE
+            
+        ip++
+    }
+}
+
+function prepare_vm() {
+    ip = 0
+    data_sp = 0
+    addr_sp = 0
+}
+
+# Test program loader
+function pack_opcodes(op1, op2, op3, op4) {
+    return op1 + (op2 * 256) + (op3 * 65536) + (op4 * 16777216)
+}
+
+function load_test_program() {
+    # Simple test program that adds 10 and 5
+    image[0] = pack_opcodes(OP_LIT, 0, 0, 0)  # Push literal
+    image[1] = 10                             # Value 10
+    image[2] = pack_opcodes(OP_LIT, 0, 0, 0)  # Push literal
+    image[3] = 5                              # Value 5
+    image[4] = pack_opcodes(OP_ADD, 0, 0, 0)  # Add them
+    image[5] = pack_opcodes(OP_HALT, 0, 0, 0) # Halt
+}
+
+# Debug helper
+function print_stack() {
+    for (i = 1; i <= data_sp; i++) {
+        print "Item", i ":", data_stack[i]
+    }
+}
\ No newline at end of file
diff --git a/awk/retro/test.awk b/awk/retro/test.awk
new file mode 100755
index 0000000..191fa5b
--- /dev/null
+++ b/awk/retro/test.awk
@@ -0,0 +1,52 @@
+#!/usr/bin/awk -f
+
+@include "vm.awk"
+
+# Complex test program
+BEGIN {
+    # Test program to calculate factorial of 5
+    i = 0
+    
+    # Push 5 onto stack
+    image[i++] = pack_opcodes(OP_LIT, 0, 0, 0)
+    image[i++] = 5
+    
+    # Push 1 onto stack (accumulator)
+    image[i++] = pack_opcodes(OP_LIT, 0, 0, 0)
+    image[i++] = 1
+    
+    # Start of multiplication loop
+    loop_start = i
+    
+    # Duplicate top number (counter)
+    image[i++] = pack_opcodes(OP_DUP, 0, 0, 0)
+    
+    # Test if counter is zero
+    image[i++] = pack_opcodes(OP_ZERO_EXIT, 0, 0, 0)
+    
+    # Multiply accumulator by counter
+    image[i++] = pack_opcodes(OP_MUL, 0, 0, 0)
+    
+    # Decrement counter
+    image[i++] = pack_opcodes(OP_LIT, 0, 0, 0)
+    image[i++] = 1
+    image[i++] = pack_opcodes(OP_SUB, 0, 0, 0)
+    
+    # Jump back to start of loop
+    image[i++] = pack_opcodes(OP_LIT, 0, 0, 0)
+    image[i++] = loop_start
+    image[i++] = pack_opcodes(OP_JUMP, 0, 0, 0)
+    
+    # Halt
+    image[i++] = pack_opcodes(OP_HALT, 0, 0, 0)
+    
+    # Execute program
+    execute(0)
+    
+    # Print result (should be 120 - factorial of 5)
+    print "Factorial of 5:", stack_tos("data")
+}
+
+function pack_opcodes(op1, op2, op3, op4) {
+    return op1 + (op2 * 256) + (op3 * 65536) + (op4 * 16777216)
+}
\ No newline at end of file
diff --git a/awk/retro/vm.awk b/awk/retro/vm.awk
new file mode 100755
index 0000000..cd894c5
--- /dev/null
+++ b/awk/retro/vm.awk
@@ -0,0 +1,364 @@
+#!/usr/bin/awk -f
+
+# Constants
+BEGIN {
+    IMAGE_SIZE = 524288    # Amount of simulated RAM
+    DATA_DEPTH = 8192      # Depth of data stack
+    ADDRESS_DEPTH = 32768  # Depth of the stacks
+    
+    # Initialize stacks
+    data_sp = 0
+    addr_sp = 0
+    
+    # VM state
+    ip = 0
+    
+    # Opcode definitions
+    OP_NOP = 0
+    OP_LIT = 1
+    OP_DUP = 2
+    OP_DROP = 3
+    OP_SWAP = 4
+    OP_PUSH = 5
+    OP_POP = 6
+    OP_JUMP = 7
+    OP_CALL = 8
+    OP_CCALL = 9
+    OP_RETURN = 10
+    OP_EQ = 11
+    OP_NEQ = 12
+    OP_LT = 13
+    OP_GT = 14
+    OP_FETCH = 15
+    OP_STORE = 16
+    OP_ADD = 17
+    OP_SUB = 18
+    OP_MUL = 19
+    OP_DIVMOD = 20
+    OP_AND = 21
+    OP_OR = 22
+    OP_XOR = 23
+    OP_SHIFT = 24
+    OP_ZERO_EXIT = 25
+    OP_HALT = 26
+    OP_IE = 27
+    OP_IQ = 28
+    OP_II = 29
+}
+
+# Stack operations
+function stack_push(stack_name, value) {
+    if (stack_name == "data") {
+        data_sp++
+        data_stack[data_sp] = value
+    } else if (stack_name == "addr") {
+        addr_sp++
+        addr_stack[addr_sp] = value
+    }
+}
+
+function stack_pop(stack_name) {
+    if (stack_name == "data") {
+        if (data_sp > 0) {
+            value = data_stack[data_sp]
+            data_sp--
+            return value
+        }
+    } else if (stack_name == "addr") {
+        if (addr_sp > 0) {
+            value = addr_stack[addr_sp]
+            addr_sp--
+            return value
+        }
+    }
+    return 0
+}
+
+function stack_tos(stack_name) {
+    if (stack_name == "data" && data_sp > 0) {
+        return data_stack[data_sp]
+    }
+    return 0
+}
+
+function stack_nos(stack_name) {
+    if (stack_name == "data" && data_sp > 1) {
+        return data_stack[data_sp - 1]
+    }
+    return 0
+}
+
+# Bitwise operation implementations
+function bitwise_and(x, y,    i, result, a, b) {
+    result = 0
+    for (i = 0; i < 32; i++) {
+        a = int(x / (2 ^ i)) % 2
+        b = int(y / (2 ^ i)) % 2
+        if (a == 1 && b == 1)
+            result += 2 ^ i
+    }
+    return result
+}
+
+function bitwise_or(x, y,    i, result, a, b) {
+    result = 0
+    for (i = 0; i < 32; i++) {
+        a = int(x / (2 ^ i)) % 2
+        b = int(y / (2 ^ i)) % 2
+        if (a == 1 || b == 1)
+            result += 2 ^ i
+    }
+    return result
+}
+
+function bitwise_xor(x, y,    i, result, a, b) {
+    result = 0
+    for (i = 0; i < 32; i++) {
+        a = int(x / (2 ^ i)) % 2
+        b = int(y / (2 ^ i)) % 2
+        if (a != b)
+            result += 2 ^ i
+    }
+    return result
+}
+
+function lshift(x, n) {
+    return int(x * (2 ^ n))
+}
+
+function rshift(x, n) {
+    return int(x / (2 ^ n))
+}
+
+# VM instruction implementations
+function process_opcode(opcode) {
+    if (opcode == OP_NOP) {
+        return
+    }
+    else if (opcode == OP_LIT) {
+        ip++
+        stack_push("data", image[ip])
+    }
+    else if (opcode == OP_DUP) {
+        stack_push("data", stack_tos("data"))
+    }
+    else if (opcode == OP_DROP) {
+        stack_pop("data")
+    }
+    else if (opcode == OP_SWAP) {
+        temp = stack_pop("data")
+        temp2 = stack_pop("data")
+        stack_push("data", temp)
+        stack_push("data", temp2)
+    }
+    else if (opcode == OP_PUSH) {
+        stack_push("addr", stack_pop("data"))
+    }
+    else if (opcode == OP_POP) {
+        stack_push("data", stack_pop("addr"))
+    }
+    else if (opcode == OP_JUMP) {
+        ip = stack_pop("data") - 1
+    }
+    else if (opcode == OP_CALL) {
+        stack_push("addr", ip)
+        ip = stack_pop("data") - 1
+    }
+    else if (opcode == OP_CCALL) {
+        a = stack_pop("data")
+        b = stack_pop("data")
+        if (b != 0) {
+            stack_push("addr", ip)
+            ip = a - 1
+        }
+    }
+    else if (opcode == OP_RETURN) {
+        ip = stack_pop("addr")
+    }
+    else if (opcode == OP_EQ) {
+        a = stack_pop("data")
+        b = stack_pop("data")
+        stack_push("data", (b == a) ? -1 : 0)
+    }
+    else if (opcode == OP_NEQ) {
+        a = stack_pop("data")
+        b = stack_pop("data")
+        stack_push("data", (b != a) ? -1 : 0)
+    }
+    else if (opcode == OP_LT) {
+        a = stack_pop("data")
+        b = stack_pop("data")
+        stack_push("data", (b < a) ? -1 : 0)
+    }
+    else if (opcode == OP_GT) {
+        a = stack_pop("data")
+        b = stack_pop("data")
+        stack_push("data", (b > a) ? -1 : 0)
+    }
+    else if (opcode == OP_FETCH) {
+        x = stack_pop("data")
+        if (x == -1)
+            stack_push("data", data_sp)
+        else if (x == -2)
+            stack_push("data", addr_sp)
+        else if (x == -3)
+            stack_push("data", IMAGE_SIZE)
+        else if (x == -4)
+            stack_push("data", -2147483648)
+        else if (x == -5)
+            stack_push("data", 2147483647)
+        else
+            stack_push("data", image[x])
+    }
+    else if (opcode == OP_STORE) {
+        addr = stack_pop("data")
+        value = stack_pop("data")
+        image[addr] = value
+    }
+    else if (opcode == OP_ADD) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", x + y)
+    }
+    else if (opcode == OP_SUB) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", y - x)
+    }
+    else if (opcode == OP_MUL) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", y * x)
+    }
+    else if (opcode == OP_DIVMOD) {
+        b = stack_pop("data")
+        a = stack_pop("data")
+        if (b == 0) {
+            ip = 0
+            data_sp = 0
+            addr_sp = 0
+        } else {
+            x = abs(b)
+            y = abs(a)
+            q = int(y / x)
+            r = y % x
+            if (a < 0 && b < 0)
+                r = r * -1
+            if (a > 0 && b < 0)
+                q = q * -1
+            if (a < 0 && b > 0) {
+                r = r * -1
+                q = q * -1
+            }
+            stack_push("data", r)
+            stack_push("data", q)
+        }
+    }
+    else if (opcode == OP_AND) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", bitwise_and(x, y))
+    }
+    else if (opcode == OP_OR) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", bitwise_or(x, y))
+    }
+    else if (opcode == OP_XOR) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        stack_push("data", bitwise_xor(x, y))
+    }
+    else if (opcode == OP_SHIFT) {
+        x = stack_pop("data")
+        y = stack_pop("data")
+        if (x < 0)
+            stack_push("data", lshift(y, -x))
+        else
+            stack_push("data", rshift(y, x))
+    }
+    else if (opcode == OP_ZERO_EXIT) {
+        if (stack_tos("data") == 0) {
+            stack_pop("data")
+            ip = stack_pop("addr")
+        }
+    }
+    else if (opcode == OP_HALT) {
+        ip = IMAGE_SIZE
+    }
+    
+    check_stack()
+}
+
+# Helper functions
+function abs(x) {
+    return x < 0 ? -x : x
+}
+
+function check_stack() {
+    if (data_sp < 0 || addr_sp < 0 || 
+        data_sp > DATA_DEPTH || addr_sp > ADDRESS_DEPTH) {
+        ip = 0
+        data_sp = 0
+        addr_sp = 0
+    }
+}
+
+function process_packed_opcodes(packed) {
+    ops[0] = bitwise_and(packed, 255)
+    ops[1] = bitwise_and(rshift(packed, 8), 255)
+    ops[2] = bitwise_and(rshift(packed, 16), 255)
+    ops[3] = bitwise_and(rshift(packed, 24), 255)
+    
+    for (i = 0; i < 4; i++) {
+        if (ops[i] != 0) {
+            process_opcode(ops[i])
+        }
+    }
+}
+
+# Main execution function
+function execute(offset) {
+    addr_sp = 1
+    ip = offset
+    
+    while (ip < IMAGE_SIZE) {
+        opcode = image[ip]
+        process_packed_opcodes(opcode)
+        
+        if (addr_sp == 0)
+            ip = IMAGE_SIZE
+            
+        ip++
+    }
+}
+
+# String handling functions
+function string_inject(str, buffer,    i, len) {
+    len = length(str)
+    for (i = 1; i <= len; i++) {
+        image[buffer + i - 1] = ord(substr(str, i, 1))
+        image[buffer + i] = 0
+    }
+}
+
+function string_extract(at,    str, i) {
+    str = ""
+    i = at
+    while (image[i] != 0) {
+        str = str chr(image[i])
+        i++
+    }
+    return str
+}
+
+# Initialize VM
+BEGIN {
+    prepare_vm()
+}
+
+function prepare_vm() {
+    ip = 0
+    data_sp = 0
+    addr_sp = 0
+}
\ No newline at end of file