File tree Expand file tree Collapse file tree 4 files changed +61
-2
lines changed
Expand file tree Collapse file tree 4 files changed +61
-2
lines changed Original file line number Diff line number Diff line change @@ -6,7 +6,11 @@ import {
66 SeqMatcher ,
77 SymMatcher ,
88} from './matchers' ;
9- import { BeginMatcher , EndMatcher } from './matchers/anchor-matcher' ;
9+ import {
10+ BeginMatcher ,
11+ EndMatcher ,
12+ VoidMatcher ,
13+ } from './matchers/anchor-matcher' ;
1014import { CommentMatcher } from './matchers/comment-matcher' ;
1115import { NumMatcher } from './matchers/num-matcher' ;
1216import {
@@ -173,6 +177,12 @@ abstract class AbstractBuilder<Ctx> extends TerminalBuilder<Ctx> {
173177 const builder = new SeqBuilder ( this , other ) ;
174178 return builder ;
175179 }
180+
181+ handler ( fn : ( context : Ctx ) => Ctx ) : SeqBuilder < Ctx > {
182+ const voidMatcher = new VoidBuilder ( fn ) ;
183+ const builder = new SeqBuilder ( this , voidMatcher ) ;
184+ return builder ;
185+ }
176186}
177187
178188// Anchors
@@ -200,6 +210,20 @@ export function begin<Ctx>(): BeginBuilder<Ctx> {
200210 return new BeginBuilder < Ctx > ( ) ;
201211}
202212
213+ class VoidBuilder < Ctx > extends AbstractBuilder < Ctx > {
214+ constructor ( private readonly fn : ( context : Ctx ) => Ctx ) {
215+ super ( ) ;
216+ }
217+
218+ build ( ) : VoidMatcher < Ctx > {
219+ return new VoidMatcher < Ctx > ( this . fn ) ;
220+ }
221+ }
222+
223+ export function handler < Ctx > ( fn : ( context : Ctx ) => Ctx ) : VoidBuilder < Ctx > {
224+ return new VoidBuilder ( fn ) ;
225+ }
226+
203227// Sequence
204228
205229class SeqBuilder < Ctx > extends AbstractBuilder < Ctx > {
Original file line number Diff line number Diff line change @@ -30,4 +30,14 @@ describe('query/matchers/anchor-matcher', () => {
3030 const res = lang . query ( input , query , [ ] ) ;
3131 expect ( res ) . toBeUndefined ( ) ;
3232 } ) ;
33+
34+ it ( 'supports handler builder' , ( ) => {
35+ const input = 'baz' ;
36+ const query = q
37+ . handler < Ctx > ( ( ctx ) => [ ...ctx , 'bar' ] )
38+ . sym ( handler )
39+ . handler ( ( ctx ) => ctx . map ( ( x ) => x . toUpperCase ( ) ) ) ;
40+ const res = lang . query ( input , query , [ 'foo' ] ) ;
41+ expect ( res ) . toEqual ( [ 'FOO' , 'BAR' , 'BAZ' ] ) ;
42+ } ) ;
3343} ) ;
Original file line number Diff line number Diff line change 1+ import type { Cursor } from '../../parser' ;
2+ import { clone } from '../../util/clone' ;
13import type { Checkpoint } from '../types' ;
24import { AbstractMatcher } from './abstract-matcher' ;
35
@@ -26,3 +28,26 @@ export class EndMatcher<Ctx> extends AbstractMatcher<Ctx> {
2628 return null ;
2729 }
2830}
31+
32+ export class VoidMatcher < Ctx > extends AbstractMatcher < Ctx > {
33+ private handler : ( context : Ctx ) => Ctx ;
34+
35+ constructor ( handler : ( context : Ctx ) => Ctx ) {
36+ super ( ) ;
37+ this . handler = ( context : Ctx ) => handler ( clone ( context ) ) ;
38+ }
39+
40+ match ( checkpoint : Checkpoint < Ctx > ) : Checkpoint < Ctx > | null {
41+ const { cursor, context } = checkpoint ;
42+ const newContext = this . handler ( context ) ;
43+ return { cursor, context : newContext } ;
44+ }
45+
46+ override moveRight ( cursor : Cursor ) : Cursor {
47+ return cursor ;
48+ }
49+
50+ override seekNext ( cursor : Cursor ) : Cursor {
51+ return cursor ;
52+ }
53+ }
Original file line number Diff line number Diff line change 11{
22 "name" : " good-enough-parser" ,
33 "description" : " Parse and query computer programs source code" ,
4- "version" : " 1.1.15 " ,
4+ "version" : " 1.1.16 " ,
55 "repository" : " git@github.com:zharinov/good-enough-parser.git" ,
66 "author" : " Sergei Zharinov" ,
77 "contributors" : [
You can’t perform that action at this time.
0 commit comments