You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
beautiful-racket/beautiful-racket/br/demo/basic/expander.rkt

81 lines
2.5 KiB
Racket

#lang br
(provide #%top-interaction #%app #%datum
(rename-out [basic-module-begin #%module-begin])
(rename-out [basic-top #%top])
(all-defined-out))
(require (for-syntax racket/syntax))
(define #'(basic-module-begin PARSE-TREE ...)
#'(#%module-begin
(println (quote PARSE-TREE ...))
PARSE-TREE ...))
; #%app and #%datum have to be present to make #%top work
(define #'(basic-top . id)
#'(begin
(displayln (format "got unbound identifier: ~a" 'id))
(procedure-rename (λ xs (cons 'id xs)) (format-datum "undefined:~a" 'id))))
(define #'(basic-program CR-LINE ...)
#'(begin CR-LINE ...))
(define (basic-run . lines)
(define program-lines (list->vector lines))
(void (for/fold ([line-idx 0])
([i (in-naturals)]
#:break (= line-idx (vector-length program-lines)))
(match-define (cons line-number proc)
(vector-ref program-lines line-idx))
(define maybe-jump-number (and proc (proc)))
(if (number? maybe-jump-number)
(let ([jump-number maybe-jump-number])
(for/or ([idx (in-range (vector-length program-lines))])
(and (= (car (vector-ref program-lines idx)) jump-number)
idx)))
(add1 line-idx)))))
(define-cases #'cr-line ; erases "cr"s
[#'(_ "cr" LINE) #'LINE]
[#'(_ "cr") #'(begin)])
(define #'(line NUMBER STATEMENT ...)
#'(begin STATEMENT ...))
(define-cases #'statement
[#'(statement ID "=" EXPR) (if (identifier-binding #'ID)
#'(set! ID EXPR)
#'(define ID EXPR))]
[#'(statement PROC ARG ...) #'(PROC ARG ...)])
(define-cases #'value
[#'(value "(" EXPR ")") #'EXPR]
[#'(value ID "(" ARG ... ")") #'(ID ARG ...)]
[#'(value DATUM) #'DATUM])
(define #'(expr EXPR) #'EXPR)
(define-cases sum
[(_ term op sum) (op term sum)]
[(_ term) term])
(provide - +)
(define-cases product
[(_ factor op product) (op factor product)]
[(_ factor) factor])
(provide * /)
(define print-list list)
(define (PRINT args)
(match args
[(list) (displayln "")]
[(list items ... ";" pl) (begin (for-each display items) (PRINT pl))]
[(list items ... ";") (for-each display items)]
[(list items ...) (for-each displayln items)]))
(define (TAB num) (make-string num #\space))
(define (INT num) (inexact->exact (round num)))
(define (SIN num) (sin num))
(define (comment . args) void)