@@ -10,6 +10,7 @@ import {
1010 createPosition ,
1111 Position
1212} from './location'
13+ import { isUnDef } from '../utils'
1314
1415export const enum TokenTypes {
1516 Text , // 0
@@ -26,6 +27,7 @@ export const enum TokenTypes {
2627 LinkedModifier ,
2728 ParenLeft ,
2829 ParenRight ,
30+ InvalidPlace ,
2931 EOF
3032}
3133
@@ -46,13 +48,13 @@ const EOF = undefined
4648
4749export type Token = {
4850 type : TokenTypes
49- value ?: string | number
51+ value ?: string
5052 loc ?: SourceLocation
5153}
5254
5355export type TokenizeContext = {
5456 currentType : TokenTypes
55- currentValue : string | number | undefined | null // TODO: if dont' use, should be removed
57+ currentValue : string | undefined | null // TODO: if dont' use, should be removed
5658 currentToken : Token | null
5759 offset : number
5860 startLoc : Position
@@ -62,6 +64,7 @@ export type TokenizeContext = {
6264 lastOffset : number
6365 lastStartLoc : Position
6466 lastEndLoc : Position
67+ braceNest : number
6568}
6669
6770export type Tokenizer = Readonly < {
@@ -91,24 +94,29 @@ export function createTokenizer(source: string): Tokenizer {
9194 lastToken : null ,
9295 lastOffset : _initOffset ,
9396 lastStartLoc : _initLoc ,
94- lastEndLoc : _initLoc
97+ lastEndLoc : _initLoc ,
98+ braceNest : 0
9599 }
96100
97101 const context = ( ) : TokenizeContext => _context
98102
99103 const getToken = (
100104 context : TokenizeContext ,
101105 type : TokenTypes ,
102- value ?: string | number
106+ value ?: string
103107 ) : Token => {
104108 context . endLoc = currentPosition ( )
105109 context . currentType = type
106110 context . currentValue = value
107- return {
111+ const token = {
108112 type,
109- value,
110113 loc : createLocation ( context . startLoc , context . endLoc )
114+ } as Token
115+
116+ if ( ! isUnDef ( value ) ) {
117+ token . value = value
111118 }
119+ return token
112120 }
113121
114122 const peekSpaces = ( scnr : Scanner ) : string => {
@@ -145,7 +153,7 @@ export function createTokenizer(source: string): Tokenizer {
145153 return cc >= 48 && cc <= 57 // 0-9
146154 }
147155
148- const isNamedIdentifier = (
156+ const isNamedIdentifierStart = (
149157 scnr : Scanner ,
150158 context : TokenizeContext
151159 ) : boolean => {
@@ -159,7 +167,7 @@ export function createTokenizer(source: string): Tokenizer {
159167 return ret
160168 }
161169
162- const isListIdentifier = (
170+ const isListIdentifierStart = (
163171 scnr : Scanner ,
164172 context : TokenizeContext
165173 ) : boolean => {
@@ -351,11 +359,10 @@ export function createTokenizer(source: string): Tokenizer {
351359 while ( ( ch = takeIdentifierChar ( scnr ) ) ) {
352360 name += ch
353361 }
354- skipSpaces ( scnr )
355362 return name
356363 }
357364
358- const readListIdentifier = ( scnr : Scanner ) : number => {
365+ const readListIdentifier = ( scnr : Scanner ) : string => {
359366 skipSpaces ( scnr )
360367 let value = ''
361368 if ( scnr . currentChar ( ) === '-' ) {
@@ -364,8 +371,18 @@ export function createTokenizer(source: string): Tokenizer {
364371 } else {
365372 value += getDigits ( scnr )
366373 }
374+ return value
375+ }
376+
377+ const readInvalidIdentifier = ( scnr : Scanner ) : string => {
367378 skipSpaces ( scnr )
368- return parseInt ( value , 10 )
379+ let ch : string | undefined | null = ''
380+ let identifiers = ''
381+ const closure = ( ch : string ) => ( ch !== TokenChars . BraceLeft && ch !== TokenChars . BraceRight )
382+ while ( ( ch = takeChar ( scnr , closure ) ) ) {
383+ identifiers += ch
384+ }
385+ return identifiers
369386 }
370387
371388 const readLinkedModifierArg = ( scnr : Scanner ) : string => {
@@ -428,10 +445,14 @@ export function createTokenizer(source: string): Tokenizer {
428445 case TokenChars . BraceLeft :
429446 scnr . next ( )
430447 token = getToken ( context , TokenTypes . BraceLeft , TokenChars . BraceLeft )
448+ skipSpaces ( scnr )
449+ context . braceNest ++
431450 break
432451 case TokenChars . BraceRight :
433452 scnr . next ( )
434453 token = getToken ( context , TokenTypes . BraceRight , TokenChars . BraceRight )
454+ context . braceNest --
455+ context . braceNest > 0 && skipSpaces ( scnr )
435456 break
436457 case TokenChars . LinkedAlias :
437458 scnr . next ( )
@@ -466,14 +487,30 @@ export function createTokenizer(source: string): Tokenizer {
466487 token = getToken ( context , TokenTypes . Modulo , TokenChars . Modulo )
467488 break
468489 default :
490+ let validNamedIdentifier = true
491+ let validListIdentifier = true
469492 if ( isPluralStart ( scnr ) ) {
470493 token = getToken ( context , TokenTypes . Pipe , readPlural ( scnr ) )
494+ context . braceNest = 0 // reset
471495 } else if ( isTextStart ( scnr , context ) ) {
472496 token = getToken ( context , TokenTypes . Text , readText ( scnr ) )
473- } else if ( isNamedIdentifier ( scnr , context ) ) {
497+ } else if (
498+ ( validNamedIdentifier = isNamedIdentifierStart ( scnr , context ) )
499+ ) {
474500 token = getToken ( context , TokenTypes . Named , readNamedIdentifier ( scnr ) )
475- } else if ( isListIdentifier ( scnr , context ) ) {
501+ skipSpaces ( scnr )
502+ } else if (
503+ ( validListIdentifier = isListIdentifierStart ( scnr , context ) )
504+ ) {
476505 token = getToken ( context , TokenTypes . List , readListIdentifier ( scnr ) )
506+ skipSpaces ( scnr )
507+ // } else if (!validNamedIdentifier && !validListIdentifier) {
508+ // token = getToken(
509+ // context,
510+ // TokenTypes.InvalidPlace,
511+ // readInvalidIdentifier(scnr)
512+ // )
513+ // skipSpaces(scnr)
477514 } else if ( isLinkedModifier ( scnr , context ) ) {
478515 token = getToken (
479516 context ,
0 commit comments