@@ -2,11 +2,11 @@ import { assertGreater } from "@std/assert/greater";
22import { MemoizationCacheResult , memoize } from "@std/cache/memoize" ;
33import { ArrayResult , ArrayResultError } from "../array_result.ts" ;
44
5- type Input = Readonly < { source : string ; position : number } > ;
65type ParserResult < T > = ArrayResult < Readonly < { value : T ; length : number } > > ;
7- type InnerParser < T > = ( input : Input ) => ParserResult < T > ;
6+ type InnerParser < T > = ( input : number ) => ParserResult < T > ;
87type Memo < T > = Map < number , MemoizationCacheResult < ParserResult < T > > > ;
98
9+ let currentSource = "" ;
1010const allMemo : Set < WeakRef < Memo < unknown > > > = new Set ( ) ;
1111
1212export class Parser < T > {
@@ -16,11 +16,12 @@ export class Parser<T> {
1616 allMemo . add ( new WeakRef ( cache ) ) ;
1717 this . rawParser = memoize < InnerParser < T > , number , Memo < T > > (
1818 parser ,
19- { getKey : ( { position } ) => position , cache } ,
19+ { cache } ,
2020 ) ;
2121 }
2222 generateParser ( ) : ( source : string ) => ArrayResult < T > {
23- return ( input ) => {
23+ return ( source ) => {
24+ currentSource = source ;
2425 for ( const memo of allMemo ) {
2526 const ref = memo . deref ( ) ;
2627 if ( ref == null ) {
@@ -29,7 +30,7 @@ export class Parser<T> {
2930 ref . clear ( ) ;
3031 }
3132 }
32- return this . rawParser ( { source : input , position : 0 } )
33+ return this . rawParser ( 0 )
3334 . map ( ( { value } ) => value ) ;
3435 } ;
3536 }
@@ -45,14 +46,11 @@ export class Parser<T> {
4546 ) ;
4647 }
4748 then < U > ( mapper : ( value : T ) => Parser < U > ) : Parser < U > {
48- return new Parser ( ( input ) =>
49- this . rawParser ( input )
49+ return new Parser ( ( position ) =>
50+ this . rawParser ( position )
5051 . flatMap ( ( { value, length } ) =>
5152 mapper ( value )
52- . rawParser ( {
53- source : input . source ,
54- position : input . position + length ,
55- } )
53+ . rawParser ( position + length )
5654 . map ( ( { value, length : addedLength } ) => ( {
5755 value,
5856 length : length + addedLength ,
@@ -207,8 +205,8 @@ export function matchCapture(
207205 description : string ,
208206) : Parser < RegExpMatchArray > {
209207 const newRegex = new RegExp ( `^${ regex . source } ` , regex . flags ) ;
210- return new Parser ( ( { source , position } ) => {
211- const sourceString = source . slice ( position ) ;
208+ return new Parser ( ( position ) => {
209+ const sourceString = currentSource . slice ( position ) ;
212210 const match = sourceString . match ( newRegex ) ;
213211 if ( match != null ) {
214212 return new ArrayResult ( [ { value : match , length : match [ 0 ] . length } ] ) ;
@@ -226,10 +224,10 @@ export function matchString(
226224 match : string ,
227225 description = `"${ match } "` ,
228226) : Parser < string > {
229- return new Parser ( ( { source , position } ) => {
227+ return new Parser ( ( position ) => {
230228 if (
231- source . length - position >= match . length &&
232- source . slice ( position , position + match . length ) === match
229+ currentSource . length - position >= match . length &&
230+ currentSource . slice ( position , position + match . length ) === match
233231 ) {
234232 return new ArrayResult ( [ {
235233 value : match ,
@@ -238,38 +236,38 @@ export function matchString(
238236 } else {
239237 return new ArrayResult (
240238 new UnexpectedError (
241- describeSource ( source . slice ( position ) ) ,
239+ describeSource ( currentSource . slice ( position ) ) ,
242240 description ,
243241 ) ,
244242 ) ;
245243 }
246244 } ) ;
247245}
248- export const everything = new Parser ( ( { source , position } ) =>
246+ export const everything = new Parser ( ( position ) =>
249247 new ArrayResult ( [ {
250- value : source . slice ( position ) ,
251- length : source . length - position ,
248+ value : currentSource . slice ( position ) ,
249+ length : currentSource . length - position ,
252250 } ] )
253251) ;
254252export const character = match ( / ./ us, "character" ) ;
255- export const end = new Parser ( ( input ) =>
256- input . position === input . source . length
253+ export const end = new Parser ( ( position ) =>
254+ position === currentSource . length
257255 ? new ArrayResult ( [ { value : null , length : 0 } ] )
258256 : new ArrayResult (
259257 new UnexpectedError (
260- describeSource ( input . source . slice ( input . position ) ) ,
258+ describeSource ( currentSource . slice ( position ) ) ,
261259 "end of text" ,
262260 ) ,
263261 )
264262) ;
265263export function withSource < T > (
266264 parser : Parser < T > ,
267265) : Parser < readonly [ value : T , source : string ] > {
268- return new Parser ( ( input ) =>
269- parser . rawParser ( input ) . map ( ( { value, length } ) => ( {
266+ return new Parser ( ( position ) =>
267+ parser . rawParser ( position ) . map ( ( { value, length } ) => ( {
270268 value : [
271269 value ,
272- input . source . slice ( input . position , input . position + length ) ,
270+ currentSource . slice ( position , position + length ) ,
273271 ] as const ,
274272 length,
275273 } ) )
0 commit comments