创建后缀数字球拍

Jos*_*ant 3 numbers racket

我正在尝试在Racket中尝试我能做什么,我想用字母后缀数字.

对于这个例子,我只想代表10000as 10K1000000as 1M.

有没有办法(用宏或其他方式)我可以扩展1M到:

(* 1 1000000)
Run Code Online (Sandbox Code Playgroud)

或者那种效果?

Ale*_*uth 5

在球拍之类的东西10K标识符,它通常会引用变量.有两种方法可以将它们变成数字:

1:重新定义"未定义"标识符的含义

您可以通过定义#%top宏来重新定义对未定义标识符的操作.

#lang racket
(require syntax/parse/define
         (only-in racket [#%top old-#%top]))

(define-syntax-parser #%top
  [(_ . x:id)
   #:when (id-has-a-k-at-the-end? #'x)
   (transform-id-into-number #'x)]
  [(_ . x)
   #'(old-#%top . x)])
Run Code Online (Sandbox Code Playgroud)

但是,这有一个微妙的问题.如果你的程序中有任何带有K的标识符或变量,它们可以覆盖那些以这种方式写入的数字.你需要注意不要意外地覆盖一些想要成为数字的东西.

2:进行读者扩展,将其转换为数字而不是标识符

这将花费更多的时间,但它更接近"正确的方式"来做到这一点,因为它避免了变量恰好在最后有K的冲突.

扩展阅读器的一种更简单的方法是可读.你可以创建一个扩展readtable的函数,如下所示:

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
  ;; Char InputPort Any Nat Nat Nat -> Any
  (define (rt-proc char in src ln col pos)
    ....)
  ...
  (make-readtable orig-rt
    #f 'non-terminating-macro rt-proc
    ...))
Run Code Online (Sandbox Code Playgroud)

要使用它来定义#lang语言,您需要将阅读器实现放入your-language/lang/reader.rkt.这就是目录作为单一集合包安装的number-with-k/lang/reader.rkt地方number-with-k(raco pkg install path/to/number-with-k).

数与-K /郎/ reader.rkt

#lang racket

(provide (rename-out [-read read]
                     [-read-syntax read-syntax]
                     [-get-info get-info]))

(require syntax/readerr
         syntax/module-reader)

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
  ;; Char InputPort Any Nat Nat Nat -> Any
  (define (rt-proc char in src ln col pos)
    ....)
  ...
  (make-readtable orig-rt
    #f 'non-terminating-macro rt-proc))

;; [X ... -> Y] -> [X ... -> Y]
(define ((wrap-reader rd) . args)
  (parameterize ([current-readtable (extend-readtable (current-readtable))])
    (apply rd args)))

(define-values [-read -read-syntax -get-info]
  (make-meta-reader 'number-with-k
                    "language path"
                    lang-reader-module-paths
                    wrap-reader
                    wrap-reader
                    identity))
Run Code Online (Sandbox Code Playgroud)

主要工作是填补功能中的....漏洞extend-readtable.例如,您可以让它识别以下结尾的标识符K:

;; Readtable -> Readtable
(define (extend-readtable orig-rt)
  ;; Char InputPort Any Nat Nat Nat -> Any
  (define (rt-proc char in src ln col pos)
    (define v (read-syntax/recursive src in char orig-rt #f))
    (cond
      [(and (identifier? v) (id-has-a-k-at-the-end? v))
       (transform-id-into-number v)]
      [else
       v]))

  (make-readtable orig-rt
    #f 'non-terminating-macro rt-proc))
Run Code Online (Sandbox Code Playgroud)

完成此操作后,您将number-with-k目录作为包安装,您应该能够#lang number-with-k像这样使用:

#lang number-with-k racket

(+ 12K 15)
; => 12015
Run Code Online (Sandbox Code Playgroud)