LINUX.ORG.RU

История изменений

Исправление monk, (текущая версия) :

А если предположить вариант с reader-macro, то мне не совсем ясно, как его включать в Racket.

Вот сделал

(define parse-sharp-dot
  (case-lambda
    [(ch port)
     ; ‘read' mode
     (eval (read/recursive port #f))]
    [(ch port src line col pos)
     ; ‘read-syntax' mode
     (datum->syntax
      #f
      (eval (read-syntax/recursive src port #f))
      (let-values ([(l c p) (port-next-location port)])
        (list src line col pos (and pos (- p pos)))))]))

(define sharp-dot
  (make-readtable (current-readtable)
                  #\. 'dispatch-macro parse-sharp-dot))

В REPL даже работает:

> (current-readtable sharp-dot)
> (define x 2)
> (define (test)
    (case 3 [(#.(+ x 1)) 'ok] [else 'fail]))
> (test)
'ok

А вот если эти же 4 строки ввести просто в программу, то ругается, что #. не определён.

Если даже вынести readtabl отдельный файл и добавить read и read-syntax для определения lang:

  (provide (rename-out [inner-read read] 
                       [inner-read-syntax read-syntax]))

  (define (inner-read ch port)
    (parameterize ([current-readtable sharp-dot])
      (read ch port)))
  
  (define (inner-read-syntax ch port)
    (parameterize ([current-readtable sharp-dot])
      (read-syntax ch port)))

Всё равно не работает

#lang racket
(define x 2)
#reader"reader.rkt" 
(define (test)
  (case 3 [(#.(+ x 1)) 'ok] [else 'fail]))

;; => test-reader.rkt:5:15: +: unbound identifier; also, no #%app syntax transformer is bound at: + in: (+ x 1)

Исходная версия monk, :

А если предположить вариант с reader-macro, то мне не совсем ясно, как его включать в Racket.

Вот сделал

(define parse-sharp-dot
  (case-lambda
    [(ch port)
     ; ‘read' mode
     (eval (read/recursive port #f))]
    [(ch port src line col pos)
     ; ‘read-syntax' mode
     (datum->syntax
      #f
      (eval (read-syntax/recursive src port #f))
      (let-values ([(l c p) (port-next-location port)])
        (list src line col pos (and pos (- p pos)))))]))

(define sharp-dot
  (make-readtable (current-readtable)
                  #\. 'dispatch-macro parse-sharp-dot))

В REPL даже работает:

=lisp]
> (current-readtable sharp-dot)
> (define x 2)
> (define (test)
    (case 3 [(#.(+ x 1)) 'ok] [else 'fail]))
> (test)
'ok

А вот если эти же 4 строки ввести просто в программу, то ругается, что #. не определён.

Если даже вынести readtabl отдельный файл и добавить read и read-syntax для определения lang:

  (provide (rename-out [inner-read read] 
                       [inner-read-syntax read-syntax]))

  (define (inner-read ch port)
    (parameterize ([current-readtable sharp-dot])
      (read ch port)))
  
  (define (inner-read-syntax ch port)
    (parameterize ([current-readtable sharp-dot])
      (read-syntax ch port)))

Всё равно не работает

#lang racket
(define x 2)
#reader"reader.rkt" 
(define (test)
  (case 3 [(#.(+ x 1)) 'ok] [else 'fail]))

;; => test-reader.rkt:5:15: +: unbound identifier; also, no #%app syntax transformer is bound at: + in: (+ x 1)