Skip to content

Commit

Permalink
json: do more at expand time in json:write-object
Browse files Browse the repository at this point in the history
  • Loading branch information
owaddell-beckman committed Jan 24, 2024
1 parent cf08229 commit 194045b
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 12 deletions.
52 changes: 52 additions & 0 deletions src/swish/json.ms
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,58 @@
[foo "tstep"]
[ace "rbic"])
(get))]
[(,@by-write ,@by-write ,@by-write ,@by-write ,@by-write)
;; hit difference cases where we pre-compute all or part of a field write
;; at expand-time; ideally cp0 would take it further from here
(let ()
(define (go1 x)
(json:write-object op #f json:write
[bar "rel"]
[foo "tstep"]
[ace x])
(get))
(define (go2 x)
(json:write-object op #f json:write
[bar "rel"]
[foo x]
[ace "rbic"])
(get))
(define (go3 x)
(json:write-object op #f json:write
[bar x]
[foo "tstep"]
[ace "rbic"])
(get))
(define (go4 x y)
(json:write-object op #f json:write
[bar x]
[foo "tstep"]
[ace y])
(get))
(define (go5 x y z)
(json:write-object op #f json:write
[bar x]
[foo z]
[ace y])
(get))
(list (go1 "rbic") (go2 "tstep") (go3 "rel")
(go4 "rel" "rbic")
(go5 "rel" "rbic" "tstep")))]
["{\"pi\":3.14,\"zip\":null}"
(begin
(json:write-object op #f json:write
[pi 3.14]
[zip #\nul])
(get))]
[,fail
(guard (procedure? fail))
(lambda ()
;; no error at expand time
(json:write-object op #f json:write
[abc 123456]
[bad +nan.0])
(get))]
[`(catch #(invalid-datum +nan.0)) (on-exit (get) (try (fail)))]
[,write-field-value
(lambda (op v indent wr)
(if (vector? v)
Expand Down
49 changes: 37 additions & 12 deletions src/swish/json.ss
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@
(display key op)
(json:write-structural-char #\: indent op))]
[else
(display whole op)
(display-string whole op)
#f]))

(define-syntax json-write-kv
Expand All @@ -620,15 +620,30 @@
(let-values ([(op get) (open-string-output-port)])
(write-string (json-key->string k) op)
(get)))
(define (format-value wr val)
(and (free-identifier=? wr #'json:write)
;; this should be a subset of the cases before custom-write call
;; in (W define (wr x) ...) above.
(or (boolean? val) (fixnum? val) (string? val)
(and (flonum? val) (finite? val))
(eqv? val #\nul))
(eval `(let () (import (swish json)) (json:object->string ,val)))))
(lambda (x)
(syntax-case x ()
[(_ op indent wr prefix k v #f)
[(_ op #f wr prefix k v #f)
(let ([pfx (get-preamble (datum prefix) (datum k))]
[val (format-value #'wr (datum v))])
;; someday cp0 might consolidate adjacent display-string calls
(if val
#`(begin (display-string #,(string-append pfx val) op) #f)
#`(begin (display-string #,pfx op) (wr op v #f) #f)))]
[(_ op indent-expr wr prefix k v #f)
(with-syntax ([whole (get-preamble (datum prefix) (datum k))]
[key (get-key (datum k))])
#'(let ([indent (write-key indent prefix key whole op)])
#'(let ([indent (write-key indent-expr prefix key whole op)])
(wr op v indent)
indent))]
[(_ op indent wr prefix k v-expr wfv-expr)
[(_ op indent-expr wr prefix k v-expr wfv-expr)
(with-syntax ([whole (get-preamble (datum prefix) (datum k))]
[key (get-key (datum k))])
#'(let* ([write-field-value wfv-expr] [v v-expr]
Expand Down Expand Up @@ -678,14 +693,24 @@
(valid? (datum (key ...)))
(with-syntax ([([k0 f0 wfv0] [k1 f1 wfv1] ...)
(maybe-sort (map parse-clause #'([key . spec] ...)))])
#'(let ([op op-expr] [indent indent-expr] [wr wr-expr])
(let ([indent (json-write-kv op indent wr #\{ k0 f0 wfv0)])
(json-write-kv op indent wr #\, k1 f1 wfv1)
...
(json:write-structural-char #\} indent op))
(when (eqv? indent 0)
(newline op))
#t))]))
(if (and (eq? (datum indent-expr) #f)
(identifier? #'wr-expr)
(free-identifier=? #'wr-expr #'json:write))
#'(let ([op op-expr])
;; see cp0 note above
(json-write-kv op #f json:write #\{ k0 f0 wfv0)
(json-write-kv op #f json:write #\, k1 f1 wfv1)
...
(json:write-structural-char #\} #f op)
#t)
#'(let ([op op-expr] [indent indent-expr] [wr wr-expr])
(let ([indent (json-write-kv op indent wr #\{ k0 f0 wfv0)])
(json-write-kv op indent wr #\, k1 f1 wfv1)
...
(json:write-structural-char #\} indent op))
(when (eqv? indent 0)
(newline op))
#t)))]))

(define json:pretty
(case-lambda
Expand Down

0 comments on commit 194045b

Please sign in to comment.