author | Claus Gittinger <cg@exept.de> |
Fri, 21 Feb 2020 20:48:14 +0100 | |
changeset 1231 | b7d945ef967a |
parent 1215 | 52483990fec6 |
permissions | -rw-r--r-- |
30 | 1 |
" |
2 |
COPYRIGHT (c) 1998 by eXept Software AG |
|
40 | 3 |
All Rights Reserved |
30 | 4 |
|
5 |
This software is furnished under a license and may be used |
|
6 |
only in accordance with the terms of that license and with the |
|
7 |
inclusion of the above copyright notice. This software may not |
|
8 |
be provided or otherwise made available to, or used by, any |
|
9 |
other person. No title to or ownership of the software is |
|
10 |
hereby transferred. |
|
11 |
" |
|
47 | 12 |
"{ Package: 'stx:libjavascript' }" |
30 | 13 |
|
856 | 14 |
"{ NameSpace: Smalltalk }" |
15 |
||
7 | 16 |
Scanner subclass:#JavaScriptScanner |
1102 | 17 |
instanceVariableNames:'allowDegeneratedMantissa acceptRegexString previousToken' |
18 |
classVariableNames:'Verbose SupportRegex' |
|
7 | 19 |
poolDictionaries:'' |
47 | 20 |
category:'Languages-JavaScript-Compiling & Parsing' |
7 | 21 |
! |
22 |
||
23 |
!JavaScriptScanner class methodsFor:'documentation'! |
|
24 |
||
30 | 25 |
copyright |
26 |
" |
|
27 |
COPYRIGHT (c) 1998 by eXept Software AG |
|
40 | 28 |
All Rights Reserved |
30 | 29 |
|
30 |
This software is furnished under a license and may be used |
|
31 |
only in accordance with the terms of that license and with the |
|
32 |
inclusion of the above copyright notice. This software may not |
|
33 |
be provided or otherwise made available to, or used by, any |
|
34 |
other person. No title to or ownership of the software is |
|
35 |
hereby transferred. |
|
36 |
" |
|
37 |
! |
|
38 |
||
1102 | 39 |
documentation |
40 |
" |
|
41 |
tokenizer for JavaScript |
|
1103 | 42 |
|
43 |
news: |
|
44 |
does regex '/pattern/' vs. division operator |
|
45 |
determination via a rule described in |
|
46 |
https://www-archive.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions |
|
47 |
if that makes problems, set the variable: |
|
48 |
SupportRegex |
|
49 |
to false, to get the previous behavior (which is: not supporting regex) |
|
1102 | 50 |
" |
51 |
! |
|
52 |
||
7 | 53 |
examples |
1102 | 54 |
"<<END |
55 |
[exBegin] |
|
7 | 56 |
|s in| |
57 |
||
58 |
in := ' |
|
59 |
function scalefactor(value) { |
|
60 |
scalevector[0]=value; |
|
61 |
scalevector[1]=1.; |
|
62 |
scalevector[2]=1.; |
|
63 |
} |
|
64 |
'. |
|
65 |
||
66 |
s := JavaScriptScanner for:in readStream. |
|
67 |
s nextToken |
|
1102 | 68 |
[exEnd] |
7 | 69 |
|
1102 | 70 |
[exBegin] |
7 | 71 |
|s in| |
72 |
||
73 |
in := ' |
|
74 |
function scalefactor(value) { |
|
75 |
scalevector[0]=value; |
|
76 |
scalevector[1]=1.; |
|
77 |
scalevector[2]=1.; |
|
78 |
} |
|
79 |
'. |
|
80 |
s := JavaScriptScanner new. |
|
81 |
s scanTokens:(in readStream). |
|
1102 | 82 |
[exEnd] |
83 |
||
84 |
[exBegin] |
|
85 |
|s in| |
|
86 |
||
87 |
in := ' |
|
88 |
function scalefactor(value) { |
|
89 |
return "hello"; |
|
90 |
} |
|
91 |
'. |
|
92 |
s := JavaScriptScanner new. |
|
93 |
s scanTokens:(in readStream). |
|
94 |
[exEnd] |
|
95 |
||
96 |
[exBegin] |
|
97 |
|s in| |
|
98 |
||
99 |
in := ' |
|
100 |
function scalefactor(value) { |
|
101 |
return /hello/; |
|
102 |
} |
|
103 |
'. |
|
104 |
in := in readStream. |
|
105 |
s := JavaScriptScanner for:in. |
|
106 |
[in atEnd] whileFalse:[ |
|
107 |
Transcript showCR:s nextToken |
|
108 |
] |
|
109 |
[exEnd] |
|
110 |
||
111 |
[exBegin] |
|
112 |
|s in| |
|
113 |
||
114 |
in := ' |
|
115 |
function scalefactor(value) { |
|
116 |
return a /hello/; |
|
117 |
} |
|
118 |
'. |
|
119 |
in := in readStream. |
|
120 |
s := JavaScriptScanner for:in. |
|
121 |
[in atEnd] whileFalse:[ |
|
122 |
Transcript showCR:s nextToken |
|
123 |
] |
|
124 |
[exEnd] |
|
125 |
END" |
|
7 | 126 |
|
127 |
"Created: / 13.5.1998 / 14:54:06 / cg" |
|
128 |
! ! |
|
129 |
||
130 |
!JavaScriptScanner class methodsFor:'initialization'! |
|
131 |
||
132 |
setupActions |
|
133 |
"initialize the scanners actionTables - these are used to dispatch |
|
1088 | 134 |
into scanner methods as characters are read |
135 |
Notice, this is only called if ActionArray is nil. |
|
136 |
ActionArray := nil |
|
137 |
" |
|
7 | 138 |
|
1033 | 139 |
|block actionArray typeArray| |
7 | 140 |
|
1033 | 141 |
actionArray := Array new:256. |
142 |
typeArray := Array new:256. |
|
7 | 143 |
|
144 |
block := [:s :char | s nextNumber]. |
|
1033 | 145 |
actionArray from:($0 codePoint) to:($9 codePoint) put:block. |
7 | 146 |
|
147 |
block := [:s :char | s nextToken:char]. |
|
148 | 148 |
#( $: $; $. $, ${ $} $( $) $[ $] $_ $? $~) do:[:ch | |
1033 | 149 |
actionArray at:(ch codePoint) put:block |
7 | 150 |
]. |
151 |
||
152 |
block := [:s :char | s nextIdentifier]. |
|
1033 | 153 |
actionArray from:($a codePoint) to:($z codePoint) put:block. |
154 |
actionArray from:($A codePoint) to:($Z codePoint) put:block. |
|
155 |
actionArray at:$_ codePoint put:block. |
|
7 | 156 |
|
1033 | 157 |
actionArray at:($' codePoint) put:[:s :char | s nextString ]. |
158 |
actionArray at:($" codePoint) put:[:s :char | s nextString ]. |
|
1195 | 159 |
actionArray at:($` codePoint) put:[:s :char | s nextString ]. |
1033 | 160 |
actionArray at:($!! codePoint) put:[:s :char | s nextMulti:#(($= #'!!=' (($= #'!!==')))) after:char]. |
161 |
actionArray at:($= codePoint) put:[:s :char | s nextMulti:#(($> #'=>') ($= #'==' (($= #'===')))) after:char]. |
|
162 |
actionArray at:($< codePoint) put:[:s :char | s nextMulti:#(($= #'<=') ($< #'<<' (($= #'<<=')))) after:char]. |
|
163 |
actionArray at:($> codePoint) put:[:s :char | s nextMulti:#(($= #'>=') ($> #'>>' (($> #'>>>') ($= #'>>=') ))) after:char]. |
|
7 | 164 |
|
1033 | 165 |
actionArray at:($- codePoint) put:[:s :char | s nextMulti:#(($- #'--') ($= #'-=')) after:char]. |
166 |
actionArray at:($+ codePoint) put:[:s :char | s nextMulti:#(($+ #'++') ($= #'+=')) after:char]. |
|
167 |
actionArray at:($: codePoint) put:[:s :char | s nextMulti:#(($: #'::')) after:char]. |
|
1184 | 168 |
actionArray at:($* codePoint) put:[:s :char | s nextMulti:#(($= #'*=') ($* #'**' (($= #'**=')))) after:char]. |
1102 | 169 |
actionArray at:($/ codePoint) put:[:s :char | s nextSlash]. |
1033 | 170 |
actionArray at:($% codePoint) put:[:s :char | s nextMulti:#(($= #'%=')) after:char]. |
171 |
actionArray at:($& codePoint) put:[:s :char | s nextMulti:#(($= #'&=') ($& #'&&')) after:char]. |
|
172 |
actionArray at:($^ codePoint) put:[:s :char | s nextMulti:#(($= #'^=')) after:char]. |
|
173 |
actionArray at:($| codePoint) put:[:s :char | s nextMulti:#(($= #'|=') ($| #'||')) after:char]. |
|
174 |
actionArray at:($$ codePoint) put:[:s :char | s nextCharacter ]. |
|
1085 | 175 |
actionArray at:($# codePoint) put:[:s :char | s nextSymbol ]. |
7 | 176 |
|
1033 | 177 |
ActionArray := actionArray. |
178 |
TypeArray := typeArray. |
|
179 |
UnicodeActions := Dictionary new. |
|
180 |
||
7 | 181 |
" |
182 |
JavaScriptScanner setupActions |
|
1184 | 183 |
JavaScriptParser setupActions |
184 |
JavaScriptCompiler setupActions |
|
185 |
JavaScriptSyntaxHighlighter setupActions |
|
1185 | 186 |
self withAllSubclassesDo:#setupActions |
7 | 187 |
" |
188 |
||
1011 | 189 |
"Created: / 14-05-1998 / 15:48:03 / cg" |
190 |
"Modified: / 17-05-1998 / 21:03:37 / cg" |
|
1088 | 191 |
"Modified (comment): / 09-06-2019 / 17:04:10 / Claus Gittinger" |
7 | 192 |
! ! |
193 |
||
1102 | 194 |
!JavaScriptScanner class methodsFor:'class initialization'! |
195 |
||
196 |
initialize |
|
197 |
SupportRegex := true. |
|
1106 | 198 |
"/ super initialize. -- no need for that |
1102 | 199 |
! ! |
200 |
||
285 | 201 |
!JavaScriptScanner methodsFor:'accessing'! |
202 |
||
203 |
tokenType |
|
204 |
^ tokenType |
|
205 |
! ! |
|
206 |
||
7 | 207 |
!JavaScriptScanner methodsFor:'initialization'! |
208 |
||
209 |
initialize |
|
210 |
"initialize the scanner" |
|
211 |
||
212 |
super initialize. |
|
213 |
||
214 |
"/ have my own tables ... |
|
215 |
||
176 | 216 |
self allowUnderscoreInIdentifier:true. |
217 |
self allowDollarInIdentifier:false. |
|
193 | 218 |
self allowOldStyleAssignment:false. |
219 |
parserFlags allowNationalCharactersInIdentifier:false. |
|
220 |
parserFlags allowQualifiedNames:false. |
|
221 |
||
7 | 222 |
allowDegeneratedMantissa := true. "/ something like 123. |
27 | 223 |
scanColonAsKeyword := false. |
7 | 224 |
|
298 | 225 |
actionArray := self class actionArray. |
226 |
typeArray := self class typeArray. |
|
7 | 227 |
|
228 |
"Created: / 14.5.1998 / 15:48:04 / cg" |
|
27 | 229 |
"Modified: / 26.10.1998 / 14:50:26 / cg" |
7 | 230 |
! ! |
231 |
||
232 |
!JavaScriptScanner methodsFor:'private'! |
|
233 |
||
234 |
checkForKeyword:string |
|
235 |
"check if string is a keyword (as opposed to an identifier)." |
|
236 |
||
237 |
|firstChar| |
|
238 |
||
239 |
firstChar := string at:1. |
|
240 |
(firstChar == $b) ifTrue:[ |
|
55 | 241 |
(string = 'break') ifTrue:[tokenType := #break. ^true]. |
932 | 242 |
^ false |
7 | 243 |
]. |
244 |
(firstChar == $c) ifTrue:[ |
|
55 | 245 |
(string = 'continue') ifTrue:[tokenType := #continue. ^true]. |
139 | 246 |
(string = 'case') ifTrue:[tokenType := #case. ^true]. |
171 | 247 |
(string = 'catch') ifTrue:[tokenType := #catch. ^true]. |
932 | 248 |
(string = 'const') ifTrue:[ |
249 |
parserFlags allowJavaScriptConst ifTrue:[ |
|
250 |
tokenType := #const. ^true |
|
251 |
]. |
|
252 |
]. |
|
253 |
^ false |
|
139 | 254 |
]. |
255 |
(firstChar == $d) ifTrue:[ |
|
256 |
(string = 'default') ifTrue:[tokenType := #default. ^true]. |
|
153 | 257 |
"/ do is not a keyword - it is also allowed as identifier |
932 | 258 |
^ false |
7 | 259 |
]. |
260 |
(firstChar == $e) ifTrue:[ |
|
55 | 261 |
(string = 'else') ifTrue:[tokenType := #else. ^true]. |
932 | 262 |
^ false |
7 | 263 |
]. |
264 |
(firstChar == $f) ifTrue:[ |
|
55 | 265 |
(string = 'function') ifTrue:[tokenType := #function. ^true]. |
266 |
(string = 'for') ifTrue:[tokenType := #for. ^true]. |
|
139 | 267 |
"/ (string = 'foreach') ifTrue:[tokenType := #foreach. ^true]. |
55 | 268 |
(string = 'false') ifTrue:[tokenType := #false. tokenValue := false. ^true]. |
199 | 269 |
(string = 'finally') ifTrue:[tokenType := #finally. tokenValue := false. ^true]. |
932 | 270 |
^ false |
7 | 271 |
]. |
272 |
(firstChar == $i) ifTrue:[ |
|
55 | 273 |
(string = 'if') ifTrue:[tokenType := #if. ^true]. |
1215 | 274 |
"/ import is done as Identifier - not supported by |
1214 | 275 |
"/ (string = 'import') ifTrue:[tokenType := #import. ^true]. |
932 | 276 |
^ false |
7 | 277 |
]. |
979 | 278 |
(firstChar == $l) ifTrue:[ |
980 | 279 |
(string = 'let') ifTrue:[tokenType := #let. ^true]. |
979 | 280 |
^ false |
281 |
]. |
|
29 | 282 |
(firstChar == $n) ifTrue:[ |
55 | 283 |
(string = 'null') ifTrue:[tokenType := #null. tokenValue := nil. ^true]. |
284 |
(string = 'nil') ifTrue:[tokenType := #null. tokenValue := nil. ^true]. |
|
932 | 285 |
^ false |
29 | 286 |
]. |
287 |
(firstChar == $r) ifTrue:[ |
|
55 | 288 |
(string = 'return') ifTrue:[tokenType := #return. ^true]. |
932 | 289 |
^ false |
7 | 290 |
]. |
139 | 291 |
(firstChar == $s) ifTrue:[ |
436 | 292 |
"/ (string = 'static') ifTrue:[tokenType := #static. ^true]. - handled as identifier |
1026 | 293 |
"/ (string = 'synchronized') ifTrue:[tokenType := #synchronized. ^true]. |
294 |
"/ (string = 'short') ifTrue:[tokenType := #short. ^true]. |
|
746 | 295 |
(string = 'super') ifTrue:[tokenType := #super. ^true]. |
139 | 296 |
(string = 'switch') ifTrue:[tokenType := #switch. ^true]. |
932 | 297 |
^ false |
139 | 298 |
]. |
7 | 299 |
(firstChar == $t) ifTrue:[ |
55 | 300 |
(string = 'this') ifTrue:[tokenType := #this. ^true]. |
171 | 301 |
(string = 'try') ifTrue:[tokenType := #try. ^true]. |
55 | 302 |
(string = 'true') ifTrue:[tokenType := #true. tokenValue := true. ^true]. |
280 | 303 |
(string = 'throw') ifTrue:[tokenType := #throw. ^true]. |
1026 | 304 |
"/ (string = 'transient') ifTrue:[tokenType := #transient. ^true]. |
305 |
"/ (string = 'throws') ifTrue:[tokenType := #throws. ^true]. |
|
442 | 306 |
(string = 'typeof') ifTrue:[tokenType := #typeof. ^true]. |
932 | 307 |
^ false |
7 | 308 |
]. |
772 | 309 |
(firstChar == $u) ifTrue:[ |
310 |
(string = 'undefined') ifTrue:[tokenType := #null. tokenValue := nil. ^true]. |
|
932 | 311 |
^ false |
772 | 312 |
]. |
29 | 313 |
(firstChar == $v) ifTrue:[ |
55 | 314 |
(string = 'var') ifTrue:[tokenType := #var. ^true]. |
1026 | 315 |
(string = 'void') ifTrue:[tokenType := #void. tokenValue := Void. ^true]. "/ - handled as identifier |
316 |
"/ (string = 'volatile') ifTrue:[tokenType := #volatile. ^true]. |
|
932 | 317 |
^ false |
7 | 318 |
]. |
319 |
(firstChar == $w) ifTrue:[ |
|
55 | 320 |
(string = 'with') ifTrue:[tokenType := #with. ^true]. |
321 |
(string = 'while') ifTrue:[tokenType := #while. ^true]. |
|
932 | 322 |
^ false |
7 | 323 |
]. |
324 |
^ false |
|
325 |
||
442 | 326 |
"Created: / 14-05-1998 / 15:48:04 / cg" |
932 | 327 |
"Modified: / 09-08-2017 / 00:03:56 / cg" |
1026 | 328 |
"Modified: / 31-08-2018 / 12:55:31 / Claus Gittinger" |
7 | 329 |
! |
330 |
||
517 | 331 |
handleCategoryDirective:categoryString |
332 |
"called when encountering a /** category: xxxx **/ comment; |
|
333 |
categoryString will be xxxx. |
|
334 |
Can be redefined in subclasses" |
|
335 |
||
336 |
"Created: / 26-10-2011 / 17:47:28 / cg" |
|
337 |
! |
|
338 |
||
339 |
handleCommentDirectivesIn:commentText |
|
340 |
"/ called for the text after the initial "/*" |
|
341 |
||
342 |
|plainText| |
|
343 |
||
344 |
(commentText endsWith:'**/') ifFalse:[^ self]. |
|
345 |
(commentText startsWith:'* ') ifFalse:[^ self]. |
|
346 |
||
587
ec6e40cf9b82
Changed usage of deprecated #copyWithoutLast: to #copyButLast:
Stefan Vogel <sv@exept.de>
parents:
580
diff
changeset
|
347 |
plainText := commentText copyButLast:3. |
517 | 348 |
plainText := plainText copyFrom:3. |
349 |
||
350 |
(plainText startsWith:'category: ') ifTrue:[ |
|
351 |
self handleCategoryDirective:(plainText copyFrom:'category: ' size+1) withoutSeparators. |
|
352 |
^ self. |
|
353 |
]. |
|
354 |
||
355 |
"Created: / 26-10-2011 / 17:39:35 / cg" |
|
356 |
! |
|
357 |
||
7 | 358 |
isCommentCharacter:ch |
359 |
"return true, if ch is the comment-start character" |
|
360 |
||
361 |
^ false |
|
362 |
||
363 |
"Created: / 14.5.1998 / 20:53:33 / cg" |
|
1102 | 364 |
! |
365 |
||
366 |
previousTokenInitiatesRegexForSlash |
|
367 |
"read |
|
368 |
https://www-archive.mozilla.org/js/language/js20-2002-04/rationale/syntax.html#regular-expressions |
|
369 |
for an explanation" |
|
370 |
||
371 |
^ (#( |
|
372 |
nil |
|
373 |
'!!' '!!=' '!!==' |
|
374 |
'#' '%' '%=' |
|
375 |
'&' '&&' '&&=' '&=' |
|
376 |
'(' |
|
377 |
'*' '*=' |
|
378 |
'+' '+=' |
|
379 |
',' |
|
380 |
'-' '-=' '->' |
|
381 |
'.' '..' '...' |
|
382 |
'/' '/=' |
|
383 |
':' '::' |
|
384 |
';' |
|
385 |
'<' '<<' '<<=' '<=' '=' '==' '===' |
|
386 |
'>' '>=' '>>' '>>=' '>>>' '>>>=' |
|
387 |
'?' '@' '[' '^' '^=' '^^' '^^=' |
|
388 |
'{' '|' '|=' '||' '||=' '~' |
|
389 |
'abstract' 'break' 'case' 'catch' 'const' 'continue' |
|
390 |
'debugger' 'default' 'delete' 'do' |
|
391 |
'else' 'enum' 'export' 'extends' |
|
392 |
'final' 'finally' 'for' 'function' |
|
393 |
'goto' |
|
394 |
'if' 'implements' 'import' 'in' 'instanceof' 'interface' 'is' |
|
395 |
'namespace' 'native' 'new' 'package' |
|
396 |
'return' 'static' 'switch' 'synchronized' |
|
397 |
'throw' 'throws' 'transient' 'try' 'typeof' |
|
398 |
'use' 'var' 'volatile' 'while' 'with' |
|
399 |
) includes:previousToken) |
|
7 | 400 |
! ! |
401 |
||
402 |
!JavaScriptScanner methodsFor:'reading next token'! |
|
403 |
||
144 | 404 |
hex2CharacterEscape |
405 |
|x1 x2| |
|
406 |
||
407 |
x1 := source next. |
|
408 |
x2 := source next. |
|
517 | 409 |
|
144 | 410 |
(x1 isNil or:[x2 isNil]) ifTrue:[ |
411 |
self syntaxError:'unexpected end-of-input in String' |
|
412 |
position:tokenPosition to:(source position - 1). |
|
413 |
self markStringFrom:tokenPosition to:source position-1. |
|
414 |
^ nil. |
|
415 |
]. |
|
416 |
((x1 isDigitRadix:16) and:[(x2 isDigitRadix:16)]) ifFalse:[ |
|
417 |
self syntaxError:'invalid hex-character escape' |
|
418 |
position:tokenPosition to:(source position - 1). |
|
419 |
^ Character value:0 |
|
420 |
]. |
|
421 |
^ Character value:((x1 digitValue * 16) + (x2 digitValue)) |
|
517 | 422 |
|
423 |
"Modified: / 26-10-2011 / 17:15:49 / cg" |
|
144 | 424 |
! |
425 |
||
426 |
hex4CharacterEscape |
|
427 |
|x1 x2 x3 x4| |
|
428 |
||
429 |
x1 := source next. |
|
430 |
x2 := source next. |
|
431 |
x3 := source next. |
|
432 |
x4 := source next. |
|
517 | 433 |
|
144 | 434 |
(x1 isNil or:[x2 isNil or:[x3 isNil or:[x4 isNil]]]) ifTrue:[ |
435 |
self syntaxError:'unexpected end-of-input in String' |
|
436 |
position:tokenPosition to:(source position - 1). |
|
437 |
self markStringFrom:tokenPosition to:source position-1. |
|
438 |
^ nil. |
|
439 |
]. |
|
440 |
((x1 isDigitRadix:16) |
|
441 |
and:[(x2 isDigitRadix:16) |
|
442 |
and:[(x3 isDigitRadix:16) |
|
443 |
and:[(x4 isDigitRadix:16)]]]) ifFalse:[ |
|
444 |
self syntaxError:'invalid hex-character escape' |
|
445 |
position:tokenPosition to:(source position - 1). |
|
446 |
^ Character value:0 |
|
447 |
]. |
|
448 |
^ Character value:(((((x1 digitValue * 16) + (x2 digitValue)) * 16) + (x3 digitValue)) * 16) + (x4 digitValue). |
|
517 | 449 |
|
450 |
"Modified: / 26-10-2011 / 17:15:45 / cg" |
|
144 | 451 |
! |
452 |
||
193 | 453 |
nextCharacter |
1085 | 454 |
"this is a special (non-JavaScript) extension to support $'x' for character literals" |
455 |
||
639 | 456 |
|pos| |
193 | 457 |
|
458 |
pos := tokenPosition. |
|
459 |
source next. |
|
460 |
||
461 |
(hereChar := source peek) == $' ifTrue:[ |
|
462 |
^ self nextStringOrCharacter:true |
|
463 |
]. |
|
464 |
||
1091 | 465 |
self syntaxError:'incorrect character constant (expected $''x'')' |
639 | 466 |
position:pos to:(source position). |
1085 | 467 |
|
1091 | 468 |
"Modified: / 15-06-2019 / 09:56:53 / Claus Gittinger" |
193 | 469 |
! |
470 |
||
7 | 471 |
nextMulti:list after:firstChar |
472 |
"a char has been read - peek ahead in list" |
|
473 |
||
474 |
|pc| |
|
475 |
||
476 |
peekChar isNil ifTrue:[ |
|
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
477 |
source next. |
7 | 478 |
] ifFalse:[ |
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
479 |
peekChar := nil. |
7 | 480 |
]. |
481 |
pc := source peek. |
|
482 |
||
483 |
list do:[:spec | |
|
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
484 |
|ch tok idx chOrSelectorOrSpec| |
7 | 485 |
|
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
486 |
ch := spec at:1. |
7 | 487 |
|
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
488 |
pc == ch ifTrue:[ |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
489 |
tok := spec at:2. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
490 |
idx := 3. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
491 |
|
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
492 |
peekChar isNil ifTrue:[ |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
493 |
source next. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
494 |
] ifFalse:[ |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
495 |
peekChar := nil. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
496 |
]. |
7 | 497 |
|
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
498 |
spec size > 2 ifTrue:[ |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
499 |
"/ continue |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
500 |
chOrSelectorOrSpec := (spec at:3). |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
501 |
chOrSelectorOrSpec isArray ifTrue:[ |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
502 |
peekChar := source peek. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
503 |
^ self nextMulti:chOrSelectorOrSpec after:tok. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
504 |
]. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
505 |
source peek == chOrSelectorOrSpec ifTrue:[ |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
506 |
source next. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
507 |
tok := spec at:4. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
508 |
idx := 5. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
509 |
] |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
510 |
]. |
7 | 511 |
|
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
512 |
tok isNil ifTrue:[ |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
513 |
^ self perform:(spec at:idx). |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
514 |
]. |
9 | 515 |
|
147
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
516 |
tokenType := token := tok. |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
517 |
^ tokenType |
d781c3f05226
scanner fixes (3-char-operators)
Claus Gittinger <cg@exept.de>
parents:
144
diff
changeset
|
518 |
] |
7 | 519 |
]. |
520 |
||
521 |
tokenType := token := firstChar. |
|
522 |
^ tokenType |
|
523 |
||
524 |
"Created: / 14.5.1998 / 19:19:34 / cg" |
|
9 | 525 |
"Modified: / 16.5.1998 / 19:09:59 / cg" |
7 | 526 |
! |
527 |
||
528 |
nextNumber |
|
121 | 529 |
|nextChar value s| |
7 | 530 |
|
531 |
value := 0. |
|
532 |
nextChar := source peekOrNil. |
|
533 |
nextChar == $0 ifTrue:[ |
|
121 | 534 |
source next. |
535 |
nextChar := source peekOrNil. |
|
128 | 536 |
nextChar isNil ifTrue:[ |
537 |
tokenValue := token := value. |
|
538 |
tokenType := #Integer. |
|
539 |
^ tokenType |
|
540 |
]. |
|
121 | 541 |
(nextChar == $x or:[nextChar == $X]) ifTrue:[ |
542 |
source next. |
|
543 |
value := Integer readFrom:source radix:16. |
|
7 | 544 |
|
121 | 545 |
tokenValue := token := value. |
546 |
tokenType := #Integer. |
|
547 |
^ tokenType |
|
548 |
]. |
|
742 | 549 |
(nextChar == $b or:[nextChar == $b]) ifTrue:[ |
550 |
source next. |
|
551 |
value := Integer readFrom:source radix:2. |
|
552 |
||
553 |
tokenValue := token := value. |
|
554 |
tokenType := #Integer. |
|
555 |
^ tokenType |
|
556 |
]. |
|
121 | 557 |
(nextChar between:$0 and:$7) ifTrue:[ |
558 |
value := Integer readFrom:source radix:8. |
|
559 |
tokenValue := token := value. |
|
560 |
tokenType := #Integer. |
|
561 |
^ tokenType |
|
562 |
]. |
|
7 | 563 |
]. |
564 |
||
565 |
nextChar isDigit ifTrue:[ |
|
121 | 566 |
value := Integer readFrom:source radix:10. |
567 |
nextChar := source peekOrNil. |
|
7 | 568 |
]. |
569 |
||
570 |
(nextChar == $.) ifTrue:[ |
|
121 | 571 |
nextChar := source nextPeek. |
572 |
(nextChar notNil and:[nextChar isDigitRadix:10]) ifTrue:[ |
|
573 |
value := value asFloat + (self nextMantissaAndScaledPartWithRadix:10) first. |
|
574 |
nextChar := source peekOrNil |
|
575 |
] ifFalse:[ |
|
576 |
allowDegeneratedMantissa == true ifTrue:[ |
|
197 | 577 |
(nextChar notNil and:[nextChar isSeparator]) ifTrue:[ |
578 |
self warning:'degenerated float constant: ' , value printString , '.' . |
|
579 |
tokenValue := token := value asFloat. |
|
580 |
tokenType := #Float. |
|
581 |
^ tokenType |
|
582 |
]. |
|
121 | 583 |
]. |
7 | 584 |
|
585 |
"/ nextChar == (Character cr) ifTrue:[ |
|
586 |
"/ lineNr := lineNr + 1. |
|
587 |
"/ ]. |
|
121 | 588 |
nextChar := peekChar := $.. |
589 |
] |
|
7 | 590 |
]. |
591 |
((nextChar == $e) or:[nextChar == $E]) ifTrue:[ |
|
121 | 592 |
nextChar := source nextPeek. |
593 |
(nextChar notNil and:[(nextChar isDigitRadix:10) or:['+-' includes:nextChar]]) ifTrue:[ |
|
594 |
s := 1. |
|
595 |
(nextChar == $+) ifTrue:[ |
|
596 |
nextChar := source nextPeek |
|
597 |
] ifFalse:[ |
|
598 |
(nextChar == $-) ifTrue:[ |
|
599 |
nextChar := source nextPeek. |
|
600 |
s := s negated |
|
601 |
] |
|
602 |
]. |
|
603 |
value := value asFloat |
|
604 |
* (10.0 raisedToInteger:((Integer readFrom:source radix:10) * s)) |
|
605 |
] |
|
7 | 606 |
]. |
607 |
nextChar == $- ifTrue:[ |
|
121 | 608 |
self |
609 |
warnPossibleIncompatibility:'add a space before ''-'' for compatibility with other systems' |
|
139 | 610 |
position:(source position) to:(source position). |
7 | 611 |
]. |
612 |
||
613 |
tokenValue := token := value. |
|
121 | 614 |
(value isLimitedPrecisionReal) ifTrue:[ |
615 |
(nextChar == $d) ifTrue:[ |
|
616 |
source next |
|
617 |
]. |
|
618 |
tokenType := #Float |
|
7 | 619 |
] ifFalse:[ |
121 | 620 |
tokenType := #Integer |
7 | 621 |
]. |
622 |
"/ self markConstantFrom:tokenPosition to:(source position - 1). |
|
623 |
^ tokenType |
|
624 |
||
625 |
"Created: / 14.5.1998 / 20:00:25 / cg" |
|
626 |
"Modified: / 16.5.1998 / 15:51:46 / cg" |
|
627 |
! |
|
628 |
||
1102 | 629 |
nextRegex |
630 |
"notice: initial '/' has already been read" |
|
631 |
||
632 |
|delimiter s pos endPos nextChar inString badEscapeChar| |
|
633 |
||
634 |
delimiter := hereChar. |
|
635 |
||
636 |
s := (String new:20) writeStream. |
|
637 |
pos := tokenPosition. |
|
638 |
nextChar := source next. |
|
639 |
inString := true. |
|
640 |
||
641 |
[inString] whileTrue:[ |
|
642 |
nextChar isNil ifTrue:[ |
|
643 |
self syntaxError:'unexpected end-of-input in String' |
|
644 |
position:pos to:(source position). |
|
645 |
self markStringFrom:pos to:source position. |
|
646 |
token := tokenName := nil. |
|
647 |
tokenType := #EOF. |
|
648 |
^ tokenType |
|
649 |
]. |
|
650 |
||
651 |
nextChar == $\ ifTrue:[ |
|
652 |
nextChar := source next. |
|
653 |
nextChar == $b ifTrue:[ |
|
654 |
nextChar := Character backspace |
|
655 |
] ifFalse:[ nextChar == $t ifTrue:[ |
|
656 |
nextChar := Character tab |
|
657 |
] ifFalse:[ nextChar == $n ifTrue:[ |
|
658 |
nextChar := Character cr |
|
659 |
] ifFalse:[ nextChar == $r ifTrue:[ |
|
660 |
nextChar := Character return |
|
661 |
] ifFalse:[ nextChar == $f ifTrue:[ |
|
662 |
nextChar := Character newPage |
|
663 |
] ifFalse:[ nextChar == $x ifTrue:[ |
|
664 |
nextChar := self hex2CharacterEscape. |
|
665 |
nextChar isNil ifTrue:[ |
|
666 |
token := tokenName := nil. |
|
667 |
tokenType := #EOF. |
|
668 |
^ tokenType |
|
669 |
]. |
|
670 |
] ifFalse:[ nextChar == $u ifTrue:[ |
|
671 |
nextChar := self hex4CharacterEscape. |
|
672 |
nextChar isNil ifTrue:[ |
|
673 |
token := nil. |
|
674 |
tokenType := tokenName := #EOF. |
|
675 |
^ tokenType |
|
676 |
]. |
|
677 |
] ifFalse:[ nextChar == Character cr ifTrue:[ |
|
678 |
nextChar := nil |
|
679 |
] ifFalse:[ |
|
680 |
((nextChar == $') or:[nextChar == $" or:[nextChar == $\]]) ifFalse:[ |
|
681 |
parserFlags warnAboutUnknownCharacterEscapesInJavaScriptStringConstant ifTrue:[ |
|
682 |
badEscapeChar isNil ifTrue:[ badEscapeChar := nextChar asString ] |
|
683 |
]. |
|
684 |
] |
|
685 |
]]]]]]]] |
|
686 |
] ifFalse:[ |
|
687 |
(nextChar == Character cr) ifTrue:[ |
|
688 |
lineNr := lineNr + 1 |
|
689 |
] ifFalse:[ |
|
690 |
(nextChar == delimiter) ifTrue:[ |
|
691 |
(source peekOrNil == delimiter) ifTrue:[ |
|
692 |
source next |
|
693 |
] ifFalse:[ |
|
694 |
inString := false |
|
695 |
] |
|
696 |
]. |
|
697 |
]. |
|
698 |
]. |
|
699 |
inString ifTrue:[ |
|
700 |
nextChar notNil ifTrue:[ |
|
701 |
nextChar bitsPerCharacter > s contents bitsPerCharacter ifTrue:[ |
|
702 |
s setCollection:(nextChar stringSpecies fromString:s collection). |
|
703 |
]. |
|
704 |
s nextPut:nextChar. |
|
705 |
]. |
|
706 |
nextChar := source next |
|
707 |
] |
|
708 |
]. |
|
709 |
endPos := source position. |
|
710 |
self markStringFrom:pos to:endPos. |
|
711 |
badEscapeChar notNil ifTrue:[ |
|
712 |
self warning:('Unknown character escape: "\',badEscapeChar asString,'"') position:pos to:endPos. |
|
713 |
]. |
|
714 |
||
715 |
tokenValue := token := s contents. |
|
716 |
tokenType := #Regex. |
|
717 |
^ tokenType |
|
718 |
! |
|
719 |
||
720 |
nextSlash |
|
721 |
|pc| |
|
722 |
||
723 |
(SupportRegex == true |
|
724 |
and:[ |
|
725 |
acceptRegexString == true |
|
726 |
or:[self previousTokenInitiatesRegexForSlash ] |
|
727 |
]) ifTrue:[ |
|
728 |
peekChar isNil ifTrue:[ |
|
729 |
source next. |
|
730 |
] ifFalse:[ |
|
731 |
peekChar := nil. |
|
732 |
]. |
|
733 |
pc := source peek. |
|
1105 | 734 |
pc == $/ ifTrue:[ source next. ^ self skipEOLComment]. |
735 |
pc == $* ifTrue:[ source next. ^ self skipComment]. |
|
1102 | 736 |
^ self nextRegex |
737 |
]. |
|
738 |
^ self nextMulti:#( |
|
739 |
($= #'/=') |
|
740 |
($* nil #skipComment) |
|
741 |
($/ nil #skipEOLComment) |
|
742 |
) after:$/ |
|
743 |
! |
|
744 |
||
193 | 745 |
nextString |
1102 | 746 |
^ self nextStringOrCharacter:false orRegex:false |
193 | 747 |
! |
748 |
||
749 |
nextStringOrCharacter:asCharacter |
|
1102 | 750 |
^ self nextStringOrCharacter:asCharacter orRegex:false |
751 |
! |
|
752 |
||
753 |
nextStringOrCharacter:asCharacter orRegex:asRegex |
|
513
eab735628cc6
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
512
diff
changeset
|
754 |
|delimiter s pos endPos nextChar inString badEscapeChar| |
193 | 755 |
|
756 |
delimiter := hereChar. |
|
7 | 757 |
|
758 |
s := (String new:20) writeStream. |
|
759 |
||
144 | 760 |
pos := tokenPosition. |
1089 | 761 |
source next. "/ skip over initial quote |
7 | 762 |
nextChar := source next. |
1152 | 763 |
"/ self assert:(nextChar isNil or:[nextChar isCharacter]). |
764 |
||
7 | 765 |
inString := true. |
766 |
||
767 |
[inString] whileTrue:[ |
|
144 | 768 |
nextChar isNil ifTrue:[ |
769 |
self syntaxError:'unexpected end-of-input in String' |
|
647 | 770 |
position:pos to:(source position). |
639 | 771 |
self markStringFrom:pos to:source position. |
1075 | 772 |
token := tokenName := nil. |
144 | 773 |
tokenType := #EOF. |
774 |
^ tokenType |
|
775 |
]. |
|
1010 | 776 |
|
144 | 777 |
nextChar == $\ ifTrue:[ |
778 |
nextChar := source next. |
|
1152 | 779 |
"/ self assert:(nextChar isNil or:[nextChar isCharacter]). |
144 | 780 |
nextChar == $b ifTrue:[ |
781 |
nextChar := Character backspace |
|
782 |
] ifFalse:[ nextChar == $t ifTrue:[ |
|
783 |
nextChar := Character tab |
|
784 |
] ifFalse:[ nextChar == $n ifTrue:[ |
|
785 |
nextChar := Character cr |
|
786 |
] ifFalse:[ nextChar == $r ifTrue:[ |
|
787 |
nextChar := Character return |
|
788 |
] ifFalse:[ nextChar == $f ifTrue:[ |
|
789 |
nextChar := Character newPage |
|
790 |
] ifFalse:[ nextChar == $x ifTrue:[ |
|
791 |
nextChar := self hex2CharacterEscape. |
|
1152 | 792 |
"/ self assert:(nextChar isNil or:[nextChar isCharacter]). |
144 | 793 |
nextChar isNil ifTrue:[ |
1075 | 794 |
token := tokenName := nil. |
144 | 795 |
tokenType := #EOF. |
796 |
^ tokenType |
|
797 |
]. |
|
798 |
] ifFalse:[ nextChar == $u ifTrue:[ |
|
799 |
nextChar := self hex4CharacterEscape. |
|
1152 | 800 |
"/ self assert:(nextChar isNil or:[nextChar isCharacter]). |
144 | 801 |
nextChar isNil ifTrue:[ |
802 |
token := nil. |
|
1075 | 803 |
tokenType := tokenName := #EOF. |
144 | 804 |
^ tokenType |
805 |
]. |
|
1010 | 806 |
] ifFalse:[ nextChar == Character cr ifTrue:[ |
807 |
nextChar := nil |
|
512
0c6937eb1329
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
500
diff
changeset
|
808 |
] ifFalse:[ |
580 | 809 |
((nextChar == $') or:[nextChar == $" or:[nextChar == $\]]) ifFalse:[ |
810 |
parserFlags warnAboutUnknownCharacterEscapesInJavaScriptStringConstant ifTrue:[ |
|
811 |
badEscapeChar isNil ifTrue:[ badEscapeChar := nextChar asString ] |
|
812 |
]. |
|
512
0c6937eb1329
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
500
diff
changeset
|
813 |
] |
1010 | 814 |
]]]]]]]] |
144 | 815 |
] ifFalse:[ |
816 |
(nextChar == Character cr) ifTrue:[ |
|
817 |
lineNr := lineNr + 1 |
|
818 |
] ifFalse:[ |
|
819 |
(nextChar == delimiter) ifTrue:[ |
|
820 |
(source peekOrNil == delimiter) ifTrue:[ |
|
821 |
source next |
|
822 |
] ifFalse:[ |
|
823 |
inString := false |
|
824 |
] |
|
825 |
]. |
|
826 |
]. |
|
827 |
]. |
|
828 |
inString ifTrue:[ |
|
1010 | 829 |
nextChar notNil ifTrue:[ |
830 |
nextChar bitsPerCharacter > s contents bitsPerCharacter ifTrue:[ |
|
831 |
s setCollection:(nextChar stringSpecies fromString:s collection). |
|
832 |
]. |
|
833 |
s nextPut:nextChar. |
|
834 |
]. |
|
1152 | 835 |
nextChar := source next. |
836 |
"/ self assert:(nextChar isNil or:[nextChar isCharacter]). |
|
144 | 837 |
] |
7 | 838 |
]. |
639 | 839 |
endPos := source position. |
513
eab735628cc6
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
512
diff
changeset
|
840 |
self markStringFrom:pos to:endPos. |
eab735628cc6
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
512
diff
changeset
|
841 |
badEscapeChar notNil ifTrue:[ |
eab735628cc6
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
512
diff
changeset
|
842 |
self warning:('Unknown character escape: "\',badEscapeChar asString,'"') position:pos to:endPos. |
eab735628cc6
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
512
diff
changeset
|
843 |
]. |
7 | 844 |
|
845 |
tokenValue := token := s contents. |
|
846 |
tokenType := #String. |
|
193 | 847 |
|
848 |
asCharacter ifTrue:[ |
|
849 |
token size ~~ 1 ifTrue:[ |
|
513
eab735628cc6
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
512
diff
changeset
|
850 |
self syntaxError:'Character constant must be of size 1' position:pos to:endPos. |
193 | 851 |
]. |
852 |
tokenType := #Character. |
|
853 |
tokenValue := token := token first |
|
854 |
]. |
|
855 |
||
7 | 856 |
^ tokenType |
857 |
||
512
0c6937eb1329
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
500
diff
changeset
|
858 |
"Created: / 16-05-1998 / 19:53:05 / cg" |
513
eab735628cc6
changed: #nextStringOrCharacter:
Claus Gittinger <cg@exept.de>
parents:
512
diff
changeset
|
859 |
"Modified: / 04-10-2011 / 20:08:58 / cg" |
1075 | 860 |
"Modified: / 08-03-2019 / 12:41:24 / Claus Gittinger" |
1089 | 861 |
"Modified (comment): / 09-06-2019 / 17:11:51 / Claus Gittinger" |
7 | 862 |
! |
863 |
||
1085 | 864 |
nextSymbol |
865 |
"this is a special (non-JavaScript) extension to support #'x' for symbol literals" |
|
866 |
||
867 |
|pos| |
|
868 |
||
869 |
pos := tokenPosition. |
|
870 |
source next. |
|
871 |
||
872 |
(hereChar := source peek) == $' ifTrue:[ |
|
1086 | 873 |
self nextStringOrCharacter:false. |
1089 | 874 |
tokenType == #String ifTrue:[ |
875 |
tokenValue := token := tokenValue asSymbol. |
|
876 |
tokenType := #Symbol. |
|
877 |
]. |
|
1086 | 878 |
^ token. |
1085 | 879 |
]. |
880 |
||
1086 | 881 |
self syntaxError:'incorrect symbol constant' |
1085 | 882 |
position:pos to:(source position). |
883 |
||
884 |
"Created: / 09-06-2019 / 16:34:35 / Claus Gittinger" |
|
885 |
! |
|
886 |
||
7 | 887 |
nextToken |
888 |
|t| |
|
889 |
||
9 | 890 |
[ |
355 | 891 |
t := super nextToken. |
892 |
t isNil |
|
9 | 893 |
] whileTrue. |
7 | 894 |
Verbose == true ifTrue:[Transcript showCR:t]. |
1102 | 895 |
previousToken := token. |
7 | 896 |
^ t |
897 |
||
355 | 898 |
" |
899 |
Verbose := true |
|
900 |
" |
|
901 |
||
7 | 902 |
"Created: / 14.5.1998 / 15:48:04 / cg" |
9 | 903 |
"Modified: / 16.5.1998 / 19:12:29 / cg" |
904 |
! |
|
905 |
||
61 | 906 |
skipComment |
95 | 907 |
"/* has already been read" |
86 | 908 |
|
500 | 909 |
|nextChar startPos commentStream commentText| |
95 | 910 |
|
1105 | 911 |
startPos := (source position-1) max:1. |
61 | 912 |
|
856 | 913 |
commentStream := CharacterWriteStream new:30. |
500 | 914 |
|
61 | 915 |
hereChar := source peek. |
916 |
[true] whileTrue:[ |
|
500 | 917 |
hereChar isNil ifTrue:[ |
918 |
"/ EOF in comment ?!!? |
|
517 | 919 |
commentText := commentStream contents. |
920 |
self handleCommentDirectivesIn:commentText. |
|
500 | 921 |
saveComments ifTrue:[ |
922 |
self endComment:commentText type:#regularComment. |
|
923 |
]. |
|
924 |
^ nil |
|
925 |
]. |
|
517 | 926 |
commentStream notNil ifTrue:[ commentStream nextPut:hereChar ]. |
500 | 927 |
|
61 | 928 |
hereChar == $* ifTrue:[ |
929 |
outStream notNil ifTrue:[ |
|
930 |
outStream nextPut:hereChar. |
|
931 |
outCol := outCol + 1 |
|
932 |
]. |
|
933 |
hereChar := source nextPeek. |
|
934 |
hereChar == $/ ifTrue:[ |
|
517 | 935 |
commentStream notNil ifTrue:[ commentStream nextPut:hereChar ]. |
95 | 936 |
self markCommentFrom:startPos to:(source position). |
61 | 937 |
hereChar := source nextPeek. |
517 | 938 |
commentText := commentStream contents. |
939 |
self handleCommentDirectivesIn:commentText. |
|
500 | 940 |
saveComments ifTrue:[ |
941 |
self endComment:commentText type:#regularComment. |
|
942 |
]. |
|
61 | 943 |
^ nil |
944 |
]. |
|
86 | 945 |
nextChar := hereChar. |
946 |
] ifFalse:[ |
|
157 | 947 |
hereChar == Character cr ifTrue:[ |
948 |
lineNr := lineNr + 1. |
|
949 |
]. |
|
86 | 950 |
nextChar := source nextPeek. |
61 | 951 |
]. |
952 |
||
953 |
outStream notNil ifTrue:[ |
|
954 |
outStream nextPut:hereChar. |
|
955 |
outCol := outCol + 1 |
|
956 |
]. |
|
86 | 957 |
hereChar := nextChar. |
61 | 958 |
]. |
500 | 959 |
|
517 | 960 |
"Modified: / 26-10-2011 / 17:42:14 / cg" |
61 | 961 |
! |
962 |
||
9 | 963 |
skipEOLComment |
95 | 964 |
"// has already been read" |
965 |
||
500 | 966 |
|startPos commentStream commentText| |
95 | 967 |
|
1104 | 968 |
startPos := (source position-1) max:1. |
95 | 969 |
|
856 | 970 |
commentStream := CharacterWriteStream new:30. |
517 | 971 |
commentStream nextPutAll:'//'. |
500 | 972 |
|
9 | 973 |
hereChar := source peek. |
974 |
[hereChar notNil and:[hereChar ~~ Character cr]] whileTrue:[ |
|
517 | 975 |
commentStream notNil ifTrue:[ |
976 |
commentStream nextPut:hereChar |
|
977 |
]. |
|
95 | 978 |
outStream notNil ifTrue:[ |
979 |
outStream nextPut:hereChar. |
|
980 |
outCol := outCol + 1 |
|
981 |
]. |
|
982 |
hereChar := source nextPeek. |
|
9 | 983 |
]. |
95 | 984 |
self markCommentFrom:startPos to:(source position). |
157 | 985 |
hereChar := source nextPeek. |
9 | 986 |
lineNr := lineNr + 1. |
987 |
outStream notNil ifTrue:[ |
|
95 | 988 |
outStream cr. |
989 |
outCol := 1 |
|
9 | 990 |
]. |
517 | 991 |
commentText := commentStream contents. |
992 |
"/ self handleCommentDirectivesIn:commentText. |
|
500 | 993 |
saveComments ifTrue:[ |
994 |
self endComment:commentText type:#eolComment. |
|
995 |
]. |
|
9 | 996 |
^ nil. |
997 |
||
500 | 998 |
"Created: / 16-05-1998 / 19:11:05 / cg" |
517 | 999 |
"Modified: / 26-10-2011 / 17:43:46 / cg" |
7 | 1000 |
! ! |
1001 |
||
1002 |
!JavaScriptScanner class methodsFor:'documentation'! |
|
1003 |
||
1004 |
version |
|
1005 |
^ '$Header$' |
|
435 | 1006 |
! |
1007 |
||
1008 |
version_CVS |
|
1009 |
^ '$Header$' |
|
7 | 1010 |
! ! |
580 | 1011 |
|
1102 | 1012 |
|
1013 |
JavaScriptScanner initialize! |