[ prog / sol / mona ]

prog


Post macros.

21 2020-06-04 21:21

Here's part of a Forth-like interpreter that I wrote for one of the exercises on Exercism:

(define-syntax $~
  (lambda (x)
    (syntax-case x (-> :)
      ((_ st : (var ...) -> (body ...))
       (with-syntax ((len (length (syntax->datum #'(var ...))))
                     (((name . pos) ...)
                      (map cons
                           (map (lambda (i) (datum->syntax #'i i)) (syntax->datum #'(var ...)))
                           (reverse (iota (length (syntax->datum #'(var ...)))))))
                     ((rbody ...)
                      (reverse (map (lambda (i) (datum->syntax #'i i))
                                    (syntax->datum #'(body ...))))))
         #'(let ((name (list-ref st pos))
                 ...
                 (rest (list-tail st len)))
             (append (list rbody ...) rest)))))))

(define (eval stack instr)
  (cond
   ((eq? instr '+)    ($~ stack : (a b) -> ((+ a b))))
   ((eq? instr '-)    ($~ stack : (a b) -> ((- a b))))
   ((eq? instr '*)    ($~ stack : (a b) -> ((* a b))))
   ((eq? instr '/)    ($~ stack : (a b) -> ((truncate (/ a b)))))
   ((eq? instr 'dup)  ($~ stack :   (a) -> (a a)))
   ((eq? instr 'drop) ($~ stack :   (a) -> ()))
   ((eq? instr 'swap) ($~ stack : (a b) -> (b a)))
   ((eq? instr 'over) ($~ stack : (a b) -> (a b a)))
   ((number? instr) (cons instr stack))
   (else (error 'forth "unknown operation"))))
40


VIP:

do not edit these