@@ -39,7 +39,7 @@ type Context = {
3939}
4040type Compiler < T > = ( ctx : Context ) => T ;
4141
42- const compileRule = ( { name, formals, body } : g . Rule ) : Compiler < {
42+ const compileRule = ( { name, formals, body, display } : g . Rule ) : Compiler < {
4343 name : string | undefined ,
4444 expr : t . Statement ,
4545 type : t . Statement ,
@@ -50,7 +50,7 @@ const compileRule = ({ name, formals, body }: g.Rule): Compiler<{
5050
5151 const { expr : exprCode , type : typeCode } = compileExpr ( body ) ( ctx ) ;
5252
53- const bodyCode = compileFormals ( name , formals , exprCode ) ;
53+ const bodyCode = compileFormals ( name , formals , compileDisplay ( display , exprCode ) ) ;
5454
5555 return {
5656 name : formals . length > 0 ? undefined : name ,
@@ -69,6 +69,15 @@ const compileRule = ({ name, formals, body }: g.Rule): Compiler<{
6969 } ;
7070} ;
7171
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+
7281const compileFormals = ( name : string , formals : readonly string [ ] , bodyCode : t . Expression ) : t . Expression => {
7382 if ( formals . length === 0 ) {
7483 return bodyCode ;
@@ -216,10 +225,17 @@ const compileClass = ({ insensitive, negated, seqs }: g.Class): Compiler<ExprWit
216225 const children = seqs . map ( seq => compileSeq ( seq ) ) ;
217226 const body = children . map ( child => child . expr ) . join ( '' ) ;
218227 const types = children . map ( child => child . type ) ;
228+ const expectables = t . arrayExpression ( children . map ( child => child . exp ) ) ;
219229 return ewt (
220230 emitCall (
221231 '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+ ] ,
223239 [ t . tsUnionType ( types ) ]
224240 ) ,
225241 t . tsUnionType ( types ) ,
@@ -295,7 +311,7 @@ const compileCall = (node: g.Call): Compiler<ExprWithType> => ctx => {
295311 return ewt ( wrapInRef ( node . name , body ) , type ) ;
296312} ;
297313
298- type TypedString = { expr : string , type : t . TSType } ;
314+ type TypedString = { expr : string , type : t . TSType , exp : t . Expression } ;
299315
300316const compileChar = ( node : g . Escape | g . Special | g . Char ) : string => {
301317 switch ( node . $ ) {
@@ -309,16 +325,20 @@ const compileChar = (node: g.Escape | g.Special | g.Char): string => {
309325const compileSeq = ( node : g . Group | g . ClassChar | g . SpecialClass | g . Escape ) : TypedString => {
310326 switch ( node . $ ) {
311327 case 'Group' :
328+ const from = compileSeq ( node . from ) . expr ;
329+ const to = compileSeq ( node . to ) . expr ;
312330 return {
313- expr : compileSeq ( node . from ) . expr + '-' + compileSeq ( node . to ) . expr ,
331+ expr : from + '-' + to ,
314332 type : t . tsStringKeyword ( ) ,
333+ exp : emitCall ( 'ExpRange' , [ t . stringLiteral ( from ) , t . stringLiteral ( to ) ] )
315334 } ;
316335 case 'ClassChar' :
317336 return {
318337 expr : node . value === '\\' || node . value === '\]'
319338 ? `\\${ node . value } `
320339 : node . value ,
321340 type : t . tsLiteralType ( t . stringLiteral ( node . value ) ) ,
341+ exp : emitCall ( 'ExpString' , [ t . stringLiteral ( node . value ) ] )
322342 } ;
323343 default :
324344 return compileEscape ( node ) ;
@@ -330,18 +350,20 @@ const compileEscape = (node: g.Escape | g.Special | g.SpecialClass): TypedString
330350
331351 const str = `"${ expr } "` ;
332352
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+ }
345367} ;
346368
347369const compileEscapeToString = ( node : g . Escape | g . Special | g . SpecialClass ) : string => {
0 commit comments