All pastes #955815 Raw Edit

Someone

public text v1 · immutable
#955815 ·published 2008-03-24 21:29 UTC
rendered paste body
#!/usr/bin/mzscheme -r

(define *codefile*
  (open-input-file
   (vector-ref (current-command-line-arguments) 0)
   'binary))

(define *stack* '())

(define *handlers* (make-vector 256 #f))

(define (push x)
    (set! *stack* (cons x *stack*)))

(define (pop)
    (if (null? (car *stack*))
        (error "Attempt to pop from empty stack")
        (let ((x (car *stack*)))
          (set! *stack* (cdr *stack*))
          x)))

(define (peek)
    (let ((x (car *stack*)))
      (if (null? x)
          (error "Attempt to peek on empty stack")
          x)))

(define (read-op)
    (read-byte *codefile*))

(define (safe-read-op)
    (let ((op (read-op)))
      (if (eof-object? op)
          (error "EOF while reading from file")
          op)))

(define-syntax define-instruction
  (syntax-rules ()
    ((define-instruction op (name) (handler ...) ...)
     (begin
       (define (name)
         (handler ...) ...)
       (set-handler op name)))
    ((define-instruction op (name args ...) formhandler (handler ...) ...)
     (begin
       (define (name)
         (apply (lambda (args ...) (handler ...) ...) (formhandler)))
       (set-handler op name)))))

(define (call-handler op)
  (let ((handler (vector-ref *handlers* op)))
    (if (not handler)
        (error "Unknown opcode")
        (handler))))

(define (set-handler op name)
  (vector-set! *handlers* op name))

(define-syntax arithmetic
  (syntax-rules ()
    ((arithmetic operator)
     (push (operator (pop) (pop))))))

(define (push_form)
  (list (safe-read-op)))

(define-instruction 0 (quit_h)
  (error "DONE!"))

(define-instruction 1 (push_h x) push_form
  (push x))

(define-instruction 2 (add_h)
  (arithmetic +))

(define-instruction 3 (print_h)
  (display (format "~A" (peek)))
  (newline))

(define-instruction 4 (sub_h)
  (arithmetic -))

(define-instruction 5 (mul_h)
  (arithmetic *))

(define-instruction 6 (div_h)
  (arithmetic /))

; Opcodes:
; 0x1 - Push
; 0x2 - Add
; 0x3 - Print
; 0x4 - Sub
; 0x5 - Mul
; 0x6 - Div
(do ((opcode (read-op) (read-op))
     (done #f))
    ((or (eof-object? opcode) done))
  (call-handler opcode))