Work on layout... almost there
This commit is contained in:
parent
9019652c6f
commit
b1de40ebfe
|
@ -8,8 +8,11 @@
|
|||
(prefix-in remix: remix/stx0)
|
||||
remix/stx/singleton-struct0
|
||||
(for-syntax racket/base
|
||||
racket/syntax
|
||||
syntax/parse
|
||||
(prefix-in remix: remix/stx0)))
|
||||
racket/unsafe/ops
|
||||
racket/performance-hint
|
||||
(prefix-in remix: remix/stx0))
|
||||
|
||||
(begin-for-syntax
|
||||
|
@ -34,7 +37,11 @@
|
|||
(~optional
|
||||
(~seq #:is rhs-dt:id)
|
||||
#:defaults ([rhs-dt #'#f])))
|
||||
...)
|
||||
...
|
||||
(~optional
|
||||
(~seq #:extensions
|
||||
extension ...)
|
||||
#:defaults ([[extension 1] '()])))
|
||||
(with-syntax ([int-name (syntax-local-name)]
|
||||
[(def-rhs ...) (generate-temporaries #'(rhs ...))])
|
||||
(syntax/loc stx
|
||||
|
@ -75,9 +82,8 @@
|
|||
(if xd #'xb #'(make-rename-transformer #'xb))])
|
||||
(quasisyntax/loc stx
|
||||
(remix:def (remix:#%brackets x-def #,x-stx) x-def-v))))
|
||||
;; XXX add the ability to add other properties,
|
||||
;; interfaces, etc.
|
||||
(singleton-struct
|
||||
;; XXX some way to overload this with #:extensions
|
||||
#:property prop:procedure
|
||||
(λ (_ stx)
|
||||
(raise-syntax-error 'int-name "Illegal in expression context" stx))
|
||||
|
@ -120,24 +126,80 @@
|
|||
(remix:def (remix:#%brackets remix:stx i)
|
||||
(phase1:static-interface
|
||||
(remix:#%brackets lhs def-rhs)
|
||||
...)))))]))]))))])))
|
||||
...)))))]))]
|
||||
extension ...))))])))
|
||||
|
||||
(define-syntax phase0:static-interface
|
||||
(singleton-struct
|
||||
#:property prop:procedure
|
||||
(λ (_ stx)
|
||||
(raise-syntax-error 'static-interface "Illegal outside def" stx))
|
||||
#:methods remix:gen:def-transformer
|
||||
[(define (def-transform _ stx)
|
||||
(syntax-parse stx
|
||||
#:literals (remix:#%brackets)
|
||||
[(def (remix:#%brackets me:id i:id) . body:expr)
|
||||
(syntax/loc stx
|
||||
(remix:def (remix:#%brackets remix:stx i)
|
||||
(phase1:static-interface . body)))]))]))
|
||||
(define-syntax (define-phase0-def->phase1-macro stx)
|
||||
(syntax-parse stx
|
||||
[(_ base:id)
|
||||
(with-syntax ([phase0:base (format-id #'base "phase0:~a" #'base)]
|
||||
[phase1:base (format-id #'base "phase1:~a" #'base)])
|
||||
(syntax/loc stx
|
||||
(define-syntax phase0:base
|
||||
(singleton-struct
|
||||
#:property prop:procedure
|
||||
(λ (_ stx)
|
||||
(raise-syntax-error 'base "Illegal outside def" stx))
|
||||
#:methods remix:gen:def-transformer
|
||||
[(define (def-transform _ stx)
|
||||
(syntax-parse stx
|
||||
#:literals (remix:#%brackets)
|
||||
[(def (remix:#%brackets me:id i:id) . body:expr)
|
||||
(syntax/loc stx
|
||||
(remix:def (remix:#%brackets remix:stx i)
|
||||
(phase1:base . body)))]))]))))]))
|
||||
|
||||
(define-phase0-def->phase1-macro static-interface)
|
||||
|
||||
(provide (rename-out [phase0:static-interface static-interface])
|
||||
(for-syntax (rename-out [phase1:static-interface static-interface])
|
||||
gen:static-interface
|
||||
static-interface?))
|
||||
static-interface?
|
||||
static-interface-members))
|
||||
|
||||
(begin-for-syntax
|
||||
;; XXX fill this in
|
||||
(define-generics layout))
|
||||
|
||||
(define-syntax phase0:layout
|
||||
(singleton-struct
|
||||
#:property prop:procedure
|
||||
(λ (_ stx)
|
||||
(raise-syntax-error 'layout "Illegal outside def" stx))
|
||||
#:methods remix:gen:def-transformer
|
||||
[(define (def-transform _ stx)
|
||||
(syntax-parse stx
|
||||
#:literals (remix:#%brackets)
|
||||
[(def (remix:#%brackets me:id name:id)
|
||||
f:id ...)
|
||||
(with-syntax* ([name-alloc (format-id #f "~a-alloc" #'name)]
|
||||
[name-set (format-id #f "~a-set" #'name)]
|
||||
[(f-idx ...)
|
||||
(for/list ([i (in-naturals)]
|
||||
[f (in-list (syntax->list #'(f ...)))])
|
||||
i)]
|
||||
[(name-f ...)
|
||||
(generate-temporaries #'(f ...))])
|
||||
(syntax/loc stx
|
||||
(begin
|
||||
(define-syntax (name-alloc stx)
|
||||
(raise-syntax-error 'name-alloc "XXX alloc"))
|
||||
(define-syntax (name-set stx)
|
||||
(raise-syntax-error 'name-set "XXX set"))
|
||||
(begin-encourage-inline
|
||||
(define (name-f v) (unsafe-vector*-ref v f-idx))
|
||||
...)
|
||||
(define-syntax name
|
||||
(phase1:static-interface
|
||||
(remix:#%brackets #:alloc name-alloc)
|
||||
(remix:#%brackets #:set name-set)
|
||||
(remix:#%brackets #:= name-set)
|
||||
(remix:#%brackets f name-f)
|
||||
...
|
||||
#:extensions
|
||||
#:methods gen:layout
|
||||
[])))))]))]))
|
||||
|
||||
(provide (rename-out [phase0:layout layout])
|
||||
(for-syntax gen:layout
|
||||
layout?))
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
(#rocket.alloc [h h] [dh dh]))
|
||||
#:implements world/anim^
|
||||
(def (tick)
|
||||
(r.= [h {r.h + r.dh}]))
|
||||
(r.= [h {r.h + r.dh}]))
|
||||
(def (draw)
|
||||
(circle 'yellow 5)))
|
||||
|
||||
|
|
|
@ -298,6 +298,9 @@
|
|||
{(example3^.fg.g 2) ≡ 2}
|
||||
{example3^.h ≡ 19})
|
||||
|
||||
;; XXX show an example where it isn't an interface but any def
|
||||
;; transformer.
|
||||
|
||||
;; The syntax of interface members is not limited to identifiers. In
|
||||
;; particular, #:keywords are useful. Furthermore, static-interface is
|
||||
;; a def transformer itself, to clean up the syntax a little bit. I
|
||||
|
@ -311,3 +314,85 @@
|
|||
{example4^.#:key ≡ '#:key}
|
||||
{example4^.key ≡ 'key})
|
||||
|
||||
;; A layout is a container with no sealing or representation
|
||||
;; guarantees. This means you can't necessarily protect the contents
|
||||
;; nor can you necessarily tell that you have one when you do.
|
||||
|
||||
;; layout is a def-transformer (XXX I wish I could make it phase1
|
||||
;; macro also but it needs to define some functions that could be
|
||||
;; called)
|
||||
|
||||
;; The most basic syntax is a list of fields, which are identifiers.
|
||||
(def [layout posn]
|
||||
x y)
|
||||
(module+ test
|
||||
;; You will get an allocation function named #:alloc
|
||||
(def p1 (posn.#:alloc [x 5] [y 7]))
|
||||
;; And accessors
|
||||
{p1.x ≡ 5}
|
||||
{p1.y ≡ 7}
|
||||
;; You will also get a copying function (XXX: Should it be named
|
||||
;; `copy`? `update`? My analogy here is with hash-set)
|
||||
(def p2 (p1.#:set [x 8] [y {p1.y + 2}]))
|
||||
;; Notice that these built-in functions are keywords, so that they
|
||||
;; can't conflict with the fields you've defined.
|
||||
{p2.x ≡ 8}
|
||||
{p2.y ≡ 9}
|
||||
;; This is aliased to =, which I expect is nicer to use.
|
||||
(def p3 (p1.#:= [x 8] [y {p1.y + 2}]))
|
||||
{p3.x ≡ 8}
|
||||
{p3.y ≡ 9})
|
||||
|
||||
;; A layout can have a parent, which provides the guarantee that the
|
||||
;; parent's functions will work on the child. A layout has one or zero
|
||||
;; parents.
|
||||
#;
|
||||
(def [layout quat]
|
||||
#:parent posn
|
||||
z)
|
||||
|
||||
;; A layout's fields may be specified as other layouts. When the first
|
||||
;; field is a layout, this is not necessarily the same thing as a
|
||||
;; parent (like C structs) but it may be.
|
||||
#;
|
||||
(def [layout circle]
|
||||
[posn cx] r)
|
||||
|
||||
;; A layout's fields can _actually_ just be any def transformer, and
|
||||
;; thus could be static interfaces
|
||||
#;
|
||||
(def [layout weird]
|
||||
[example1^ e])
|
||||
|
||||
;; Now, the big reveal, layout has an extensible representation
|
||||
;; planner system. At the moment, the only representations are
|
||||
;;
|
||||
;; layout-immutable : The default, backed by immutable vectors
|
||||
;; layout-mutable : Backed by mutable vectors, with mutation support
|
||||
;;
|
||||
;; I expect to produce a few more
|
||||
;;
|
||||
;; (XXX) layout-c : Compatible with C
|
||||
;; (XXX) layout-optimize : Optimize for removing padding and have
|
||||
;; cache-line-aligned accesses
|
||||
;;
|
||||
;; It would be possible to make layout-c right now, but define-cstruct
|
||||
;; is really slow. It is trivial to have layout-optimize if you have
|
||||
;; layout-c, but it would not be useful to use. mflatt and I talked
|
||||
;; about a fast way of implementing them in Racket. The basic idea is
|
||||
;; to have a new type of object in the VM where the pointer goes to
|
||||
;; the middle of the allocated space which looks like
|
||||
;;
|
||||
;; [ <raw-values> | <tag> <vector layout> ]
|
||||
;;
|
||||
;; There may be necessary padding, but then the existing vector
|
||||
;; functions would work. The raw values would use computed offsets to
|
||||
;; get the values. The goal would be that parent structs would just
|
||||
;; work and it would be easy to pass to C by sorting the _racket
|
||||
;; pointers to the end.
|
||||
;;
|
||||
;; Anyways, here's a mutable example.
|
||||
#;
|
||||
(def [layout world]
|
||||
#:rep layout-mutable
|
||||
[circle c1] [circle c2])
|
||||
|
|
Loading…
Reference in New Issue
Block a user