10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 |
12 |
13 Object subclass:#Scanner |
13 Object subclass:#Scanner |
14 instanceVariableNames:'source |
14 instanceVariableNames:'source |
15 token tokenType tokenPosition tokenValue |
15 token tokenType tokenPosition tokenValue |
16 tokenName tokenLineNr tokenRadix |
16 tokenName tokenLineNr tokenRadix |
17 thisChar peekChar |
17 thisChar peekChar |
18 requestor exitBlock |
18 requestor exitBlock |
19 errorFlag |
19 errorFlag |
20 ignoreErrors ignoreWarnings |
20 ignoreErrors ignoreWarnings |
21 saveComments currentComments |
21 saveComments currentComments |
22 warnSTXSpecialComment |
22 warnSTXSpecialComment |
23 outStream outCol' |
23 outStream outCol' |
24 classVariableNames:'TypeArray ActionArray Warnings WarnSTXSpecials' |
24 classVariableNames:'TypeArray ActionArray Warnings WarnSTXSpecials' |
25 poolDictionaries:'' |
25 poolDictionaries:'' |
26 category:'System-Compiler' |
26 category:'System-Compiler' |
27 ! |
27 ! |
28 |
28 |
29 Scanner comment:' |
29 Scanner comment:' |
30 COPYRIGHT (c) 1989 by Claus Gittinger |
30 COPYRIGHT (c) 1989 by Claus Gittinger |
31 All Rights Reserved |
31 All Rights Reserved |
32 |
32 |
33 $Header: /cvs/stx/stx/libcomp/Scanner.st,v 1.12 1994-08-23 23:05:01 claus Exp $ |
33 $Header: /cvs/stx/stx/libcomp/Scanner.st,v 1.13 1994-10-10 00:57:45 claus Exp $ |
34 '! |
34 '! |
35 |
35 |
36 !Scanner class methodsFor:'documentation'! |
36 !Scanner class methodsFor:'documentation'! |
37 |
37 |
38 copyright |
38 copyright |
39 " |
39 " |
40 COPYRIGHT (c) 1989 by Claus Gittinger |
40 COPYRIGHT (c) 1989 by Claus Gittinger |
41 All Rights Reserved |
41 All Rights Reserved |
42 |
42 |
43 This software is furnished under a license and may be used |
43 This software is furnished under a license and may be used |
44 only in accordance with the terms of that license and with the |
44 only in accordance with the terms of that license and with the |
45 inclusion of the above copyright notice. This software may not |
45 inclusion of the above copyright notice. This software may not |
46 be provided or otherwise made available to, or used by, any |
46 be provided or otherwise made available to, or used by, any |
98 ActionArray := Array new:256. |
98 ActionArray := Array new:256. |
99 TypeArray := Array new:256. |
99 TypeArray := Array new:256. |
100 |
100 |
101 block := [:s :char | s nextNumber]. |
101 block := [:s :char | s nextNumber]. |
102 ($0 asciiValue) to:($9 asciiValue) do:[:index | |
102 ($0 asciiValue) to:($9 asciiValue) do:[:index | |
103 ActionArray at:index put:block |
103 ActionArray at:index put:block |
104 ]. |
104 ]. |
105 |
105 |
106 block := [:s :char | s nextIdentifier]. |
106 block := [:s :char | s nextIdentifier]. |
107 ($a asciiValue) to:($z asciiValue) do:[:index | |
107 ($a asciiValue) to:($z asciiValue) do:[:index | |
108 ActionArray at:index put:block |
108 ActionArray at:index put:block |
109 ]. |
109 ]. |
110 ($A asciiValue) to:($Z asciiValue) do:[:index | |
110 ($A asciiValue) to:($Z asciiValue) do:[:index | |
111 ActionArray at:index put:block |
111 ActionArray at:index put:block |
112 ]. |
112 ]. |
113 |
113 |
114 block := [:s :char | s nextSpecial]. |
114 block := [:s :char | s nextSpecial]. |
115 #( $& $- $+ $= $* $/ $\ $< $> $~ $@ $, $? ) do:[:binop | |
115 #( $& $- $+ $= $* $/ $\ $< $> $~ $@ $, $? ) do:[:binop | |
116 TypeArray at:(binop asciiValue) put:#special. |
116 TypeArray at:(binop asciiValue) put:#special. |
117 ActionArray at:(binop asciiValue) put:block |
117 ActionArray at:(binop asciiValue) put:block |
118 ]. |
118 ]. |
119 |
119 |
120 block := [:s :char | s nextToken:char]. |
120 block := [:s :char | s nextToken:char]. |
121 #( $; $. $( $) $[ $] $!! $^ $| $_ ) do:[:ch | |
121 #( $; $. $( $) $[ $] $!! $^ $| $_ ) do:[:ch | |
122 ActionArray at:(ch asciiValue) put:block |
122 ActionArray at:(ch asciiValue) put:block |
123 ]. |
123 ]. |
124 |
124 |
125 "kludge: action is characterToken, but type is special" |
125 "kludge: action is characterToken, but type is special" |
126 TypeArray at:($| asciiValue) put:#special. |
126 TypeArray at:($| asciiValue) put:#special. |
127 |
127 |
193 backupPosition |
193 backupPosition |
194 "if reading from a stream, at the end we might have read |
194 "if reading from a stream, at the end we might have read |
195 one token too many" |
195 one token too many" |
196 |
196 |
197 (tokenType == #EOF) ifFalse:[ |
197 (tokenType == #EOF) ifFalse:[ |
198 source position:tokenPosition |
198 source position:tokenPosition |
199 ] |
199 ] |
200 ! |
200 ! |
201 |
201 |
202 beginComment |
202 beginComment |
203 ^ self |
203 ^ self |
204 ! |
204 ! |
205 |
205 |
206 endComment:comment |
206 endComment:comment |
207 saveComments ifTrue:[ |
207 saveComments ifTrue:[ |
208 currentComments isNil ifTrue:[ |
208 currentComments isNil ifTrue:[ |
209 currentComments := OrderedCollection with:comment |
209 currentComments := OrderedCollection with:comment |
210 ] ifFalse:[ |
210 ] ifFalse:[ |
211 currentComments add:comment |
211 currentComments add:comment |
212 ] |
212 ] |
213 ]. |
213 ]. |
214 ! ! |
214 ! ! |
215 |
215 |
216 !Scanner methodsFor:'error handling'! |
216 !Scanner methodsFor:'error handling'! |
217 |
217 |
218 showErrorMessage:aMessage position:pos |
218 showErrorMessage:aMessage position:pos |
219 "show an errormessage on the Transcript" |
219 "show an errormessage on the Transcript" |
220 |
220 |
221 ignoreErrors ifFalse:[ |
221 ignoreErrors ifFalse:[ |
222 Smalltalk silentLoading == true ifFalse:[ |
222 Smalltalk silentLoading == true ifFalse:[ |
223 Transcript showCr:(pos printString , ' ' , aMessage) |
223 Transcript showCr:(pos printString , ' ' , aMessage) |
224 ] |
224 ] |
225 ] |
225 ] |
226 ! |
226 ! |
227 |
227 |
228 notifyError:aMessage position:position to:endPos |
228 notifyError:aMessage position:position to:endPos |
229 "notify requestor of an error - if there is no requestor |
229 "notify requestor of an error - if there is no requestor |
230 put it on the transcript. |
230 put it on the transcript. |
231 Return the result passed back by the requestor." |
231 Return the result passed back by the requestor." |
232 |
232 |
233 requestor isNil ifTrue:[ |
233 requestor isNil ifTrue:[ |
234 self showErrorMessage:aMessage position:position. |
234 self showErrorMessage:aMessage position:position. |
235 ^ false |
235 ^ false |
236 ]. |
236 ]. |
237 |
237 |
238 ^ requestor error:aMessage position:position to:endPos |
238 ^ requestor error:aMessage position:position to:endPos |
239 ! |
239 ! |
240 |
240 |
356 Since this is non-standard, use it in very rare cases only. |
356 Since this is non-standard, use it in very rare cases only. |
357 (maybe the upcoming ansi-standard adds something similar - in this case, I will |
357 (maybe the upcoming ansi-standard adds something similar - in this case, I will |
358 change it without notice)" |
358 change it without notice)" |
359 |
359 |
360 thisChar == $/ ifTrue:[ |
360 thisChar == $/ ifTrue:[ |
361 [thisChar notNil and:[thisChar ~~ Character cr]] whileTrue:[ |
361 [thisChar notNil and:[thisChar ~~ Character cr]] whileTrue:[ |
362 saveComments ifTrue:[ |
362 saveComments ifTrue:[ |
363 comment := comment copyWith:thisChar |
363 comment := comment copyWith:thisChar |
364 ]. |
364 ]. |
365 outStream notNil ifTrue:[ |
365 outStream notNil ifTrue:[ |
366 outStream nextPut:thisChar. |
366 outStream nextPut:thisChar. |
367 outCol := outCol + 1 |
367 outCol := outCol + 1 |
368 ]. |
368 ]. |
369 thisChar := source nextPeek. |
369 thisChar := source nextPeek. |
370 ]. |
370 ]. |
371 tokenLineNr := tokenLineNr + 1. |
371 tokenLineNr := tokenLineNr + 1. |
372 ignoreWarnings ifFalse:[ |
372 ignoreWarnings ifFalse:[ |
373 warnSTXSpecialComment ifTrue:[ |
373 warnSTXSpecialComment ifTrue:[ |
374 self warning:'end-of-line comments are a nonstandard feature of ST/X' |
374 self warning:'end-of-line comments are a nonstandard feature of ST/X' |
375 position:startPos to:(source position). |
375 position:startPos to:(source position). |
376 " |
376 " |
377 only warn once |
377 only warn once |
378 " |
378 " |
379 warnSTXSpecialComment := false |
379 warnSTXSpecialComment := false |
380 ] |
380 ] |
381 ]. |
381 ]. |
382 outStream notNil ifTrue:[ |
382 outStream notNil ifTrue:[ |
383 outStream cr. |
383 outStream cr. |
384 outCol := 1 |
384 outCol := 1 |
385 ]. |
385 ]. |
386 ] ifFalse:[ |
386 ] ifFalse:[ |
387 [thisChar notNil and:[thisChar ~~ (Character doubleQuote)]] whileTrue:[ |
387 [thisChar notNil and:[thisChar ~~ (Character doubleQuote)]] whileTrue:[ |
388 thisChar == (Character cr) ifTrue:[ |
388 thisChar == (Character cr) ifTrue:[ |
389 tokenLineNr := tokenLineNr + 1. |
389 tokenLineNr := tokenLineNr + 1. |
390 ]. |
390 ]. |
391 saveComments ifTrue:[ |
391 saveComments ifTrue:[ |
392 comment := comment copyWith:thisChar |
392 comment := comment copyWith:thisChar |
393 ]. |
393 ]. |
394 outStream notNil ifTrue:[ |
394 outStream notNil ifTrue:[ |
395 outStream nextPut:thisChar. |
395 outStream nextPut:thisChar. |
396 outCol := outCol + 1 |
396 outCol := outCol + 1 |
397 ]. |
397 ]. |
398 thisChar := source nextPeek |
398 thisChar := source nextPeek |
399 ]. |
399 ]. |
400 thisChar isNil ifTrue:[ |
400 thisChar isNil ifTrue:[ |
401 self warning:'unclosed comment' position:startPos to:(source position) |
401 self warning:'unclosed comment' position:startPos to:(source position) |
402 ] ifFalse:[ |
402 ] ifFalse:[ |
403 outStream notNil ifTrue:[ |
403 outStream notNil ifTrue:[ |
404 outStream nextPut:(Character doubleQuote). |
404 outStream nextPut:(Character doubleQuote). |
405 outCol := outCol + 1 |
405 outCol := outCol + 1 |
406 ]. |
406 ]. |
407 ] |
407 ] |
408 ]. |
408 ]. |
409 |
409 |
410 saveComments ifTrue:[ |
410 saveComments ifTrue:[ |
411 currentComments isNil ifTrue:[ |
411 currentComments isNil ifTrue:[ |
412 currentComments := OrderedCollection with:comment |
412 currentComments := OrderedCollection with:comment |
413 ] ifFalse:[ |
413 ] ifFalse:[ |
414 currentComments add:comment |
414 currentComments add:comment |
415 ] |
415 ] |
416 ]. |
416 ]. |
417 |
417 |
418 "skip final dQuote or cr" |
418 "skip final dQuote or cr" |
419 source next. |
419 source next. |
420 |
420 |
425 "return the next token from the source-stream" |
425 "return the next token from the source-stream" |
426 |
426 |
427 |skipping actionBlock| |
427 |skipping actionBlock| |
428 |
428 |
429 peekChar notNil ifTrue:[ |
429 peekChar notNil ifTrue:[ |
430 thisChar := peekChar. |
430 thisChar := peekChar. |
431 peekChar := nil |
431 peekChar := nil |
432 ] ifFalse:[ |
432 ] ifFalse:[ |
433 skipping := true. |
433 skipping := true. |
434 [skipping] whileTrue:[ |
434 [skipping] whileTrue:[ |
435 outStream notNil ifTrue:[ |
435 outStream notNil ifTrue:[ |
436 [(thisChar := source peek) == Character space] whileTrue:[ |
436 [(thisChar := source peek) == Character space] whileTrue:[ |
437 source next. |
437 source next. |
438 outStream space. |
438 outStream space. |
439 outCol := outCol + 1. |
439 outCol := outCol + 1. |
440 ] |
440 ] |
441 ] ifFalse:[ |
441 ] ifFalse:[ |
442 thisChar := source skipSeparatorsExceptCR. |
442 thisChar := source skipSeparatorsExceptCR. |
443 ]. |
443 ]. |
444 thisChar == (Character cr) ifTrue:[ |
444 thisChar == (Character cr) ifTrue:[ |
445 tokenLineNr := tokenLineNr + 1. |
445 tokenLineNr := tokenLineNr + 1. |
446 source next. |
446 source next. |
447 outStream notNil ifTrue:[ |
447 outStream notNil ifTrue:[ |
448 outStream cr. |
448 outStream cr. |
449 outCol := 1 |
449 outCol := 1 |
450 ] |
450 ] |
451 ] ifFalse:[ |
451 ] ifFalse:[ |
452 thisChar == (Character doubleQuote) ifTrue:[ |
452 thisChar == (Character doubleQuote) ifTrue:[ |
453 "start of a comment" |
453 "start of a comment" |
454 |
454 |
455 self skipComment. |
455 self skipComment. |
456 thisChar := source peek. |
456 thisChar := source peek. |
457 ] ifFalse:[ |
457 ] ifFalse:[ |
458 skipping := false |
458 skipping := false |
459 ] |
459 ] |
460 ] |
460 ] |
461 ]. |
461 ]. |
462 thisChar isNil ifTrue:[ |
462 thisChar isNil ifTrue:[ |
463 tokenType := #EOF. |
463 tokenType := #EOF. |
464 ^ tokenType |
464 ^ tokenType |
465 ] |
465 ] |
466 ]. |
466 ]. |
467 tokenPosition := source position. |
467 tokenPosition := source position. |
468 |
468 |
469 actionBlock := ActionArray at:(thisChar asciiValue). |
469 actionBlock := ActionArray at:(thisChar asciiValue). |
470 actionBlock notNil ifTrue:[ |
470 actionBlock notNil ifTrue:[ |
471 ^ actionBlock value:self value:thisChar |
471 ^ actionBlock value:self value:thisChar |
472 ]. |
472 ]. |
473 |
473 |
474 self syntaxError:('invalid character: ''' , thisChar asString , ''' ', |
474 self syntaxError:('invalid character: ''' , thisChar asString , ''' ', |
475 '(' , thisChar asciiValue printString , ')') |
475 '(' , thisChar asciiValue printString , ')') |
476 position:tokenPosition to:tokenPosition. |
476 position:tokenPosition to:tokenPosition. |
477 tokenType := #Error. |
477 tokenType := #Error. |
478 ^ #Error |
478 ^ #Error |
479 ! |
479 ! |
480 |
480 |
481 nextToken:aCharacter |
481 nextToken:aCharacter |
503 |firstChar secondChar thirdChar string p| |
503 |firstChar secondChar thirdChar string p| |
504 |
504 |
505 firstChar := source next. |
505 firstChar := source next. |
506 secondChar := source peek. |
506 secondChar := source peek. |
507 (firstChar == $-) ifTrue:[ |
507 (firstChar == $-) ifTrue:[ |
508 secondChar isDigit ifTrue:[ |
508 secondChar isDigit ifTrue:[ |
509 self nextNumber. |
509 self nextNumber. |
510 tokenValue := tokenValue negated. |
510 tokenValue := tokenValue negated. |
511 ^ tokenType |
511 ^ tokenType |
512 ] |
512 ] |
513 ]. |
513 ]. |
514 string := firstChar asString. |
514 string := firstChar asString. |
515 secondChar notNil ifTrue:[ |
515 secondChar notNil ifTrue:[ |
516 ((TypeArray at:(secondChar asciiValue)) == #special) ifTrue:[ |
516 ((TypeArray at:(secondChar asciiValue)) == #special) ifTrue:[ |
517 (secondChar == $-) ifTrue:[ |
517 (secondChar == $-) ifTrue:[ |
518 "special- look if minus belongs to number following" |
518 "special- look if minus belongs to number following" |
519 p := source position. |
519 p := source position. |
520 source next. |
520 source next. |
521 thirdChar := source peek. |
521 thirdChar := source peek. |
522 source position:p. |
522 source position:p. |
523 thirdChar isDigit ifTrue:[ |
523 thirdChar isDigit ifTrue:[ |
524 tokenName := string. |
524 tokenName := string. |
525 tokenType := #BinaryOperator. |
525 tokenType := #BinaryOperator. |
526 ^ tokenType |
526 ^ tokenType |
527 ] |
527 ] |
528 ]. |
528 ]. |
529 source next. |
529 source next. |
530 string := string copyWith:secondChar |
530 string := string copyWith:secondChar |
531 ]. |
531 ]. |
532 ]. |
532 ]. |
533 tokenName := string. |
533 tokenName := string. |
534 tokenType := #BinaryOperator. |
534 tokenType := #BinaryOperator. |
535 ^ tokenType |
535 ^ tokenType |
536 ! |
536 ! |
570 |
570 |
571 tokenRadix := 10. |
571 tokenRadix := 10. |
572 value := Integer readFrom:source radix:tokenRadix. |
572 value := Integer readFrom:source radix:tokenRadix. |
573 nextChar := source peek. |
573 nextChar := source peek. |
574 (nextChar == $r) ifTrue:[ |
574 (nextChar == $r) ifTrue:[ |
575 tokenRadix := value. |
575 tokenRadix := value. |
576 source next. |
576 source next. |
577 s := 1. |
577 s := 1. |
578 source peek == $- ifTrue:[ |
578 source peek == $- ifTrue:[ |
579 source next. |
579 source next. |
580 s := -1 |
580 s := -1 |
581 ]. |
581 ]. |
582 value := Integer readFrom:source radix:tokenRadix. |
582 value := Integer readFrom:source radix:tokenRadix. |
583 value := value * s. |
583 value := value * s. |
584 nextChar := source peek |
584 nextChar := source peek |
585 ]. |
585 ]. |
586 (nextChar == $.) ifTrue:[ |
586 (nextChar == $.) ifTrue:[ |
587 nextChar := source nextPeek. |
587 nextChar := source nextPeek. |
588 (nextChar notNil and:[nextChar isDigitRadix:tokenRadix]) ifTrue:[ |
588 (nextChar notNil and:[nextChar isDigitRadix:tokenRadix]) ifTrue:[ |
589 value := value asFloat + (self nextMantissa:tokenRadix). |
589 value := value asFloat + (self nextMantissa:tokenRadix). |
590 nextChar := source peek |
590 nextChar := source peek |
591 ] ifFalse:[ |
591 ] ifFalse:[ |
592 nextChar == (Character cr) ifTrue:[ |
592 nextChar == (Character cr) ifTrue:[ |
593 tokenLineNr := tokenLineNr + 1. |
593 tokenLineNr := tokenLineNr + 1. |
594 ]. |
594 ]. |
595 peekChar := $. |
595 peekChar := $. |
596 ] |
596 ] |
597 ]. |
597 ]. |
598 ((nextChar == $e) or:[nextChar == $E]) ifTrue:[ |
598 ((nextChar == $e) or:[nextChar == $E]) ifTrue:[ |
599 nextChar := source nextPeek. |
599 nextChar := source nextPeek. |
600 (nextChar notNil and:[(nextChar isDigitRadix:tokenRadix) or:['+-' includes:nextChar]]) ifTrue:[ |
600 (nextChar notNil and:[(nextChar isDigitRadix:tokenRadix) or:['+-' includes:nextChar]]) ifTrue:[ |
601 s := 1. |
601 s := 1. |
602 (nextChar == $+) ifTrue:[ |
602 (nextChar == $+) ifTrue:[ |
603 nextChar := source nextPeek |
603 nextChar := source nextPeek |
604 ] ifFalse:[ |
604 ] ifFalse:[ |
605 (nextChar == $-) ifTrue:[ |
605 (nextChar == $-) ifTrue:[ |
606 nextChar := source nextPeek. |
606 nextChar := source nextPeek. |
607 s := s negated |
607 s := s negated |
608 ] |
608 ] |
609 ]. |
609 ]. |
610 value := value asFloat |
610 value := value asFloat |
611 * (10.0 raisedToInteger:((Integer readFrom:source radix:tokenRadix) * s)) |
611 * (10.0 raisedToInteger:((Integer readFrom:source radix:tokenRadix) * s)) |
612 ] |
612 ] |
613 ]. |
613 ]. |
614 tokenValue := value. |
614 tokenValue := value. |
615 (value isMemberOf:Float) ifTrue:[ |
615 (value isMemberOf:Float) ifTrue:[ |
616 tokenType := #Float |
616 tokenType := #Float |
617 ] ifFalse:[ |
617 ] ifFalse:[ |
618 tokenType := #Integer |
618 tokenType := #Integer |
619 ]. |
619 ]. |
620 ^ tokenType |
620 ^ tokenType |
621 ! |
621 ! |
622 |
622 |
623 nextId |
623 nextId |
628 nextChar := source peek. |
628 nextChar := source peek. |
629 string := String new:10. |
629 string := String new:10. |
630 index := 0. |
630 index := 0. |
631 max := 10. |
631 max := 10. |
632 [true] whileTrue:[ |
632 [true] whileTrue:[ |
633 (nextChar notNil and:[nextChar isAlphaNumeric]) ifFalse:[ |
633 (nextChar notNil and:[nextChar isLetterOrDigit]) ifFalse:[ |
634 ^ string copyTo:index |
634 ^ string copyTo:index |
635 ]. |
635 ]. |
636 (index == max) ifTrue:[ |
636 (index == max) ifTrue:[ |
637 oldString := string. |
637 oldString := string. |
638 string := String new:(max * 2). |
638 string := String new:(max * 2). |
639 string replaceFrom:1 to:max with:oldString. |
639 string replaceFrom:1 to:max with:oldString. |
640 max := max * 2 |
640 max := max * 2 |
641 ]. |
641 ]. |
642 index := index + 1. |
642 index := index + 1. |
643 string at:index put:nextChar. |
643 string at:index put:nextChar. |
644 nextChar := source nextPeek |
644 nextChar := source nextPeek |
645 ] |
645 ] |
646 ! |
646 ! |
647 |
647 |
648 nextIdentifier |
648 nextIdentifier |
649 |nextChar string firstChar| |
649 |nextChar string firstChar| |
650 |
650 |
651 string := source nextWord "self nextId". |
651 string := source nextWord "self nextId". |
652 nextChar := source peek. |
652 nextChar := source peek. |
653 (nextChar == $:) ifTrue:[ |
653 (nextChar == $:) ifTrue:[ |
654 source next. |
654 source next. |
655 (source peek == $=) ifFalse:[ |
655 (source peek == $=) ifFalse:[ |
656 tokenName := string copyWith:nextChar. |
656 tokenName := string copyWith:nextChar. |
657 tokenType := #Keyword. |
657 tokenType := #Keyword. |
658 ^ self |
658 ^ self |
659 ]. |
659 ]. |
660 peekChar := $_ |
660 peekChar := $_ |
661 ]. |
661 ]. |
662 tokenName := string. |
662 tokenName := string. |
663 firstChar := string at:1. |
663 firstChar := string at:1. |
664 (firstChar == $s) ifTrue:[ |
664 (firstChar == $s) ifTrue:[ |
665 (string = 'self') ifTrue:[tokenType := #Self. ^self]. |
665 (string = 'self') ifTrue:[tokenType := #Self. ^self]. |
666 (string = 'super') ifTrue:[tokenType := #Super. ^self] |
666 (string = 'super') ifTrue:[tokenType := #Super. ^self] |
667 ]. |
667 ]. |
668 (firstChar == $n) ifTrue:[ |
668 (firstChar == $n) ifTrue:[ |
669 (string = 'nil') ifTrue:[tokenType := #Nil. ^self] |
669 (string = 'nil') ifTrue:[tokenType := #Nil. ^self] |
670 ]. |
670 ]. |
671 (firstChar == $t) ifTrue:[ |
671 (firstChar == $t) ifTrue:[ |
672 (string = 'true') ifTrue:[tokenType := #True. ^self]. |
672 (string = 'true') ifTrue:[tokenType := #True. ^self]. |
673 (string = 'thisContext') ifTrue:[tokenType := #ThisContext. ^self] |
673 (string = 'thisContext') ifTrue:[tokenType := #ThisContext. ^self] |
674 ]. |
674 ]. |
675 (firstChar == $f) ifTrue:[ |
675 (firstChar == $f) ifTrue:[ |
676 (string = 'false') ifTrue:[tokenType := #False. ^self] |
676 (string = 'false') ifTrue:[tokenType := #False. ^self] |
677 ]. |
677 ]. |
678 tokenType := #Identifier. |
678 tokenType := #Identifier. |
679 ^ tokenType |
679 ^ tokenType |
680 ! |
680 ! |
681 |
681 |
687 nextChar := source nextPeek. |
687 nextChar := source nextPeek. |
688 string := String new:500. |
688 string := String new:500. |
689 len := 500. |
689 len := 500. |
690 index := 1. |
690 index := 1. |
691 (nextChar == ${) ifTrue:[ |
691 (nextChar == ${) ifTrue:[ |
692 nextChar := source nextPeek. |
692 nextChar := source nextPeek. |
693 inPrimitive := true. |
693 inPrimitive := true. |
694 [inPrimitive] whileTrue:[ |
694 [inPrimitive] whileTrue:[ |
695 [nextChar == $%] whileFalse:[ |
695 [nextChar == $%] whileFalse:[ |
696 string at:index put:nextChar. |
696 string at:index put:nextChar. |
697 (index == len) ifTrue:[ |
697 (index == len) ifTrue:[ |
698 string := string , (String new:len). |
698 string := string , (String new:len). |
699 len := len * 2 |
699 len := len * 2 |
700 ]. |
700 ]. |
701 index := index + 1. |
701 index := index + 1. |
702 nextChar := source next |
702 nextChar := source next |
703 ]. |
703 ]. |
704 (source peek == $}) ifTrue:[ |
704 (source peek == $}) ifTrue:[ |
705 inPrimitive := false |
705 inPrimitive := false |
706 ] ifFalse:[ |
706 ] ifFalse:[ |
707 string at:index put:nextChar. |
707 string at:index put:nextChar. |
708 (index == len) ifTrue:[ |
708 (index == len) ifTrue:[ |
709 string := string , (String new:len). |
709 string := string , (String new:len). |
710 len := len * 2 |
710 len := len * 2 |
711 ]. |
711 ]. |
712 index := index + 1. |
712 index := index + 1. |
713 nextChar := source next |
713 nextChar := source next |
714 ] |
714 ] |
715 ]. |
715 ]. |
716 source next. |
716 source next. |
717 tokenValue := string copyTo:(index - 1). |
717 tokenValue := string copyTo:(index - 1). |
718 tokenType := #Primitive. |
718 tokenType := #Primitive. |
719 tokenLineNr := tokenLineNr + (tokenValue occurrencesOf:(Character cr)). |
719 tokenLineNr := tokenLineNr + (tokenValue occurrencesOf:(Character cr)). |
720 ^ tokenType |
720 ^ tokenType |
721 ]. |
721 ]. |
722 |
722 |
723 "a % alone is a binary operator" |
723 "a % alone is a binary operator" |
724 tokenName := '%'. |
724 tokenName := '%'. |
725 tokenType := #BinaryOperator. |
725 tokenType := #BinaryOperator. |
726 ^ tokenType. |
726 ^ tokenType. |
727 " |
727 " |
728 self syntaxError:('invalid character: ''' , nextChar asString , '''') |
728 self syntaxError:('invalid character: ''' , nextChar asString , '''') |
729 position:tokenPosition to:(tokenPosition + 1). |
729 position:tokenPosition to:(tokenPosition + 1). |
730 ^ #Error |
730 ^ #Error |
731 " |
731 " |
732 ! |
732 ! |
733 |
733 |
734 nextHash |
734 nextHash |
735 |nextChar string| |
735 |nextChar string| |
736 |
736 |
737 nextChar := source nextPeek. |
737 nextChar := source nextPeek. |
738 nextChar notNil ifTrue:[ |
738 nextChar notNil ifTrue:[ |
739 nextChar isAlphaNumeric ifTrue:[ |
739 nextChar isLetterOrDigit ifTrue:[ |
740 string := ''. |
740 string := ''. |
741 [nextChar notNil and:[nextChar isAlphaNumeric]] whileTrue:[ |
741 [nextChar notNil and:[nextChar isLetterOrDigit]] whileTrue:[ |
742 string := string , (source nextWord "self nextId"). |
742 string := string , (source nextWord "self nextId"). |
743 nextChar := source peek. |
743 nextChar := source peek. |
744 (nextChar == $:) ifFalse:[ |
744 (nextChar == $:) ifFalse:[ |
745 tokenValue := string asSymbol. |
745 tokenValue := string asSymbol. |
746 tokenType := #Symbol. |
746 tokenType := #Symbol. |
747 ^ tokenType |
747 ^ tokenType |
748 ]. |
748 ]. |
749 string := string copyWith:nextChar. |
749 string := string copyWith:nextChar. |
750 nextChar := source nextPeek |
750 nextChar := source nextPeek |
751 ]. |
751 ]. |
752 tokenValue := string asSymbol. |
752 tokenValue := string asSymbol. |
753 tokenType := #Symbol. |
753 tokenType := #Symbol. |
754 ^ tokenType |
754 ^ tokenType |
755 ]. |
755 ]. |
756 (nextChar == $( ) ifTrue:[ |
756 (nextChar == $( ) ifTrue:[ |
757 source next. |
757 source next. |
758 tokenType := #HashLeftParen. |
758 tokenType := #HashLeftParen. |
759 ^ tokenType |
759 ^ tokenType |
760 ]. |
760 ]. |
761 (nextChar == $[ ) ifTrue:[ |
761 (nextChar == $[ ) ifTrue:[ |
762 "it seems that ST-80 supports Constant ByteArrays as #[...] |
762 "it seems that ST-80 supports Constant ByteArrays as #[...] |
763 (seen in a PD program)" |
763 (seen in a PD program)" |
764 source next. |
764 source next. |
765 tokenType := #HashLeftBrack. |
765 tokenType := #HashLeftBrack. |
766 ^ tokenType |
766 ^ tokenType |
767 ]. |
767 ]. |
768 (nextChar == $' ) ifTrue:[ |
768 (nextChar == $' ) ifTrue:[ |
769 "it seems that ST-80 supports arbitrary symbols as #'...' |
769 "it seems that ST-80 supports arbitrary symbols as #'...' |
770 (seen in a PD program)" |
770 (seen in a PD program)" |
771 self nextString. |
771 self nextString. |
772 tokenValue := tokenValue asSymbol. |
772 tokenValue := tokenValue asSymbol. |
773 tokenType := #Symbol. |
773 tokenType := #Symbol. |
774 ^ tokenType |
774 ^ tokenType |
775 ]. |
775 ]. |
776 ((TypeArray at:(nextChar asciiValue)) == #special) ifTrue:[ |
776 ((TypeArray at:(nextChar asciiValue)) == #special) ifTrue:[ |
777 string := source next asString. |
777 string := source next asString. |
778 nextChar := source peek. |
778 nextChar := source peek. |
779 nextChar notNil ifTrue:[ |
779 nextChar notNil ifTrue:[ |
780 ((TypeArray at:(nextChar asciiValue)) == #special) ifTrue:[ |
780 ((TypeArray at:(nextChar asciiValue)) == #special) ifTrue:[ |
781 source next. |
781 source next. |
782 string := string copyWith:nextChar |
782 string := string copyWith:nextChar |
783 ] |
783 ] |
784 ]. |
784 ]. |
785 tokenValue := string asSymbol. |
785 tokenValue := string asSymbol. |
786 tokenType := #Symbol. |
786 tokenType := #Symbol. |
787 ^ tokenType |
787 ^ tokenType |
788 ] |
788 ] |
789 ]. |
789 ]. |
790 "this allows hash to be used as binop - |
790 "this allows hash to be used as binop - |
791 I dont know, if this is correct ..." |
791 I dont know, if this is correct ..." |
792 |
792 |
793 tokenName := '#'. |
793 tokenName := '#'. |
794 tokenType := BinaryOperator. |
794 tokenType := #BinaryOperator. |
795 ^ tokenType |
795 ^ tokenType |
796 " |
796 " |
797 self syntaxError:'unexpected end-of-input in Symbol' |
797 self syntaxError:'unexpected end-of-input in Symbol' |
798 position:tokenPosition to:(tokenPosition + 1). |
798 position:tokenPosition to:(tokenPosition + 1). |
799 ^ #Error |
799 ^ #Error |
800 " |
800 " |
801 ! |
801 ! |
802 |
802 |
803 nextString |
803 nextString |
813 source next. |
813 source next. |
814 nextChar := source next. |
814 nextChar := source next. |
815 inString := true. |
815 inString := true. |
816 |
816 |
817 [inString] whileTrue:[ |
817 [inString] whileTrue:[ |
818 nextChar isNil ifTrue:[ |
818 nextChar isNil ifTrue:[ |
819 self syntaxError:'unexpected end-of-input in String' |
819 self syntaxError:'unexpected end-of-input in String' |
820 position:pos to:(source position - 1). |
820 position:pos to:(source position - 1). |
821 tokenType := #EOF. |
821 tokenType := #EOF. |
822 ^ tokenType |
822 ^ tokenType |
823 ]. |
823 ]. |
824 (nextChar == Character cr) ifTrue:[ |
824 (nextChar == Character cr) ifTrue:[ |
825 tokenLineNr := tokenLineNr + 1 |
825 tokenLineNr := tokenLineNr + 1 |
826 ]. |
826 ]. |
827 (nextChar == Character quote) ifTrue:[ |
827 (nextChar == Character quote) ifTrue:[ |
828 (source peek == Character quote) ifTrue:[ |
828 (source peek == Character quote) ifTrue:[ |
829 source next |
829 source next |
830 ] ifFalse:[ |
830 ] ifFalse:[ |
831 inString := false |
831 inString := false |
832 ] |
832 ] |
833 ]. |
833 ]. |
834 inString ifTrue:[ |
834 inString ifTrue:[ |
835 string at:index put:nextChar. |
835 string at:index put:nextChar. |
836 (index == len) ifTrue:[ |
836 (index == len) ifTrue:[ |
837 string := string , (String new:len). |
837 string := string , (String new:len). |
838 len := len * 2 |
838 len := len * 2 |
839 ]. |
839 ]. |
840 index := index + 1. |
840 index := index + 1. |
841 nextChar := source next |
841 nextChar := source next |
842 ] |
842 ] |
843 ]. |
843 ]. |
844 tokenValue := string copyTo:(index - 1). |
844 tokenValue := string copyTo:(index - 1). |
845 tokenType := #String. |
845 tokenType := #String. |
846 ^ tokenType |
846 ^ tokenType |
847 ! ! |
847 ! ! |