initial interfaces
This commit is contained in:
parent
0fbc60484d
commit
754bffbe79
55
remix/data0.rkt
Normal file
55
remix/data0.rkt
Normal file
|
@ -0,0 +1,55 @@
|
|||
#lang racket/base
|
||||
(require (for-syntax
|
||||
racket/base
|
||||
syntax/parse
|
||||
racket/syntax
|
||||
(prefix-in remix: remix/stx0)
|
||||
remix/stx/singleton-struct0
|
||||
(for-syntax racket/base
|
||||
syntax/parse))
|
||||
(prefix-in remix: remix/stx0))
|
||||
|
||||
(begin-for-syntax
|
||||
(define-syntax (static-interface stx)
|
||||
(syntax-parse stx
|
||||
#:literals (remix:#%brackets)
|
||||
[(_si (remix:#%brackets lhs:id rhs:id) ...)
|
||||
(with-syntax ([int-name (syntax-local-name)])
|
||||
(syntax/loc stx
|
||||
(let ()
|
||||
(define int-id->orig-id
|
||||
(make-immutable-hasheq
|
||||
(list (cons 'lhs #'rhs)
|
||||
...)))
|
||||
(define available-ids
|
||||
(sort (hash-keys int-id->orig-id)
|
||||
string<=?
|
||||
#:key symbol->string))
|
||||
(define (get-binding stx x)
|
||||
(define xv (syntax->datum x))
|
||||
(hash-ref int-id->orig-id
|
||||
xv
|
||||
(λ ()
|
||||
(raise-syntax-error
|
||||
'int-name
|
||||
(format "Unknown component ~v, expected one of ~v"
|
||||
xv
|
||||
available-ids)
|
||||
stx
|
||||
x))))
|
||||
(singleton-struct
|
||||
#:property prop:procedure
|
||||
(λ (_ stx)
|
||||
(raise-syntax-error 'int-name "Illegal in expression context" stx))
|
||||
#:methods remix:gen:dot-transformer
|
||||
[(define (dot-transform _ stx)
|
||||
(syntax-parse stx
|
||||
[(_dot me:id x:id)
|
||||
(get-binding stx #'x)]
|
||||
[(_dot me:id x:id . more:expr)
|
||||
(with-syntax ([xb (get-binding stx #'x)])
|
||||
(syntax/loc stx
|
||||
(let-syntax ([x (make-rename-transformer #'xb)])
|
||||
(remix:#%dot x . more))))]))]))))])))
|
||||
|
||||
(provide (for-syntax static-interface))
|
|
@ -293,6 +293,7 @@
|
|||
[remix-cond cond]
|
||||
[remix-cut-$ $])
|
||||
#%rest
|
||||
(rename-out [remix-block block])
|
||||
#%brackets
|
||||
#%braces
|
||||
(for-syntax gen:binary-operator
|
||||
|
|
|
@ -35,6 +35,14 @@
|
|||
(module+ test
|
||||
{(f x x) ≡ 126})
|
||||
|
||||
;; That's the same as just 'block' if you want to be specific
|
||||
(def (other-f x y)
|
||||
(+ (block (def z (+ x x))
|
||||
z)
|
||||
y))
|
||||
(module+ test
|
||||
{(other-f x x) ≡ 126})
|
||||
|
||||
;; cond requires []s for the question-answer pairs. It uses this to
|
||||
;; make any code in between clauses go in between the `if`s that pop
|
||||
;; out of the cond macro. finally, cond REQUIRES a #:else clause.
|
||||
|
@ -210,3 +218,31 @@
|
|||
(f y x …))
|
||||
(module+ test
|
||||
{(flipper - 5 9 0) ≡ (- 0 5 9)})
|
||||
|
||||
;; data gives us data structures and that sort of thing
|
||||
(require remix/data0)
|
||||
|
||||
;; First, we can define static interfaces, which associate dot-terms
|
||||
;; with particular functions.
|
||||
(def (example-f x y) x)
|
||||
(def (example-g x y) y)
|
||||
(def [stx example^]
|
||||
(static-interface
|
||||
[f example-f]
|
||||
[g example-g]))
|
||||
(module+ test
|
||||
{(example^.f 1 2) ≡ 1}
|
||||
{(example^.g 1 2) ≡ 2})
|
||||
|
||||
;; These static interfaces allow nesting
|
||||
(def example2-h 19)
|
||||
(def [stx example2^]
|
||||
(static-interface
|
||||
[fg example^]
|
||||
[h example2-h]))
|
||||
(module+ test
|
||||
{(example2^.fg.f 1 2) ≡ 1}
|
||||
{(example2^.fg.g 1 2) ≡ 2}
|
||||
{example2^.h ≡ 19})
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user