@@ -30,9 +30,7 @@ public static class ScriptTokenizer {
30
30
{ "setget" , TokenType . PrSetget } ,
31
31
{ "static" , TokenType . PrStatic } ,
32
32
33
- { "void" , TokenType . PrVoid } ,
34
- { "enum" , TokenType . PrEnum } ,
35
-
33
+ { "void" , TokenType . PrVoid } , { "enum" , TokenType . PrEnum } ,
36
34
{ "preload" , TokenType . PrPreload } ,
37
35
{ "assert" , TokenType . PrAssert } ,
38
36
@@ -182,83 +180,149 @@ public static class ScriptTokenizer {
182
180
183
181
private static readonly List < string > BuiltinFunctions = Enum . GetNames < BuiltinFunction > ( ) . ToList ( ) ;
184
182
183
+ private static void InsertNewLine ( IEnumerator < string > enumerator , uint baseIndent , List < Token > toFlush ) {
184
+ if ( ! enumerator . MoveNext ( ) ) {
185
+ return ;
186
+ }
187
+
188
+ var tabCount = uint . Parse ( enumerator . Current ) ;
189
+ toFlush . Add ( new Token ( TokenType . Newline , tabCount + baseIndent ) ) ;
190
+ }
191
+
192
+ private static void BuildIdentifierName ( IEnumerator < string > enumerator , List < Token > toFlush , out string ? found ) {
193
+ found = string . Empty ;
194
+ if ( ! enumerator . MoveNext ( ) ) {
195
+ return ;
196
+ }
197
+
198
+ if ( enumerator . Current == ":" ) {
199
+ toFlush . Add ( new Token ( TokenType . Wildcard ) ) ;
200
+ toFlush . Add ( new Token ( TokenType . Semicolon ) ) ;
201
+ return ;
202
+ }
203
+
204
+ found = "_" + enumerator . Current ;
205
+ }
206
+
207
+ private static void BuildNumber ( IEnumerator < string > enumerator , List < Token > toFlush ) {
208
+ int sign = 1 ;
209
+
210
+ if ( enumerator . Current == "-" ) {
211
+ sign = - 1 ;
212
+ if ( ! enumerator . MoveNext ( ) ) return ;
213
+ }
214
+
215
+ if ( ! long . TryParse ( enumerator . Current , out long upper ) ) {
216
+ toFlush . Add ( new Token ( TokenType . OpSub ) ) ;
217
+ return ;
218
+ }
219
+
220
+ if ( ! enumerator . MoveNext ( ) ) return ;
221
+
222
+ if ( enumerator . Current != "." ) {
223
+ toFlush . Add ( new ConstantToken ( new IntVariant ( upper * sign ) ) ) ;
224
+ return ;
225
+ }
226
+
227
+ if ( ! enumerator . MoveNext ( ) ) return ;
228
+
229
+ if ( ! long . TryParse ( enumerator . Current , out long lower ) ) {
230
+ // I dont think there is really a proper return for here.
231
+ // You'd have a number that looks like this "1000."
232
+ // No following decimal
233
+ // Comment if you had ideas
234
+ return ;
235
+ }
236
+
237
+ var result = upper + ( lower / Math . Pow ( 10 , lower . ToString ( ) . Length ) ) ;
238
+ toFlush . Add ( new ConstantToken ( new RealVariant ( result * sign ) ) ) ;
239
+ }
240
+
185
241
public static IEnumerable < Token > Tokenize ( string gdScript , uint baseIndent = 0 ) {
242
+ var finalTokens = new List < Token > ( ) ;
186
243
var tokens = SanitizeInput ( TokenizeString ( gdScript + " " ) ) ;
187
244
188
245
var previous = string . Empty ;
189
246
var idName = string . Empty ;
190
247
191
- List < Token > toFlush = new ( 2 ) ;
192
- yield return new Token ( TokenType . Newline , baseIndent ) ;
193
- foreach ( var current in tokens ) {
248
+ var toFlush = new List < Token > ( 2 ) ;
249
+ finalTokens . Add ( new Token ( TokenType . Newline , baseIndent ) ) ;
250
+ var enumerator = tokens . GetEnumerator ( ) ;
251
+ while ( enumerator . MoveNext ( ) ) {
252
+ var current = enumerator . Current ;
194
253
if ( current == "\n " ) {
195
- goto endAndFlushId ;
196
- }
197
-
198
- if ( previous == "\n " ) {
199
- var tabCount = uint . Parse ( current ) ;
200
- toFlush . Add ( new Token ( TokenType . Newline , tabCount + baseIndent ) ) ;
201
- goto end ;
254
+ InsertNewLine ( enumerator , baseIndent , toFlush ) ;
255
+ endAndFlushId ( ) ;
256
+ continue ;
202
257
}
203
258
204
259
if ( current == "_" ) {
205
- goto end ;
260
+ BuildIdentifierName ( enumerator , toFlush , out string ? found ) ;
261
+ if ( found == string . Empty ) {
262
+ endAndFlushId ( ) ;
263
+ continue ;
264
+ }
265
+
266
+ idName += found ;
267
+
268
+ end ( ) ;
269
+ continue ;
206
270
}
207
271
208
- if ( previous == "_" && current == ":" ) {
209
- toFlush . Add ( new Token ( TokenType . Wildcard ) ) ;
210
- toFlush . Add ( new Token ( TokenType . Semicolon ) ) ;
211
- goto endAndFlushId ;
212
- } else if ( previous == "_" ) {
213
- idName += "_" + current ;
214
- goto end ;
272
+ if ( current == "-" || char . IsDigit ( current [ 0 ] ) ) {
273
+ BuildNumber ( enumerator , toFlush ) ;
274
+ endAndFlushId ( ) ;
275
+ continue ;
215
276
}
216
277
217
278
if ( BuiltinFunctions . Contains ( current ) ) {
218
279
toFlush . Add ( new Token ( TokenType . BuiltInFunc , ( uint ? ) BuiltinFunctions . IndexOf ( current ) ) ) ;
219
- goto endAndFlushId ;
280
+ endAndFlushId ( ) ;
281
+ continue ;
220
282
}
221
283
222
284
if ( Tokens . TryGetValue ( current , out var type ) ) {
223
285
toFlush . Add ( new Token ( type ) ) ;
224
- goto endAndFlushId ;
286
+ endAndFlushId ( ) ;
287
+ continue ;
225
288
}
226
289
227
- if ( current [ 0 ] == '"' ) {
290
+ if ( current . StartsWith ( '"' ) ) {
228
291
toFlush . Add ( new ConstantToken ( new StringVariant ( current . Substring ( 1 , current . Length - 2 ) ) ) ) ;
229
- goto endAndFlushId ;
292
+ endAndFlushId ( ) ;
293
+ continue ;
230
294
}
231
295
232
296
if ( bool . TryParse ( current , out var resultB ) ) {
233
297
toFlush . Add ( new ConstantToken ( new BoolVariant ( resultB ) ) ) ;
234
- goto endAndFlushId ;
298
+ endAndFlushId ( ) ;
299
+ continue ;
235
300
}
236
301
237
- if ( long . TryParse ( current , out var resultL ) ) {
238
- toFlush . Add ( new ConstantToken ( new IntVariant ( resultL ) ) ) ;
239
- goto endAndFlushId ;
240
- }
302
+ idName += current ;
241
303
242
- if ( double . TryParse ( current , out var result ) ) {
243
- toFlush . Add ( new ConstantToken ( new RealVariant ( result ) ) ) ;
244
- goto endAndFlushId ;
304
+ end ( ) ;
305
+
306
+ void end ( ) {
307
+ previous = enumerator . Current ;
308
+ finalTokens . AddRange ( toFlush ) ;
309
+ toFlush . Clear ( ) ;
245
310
}
246
311
247
- idName += current ;
312
+ void endAndFlushId ( ) {
313
+ if ( idName != string . Empty ) {
314
+ finalTokens . Add ( new IdentifierToken ( idName ) ) ;
315
+ idName = string . Empty ;
316
+ }
248
317
249
- goto end ;
250
- endAndFlushId :
251
- if ( idName != string . Empty ) {
252
- yield return new IdentifierToken ( idName ) ;
253
- idName = string . Empty ;
318
+ end ( ) ;
254
319
}
255
- end :
256
- previous = current ;
257
- foreach ( var token in toFlush ) yield return token ;
258
- toFlush . Clear ( ) ;
259
320
}
260
321
261
- yield return new ( TokenType . Newline , baseIndent ) ;
322
+ finalTokens . Add ( new ( TokenType . Newline , baseIndent ) ) ;
323
+
324
+ foreach ( var t in finalTokens ) yield return t ;
325
+
262
326
}
263
327
264
328
private static IEnumerable < string > SanitizeInput ( IEnumerable < string > tokens ) {
0 commit comments