All pastes #949811 Raw Edit

Miscellany

public text v1 · immutable
·published 2008-03-20 01:54 UTC
rendered paste body
(define *codefile*
  (open-input-file
   (vector-ref (current-command-line-arguments) 0)
   'binary))
(define *stack* '())

(require (lib "defmacro.ss"))

(define-macro make-handler
  (lambda (func arglist . body)
    `(let (,@(do ((args arglist (cdr args))
                  (lets '() (cons (list (car args) (list func)) lets)))
                 ((null? args) lets)))
       ,@body)))

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

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

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

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

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

; 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))
  
  (case opcode
    ((0) (set! done #t))
    ((1) (make-handler safe-read-op (x)
                       (push x)))
    ((2) (make-handler pop (x y)
                       (push (+ x y))
                       (display (format "~A + ~A " x y))))
    ((3) (make-handler peek (x)
                       (display (format "~A" x))
                       (newline)))
    ((4) (make-handler pop (x y)
                       (push (- x y))
                       (display (format "~A - ~A " x y))))
    ((5) (make-handler pop (x y)
                       (push (* x y))
                       (display (format "~A - ~A " x y))))
    ((6) (make-handler pop (x y)
                       (push (/ x y))
                       (display (format "~A - ~A " x y))))
    (else (error (format "Unknown opcode ~A" opcode)))))