about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--main.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/main.c b/main.c
index 614faa0..021874f 100644
--- a/main.c
+++ b/main.c
@@ -245,6 +245,9 @@ updatebarpos(void) {
 		XMoveWindow(dpy, barwin, sx, sy - bh);
 		break;
 	}
+	XRaiseWindow(dpy, barwin);
+	XSync(dpy, False);
+	while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
 }
 
 /* There's no way to check accesses to destroyed windows, thus those cases are
>107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
#!/usr/bin/awk -f


# Stack: DROP, DUP, OVER, PUSH, POP
# Math:	+ AND XOR NOT 2* 2/ multiply-step
# Call:	JUMP CALL RETURN IF -IF
# Loop:	NEXT UNEXT
# Register:	A A! B!
# Memory: @ ! @+ !+ @B !B @P !P
# NO-OP: .


BEGIN {
    # Initialize VM state
    stack_pointer = 0    # Points to next free position
    pc = 0               # Program counter
    MAX_STACK = 100      # Maximum stack size
    MAX_MEM = 1000       # Memory size
    
    # Initialize registers
    A = 0              # A register
    B = 0              # B register
    P = 0              # P register (auxiliary pointer)
    
    # Stack operations
    split("", stack)   # Initialize stack array
    split("", memory)  # Initialize memory array
}

# Stack operations
function push(value) {
    if (stack_pointer >= MAX_STACK) {
        print "Stack overflow!" > "/dev/stderr"
        exit 1
    }
    printf "# DEBUG: Pushing %d onto stack\n", value > "/dev/stderr"
    stack[stack_pointer++] = value
}

function pop() {
    if (stack_pointer <= 0) {
        print "Stack underflow!" > "/dev/stderr"
        exit 1
    }
    value = stack[--stack_pointer]
    printf "# DEBUG: Popping %d from stack\n", value > "/dev/stderr"
    return value
}

# Basic stack manipulation
function op_drop() {
    pop()
}

function op_dup() {
    if (stack_pointer <= 0) {
        print "Stack underflow on DUP!" > "/dev/stderr"
        exit 1
    }
    push(stack[stack_pointer - 1])
}

function op_over() {
    if (stack_pointer <= 1) {
        print "Stack underflow on OVER!" > "/dev/stderr"
        exit 1
    }
    push(stack[stack_pointer - 2])
}

# Basic arithmetic operations
function op_add() {
    b = pop()
    a = pop()
    result = a + b
    printf "# DEBUG: Adding %d + %d = %d\n", a, b, result > "/dev/stderr"
    push(result)
}

function op_and() {
    b = pop()
    a = pop()
    # For now, we'll just multiply as a placeholder
    # In a real implementation, we'd need to implement proper bitwise AND
    push(a * b)
}

function op_xor() {
    b = pop()
    a = pop()
    # For now, we'll just add as a placeholder
    # In a real implementation, we'd need to implement proper bitwise XOR
    push(a + b)
}

function op_not() {
    a = pop()
    # For now, we'll just negate as a placeholder
    # In a real implementation, we'd need to implement proper bitwise NOT
    push(-a - 1)
}

function op_2times() {
    a = pop()
    push(a * 2)
}

function op_2div() {
    a = pop()
    push(int(a / 2))
}

function op_multiply() {
    b = pop()
    a = pop()
    result = a * b
    printf "# DEBUG: Multiplying %d * %d = %d\n", a, b, result > "/dev/stderr"
    push(result)
}

# Register operations
function op_a() {
    push(A)
}

function op_astore() {
    A = pop()
}

function op_bstore() {
    B = pop()
}

# Memory operations
function op_fetch() {
    addr = pop()
    value = memory[addr]
    printf "# DEBUG: Fetching %d from memory[%d]\n", value, addr > "/dev/stderr"
    push(value)
}

function op_store() {
    addr = pop()  # First pop the address
    value = pop() # Then pop the value
    printf "# DEBUG: Storing %d at memory[%d]\n", value, addr > "/dev/stderr"
    memory[addr] = value
}

function op_fetchplus() {
    push(memory[P++])
}

function op_storeplus() {
    memory[P++] = pop()
}

function op_fetchb() {
    push(memory[B])
}

function op_storeb() {
    memory[B] = pop()
}

function op_fetchp() {
    push(memory[P])
}

function op_storep() {
    memory[P] = pop()
}

function print_stack() {
    printf "Stack: "
    for (i = 0; i < stack_pointer; i++) {
        printf "%d ", stack[i]
    }
    printf "\n"
}

function print_state() {
    print_stack()
    printf "Registers: A=%d B=%d P=%d\n", A, B, P
    printf "Memory[P]=%d Memory[B]=%d\n", memory[P], memory[B]
    printf "Memory: "
    for (i = 0; i < 4; i++) {  # Show first 4 memory locations
        printf "[%d]=%d ", i, memory[i]
    }
    printf "\n-------------------\n"
}

function op_swap() {
    if (stack_pointer < 2) {
        print "Stack underflow on SWAP!" > "/dev/stderr"
        exit 1
    }
    # Swap the top two elements on the stack
    temp = stack[stack_pointer - 1]
    stack[stack_pointer - 1] = stack[stack_pointer - 2]
    stack[stack_pointer - 2] = temp
    printf "# DEBUG: Swapping top two stack elements\n" > "/dev/stderr"
}

function execute_instruction(inst) {
    if (inst ~ /^[0-9]+$/) {
        # Numbers are pushed onto the stack
        push(int(inst))
        return
    }
    
    if (inst == "BYE")      { exit 0 } # not really in the minimal spec as set out by Chuck Moore, but useful for a graceful exit.
    if (inst == "DROP")     { op_drop(); return }
    if (inst == "DUP")      { op_dup(); return }
    if (inst == "OVER")     { op_over(); return } # copy second item to top of stack
    if (inst == "SWAP")     { op_swap(); return } # swap top two stack items
    if (inst == "+")        { op_add(); return }
    if (inst == "AND")      { op_and(); return }
    if (inst == "XOR")      { op_xor(); return }
    if (inst == "NOT")      { op_not(); return }
    if (inst == "2*")       { op_2times(); return } # multiply-step
    if (inst == "2/")       { op_2div(); return } # divide-step
    if (inst == "*")        { op_multiply(); return }
    if (inst == "A")        { op_a(); return } # push A register
    if (inst == "A!")       { op_astore(); return } # store A register
    if (inst == "B!")       { op_bstore(); return } # store B register
    if (inst == "@")        { op_fetch(); return } # fetch from memory
    if (inst == "!")        { op_store(); return } # store to memory
    if (inst == "@+")       { op_fetchplus(); return } # fetch from memory at P+
    if (inst == "!+")       { op_storeplus(); return } # store to memory at P+
    if (inst == "@B")       { op_fetchb(); return } # fetch from memory at B
    if (inst == "!B")       { op_storeb(); return } # store to memory at B
    if (inst == "@P")       { op_fetchp(); return } # fetch from memory at P
    if (inst == "!P")       { op_storep(); return } # store to memory at P
    if (inst == ".")        { return }  # NO-OP
    if (inst == "SHOW")     { print_state(); return } # show state info
    
    print "Unknown instruction: " inst > "/dev/stderr"
    exit 1
}

# Main execution loop
{
    # Remove comments (everything after #)
    sub(/#.*$/, "")
    
    # Skip empty lines after comment removal
    if (NF == 0) next
    
    # Split the input line into words
    n = split($0, words)
    for (i = 1; i <= n; i++) {
        execute_instruction(words[i])
    }
}