@@ -197,8 +197,13 @@ export function deepAssignWithTable(target: Record<string, unknown>, table: {
197197// Parser combinators and generators
198198// ---------------------------------
199199
200- function or < T > ( parsers : ParserComponent < T > [ ] ) : ParserComponent < T > {
201- return ( scanner : Scanner ) : ParseResult < T > => {
200+ // deno-lint-ignore no-explicit-any
201+ function or < T extends readonly ParserComponent < any > [ ] > (
202+ parsers : T ,
203+ ) : ParserComponent <
204+ ReturnType < T [ number ] > extends ParseResult < infer R > ? R : Failure
205+ > {
206+ return ( scanner : Scanner ) => {
202207 for ( const parse of parsers ) {
203208 const result = parse ( scanner ) ;
204209 if ( result . ok ) return result ;
@@ -533,22 +538,41 @@ export function multilineLiteralString(
533538 return success ( acc . join ( "" ) ) ;
534539}
535540
536- const symbolPairs : [ string , unknown ] [ ] = [
537- [ "true" , true ] ,
538- [ "false" , false ] ,
541+ const BOOLEAN_REGEXP = / (?: t r u e | f a l s e ) \b / y;
542+ export function boolean ( scanner : Scanner ) : ParseResult < boolean > {
543+ scanner . skipWhitespaces ( ) ;
544+ const match = scanner . match ( BOOLEAN_REGEXP ) ;
545+ if ( ! match ) return failure ( ) ;
546+ const string = match [ 0 ] ;
547+ scanner . next ( string . length ) ;
548+ const value = string === "true" ;
549+ return success ( value ) ;
550+ }
551+
552+ const INFINITY_MAP = new Map < string , number > ( [
539553 [ "inf" , Infinity ] ,
540554 [ "+inf" , Infinity ] ,
541555 [ "-inf" , - Infinity ] ,
542- [ "nan" , NaN ] ,
543- [ "+nan" , NaN ] ,
544- [ "-nan" , NaN ] ,
545- ] ;
546- export function symbols ( scanner : Scanner ) : ParseResult < unknown > {
556+ ] ) ;
557+ const INFINITY_REGEXP = / [ + - ] ? i n f \b / y;
558+ export function infinity ( scanner : Scanner ) : ParseResult < number > {
547559 scanner . skipWhitespaces ( ) ;
548- const found = symbolPairs . find ( ( [ str ] ) => scanner . startsWith ( str ) ) ;
549- if ( ! found ) return failure ( ) ;
550- const [ str , value ] = found ;
551- scanner . next ( str . length ) ;
560+ const match = scanner . match ( INFINITY_REGEXP ) ;
561+ if ( ! match ) return failure ( ) ;
562+ const string = match [ 0 ] ;
563+ scanner . next ( string . length ) ;
564+ const value = INFINITY_MAP . get ( string ) ! ;
565+ return success ( value ) ;
566+ }
567+
568+ const NAN_REGEXP = / [ + - ] ? n a n \b / y;
569+ export function nan ( scanner : Scanner ) : ParseResult < number > {
570+ scanner . skipWhitespaces ( ) ;
571+ const match = scanner . match ( NAN_REGEXP ) ;
572+ if ( ! match ) return failure ( ) ;
573+ const string = match [ 0 ] ;
574+ scanner . next ( string . length ) ;
575+ const value = NaN ;
552576 return success ( value ) ;
553577}
554578
@@ -683,7 +707,9 @@ export const value = or([
683707 multilineLiteralString ,
684708 basicString ,
685709 literalString ,
686- symbols ,
710+ boolean ,
711+ infinity ,
712+ nan ,
687713 dateTime ,
688714 localTime ,
689715 binary ,
0 commit comments