#lang planet dyoo/whalesong (require "semantics.rkt" (for-syntax racket/base)) (provide greater-than less-than plus minus period comma brackets (rename-out [my-module-begin #%module-begin])) ;; Every module in this language will make sure that it ;; uses a fresh state. We create one, and then within ;; the lexical context of a my-module-begin, all the ;; other forms will refer to current-state. (define-syntax (my-module-begin stx) (syntax-case stx () [(_ body ...) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (syntax/loc stx (#%plain-module-begin (define-values (current-data current-ptr) (new-state)) (define (run) (begin body ... (void))) (run))))])) ;; In order to produce good runtime error messages ;; for greater-than and less-than, we latch onto ;; the syntax object for dear life, since it has ;; information about where it came from in the ;; source syntax. ;; ;; The #'#,stx nonsense below allows us to pass the ;; syntax object. The semantics can then raise an ;; appropriate syntactic error with raise-syntax-error ;; if it sees anything bad happen at runtime. (define-syntax (greater-than stx) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (syntax-case stx () [(_) (quasisyntax/loc stx (increment-ptr current-data current-ptr (srcloc '#,(syntax-source stx) '#,(syntax-line stx) '#,(syntax-column stx) '#,(syntax-position stx) '#,(syntax-span stx))))]))) (define-syntax (less-than stx) (syntax-case stx () [(_) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (quasisyntax/loc stx (decrement-ptr current-data current-ptr (srcloc '#,(syntax-source stx) '#,(syntax-line stx) '#,(syntax-column stx) '#,(syntax-position stx) '#,(syntax-span stx)))))])) (define-syntax (plus stx) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (syntax/loc stx (increment-byte current-data current-ptr)))) (define-syntax (minus stx) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (syntax/loc stx (decrement-byte current-data current-ptr)))) (define-syntax (period stx) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (syntax/loc stx (write-byte-to-stdout current-data current-ptr)))) (define-syntax (comma stx) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (syntax/loc stx (read-byte-from-stdin current-data current-ptr)))) (define-syntax (brackets stx) (syntax-case stx () [(_ body ...) (with-syntax ([current-data (datum->syntax stx 'current-data)] [current-ptr (datum->syntax stx 'current-ptr)]) (syntax/loc stx (loop current-data current-ptr body ...)))]))