ref: 260b588d2228f593be128e9de725822b2ffac663
parent: 1d8152b420445c36407a1c5cf95932dc43922879
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Jun 10 16:45:19 EDT 2024
multiple attributes; combine field and fieldarr
--- a/otf.rkt
+++ b/otf.rkt
@@ -47,42 +47,48 @@
(-> type? positive?)
(/ (type-bits t) 8))
-(define-struct field (type name unused)
+(define (field-unused? f)
+ (assoc 'unused (field-attrs f)))
+
+(define (field-count f)
+ (assoc 'count (field-attrs f)))
+
+(define (field-ptr f)
+ (if (field-count f) "*" ""))
+
+(define-struct field (type name attrs)
#:transparent
#:methods gen:code
[(define/generic super-c-type c-type)
(define (gen-h f)
- (list (~a (if (field-unused f) "// unused " "")
+ (list (~a (if (field-unused? f) "// unused " "")
(super-c-type (field-type f))
" "
+ (field-ptr f)
(field-name f)
";")))
(define (gen-c f)
- (list (if (field-unused f)
- (~a "if(skip_bytes(ctx, " (type-size (field-type f)) ") < 0){")- (~a "if(read_" (type-name (field-type f)) "(ctx, &v->" (field-name f) ") < 0){"))+ (define (size t)
+ (if (type? t) (type-size t) 0))
+ (define (name t)
+ (if (type? t) (type-name t) (cmplx-name t)))
+ (list (match (field-count f)
+ [#f
+ (if (field-unused? f)
+ (~a "if(skip_bytes(ctx, " (size (field-type f)) ") < 0){")+ (~a "if(read_" (name (field-type f)) "(ctx, &v->" (field-name f) ") < 0){"))]+ [count
+ (~a "if(read_array(ctx, &v->"
+ (field-name f)
+ ", read_"
+ (super-c-type (field-type f))
+ ", v->"
+ (cadr count)
+ ") < 0){")])(~a "\twerror(\"%s: %r\", \"" (field-name f) "\");")
(~a "\tgoto err;")
(~a "}")))])
-(define-struct (fieldarr field) (count)
- #:transparent
- #:methods gen:code
- [(define/generic super-c-type c-type)
- (define (gen-h a)
- (list (~a (super-c-type (field-type a)) " *" (field-name a) ";")))
- (define (gen-c a)
- (list (~a "if(read_array(ctx, &v->"
- (field-name a)
- ", read_"
- (super-c-type (field-type a))
- ", v->"
- (fieldarr-count a)
- ") < 0){")- (~a "\twerror(\"%s: %r\", \"" (field-name a) "\");")
- (~a "\tgoto err;")
- (~a "}")))])
-
(define-struct cmplx (name fields tag)
#:transparent
#:methods gen:code
@@ -135,21 +141,35 @@
(set! cmplxs (append cmplxs (list typ))))]
[(_ typ:id fields:expr) #'(mkcmplx typ fields "")]))
+(define-for-syntax fields '())
+
+(define-syntax (mkattr stx)
+ (syntax-parse stx
+ [(_ ({~literal =} vs:number ...+)) #''(= vs ...)]+ [(_ ({~literal count} n:id))+ (begin
+ (if (assoc (syntax->datum #`n) fields)
+ #''(count n)
+ (raise-syntax-error #f "no such field" stx #'n)))]
+ [(_ {~literal unused}) #''(unused #t)]))+
(define-syntax (mkfield stx)
(syntax-parse stx
- [(_ {~literal //} type:id name:id)- #'(field type
- `name
- #t)]
- [(_ type:id name:id [count:id]) #'(fieldarr type `name #f `count)]
- [(_ type:id name:id)
- #'(field type
- `name
- #f)]))
+ [(_ type:id name:id attrs ...)
+ (begin
+ (let ([f #'(field type
+ `name
+ (list (mkattr [~@ attrs]) ...))])
+ (begin
+ (set! fields (append fields (list (syntax->datum #'(name type)))))
+ f)))]))
(define-syntax (mkfields stx)
(syntax-parse stx
- [(_ x ...) #'(list (mkfield {~@ . x}) ...)]))+ [(_ x ...)
+ (begin
+ (set! fields '())
+ #'(list (mkfield [~@ . x]) ...))]))
(mktype uint8 8 u8int)
(mktype int8 8 s8int)
@@ -177,30 +197,32 @@
(mkcmplx TableRecord (mkfields {Tag tableTag} {uint32 checksum} {Offset32 offset} {uint32 length}))(mkcmplx TableDirectory
- (mkfields {uint32 sfntVersion}+ (mkfields {uint32 sfntVersion (= #x000100000 #x4f54544f)} {uint16 numTables} {uint16 searchRange} {uint16 entrySelector} {uint16 rangeShift}- {TableRecord tableRecords [numTables]}))+ {TableRecord tableRecords (count numTables)}))(mkcmplx EncodingRecord
- (mkfields {uint16 platformID} {uint16 encodingID} {Offset32 subtableOffset}))+ (mkfields {uint16 platformID (= 0 1 2 3 4)} {uint16 encodingID} {Offset32 subtableOffset}))(mkcmplx TableCmap
- (mkfields {uint16 version} {uint16 numTables} {EncodingRecord encodingRecords [numTables]})+ (mkfields {uint16 version (= 0)}+ {uint16 numTables}+ {EncodingRecord encodingRecords (count numTables)})"cmap")
(mkcmplx TableHead
- (mkfields {uint16 majorVersion}- {uint16 minorVersion}+ (mkfields {uint16 majorVersion (= 1)}+ {uint16 minorVersion (= 0)} {Fixed fontRevision} {uint32 checksumAdjustment}- {uint32 magicNumber}+ {uint32 magicNumber (= #x5f0f3cf5)} {uint16 flags} {uint16 unitsPerEm}- {// LONGDATETIME created}- {// LONGDATETIME modified}+ {LONGDATETIME created unused}+ {LONGDATETIME modified unused} {int16 xMin} {int16 yMin} {int16 xMax}@@ -207,9 +229,9 @@
{int16 yMax} {uint16 macStyle} {uint16 lowestRecPPEM}- {int16 fontDirectionHint}- {int16 indexToLocFormat}- {int16 glyphDataFormat})+ {int16 fontDirectionHint unused (= -2 -1 0 1 2)}+ {int16 indexToLocFormat (= 0 1)}+ {int16 glyphDataFormat (= 0)})"head")
(printf (format gen-h))
--
⑨