@@ -40,10 +40,9 @@ var assert = (condition, message = "Assertion failed") => {
4040var assertEq = ( a , b , message = "Assertion failed" ) => {
4141 if ( a !== b ) throw new Error ( `${ message } : '${ a } ' !== '${ b } '` ) ;
4242} ;
43- var numbers = "0123456789" ;
4443var JsonParser = class {
4544 #queue;
46- #last = "" ;
45+ #text = "" ;
4746 #index = 0 ;
4847 #stream;
4948 constructor ( queue ) {
@@ -54,13 +53,7 @@ var JsonParser = class {
5453 return char === " " || char === "\n" || char === " " || char === "\r" ;
5554 }
5655 async #next( len = 1 ) {
57- let str = "" ;
58- for ( let i = 0 ; i < len ; i ++ ) {
59- const char = await this . #queue. shiftUnsafe ( ) ;
60- if ( char === import_superqueue . default . EOF ) return void 0 ;
61- str += char ;
62- }
63- this . #last = str . charAt ( len - 1 ) ;
56+ const str = await this . #peek( len ) ;
6457 this . #index += len ;
6558 return str ;
6659 }
@@ -69,9 +62,23 @@ var JsonParser = class {
6962 assert ( chunk !== void 0 , `Unexpected end of JSON input at index ${ this . #index} : ${ message } ` ) ;
7063 return chunk ;
7164 }
65+ async #peek( len = 1 ) {
66+ while ( this . #text. length < this . #index + len ) {
67+ const char = await this . #queue. shiftUnsafe ( ) ;
68+ if ( char === import_superqueue . default . EOF ) return void 0 ;
69+ this . #text += char ;
70+ }
71+ const result = this . #text. slice ( this . #index, this . #index + len ) ;
72+ return result ;
73+ }
74+ async #peekNonEof( len , message ) {
75+ const chunk = await this . #peek( len ) ;
76+ assert ( chunk !== void 0 , `Unexpected end of JSON input at index ${ this . #index} : ${ message } ` ) ;
77+ return chunk ;
78+ }
7279 async #skipWhiteSpaces( ) {
73- for ( let char = await this . #nextNonEof ( 1 , "skipWhiteSpaces" ) ; ; char = await this . #nextNonEof ( 1 , "skipWhiteSpaces" ) ) {
74- if ( ! this . #isWhitespace ( char ) ) return char ;
80+ for ( let char = await this . #peekNonEof ( 1 , "skipWhiteSpaces" ) ; this . #isWhitespace ( char ) ; char = await this . #peekNonEof ( 1 , "skipWhiteSpaces" ) ) {
81+ this . #nextNonEof ( ) ;
7582 }
7683 }
7784 async #expectNext( expected ) {
@@ -86,15 +93,14 @@ var JsonParser = class {
8693 throw new Error ( "Data must be a function when using deep: true" ) ;
8794 }
8895 const newData = data ( result . data ) ;
89- if ( newData ) {
96+ if ( newData !== void 0 ) {
9097 throw new Error (
9198 "Update data must be undefined when using deep: true"
9299 ) ;
93100 }
94- return ;
95101 } else {
96102 const newData = data instanceof Function ? data ( result . data ) : data ;
97- if ( ! newData ) {
103+ if ( newData === void 0 ) {
98104 throw new Error ( "Update data cannot be undefined" ) ;
99105 }
100106 result . data = newData ;
@@ -108,7 +114,8 @@ var JsonParser = class {
108114 }
109115 async parseValue ( skip = true ) {
110116 if ( skip ) await this . #skipWhiteSpaces( ) ;
111- switch ( this . #last) {
117+ const next = await this . #peekNonEof( ) ;
118+ switch ( next ) {
112119 case "{" :
113120 return this . parseObject ( ) ;
114121 case "[" :
@@ -121,6 +128,7 @@ var JsonParser = class {
121128 return this . parseBoolean ( false ) ;
122129 case "n" :
123130 return this . parseNull ( ) ;
131+ case "-" :
124132 case "0" :
125133 case "1" :
126134 case "2" :
@@ -133,60 +141,84 @@ var JsonParser = class {
133141 case "9" :
134142 return this . parseNumber ( ) ;
135143 default :
136- throw new Error ( `Unexpected token ${ this . #last } at index ${ this . #index} while parsing value in JSON` ) ;
144+ throw new Error ( `Unexpected token ${ next } at index ${ this . #index} while parsing value in JSON` ) ;
137145 }
138146 }
139147 parseObject ( ) {
140148 return this . #wrapResult( { } , async ( update ) => {
141- while ( true ) {
149+ await this . #expectNext( "{" ) ;
150+ do {
142151 await this . #skipWhiteSpaces( ) ;
143- if ( this . #last === "}" ) break ;
144- const key = this . parseString ( ) ;
152+ if ( await this . #peekNonEof ( ) === "}" ) break ;
153+ const key = this . parseKey ( ) ;
145154 await key . wait ;
146- assertEq ( await this . #skipWhiteSpaces( ) , ":" ) ;
155+ await this . #skipWhiteSpaces( ) ;
156+ await this . #expectNext( ":" ) ;
147157 const val = await this . parseValue ( ) ;
148158 update ( ( data ) => void ( data [ key . data ] = val ) , true ) ;
149159 await val . wait ;
150- if ( typeof val . data !== "number" || this . #isWhitespace( this . #last) ) {
151- await this . #skipWhiteSpaces( ) ;
152- }
153- if ( this . #last === "}" ) break ;
154- if ( this . #last !== "," ) {
155- throw new Error ( `Unexpected token ${ this . #last} at index ${ this . #index} while parsing object in JSON` ) ;
156- }
157- }
160+ await this . #skipWhiteSpaces( ) ;
161+ if ( await this . #peekNonEof( ) === "}" ) break ;
162+ await this . #expectNext( "," ) ;
163+ } while ( true ) ;
164+ await this . #expectNext( "}" ) ;
158165 } ) ;
159166 }
160167 parseArray ( ) {
161168 return this . #wrapResult( [ ] , async ( update ) => {
162- while ( true ) {
169+ await this . #expectNext( "[" ) ;
170+ do {
163171 await this . #skipWhiteSpaces( ) ;
164- if ( this . #last === "]" ) break ;
172+ if ( await this . #peekNonEof ( ) === "]" ) break ;
165173 const val = await this . parseValue ( false ) ;
166174 update ( ( data ) => void data . push ( val ) , true ) ;
167175 await val . wait ;
168- if ( typeof val . data !== "number" || this . #isWhitespace( this . #last) ) {
169- await this . #skipWhiteSpaces( ) ;
170- }
171- if ( this . #last === "]" ) break ;
172- if ( this . #last !== "," )
173- throw new Error ( `Unexpected token ${ this . #last} at index ${ this . #index} while parsing array in JSON` ) ;
174- }
176+ await this . #skipWhiteSpaces( ) ;
177+ if ( await this . #peekNonEof( ) === "]" ) break ;
178+ await this . #expectNext( "," ) ;
179+ } while ( true ) ;
180+ await this . #expectNext( "]" ) ;
175181 } ) ;
176182 }
183+ #numbers = "0123456789" ;
177184 parseNumber ( ) {
178- return this . #wrapResult( parseInt ( this . #last) , async ( update ) => {
179- for ( let char = await this . #next( ) ; ; char = await this . #next( ) ) {
180- if ( ! char || ! ( numbers . includes ( char ) && char !== "." ) ) {
181- break ;
182- }
183- update ( ( num ) => parseFloat ( num . toString ( ) + char ) ) ;
185+ return this . #wrapResult( 0 , async ( update ) => {
186+ let str = "" ;
187+ const negative = await this . #peekNonEof( ) === "-" ;
188+ if ( negative ) {
189+ str += "-" ;
190+ await this . #nextNonEof( ) ;
191+ }
192+ for ( let char = await this . #peekNonEof( ) ; this . #numbers. includes ( char ) || char === "." ; char = await this . #peekNonEof( ) ) {
193+ await this . #nextNonEof( ) ;
194+ str += char ;
195+ update ( ( ) => Number ( str ) ) ;
196+ }
197+ } ) ;
198+ }
199+ parseKey ( ) {
200+ return this . #wrapResult( "" , async ( update ) => {
201+ const char = await this . #peekNonEof( ) ;
202+ const key = char === '"' ? this . parseString ( ) : this . parseIdentifier ( ) ;
203+ await key . wait ;
204+ update ( key . data ) ;
205+ } ) ;
206+ }
207+ #letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890" ;
208+ parseIdentifier ( ) {
209+ return this . #wrapResult( "" , async ( update ) => {
210+ for ( let char = await this . #peekNonEof( ) ; this . #letters. includes ( char ) ; char = await this . #peekNonEof( ) ) {
211+ await this . #nextNonEof( ) ;
212+ update ( ( id ) => id + char ) ;
184213 }
185214 } ) ;
186215 }
187216 parseString ( ) {
188217 return this . #wrapResult( "" , async ( update ) => {
189- for ( let char = await this . #nextNonEof( ) ; char !== '"' ; char = await this . #nextNonEof( ) ) {
218+ await this . #expectNext( '"' ) ;
219+ await this . #peekNonEof( ) ;
220+ while ( await this . #peekNonEof( ) !== '"' ) {
221+ const char = await this . #nextNonEof( ) ;
190222 if ( char !== "\\" ) {
191223 update ( ( str ) => str + char ) ;
192224 continue ;
@@ -212,19 +244,21 @@ var JsonParser = class {
212244 } else if ( nextChar === "U" ) {
213245 const char2 = parseInt ( await this . #nextNonEof( 8 ) , 16 ) ;
214246 update ( ( str ) => str + String . fromCharCode ( char2 ) ) ;
247+ } else {
248+ throw new Error ( `Invalid escape sequence ${ nextChar } at index ${ this . #index} in JSON` ) ;
215249 }
216- throw new Error ( `Invalid escape sequence ${ nextChar } at index ${ this . #index} in JSON` ) ;
217250 }
251+ await this . #expectNext( '"' ) ;
218252 } ) ;
219253 }
220254 parseBoolean ( expected ) {
221255 return this . #wrapResult(
222256 expected ,
223- ( ) => this . #expectNext( expected ? "rue " : "alse " )
257+ ( ) => this . #expectNext( expected ? "true " : "false " )
224258 ) ;
225259 }
226260 parseNull ( ) {
227- return this . #wrapResult( null , ( ) => this . #expectNext( "ull " ) ) ;
261+ return this . #wrapResult( null , ( ) => this . #expectNext( "null " ) ) ;
228262 }
229263 async resolve ( ) {
230264 return this . #resolve( await this . #stream) ;
@@ -234,7 +268,10 @@ var JsonParser = class {
234268 case "object" :
235269 if ( Array . isArray ( stream . data ) ) {
236270 return stream . data . map ( this . #resolve) ;
237- } else {
271+ } else if ( stream . data === null ) {
272+ return null ;
273+ }
274+ {
238275 const result = { } ;
239276 for ( const key in stream . data ) {
240277 result [ key ] = this . #resolve( stream . data [ key ] ) ;
0 commit comments