-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathJsonLowToHigh.js
110 lines (105 loc) · 3.06 KB
/
JsonLowToHigh.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import {CodePoint} from './JsonLow.js'
const {_t_, _n_, _b_, _r_, _f_} = CodePoint
export const JsonLowToHigh = (next) => {
let mode = 'top'
let stringBuffer = ''
let numberBuffer = ''
let hexBuf = []
const feedbackQueue = []
const valFeedback = (val) => {
return feedbackQueue.length > 0? [feedbackQueue.pop(), val]: [val]
}
const openStringKey = () => {
stringBuffer = ''
mode = 'string'
return feedbackQueue.length > 0? [feedbackQueue.pop()]: []
}
const self = {
openString: openStringKey,
openKey: openStringKey,
openNumber: (codePoint) => {
numberBuffer = String.fromCharCode(codePoint)
mode = 'number'
return feedbackQueue.length > 0? [feedbackQueue.pop()]: []
},
openObject: () => {
return valFeedback(next.openObject?.())
},
openArray: () => {
return valFeedback(next.openArray?.())
},
closeObject: () => {
return valFeedback(next.closeObject?.())
},
closeArray: () => {
return valFeedback(next.closeArray?.())
},
closeTrue: () => {
return valFeedback(next.value?.(true))
},
closeFalse: () => {
return valFeedback(next.value?.(false))
},
closeNull: () => {
return valFeedback(next.value?.(null))
},
codePoint: (codePoint) => {
if (mode === 'string') {
stringBuffer += String.fromCodePoint(codePoint)
} else if (mode === 'escape') {
if (codePoint === _n_) stringBuffer += '\n'
else if (codePoint === _t_) stringBuffer += '\t'
else if (codePoint === _r_) stringBuffer += '\r'
else if (codePoint === _b_) stringBuffer += '\b'
else if (codePoint === _f_) stringBuffer += '\f'
else {
// " or \\ or /
stringBuffer += String.fromCharCode(codePoint)
}
mode = 'string'
} else if (mode === 'hex') {
hexBuf.push(codePoint)
} else if (mode === 'number') {
numberBuffer += String.fromCharCode(codePoint)
}
return feedbackQueue.length > 0? [feedbackQueue.pop()]: []
},
escape: () => {
mode = 'escape'
return feedbackQueue.length > 0? [feedbackQueue.pop()]: []
},
openHex: () => {
hexBuf = []
mode = 'hex'
return feedbackQueue.length > 0? [feedbackQueue.pop()]: []
},
closeString: () => {
mode = 'top'
return valFeedback(next.value?.(stringBuffer))
},
closeKey: () => {
mode = 'top'
return valFeedback(next.key?.(stringBuffer))
},
closeHex: (codePoint) => {
hexBuf.push(codePoint)
stringBuffer += String.fromCharCode(Number.parseInt(String.fromCharCode(...hexBuf), 16))
mode = 'string'
return feedbackQueue.length > 0? [feedbackQueue.pop()]: []
},
closeNumber: () => {
mode = 'top'
feedbackQueue.push(next.value?.(
Number.parseFloat(numberBuffer),
))
return []
},
end: () => {
const feedback = []
if (feedbackQueue.length > 0) feedback.push(feedbackQueue.pop())
feedback.push(next.end?.())
return feedback
},
}
return self
}