@@ -57,33 +57,6 @@ Rebol [
57
57
;-----------------------------------------------------------
58
58
;-- Generic support funcs
59
59
60
- BOM: [
61
- UTF-8 #{ EFBBBF }
62
- UTF-16-BE #{ FEFF }
63
- UTF-16-LE #{ FFFE }
64
- UTF-32-BE #{ 0000FEFF }
65
- UTF-32-LE #{ FFFE0000 }
66
- ]
67
-
68
- BOM-UTF-16? : func [ data [string! binary! ]] [
69
- any [find/match/tail data BOM/UTF-16-BE find/match/tail data BOM/UTF-16-LE ]
70
- ]
71
-
72
- BOM-UTF-32? : func [ data [string! binary! ]] [
73
- any [find/match/tail data BOM/UTF-32-BE find/match/tail data BOM/UTF-32-LE ]
74
- ]
75
-
76
-
77
- ; MOLD adds quotes string!, but not all any-string! values.
78
- enquote : func [ str [string! ] "(modified)" ] [append insert str {"} {"} ]
79
-
80
- high-surrogate? : func [ codepoint [integer! ]] [
81
- all [codepoint >= 55296 codepoint <= 56319 ] ;D800h DBFFh
82
- ]
83
-
84
- low-surrogate? : func [ codepoint [integer! ]] [
85
- all [codepoint >= 56320 codepoint <= 57343 ] ;DC00h DFFFh
86
- ]
87
60
88
61
translit : func [
89
62
"Transliterate sub-strings in a string"
@@ -106,8 +79,8 @@ translit: func [
106
79
107
80
;TBD: I think this can be improved. --Gregg
108
81
109
- json-to-red -escape-table: [
110
- ; JSON Red
82
+ json-to-rebol -escape-table: [
83
+ ; JSON Rebol
111
84
{\"} "^" "
112
85
{\\} "\"
113
86
{\/} "/"
@@ -117,46 +90,46 @@ json-to-red-escape-table: [
117
90
{\r} "^M "
118
91
{\t} "^- "
119
92
]
120
- red -to-json-escape-table: reverse copy json-to-red -escape-table
93
+ rebol -to-json-escape-table: reverse copy json-to-rebol -escape-table
121
94
122
- json -esc-ch: charset {"t\/nrbf} ; Backslash escaped JSON chars
123
- json-escaped: [ #"\" json-esc-ch] ; Backslash escape rule
124
- red-esc-ch: charset { ^"^- \/ ^/^M^H^L } ; Red chars requiring JSON backslash escapes
95
+ rebol -esc-ch: charset {^"^- \/ ^/^M^H^L } ; Rebol chars requiring JSON backslash escapes
96
+ json-esc-ch: charset {"t\/nrbf} ; Backslash escaped JSON chars
97
+ json-escaped: [ #"\" json-esc-ch] ; Backslash escape rule
125
98
126
99
decode-backslash-escapes : func [ string [string! ] "(modified)" ] [
127
- translit string json-escaped json-to-red -escape-table
100
+ translit string json-escaped json-to-rebol -escape-table
128
101
]
129
102
130
103
encode-backslash-escapes : func [ string [string! ] "(modified)" ] [
131
- translit string red -esc-ch red -to-json-escape-table
104
+ translit string rebol -esc-ch rebol -to-json-escape-table
132
105
]
133
106
134
- ctrl-char: charset [#"^@" - #"^_" ] ; Control chars 0-31
135
107
;-----------------------------------------------------------
136
- ;-- JSON decoder
108
+ ;-- JSON decoder
137
109
;-----------------------------------------------------------
138
110
139
111
;# Basic rules
140
- ws: charset " ^-^/^M " ; Whitespace
112
+ hex-char: system/catalog/bitsets/hex-digits
113
+ digit: system/catalog/bitsets/numeric
114
+ ws: system/catalog/bitsets/whitespace
141
115
ws*: [any ws]
142
116
ws+: [some ws]
143
- sep: [ws* #"," ws*] ; JSON value separator
144
- digit: charset "0123456789"
145
- non-zero-digit: charset "123456789"
146
- hex-char: charset "0123456789ABCDEFabcdef"
147
- chars: charset [not {\"} #"^@" - #"^_" ] ; Unescaped chars (NOT creates a virtual bitset)
117
+ sep: [ws* #"," ws*] ; JSON value separator
118
+ non-zero-digit: #[bitset! #{ 0000000000007FC0 } ] ;= charset "123456789"
119
+ ; Unescaped chars (NOT creates a virtual bitset)
120
+ chars: #[bitset! [not bits #{ FFFFFFFF2000000000000008 } ]] ;=charset [not {\"} #"^@"-#"^_"]
148
121
149
- ; chars allowed in Red word! values - note that we don't allow < and > at all even though they are somewhat valid in word!
122
+ ; chars allowed in Rebol word! values - note that we don't allow < and > at all even though they are somewhat valid in word!
150
123
not-word-char: charset {/\^^ ,[](){} "#%$@:;^/^(00A0) ^-^M <>}
151
- word-1st: complement append union not-word-char digit #"'"
124
+ word-1st: complement append union not-word-char digit #"'"
152
125
word-char: complement not-word-char
153
126
154
127
;-----------------------------------------------------------
155
- ;-- JSON value rules
128
+ ;-- JSON value rules
156
129
;-----------------------------------------------------------
157
130
158
131
;-----------------------------------------------------------
159
- ;-- Number
132
+ ;-- Number
160
133
sign: [#"-" ]
161
134
; Integers can't have leading zeros, but zero by itself is valid.
162
135
int: [[non-zero-digit any digit] | digit]
@@ -166,12 +139,12 @@ number: [opt sign int opt frac opt exp]
166
139
numeric-literal: :number
167
140
168
141
;-----------------------------------------------------------
169
- ;-- String
142
+ ;-- String
170
143
string-literal: [
171
144
#"^"" copy _str [
172
145
any [some chars | #"\" [#"u" 4 hex-char | json-esc-ch]]
173
146
] #"^"" (
174
- if not empty? _str: any [_str copy "" ] [
147
+ if not empty? _str: any [_str copy "" ][
175
148
;!! If we reverse the decode-backslash-escapes and replace-unicode-escapes
176
149
;!! calls, the string gets munged (extra U+ chars). Need to investigate.
177
150
decode-backslash-escapes _str ; _str is modified
@@ -186,7 +159,7 @@ decode-unicode-char: func [
186
159
ch [string! ] "4 hex digits"
187
160
] [
188
161
buf: {#"^^ (0000)"} ; Don't COPY buffer, reuse it
189
- if not parse ch [4 hex-char] [return none] ; Validate input data
162
+ if not parse ch [4 hex-char][return none] ; Validate input data
190
163
attempt [load head change at buf 5 ch] ; Replace 0000 section in buf
191
164
]
192
165
@@ -209,7 +182,7 @@ replace-unicode-escapes: func [
209
182
;mod-str: json-ctx/replace-unicode-escapes decode-backslash-escapes copy str
210
183
211
184
;-----------------------------------------------------------
212
- ;-- Object
185
+ ;-- Object
213
186
json-object: [
214
187
; Emit a new block to our output target, and push it on our
215
188
; working stack, to handle nested structures. Emit returns
@@ -244,7 +217,7 @@ property: [
244
217
json-name: [ws* string-literal ws* #":" ]
245
218
246
219
;-----------------------------------------------------------
247
- ;-- List
220
+ ;-- List
248
221
array-list: [json-value any [sep json-value]]
249
222
json-array: [
250
223
; Emit a new block to our output target, and push it on our
@@ -258,7 +231,7 @@ json-array: [
258
231
]
259
232
260
233
;-----------------------------------------------------------
261
- ;-- Any JSON Value (top level JSON parse rule)
234
+ ;-- Any JSON Value (top level JSON parse rule)
262
235
json-value: [
263
236
ws*
264
237
[
@@ -275,7 +248,7 @@ json-value: [
275
248
]
276
249
277
250
;-----------------------------------------------------------
278
- ;-- Decoder data structures
251
+ ;-- Decoder data structures
279
252
280
253
; The stack is used to handle nested structures (objects and lists)
281
254
stack: copy []
@@ -294,26 +267,23 @@ mark: none ; Current parse position
294
267
emit : func [ value] [_res: insert /only _res value]
295
268
296
269
;-----------------------------------------------------------
297
- ;-- Main decoder func
270
+ ;-- Main decoder func
298
271
299
272
load-json : func [
300
- "Convert a JSON string to Red data"
273
+ "Convert a JSON string to Rebol data"
301
274
input [string! ] "The JSON string"
302
- ] [
275
+ ] [
303
276
_out: _res: copy [] ; These point to the same position to start with
304
277
mark: input
305
- either parse/case input json-value [pick _out 1 ] [
278
+ either parse/case input json-value [pick _out 1 ][
306
279
make error! form reduce [
307
- "Invalid json string. Near:"
308
- either tail? mark ["<end of input>" ] [mold copy/part mark 40 ]
280
+ "Invalid JSON string. Near:"
281
+ either tail? mark ["<end of input>" ][mold copy/part mark 40 ]
309
282
]
310
283
]
311
284
]
312
285
313
286
314
-
315
-
316
-
317
287
;----------------------------------------------------------------
318
288
;@@ to-json
319
289
@@ -330,40 +300,43 @@ escapes: #[map! [
330
300
#"^-" "\t"
331
301
]]
332
302
333
- init-state : func [ ind ascii?] [
303
+ init-state : func [ ind ascii?] [
334
304
indent: ind
335
305
indent-level: 0
336
306
; 34 is double quote "
337
307
; 92 is backslash \
338
308
normal-chars: either ascii? [
339
- charset [32 33 35 - 91 93 - 127 ]
340
- ] [
341
- complement charset [0 - 31 34 92 ]
309
+ #[bitset! #{ 00000000DFFFFFFFFFFFFFF7FFFFFFFF } ]
310
+ ;= charset [32 33 35 - 91 93 - 127]
311
+ ][
312
+ #[bitset! [not bits #{ FFFFFFFF2000000000000008 } ]]
313
+ ;= complement charset [0 - 31 34 92]
342
314
]
343
315
]
344
316
345
- emit-indent : func [ output level] [
317
+ emit-indent : func [ output level] [
346
318
indent-level: indent-level + level
347
319
append /dup output indent indent-level
348
320
]
349
321
350
- emit-key-value : function [ output sep map key] [
322
+ emit-key-value : function [ output sep map key] [
351
323
value: select/case map :key
352
- if any-word? :key [key: form key]
324
+ if any-word? :key [key: form key]
353
325
unless string? :key [key: mold :key ]
354
- red -to-json-value output key
355
- append output sep
356
- red -to-json-value output :value
326
+ rebol -to-json-value output : key
327
+ append output : sep
328
+ rebol -to-json-value output :value
357
329
]
358
330
359
- red -to-json-value : function [ output value] [
331
+ rebol -to-json-value : function [ output value] [
360
332
special-char: none
361
333
switch /default type? /word :value [
362
- none! [append output "null" ]
363
- logic! [append output pick ["true" "false" ] value]
364
- integer! decimal! [append output value]
365
- percent! [append output to decimal! value]
366
- string! [
334
+ none! [append output "null" ]
335
+ logic! [append output pick ["true" "false" ] value]
336
+ integer!
337
+ decimal! [append output value]
338
+ percent! [append output to decimal! value]
339
+ string! [
367
340
append output #"^""
368
341
parse value [
369
342
any [
@@ -372,7 +345,7 @@ red-to-json-value: function [output value] [
372
345
set special-char skip (
373
346
either escape: select escapes special-char [
374
347
append output escape
375
- ] [
348
+ ][
376
349
insert insert tail output "\u" to-hex /size to integer! special-char 4
377
350
]
378
351
)
@@ -383,36 +356,37 @@ red-to-json-value: function [output value] [
383
356
block! [
384
357
either empty? value [
385
358
append output "[]"
386
- ] [
359
+ ][
387
360
either indent [
388
361
append output "[^/ "
389
362
emit-indent output +1
390
- red -to-json-value output first value
363
+ rebol -to-json-value output first value
391
364
foreach v next value [
392
365
append output ",^/ "
393
366
append /dup output indent indent-level
394
- red -to-json-value output :v
367
+ rebol -to-json-value output :v
395
368
]
396
369
append output #"^/"
397
370
emit-indent output -1
398
- ] [
371
+ ][
399
372
append output #"["
400
- red -to-json-value output first value
373
+ rebol -to-json-value output first value
401
374
foreach v next value [
402
375
append output #","
403
- red -to-json-value output :v
376
+ rebol -to-json-value output :v
404
377
]
405
378
]
406
379
append output #"]"
407
380
]
408
381
]
409
- map! object! [
382
+ map!
383
+ object! [
410
384
keys: words-of value
411
385
either empty? keys [
412
386
append output "{}"
413
- ] [
387
+ ][
414
388
either indent [
415
- append output "{^/ " ; }
389
+ append output "{^/ "
416
390
emit-indent output +1
417
391
emit-key-value output ": " value first keys
418
392
foreach k next keys [
@@ -422,8 +396,8 @@ red-to-json-value: function [output value] [
422
396
]
423
397
append output #"^/"
424
398
emit-indent output -1
425
- ] [
426
- append output #"{" ; }
399
+ ][
400
+ append output #"{"
427
401
emit-key-value output #":" value first keys
428
402
foreach k next keys [
429
403
append output #","
@@ -433,25 +407,25 @@ red-to-json-value: function [output value] [
433
407
append output #"}"
434
408
]
435
409
]
436
- ] [
437
- red -to-json-value output either any-block? :value [
410
+ ][
411
+ rebol -to-json-value output either any-block? :value [
438
412
to block! :value
439
- ] [
440
- either any-string? :value [form value] [mold :value ]
413
+ ][
414
+ either any-string? :value [form value][mold :value ]
441
415
]
442
416
]
443
417
output
444
418
]
445
419
446
420
to-json : function [
447
- "Convert Red data to a JSON string"
421
+ "Convert Rebol data to a JSON string"
448
422
data
449
423
/pretty indent [string! ] "Pretty format the output, using given indentation"
450
424
/ascii "Force ASCII output (instead of UTF-8)"
451
- ] [
425
+ ] [
452
426
result: make string! 4000
453
427
init-state indent ascii
454
- red -to-json-value result data
428
+ rebol -to-json-value result data
455
429
]
456
430
457
431
@@ -462,11 +436,11 @@ register-codec [
462
436
title: "JavaScript Object Notation"
463
437
suffixes: [%.json ]
464
438
465
- encode : func [ data [any-type! ]] [
439
+ encode : func [ data [any-type! ]] [
466
440
to-json data
467
441
]
468
- decode : func [ text [string! binary! file! ]] [
469
- if file? text [text: read text]
442
+ decode : func [ text [string! binary! file! ]] [
443
+ if file? text [text: read text]
470
444
if binary? text [text: to string! text]
471
445
load-json text
472
446
]
0 commit comments