@@ -39,7 +39,7 @@ type Context = {
39
39
}
40
40
type Compiler < T > = ( ctx : Context ) => T ;
41
41
42
- const compileRule = ( { name, formals, body } : g . Rule ) : Compiler < {
42
+ const compileRule = ( { name, formals, body, display } : g . Rule ) : Compiler < {
43
43
name : string | undefined ,
44
44
expr : t . Statement ,
45
45
type : t . Statement ,
@@ -50,7 +50,7 @@ const compileRule = ({ name, formals, body }: g.Rule): Compiler<{
50
50
51
51
const { expr : exprCode , type : typeCode } = compileExpr ( body ) ( ctx ) ;
52
52
53
- const bodyCode = compileFormals ( name , formals , exprCode ) ;
53
+ const bodyCode = compileFormals ( name , formals , compileDisplay ( display , exprCode ) ) ;
54
54
55
55
return {
56
56
name : formals . length > 0 ? undefined : name ,
@@ -69,6 +69,15 @@ const compileRule = ({ name, formals, body }: g.Rule): Compiler<{
69
69
} ;
70
70
} ;
71
71
72
+ const compileDisplay = ( display : g . Rule [ "display" ] , expr : t . Expression ) : t . Expression => {
73
+ if ( ! display ) {
74
+ return expr ;
75
+ }
76
+ const body = display . map ( char => compileChar ( char ) ) . join ( '' ) ;
77
+ const value = JSON . parse ( `"${ body } "` ) ;
78
+ return emitCall ( 'named' , [ t . stringLiteral ( value ) , expr ] ) ;
79
+ } ;
80
+
72
81
const compileFormals = ( name : string , formals : readonly string [ ] , bodyCode : t . Expression ) : t . Expression => {
73
82
if ( formals . length === 0 ) {
74
83
return bodyCode ;
@@ -216,10 +225,17 @@ const compileClass = ({ insensitive, negated, seqs }: g.Class): Compiler<ExprWit
216
225
const children = seqs . map ( seq => compileSeq ( seq ) ) ;
217
226
const body = children . map ( child => child . expr ) . join ( '' ) ;
218
227
const types = children . map ( child => child . type ) ;
228
+ const expectables = t . arrayExpression ( children . map ( child => child . exp ) ) ;
219
229
return ewt (
220
230
emitCall (
221
231
'regex' ,
222
- [ t . stringLiteral ( prefix + body ) , t . booleanLiteral ( insensitive ) ] ,
232
+ [
233
+ t . stringLiteral ( prefix + body ) ,
234
+ negated
235
+ ? emitCall ( 'negateExps' , [ expectables ] )
236
+ : expectables ,
237
+ // t.booleanLiteral(insensitive)
238
+ ] ,
223
239
[ t . tsUnionType ( types ) ]
224
240
) ,
225
241
t . tsUnionType ( types ) ,
@@ -295,7 +311,7 @@ const compileCall = (node: g.Call): Compiler<ExprWithType> => ctx => {
295
311
return ewt ( wrapInRef ( node . name , body ) , type ) ;
296
312
} ;
297
313
298
- type TypedString = { expr : string , type : t . TSType } ;
314
+ type TypedString = { expr : string , type : t . TSType , exp : t . Expression } ;
299
315
300
316
const compileChar = ( node : g . Escape | g . Special | g . Char ) : string => {
301
317
switch ( node . $ ) {
@@ -309,16 +325,20 @@ const compileChar = (node: g.Escape | g.Special | g.Char): string => {
309
325
const compileSeq = ( node : g . Group | g . ClassChar | g . SpecialClass | g . Escape ) : TypedString => {
310
326
switch ( node . $ ) {
311
327
case 'Group' :
328
+ const from = compileSeq ( node . from ) . expr ;
329
+ const to = compileSeq ( node . to ) . expr ;
312
330
return {
313
- expr : compileSeq ( node . from ) . expr + '-' + compileSeq ( node . to ) . expr ,
331
+ expr : from + '-' + to ,
314
332
type : t . tsStringKeyword ( ) ,
333
+ exp : emitCall ( 'ExpRange' , [ t . stringLiteral ( from ) , t . stringLiteral ( to ) ] )
315
334
} ;
316
335
case 'ClassChar' :
317
336
return {
318
337
expr : node . value === '\\' || node . value === '\]'
319
338
? `\\${ node . value } `
320
339
: node . value ,
321
340
type : t . tsLiteralType ( t . stringLiteral ( node . value ) ) ,
341
+ exp : emitCall ( 'ExpString' , [ t . stringLiteral ( node . value ) ] )
322
342
} ;
323
343
default :
324
344
return compileEscape ( node ) ;
@@ -330,18 +350,20 @@ const compileEscape = (node: g.Escape | g.Special | g.SpecialClass): TypedString
330
350
331
351
const str = `"${ expr } "` ;
332
352
333
- const type = ( ( ) => {
334
- try {
335
- return t . tsLiteralType ( t . stringLiteral ( JSON . parse ( str ) ) ) ;
336
- } catch ( e ) {
337
- return t . tsStringKeyword ( ) ;
338
- }
339
- } ) ( ) ;
340
-
341
- return {
342
- expr,
343
- type,
344
- } ;
353
+ try {
354
+ const parsed = JSON . parse ( str ) ;
355
+ return {
356
+ expr,
357
+ type : t . tsLiteralType ( t . stringLiteral ( parsed ) ) ,
358
+ exp : emitCall ( 'ExpString' , [ t . stringLiteral ( parsed ) ] )
359
+ } ;
360
+ } catch ( e ) {
361
+ return {
362
+ expr,
363
+ type : t . tsStringKeyword ( ) ,
364
+ exp : emitCall ( 'ExpString' , [ t . stringLiteral ( str ) ] )
365
+ } ;
366
+ }
345
367
} ;
346
368
347
369
const compileEscapeToString = ( node : g . Escape | g . Special | g . SpecialClass ) : string => {
0 commit comments