#lang br (require racket/stxparam) (provide (all-defined-out) #%app #%top #%datum #%top-interaction) (define-macro top #'#%module-begin) (define-macro-cases ternary [(_ EXPR) #'EXPR] [(_ COND TRUE-EXPR FALSE-EXPR) #'(if COND TRUE-EXPR FALSE-EXPR)]) (define-macro-cases logical-or [(_ VAL) #'VAL] [(_ L "||" R) #'(or L R)]) (define-macro-cases logical-and [(_ VAL) #'VAL] [(_ L "&&" R) #'(and L R)]) (define-macro (my-app ID ARG ...) #'(error 'boom)) (define-macro-cases var [(_ ID VAL) #'(define ID VAL)] [(_ ID ... VAL) #'(begin (define ID VAL) ...)]) (define (add/concat . xs) (cond [(andmap number? xs) (let ([sum (apply + xs)]) (if (and (integer? sum) (inexact? sum)) (inexact->exact sum) sum))] [(ormap string? xs) (string-join (map ~a xs) "")])) (define-macro-cases add-or-sub [(_ LEFT "+" RIGHT) #'(add/concat LEFT RIGHT)] [(_ LEFT "-" RIGHT) #'(- LEFT RIGHT)] [(_ OTHER) #'OTHER]) (define-macro-cases mult-or-div [(_ LEFT "*" RIGHT) #'(* LEFT RIGHT)] [(_ LEFT "/" RIGHT) #'(/ LEFT RIGHT)] [(_ OTHER) #'OTHER]) (define-macro (object (K V) ...) #'(make-hash (list (cons K V) ...))) (define-syntax-parameter return (λ (stx) (error 'not-parameterized))) (define-macro (fun (ARG ...) STMT ...) (syntax/loc caller-stx (λ (ARG ...) (let/cc return-cc (syntax-parameterize ([return (make-rename-transformer #'return-cc)]) (void) STMT ...))))) (define-macro (defun ID (ARG ...) STMT ...) #'(define ID (fun (ARG ...) STMT ...))) (define (resolve-deref base . keys) (for/fold ([val base]) ([key (in-list keys)]) (cond [(and (hash? val) (cond [(hash-ref val key #f)] [(hash-ref val (symbol->string key) #f)] [else #f]))] [else (error 'deref-failure)]))) (define-macro (deref (BASE KEY ...)) #'(resolve-deref BASE 'KEY ...)) (define-macro app #'#%app) (define-macro-cases if-else [(_ COND TSTMT ... "else" FSTMT ...) #'(cond [COND TSTMT ...] [else FSTMT ...])] [(_ COND STMT ...) #'(when COND STMT ...)]) (define-macro-cases equal-or-not [(_ VAL) #'VAL] [(_ L "==" R) #'(equal? L R)] [(_ L "!=" R) #'(not (equal? L R))]) (define-macro-cases gt-or-lt [(_ VAL) #'VAL] [(_ L "<" R) #'(< L R)] [(_ L "<=" R) #'(<= L R)] [(_ L ">" R) #'(> L R)] [(_ L ">=" R) #'(>= L R)]) (define-macro (while COND STMT ...) #'(let loop () (when COND STMT ... (loop)))) (define (alert x) (displayln (format "ALERT! ~a" x))) #;(require racket/gui) #;(define (alert text) (define dialog (instantiate dialog% ("Alert"))) (new message% [parent dialog] [label text]) (define panel (new horizontal-panel% [parent dialog] [alignment '(center center)])) (new button% [parent panel] [label "Ok"] [callback (lambda (button event) (send dialog show #f))]) (send dialog show #t)) (define-macro-cases increment [(_ ID) #'ID] [(_ "++" ID) #'(let () (set! ID (add1 ID)) ID)] [(_ "--" ID) #'(let () (set! ID (sub1 ID)) ID)] [(_ ID "++") #'(begin0 ID (set! ID (add1 ID)))] [(_ ID "--") #'(begin0 ID (set! ID (sub1 ID)))]) (define-macro-cases reassignment [(_ ID) #'ID] [(_ ID "+=" EXPR) #'(let () (set! ID (+ ID EXPR)) ID)] [(_ ID "-=" EXPR) #'(let () (set! ID (- ID EXPR)) ID)])