@@ -24,7 +24,19 @@ import {
2424 withPosition ,
2525 withSource ,
2626} from "../src/parser/parser_lib.ts" ;
27- import { Definition , Dictionary , Noun , PartialVerb } from "./type.ts" ;
27+ import {
28+ Adjective ,
29+ Adverb ,
30+ Definition ,
31+ Determiner ,
32+ Dictionary ,
33+ Entry ,
34+ IndirectObject ,
35+ Noun ,
36+ NounForms ,
37+ PartialVerb ,
38+ PostAdjective ,
39+ } from "./type.ts" ;
2840
2941const RESERVED_SYMBOLS = "#()*+/:;<=>@[\\]^`{|}~" ;
3042
@@ -51,7 +63,7 @@ const ignore = allWithCheck(
5163 choiceWithCheck ( spaces , comment ) ,
5264 ) ,
5365) ;
54- function lex < const T > ( parser : Parser < T > ) {
66+ function lex < T > ( parser : Parser < T > ) {
5567 return parser . skip ( ignore ) ;
5668}
5769const wordWithPosition = lex (
@@ -65,7 +77,7 @@ const comma = lex(matchString(",", "comma"));
6577const semicolon = lex ( matchString ( ";" , "semicolon" ) ) ;
6678const slash = lex ( matchString ( "/" , "slash" ) ) ;
6779
68- const keyword = memoize ( < const T extends string > ( keyword : T ) =>
80+ const keyword = memoize ( < T extends string > ( keyword : T ) =>
6981 lex ( withPosition ( match ( / [ a - z \- ] + / , `"${ keyword } "` ) ) )
7082 . map ( ( positioned ) =>
7183 positioned . value === keyword ? positioned . value : throwError (
@@ -100,10 +112,10 @@ const perspective = choiceOnlyOne(
100112 keyword ( "second" ) ,
101113 keyword ( "third" ) ,
102114) ;
103- function tag < const T > ( parser : Parser < T > ) {
115+ function tag < T > ( parser : Parser < T > ) {
104116 return openParenthesis . with ( parser ) . skip ( closeParenthesis ) ;
105117}
106- function template < const T > ( parser : Parser < T > ) {
118+ function template < T > ( parser : Parser < T > ) {
107119 return openBracket . with ( parser ) . skip ( closeBracket ) ;
108120}
109121const simpleUnit = memoize ( ( kind : string ) => word . skip ( tag ( keyword ( kind ) ) ) ) ;
@@ -120,60 +132,64 @@ const nounOnly = checkedSequence(
120132 sequence ( optionalAll ( keyword ( "gerund" ) ) , optionalNumber )
121133 . skip ( closeParenthesis ) ,
122134)
123- . mapWithPositionedError ( ( [ [ noun , plural ] , [ gerund , number ] ] ) => {
124- if ( plural == null ) {
125- if ( number == null ) {
126- const sentence = nlp ( noun ) ;
127- sentence . tag ( "Noun" ) ;
128- const singular = sentence
129- . nouns ( )
130- . toSingular ( )
131- . text ( ) ;
132- const plural = sentence
133- . nouns ( )
134- . toPlural ( )
135- . text ( ) ;
136- if ( singular === "" || plural === "" ) {
137- throw `no singular or plural form found for "${ noun } ". consider ` +
138- "providing both singular and plural forms instead" ;
135+ . mapWithPositionedError (
136+ (
137+ [ [ noun , plural ] , [ gerund , number ] ] ,
138+ ) : NounForms & Readonly < { gerund : boolean } > => {
139+ if ( plural == null ) {
140+ if ( number == null ) {
141+ const sentence = nlp ( noun ) ;
142+ sentence . tag ( "Noun" ) ;
143+ const singular = sentence
144+ . nouns ( )
145+ . toSingular ( )
146+ . text ( ) ;
147+ const plural = sentence
148+ . nouns ( )
149+ . toPlural ( )
150+ . text ( ) ;
151+ if ( singular === "" || plural === "" ) {
152+ throw `no singular or plural form found for "${ noun } ". consider ` +
153+ "providing both singular and plural forms instead" ;
154+ }
155+ if ( noun !== singular ) {
156+ throw `conjugation error: "${ noun } " is not "${ singular } ". ` +
157+ "consider providing both singular and plural forms instead" ;
158+ }
159+ return {
160+ singular : escapeHtml ( singular ) ,
161+ plural : escapeHtml ( plural ) ,
162+ gerund : gerund != null ,
163+ } ;
164+ } else {
165+ const escaped = escapeHtml ( noun ) ;
166+ let singular : null | string ;
167+ let plural : null | string ;
168+ switch ( number ) {
169+ case "singular" :
170+ singular = escaped ;
171+ plural = null ;
172+ break ;
173+ case "plural" :
174+ singular = null ;
175+ plural = escaped ;
176+ break ;
177+ }
178+ return { singular, plural, gerund : gerund != null } ;
139179 }
140- if ( noun !== singular ) {
141- throw `conjugation error: "${ noun } " is not "${ singular } ". ` +
142- "consider providing both singular and plural forms instead" ;
180+ } else {
181+ if ( number != null ) {
182+ throw "plural or singular keyword within tag " +
183+ "must not be provided when singular and plural forms are defined" ;
143184 }
144185 return {
145- singular : escapeHtml ( singular ) ,
146- plural : escapeHtml ( plural ) ,
186+ singular : escapeHtml ( noun ) ,
187+ plural,
147188 gerund : gerund != null ,
148189 } ;
149- } else {
150- const escaped = escapeHtml ( noun ) ;
151- let singular : null | string ;
152- let plural : null | string ;
153- switch ( number ) {
154- case "singular" :
155- singular = escaped ;
156- plural = null ;
157- break ;
158- case "plural" :
159- singular = null ;
160- plural = escaped ;
161- break ;
162- }
163- return { singular, plural, gerund : gerund != null } ;
164190 }
165- } else {
166- if ( number != null ) {
167- throw "plural or singular keyword within tag " +
168- "must not be provided when singular and plural forms are defined" ;
169- }
170- return {
171- singular : escapeHtml ( noun ) ,
172- plural,
173- gerund : gerund != null ,
174- } ;
175- }
176- } ) ;
191+ } ,
192+ ) ;
177193const determinerType = choiceOnlyOne (
178194 keyword ( "article" ) ,
179195 keyword ( "demonstrative" ) ,
@@ -193,7 +209,7 @@ const determiner = checkedSequence(
193209 ) ,
194210 sequence ( determinerType , optionalNumber . skip ( closeParenthesis ) ) ,
195211)
196- . map ( ( [ [ determiner , plural ] , [ kind , quantity ] ] ) => ( {
212+ . map ( ( [ [ determiner , plural ] , [ kind , quantity ] ] ) : Determiner => ( {
197213 determiner,
198214 plural,
199215 kind,
@@ -218,7 +234,7 @@ const adverb = checkedSequence(
218234 word . skip ( openParenthesis ) . skip ( keyword ( "adv" ) ) ,
219235 optionalAll ( keyword ( "negative" ) ) . skip ( closeParenthesis ) ,
220236)
221- . map ( ( [ adverb , negative ] ) => ( {
237+ . map ( ( [ adverb , negative ] ) : Adverb => ( {
222238 adverb,
223239 negative : negative != null ,
224240 } ) ) ;
@@ -232,7 +248,7 @@ const adjective = checkedSequence(
232248 optionalAll ( keyword ( "gerund-like" ) ) . skip ( closeParenthesis ) ,
233249 ) ,
234250)
235- . map ( ( [ [ adverbs , adjective ] , [ kind , gerundLike ] ] ) => ( {
251+ . map ( ( [ [ adverbs , adjective ] , [ kind , gerundLike ] ] ) : Adjective => ( {
236252 adverbs,
237253 adjective,
238254 kind,
@@ -247,10 +263,10 @@ const noun = sequence(
247263 simpleUnit ( "adj" ) ,
248264 word . skip ( tag ( sequence ( keyword ( "n" ) , keyword ( "proper" ) ) ) ) ,
249265 )
250- . map ( ( [ adjective , name ] ) => ( { adjective, name } ) ) ,
266+ . map ( ( [ adjective , name ] ) : PostAdjective => ( { adjective, name } ) ) ,
251267 ) ,
252268)
253- . map ( ( [ determiners , adjectives , noun , postAdjective ] ) => ( {
269+ . map ( ( [ determiners , adjectives , noun , postAdjective ] ) : Noun => ( {
254270 ...noun ,
255271 determiners,
256272 adjectives,
@@ -264,7 +280,7 @@ const checkedNoun = new CheckedParser(
264280 ) ,
265281 noun ,
266282) ;
267- function checkedSimpleUnitWith < const T > ( tag : string , after : Parser < T > ) {
283+ function checkedSimpleUnitWith < T > ( tag : string , after : Parser < T > ) {
268284 return checkedSequence (
269285 word . skip ( openParenthesis ) . skip ( keyword ( tag ) ) ,
270286 closeParenthesis . with ( after ) ,
@@ -281,19 +297,22 @@ function checkedSimpleUnitWithTemplate(
281297 . map ( ( [ word ] ) => word ) ;
282298}
283299const interjectionDefinition = checkedSimpleUnit ( "i" )
284- . map ( ( interjection ) => ( { type : "interjection" , interjection } ) ) ;
300+ . map ( ( interjection ) : Definition => ( { type : "interjection" , interjection } ) ) ;
285301const particleDefinition = checkedSequence (
286302 word . skip ( openParenthesis ) . skip ( keyword ( "particle" ) ) ,
287303 sequence ( keyword ( "def" ) , closeParenthesis ) ,
288304)
289- . map ( ( [ definition ] ) => ( { type : "particle definition" , definition } ) ) ;
305+ . map ( ( [ definition ] ) : Definition => ( {
306+ type : "particle definition" ,
307+ definition,
308+ } ) ) ;
290309const prepositionDefinition = checkedSimpleUnitWithTemplate (
291310 "prep" ,
292311 sequence ( keyword ( "indirect" ) , keyword ( "object" ) ) ,
293312)
294- . map ( ( preposition ) => ( { type : "preposition" , preposition } ) ) ;
313+ . map ( ( preposition ) : Definition => ( { type : "preposition" , preposition } ) ) ;
295314const numeralDefinition = checkedSimpleUnit ( "num" )
296- . mapWithPositionedError ( ( num ) => {
315+ . mapWithPositionedError ( ( num ) : Definition => {
297316 const numeral = + num ;
298317 if ( ! Number . isInteger ( numeral ) || numeral < 0 ) {
299318 throw `"${ num } " is not a non-negative integer` ;
@@ -313,7 +332,7 @@ const fillerDefinition = checkedSequence(
313332 . map ( ( [ first , rest ] ) => [ first , ...rest ] ) ,
314333 closeParenthesis ,
315334)
316- . mapWithPositionedError ( ( [ forms ] ) => {
335+ . mapWithPositionedError ( ( [ forms ] ) : Definition => {
317336 if ( forms . length === 1 ) {
318337 return {
319338 type : "filler" ,
@@ -349,7 +368,7 @@ const fourFormPersonalPronounDefinition = checkedSequence(
349368 . map ( ( [
350369 [ singularSubject , singularObject , pluralSubject , pluralObject ] ,
351370 perspective ,
352- ] ) => ( {
371+ ] ) : Definition => ( {
353372 type : "personal pronoun" ,
354373 singular : { subject : singularSubject , object : singularObject } ,
355374 plural : { subject : pluralSubject , object : pluralObject } ,
@@ -365,7 +384,7 @@ const twoFormPersonalPronounDefinition = checkedSequence(
365384 number . skip ( closeParenthesis ) ,
366385 ) ,
367386)
368- . map ( ( [ [ subject , object ] , [ perspective , number ] ] ) => ( {
387+ . map ( ( [ [ subject , object ] , [ perspective , number ] ] ) : Definition => ( {
369388 type : "personal pronoun" ,
370389 singular : null ,
371390 plural : null ,
@@ -397,7 +416,7 @@ const nounDefinition = new CheckedParser(
397416 ) ,
398417 ) ,
399418)
400- . map ( ( [ noun , preposition ] ) =>
419+ . map ( ( [ noun , preposition ] ) : Definition =>
401420 preposition == null
402421 ? { ...noun , type : "noun" }
403422 : { type : "noun preposition" , noun, preposition }
@@ -410,7 +429,10 @@ const compoundAdjectiveDefinition = checkedSequence(
410429 . skip ( keyword ( "c" ) ) ,
411430 closeParenthesis . with ( adjective . parser ) ,
412431)
413- . map ( ( adjectives ) => ( { type : "compound adjective" , adjectives } ) )
432+ . map ( ( adjectives ) : Definition & { type : "compound adjective" } => ( {
433+ type : "compound adjective" ,
434+ adjectives,
435+ } ) )
414436 . filterWithPositionedError ( ( { adjectives } ) =>
415437 adjectives . every ( ( adjective ) => adjective . adverbs . length === 0 ) ||
416438 throwError ( "compound adjective cannot have adverbs" )
@@ -430,11 +452,14 @@ const verbDefinition = checkedSequence(
430452 closeBracket
431453 . with ( optionalWithCheck (
432454 checkedSimpleUnitWith ( "prep" , noun )
433- . map ( ( [ preposition , object ] ) => ( { preposition, object } ) ) ,
455+ . map ( ( [ preposition , object ] ) : IndirectObject => ( {
456+ preposition,
457+ object,
458+ } ) ) ,
434459 ) )
435460 . map ( nullableAsArray ) ,
436461 )
437- . map ( ( [ _ , indirectObjects ] ) => ( {
462+ . map ( ( [ _ , indirectObjects ] ) : null | PartialVerb => ( {
438463 directObject : null ,
439464 indirectObjects,
440465 forObject : true ,
@@ -444,7 +469,7 @@ const verbDefinition = checkedSequence(
444469 sequence ( closeParenthesis , openBracket , keyword ( "predicate" ) ) ,
445470 closeBracket ,
446471 )
447- . map ( ( ) => ( {
472+ . map ( ( ) : null | PartialVerb => ( {
448473 directObject : null ,
449474 indirectObjects : [ ] ,
450475 forObject : false ,
@@ -454,12 +479,12 @@ const verbDefinition = checkedSequence(
454479 keyword ( "modal" ) ,
455480 sequence ( closeParenthesis , template ( keyword ( "predicate" ) ) ) ,
456481 )
457- . map ( ( ) => null ) ,
482+ . map ( ( ) : null | PartialVerb => null ) ,
458483 checkedSequence (
459484 keyword ( "linking" ) ,
460485 sequence ( closeParenthesis , template ( keyword ( "predicate" ) ) ) ,
461486 )
462- . map ( ( ) => ( {
487+ . map ( ( ) : null | PartialVerb => ( {
463488 directObject : null ,
464489 indirectObjects : [ ] ,
465490 forObject : false ,
@@ -484,7 +509,7 @@ const verbDefinition = checkedSequence(
484509 ) ,
485510 ) ,
486511 )
487- . map < PartialVerb > ( ( [ _ , [ directObject , rawIndirectObject ] ] ) => {
512+ . map ( ( [ _ , [ directObject , rawIndirectObject ] ] ) : PartialVerb => {
488513 if ( rawIndirectObject == null ) {
489514 return {
490515 directObject,
@@ -516,7 +541,7 @@ const verbDefinition = checkedSequence(
516541 } ) ,
517542 ) ,
518543)
519- . mapWithPositionedError < Definition > ( ( [ [ verb , forms ] , rest ] ) => {
544+ . mapWithPositionedError ( ( [ [ verb , forms ] , rest ] ) : Definition => {
520545 if ( rest == null ) {
521546 if ( forms != null ) {
522547 throw "modal verbs shouldn't be conjugated" ;
@@ -561,12 +586,18 @@ const definition = choiceWithCheck(
561586 // compound adjective parser must come before adjective parser
562587 compoundAdjectiveDefinition ,
563588 // adjective parser must come before adverb parser
564- adjective . map ( ( adjective ) => ( { ...adjective , type : "adjective" } ) ) ,
589+ adjective . map ( ( adjective ) : Definition => ( {
590+ ...adjective ,
591+ type : "adjective" ,
592+ } ) ) ,
565593 verbDefinition ,
566- adverb . map ( ( adverb ) => ( { ...adverb , type : "adverb" } ) ) ,
594+ adverb . map ( ( adverb ) : Definition => ( { ...adverb , type : "adverb" } ) ) ,
567595 interjectionDefinition ,
568596 particleDefinition ,
569- determiner . map ( ( determiner ) => ( { ...determiner , type : "determiner" } ) ) ,
597+ determiner . map ( ( determiner ) : Definition => ( {
598+ ...determiner ,
599+ type : "determiner" ,
600+ } ) ) ,
570601 prepositionDefinition ,
571602 numeralDefinition ,
572603 fillerDefinition ,
@@ -589,7 +620,10 @@ const entry = withSource(
589620 ) ,
590621 ) ,
591622)
592- . map ( ( [ definitions , source ] ) => ( { definitions, source : source . trimEnd ( ) } ) ) ;
623+ . map ( ( [ definitions , source ] ) : Entry => ( {
624+ definitions,
625+ source : source . trimEnd ( ) ,
626+ } ) ) ;
593627export const dictionaryParser : Parser < Dictionary > = ignore
594628 . with (
595629 allWithCheck ( new CheckedParser ( notEnd , sequence ( positionedHead , entry ) ) ) ,
0 commit comments