21 usedInstVars usedClassVars usedVars |
21 usedInstVars usedClassVars usedVars |
22 modifiedInstVars modifiedClassVars |
22 modifiedInstVars modifiedClassVars |
23 localVarDefPosition |
23 localVarDefPosition |
24 evalExitBlock |
24 evalExitBlock |
25 selfNode superNode primNr logged |
25 selfNode superNode primNr logged |
26 warnedUndefVars' |
26 warnedUndefVars' |
27 classVariableNames:'prevClass prevInstVarNames |
27 classVariableNames:'prevClass prevInstVarNames |
28 prevClassVarNames prevClassInstVarNames' |
28 prevClassVarNames prevClassInstVarNames' |
29 poolDictionaries:'' |
29 poolDictionaries:'' |
30 category:'System-Compiler' |
30 category:'System-Compiler' |
31 ! |
31 ! |
41 |
41 |
42 Parser is also used to find the referenced/modified inst/classvars of |
42 Parser is also used to find the referenced/modified inst/classvars of |
43 a method - this is done by sending parseXXX message to a parser and asking |
43 a method - this is done by sending parseXXX message to a parser and asking |
44 the parser for referencedXVars or modifiedXVars (see SystemBrowser). |
44 the parser for referencedXVars or modifiedXVars (see SystemBrowser). |
45 |
45 |
46 $Header: /cvs/stx/stx/libcomp/Parser.st,v 1.3 1993-10-13 02:41:36 claus Exp $ |
46 $Header: /cvs/stx/stx/libcomp/Parser.st,v 1.4 1993-12-11 01:09:03 claus Exp $ |
47 '! |
47 '! |
48 |
48 |
49 !Parser class methodsFor:'evaluating expressions'! |
49 !Parser class methodsFor:'evaluating expressions'! |
50 |
50 |
51 evaluate:aString |
51 evaluate:aString |
146 ^ parser |
146 ^ parser |
147 ! ! |
147 ! ! |
148 |
148 |
149 !Parser class methodsFor:'parsing'! |
149 !Parser class methodsFor:'parsing'! |
150 |
150 |
|
151 selectorInExpression:aString |
|
152 "parse an expression - return the selector. Used for |
|
153 SystemBrowsers implementors/senders query-box initial text" |
|
154 |
|
155 |tree parser| |
|
156 |
|
157 (aString isNil or:[aString isEmpty]) ifTrue:[^ nil]. |
|
158 |
|
159 tree := self withSelf:nil parseExpression:aString notifying:nil ignoreErrors:true. |
|
160 (tree notNil and:[tree ~~ #Error]) ifTrue:[ |
|
161 tree isMessage ifTrue:[ |
|
162 ^ tree selector |
|
163 ]. |
|
164 ]. |
|
165 |
|
166 "mhmh, try expression without receiver" |
|
167 |
|
168 parser := self for:(ReadStream on:aString). |
|
169 parser ignoreErrors. |
|
170 parser nextToken. |
|
171 ^ parser degeneratedKeywordExpressionForSelector |
|
172 |
|
173 " |
|
174 Parser selectorInExpression:'foo at:1 put:(5 * bar)' |
|
175 Parser selectorInExpression:'(foo at:1) at:1' |
|
176 Parser selectorInExpression:'1 + 4' |
|
177 Parser selectorInExpression:'1 negated' |
|
178 Parser selectorInExpression:'at:1 put:5' |
|
179 " |
|
180 ! |
|
181 |
151 parseExpression:aString |
182 parseExpression:aString |
152 "parse aString as an expression; return the parseTree" |
183 "parse aString as an expression; return the parseTree" |
153 |
184 |
154 ^ self withSelf:nil parseExpression:aString notifying:nil |
185 ^ self withSelf:nil parseExpression:aString notifying:nil ignoreErrors:false |
155 ! |
186 ! |
156 |
187 |
157 withSelf:anObject parseExpression:aString notifying:someOne |
188 withSelf:anObject parseExpression:aString notifying:someOne |
|
189 "parse aString as an expression with self set to anObject; |
|
190 return the parseTree" |
|
191 |
|
192 ^ self withSelf:anObject parseExpression:aString notifying:someOne ignoreErrors:false |
|
193 ! |
|
194 |
|
195 withSelf:anObject parseExpression:aString notifying:someOne ignoreErrors:ignore |
158 "parse aString as an expression with self set to anObject; |
196 "parse aString as an expression with self set to anObject; |
159 return the parseTree" |
197 return the parseTree" |
160 |
198 |
161 |parser tree| |
199 |parser tree| |
162 |
200 |
163 aString isNil ifTrue:[^ nil]. |
201 aString isNil ifTrue:[^ nil]. |
164 parser := self for:(ReadStream on:aString). |
202 parser := self for:(ReadStream on:aString). |
165 parser setSelf:anObject. |
203 parser setSelf:anObject. |
166 parser notifying:someOne. |
204 parser notifying:someOne. |
|
205 ignore ifTrue:[parser ignoreErrors]. |
167 parser nextToken. |
206 parser nextToken. |
168 tree := parser expression. |
207 tree := parser expression. |
169 (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error]. |
208 (parser errorFlag or:[tree == #Error]) ifTrue:[^ #Error]. |
170 ^ tree |
209 ^ tree |
171 ! |
210 ! |
262 prevInstVarNames := nil. |
301 prevInstVarNames := nil. |
263 prevClassVarNames := nil. |
302 prevClassVarNames := nil. |
264 prevClassInstVarNames := nil. |
303 prevClassInstVarNames := nil. |
265 aClass removeDependent:Parser |
304 aClass removeDependent:Parser |
266 ] |
305 ] |
|
306 ! |
|
307 |
|
308 flush |
|
309 "unconditional flush name caches" |
|
310 |
|
311 prevClass notNil ifTrue:[ |
|
312 prevClass removeDependent:Parser |
|
313 ]. |
|
314 prevClass := nil. |
|
315 prevInstVarNames := nil. |
|
316 prevClassVarNames := nil. |
|
317 prevClassInstVarNames := nil. |
|
318 |
|
319 "Parser flush" |
267 ! ! |
320 ! ! |
268 |
321 |
269 !Parser methodsFor:'setup'! |
322 !Parser methodsFor:'setup'! |
270 |
323 |
271 setClassToCompileFor:aClass |
324 setClassToCompileFor:aClass |
450 undefError:aName position:pos1 to:pos2 |
503 undefError:aName position:pos1 to:pos2 |
451 "report an undefined variable error - return true, if it should be |
504 "report an undefined variable error - return true, if it should be |
452 corrected" |
505 corrected" |
453 |
506 |
454 requestor isNil ifTrue:[ |
507 requestor isNil ifTrue:[ |
455 warnedUndefVars notNil ifTrue:[ |
508 warnedUndefVars notNil ifTrue:[ |
456 (warnedUndefVars includes:aName) ifTrue:[ |
509 (warnedUndefVars includes:aName) ifTrue:[ |
457 "already warned about this one" |
510 "already warned about this one" |
458 ^ false |
511 ^ false |
459 ]. |
512 ]. |
460 ]. |
513 ]. |
461 self showErrorMessage:('Error: ' , aName , ' is undefined') position:pos1. |
514 self showErrorMessage:('Error: ' , aName , ' is undefined') position:pos1. |
462 warnedUndefVars isNil ifTrue:[ |
515 warnedUndefVars isNil ifTrue:[ |
463 warnedUndefVars := Set new. |
516 warnedUndefVars := Set new. |
464 ]. |
517 ]. |
465 warnedUndefVars add:aName. |
518 warnedUndefVars add:aName. |
466 ^ false |
519 ^ false |
467 ]. |
520 ]. |
468 |
521 |
469 ^ self correctableError:('Error: ' , aName , ' is undefined') |
522 ^ self correctableError:('Error: ' , aName , ' is undefined') |
470 position:pos1 to:pos2 |
523 position:pos1 to:pos2 |
471 ! |
524 ! |
548 |stats| |
601 |stats| |
549 |
602 |
550 ((tokenType == #BinaryOperator) and:[tokenName = '<']) ifTrue:[ |
603 ((tokenType == #BinaryOperator) and:[tokenName = '<']) ifTrue:[ |
551 "an ST-80 primitive - parsed but ignored" |
604 "an ST-80 primitive - parsed but ignored" |
552 self nextToken. |
605 self nextToken. |
553 primNr := self parsePrimitive. |
606 primNr := self parseST80Primitive. |
554 (primNr == #Error) ifTrue:[^ #Error]. |
607 (primNr == #Error) ifTrue:[^ #Error]. |
555 self warning:'ST-80 primitives not supported - ignored' |
608 self warning:'ST-80 primitives not supported - ignored' |
556 ]. |
609 ]. |
557 |
610 |
558 (self parseMethodBodyVarSpec == #Error) ifTrue:[^ #Error]. |
611 (self parseMethodBodyVarSpec == #Error) ifTrue:[^ #Error]. |
841 receiver lineNumber:lno |
894 receiver lineNumber:lno |
842 ]. |
895 ]. |
843 ^ receiver |
896 ^ receiver |
844 ! |
897 ! |
845 |
898 |
|
899 degeneratedKeywordExpressionForSelector |
|
900 "parse a keyword-expression without receiver - for the selector |
|
901 only. return the selector or nil" |
|
902 |
|
903 |receiver sel arg args pos1 pos2 try lno note| |
|
904 |
|
905 (tokenType == #Keyword) ifTrue:[ |
|
906 sel := tokenName. |
|
907 self nextToken. |
|
908 arg := self binaryExpression. |
|
909 (arg == #Error) ifTrue:[^ sel]. |
|
910 [tokenType == #Keyword] whileTrue:[ |
|
911 sel := sel , tokenName. |
|
912 self nextToken. |
|
913 arg := self binaryExpression. |
|
914 (arg == #Error) ifTrue:[^ sel]. |
|
915 ]. |
|
916 ^ sel |
|
917 ]. |
|
918 ^ nil |
|
919 ! |
|
920 |
846 binaryExpression |
921 binaryExpression |
847 "parse a binary-expression; return a node-tree, nil or #Error" |
922 "parse a binary-expression; return a node-tree, nil or #Error" |
848 |
923 |
849 |receiver arg sel pos try lno note| |
924 |receiver arg sel pos try lno note| |
850 |
925 |
1190 prevClassInstVarNames := nil. |
1265 prevClassInstVarNames := nil. |
1191 prevClassVarNames := nil. |
1266 prevClassVarNames := nil. |
1192 prevClass addDependent:Parser |
1267 prevClass addDependent:Parser |
1193 ]. |
1268 ]. |
1194 |
1269 |
1195 instIndex := prevInstVarNames indexOf:varName startingAt:1 |
1270 instIndex := prevInstVarNames indexOf:varName startingAt:1. |
1196 ifAbsent:[nil]. |
1271 instIndex ~~ 0 ifTrue:[ |
1197 instIndex notNil ifTrue:[ |
|
1198 usedInstVars isNil ifTrue:[ |
1272 usedInstVars isNil ifTrue:[ |
1199 usedInstVars := OrderedCollection new |
1273 usedInstVars := OrderedCollection new |
1200 ]. |
1274 ]. |
1201 (usedInstVars includes:varName) ifFalse:[ |
1275 (usedInstVars includes:varName) ifFalse:[ |
1202 usedInstVars add:varName |
1276 usedInstVars add:varName |
1218 classToCompileFor notNil ifTrue:[ |
1292 classToCompileFor notNil ifTrue:[ |
1219 prevClassInstVarNames isNil ifTrue:[ |
1293 prevClassInstVarNames isNil ifTrue:[ |
1220 prevClassInstVarNames := classToCompileFor class allInstVarNames |
1294 prevClassInstVarNames := classToCompileFor class allInstVarNames |
1221 ]. |
1295 ]. |
1222 |
1296 |
1223 instIndex := prevClassInstVarNames indexOf:varName startingAt:1 |
1297 instIndex := prevClassInstVarNames indexOf:varName startingAt:1. |
1224 ifAbsent:[nil]. |
1298 instIndex ~~ 0 ifTrue:[ |
1225 |
|
1226 instIndex notNil ifTrue:[ |
|
1227 aClass := self inWhichClassIsClassInstVar:varName. |
1299 aClass := self inWhichClassIsClassInstVar:varName. |
1228 aClass notNil ifTrue:[ |
1300 aClass notNil ifTrue:[ |
1229 usedVars isNil ifTrue:[ |
1301 usedVars isNil ifTrue:[ |
1230 usedVars := OrderedCollection new |
1302 usedVars := OrderedCollection new |
1231 ]. |
1303 ]. |
1253 ] |
1325 ] |
1254 ]. |
1326 ]. |
1255 prevClassVarNames := aClass allClassVarNames |
1327 prevClassVarNames := aClass allClassVarNames |
1256 ]. |
1328 ]. |
1257 |
1329 |
1258 instIndex := prevClassVarNames indexOf:varName startingAt:1 |
1330 instIndex := prevClassVarNames indexOf:varName startingAt:1. |
1259 ifAbsent:[nil]. |
1331 instIndex ~~ 0 ifTrue:[ |
1260 |
|
1261 instIndex notNil ifTrue:[ |
|
1262 aClass := self inWhichClassIsClassVar:varName. |
1332 aClass := self inWhichClassIsClassVar:varName. |
1263 aClass notNil ifTrue:[ |
1333 aClass notNil ifTrue:[ |
1264 usedClassVars isNil ifTrue:[ |
1334 usedClassVars isNil ifTrue:[ |
1265 usedClassVars := OrderedCollection new |
1335 usedClassVars := OrderedCollection new |
1266 ]. |
1336 ]. |
1393 self nextToken |
1466 self nextToken |
1394 ]. |
1467 ]. |
1395 self nextToken |
1468 self nextToken |
1396 ]. |
1469 ]. |
1397 node := BlockNode arguments:args home:currentBlock variables:vars. |
1470 node := BlockNode arguments:args home:currentBlock variables:vars. |
|
1471 node lineNumber:lno. |
1398 currentBlock := node. |
1472 currentBlock := node. |
1399 stats := self blockStatementList. |
1473 stats := self blockStatementList. |
1400 node statements:stats. |
1474 node statements:stats. |
1401 currentBlock := node home. |
1475 currentBlock := node home. |
1402 (stats == #Error) ifTrue:[^ #Error]. |
1476 (stats == #Error) ifTrue:[^ #Error]. |
1588 [searchBlock notNil] whileTrue:[ |
1663 [searchBlock notNil] whileTrue:[ |
1589 args := searchBlock arguments. |
1664 args := searchBlock arguments. |
1590 args notNil ifTrue:[ |
1665 args notNil ifTrue:[ |
1591 args do:[:aBlockArg | |
1666 args do:[:aBlockArg | |
1592 names add:(aBlockArg name). |
1667 names add:(aBlockArg name). |
1593 dists add:(aString levenshteinTo:(aBlockArg name)) |
1668 dists add:(aString spellAgainst: "levenshteinTo:"(aBlockArg name)) |
1594 ] |
1669 ] |
1595 ]. |
1670 ]. |
1596 |
1671 |
1597 vars := searchBlock variables. |
1672 vars := searchBlock variables. |
1598 vars notNil ifTrue:[ |
1673 vars notNil ifTrue:[ |
1599 vars do:[:aBlockVar | |
1674 vars do:[:aBlockVar | |
1600 names add:(aBlockVar name). |
1675 names add:(aBlockVar name). |
1601 dists add:(aString levenshteinTo:(aBlockVar name)) |
1676 dists add:(aString spellAgainst: "levenshteinTo:"(aBlockVar name)) |
1602 ] |
1677 ] |
1603 ]. |
1678 ]. |
1604 searchBlock := searchBlock home |
1679 searchBlock := searchBlock home |
1605 ]. |
1680 ]. |
1606 |
1681 |
1607 "method-variables" |
1682 "method-variables" |
1608 methodVars notNil ifTrue:[ |
1683 methodVars notNil ifTrue:[ |
1609 methodVarNames do:[:methodVarName | |
1684 methodVarNames do:[:methodVarName | |
1610 names add:methodVarName. |
1685 names add:methodVarName. |
1611 dists add:(aString levenshteinTo:methodVarName) |
1686 dists add:(aString spellAgainst: "levenshteinTo:"methodVarName) |
1612 ] |
1687 ] |
1613 ]. |
1688 ]. |
1614 |
1689 |
1615 "method-arguments" |
1690 "method-arguments" |
1616 methodArgs notNil ifTrue:[ |
1691 methodArgs notNil ifTrue:[ |
1617 methodArgNames do:[:methodArgName | |
1692 methodArgNames do:[:methodArgName | |
1618 names add:methodArgName. |
1693 names add:methodArgName. |
1619 dists add:(aString levenshteinTo:methodArgName) |
1694 dists add:(aString spellAgainst: "levenshteinTo:"methodArgName) |
1620 ] |
1695 ] |
1621 ]. |
1696 ]. |
1622 |
1697 |
1623 "instance-variables" |
1698 "instance-variables" |
1624 classToCompileFor notNil ifTrue:[ |
1699 classToCompileFor notNil ifTrue:[ |
1625 prevInstVarNames do:[:instVarName | |
1700 prevInstVarNames do:[:instVarName | |
1626 names add:instVarName. |
1701 names add:instVarName. |
1627 dists add:(aString levenshteinTo:instVarName) |
1702 dists add:(aString spellAgainst: "levenshteinTo:"instVarName) |
1628 ] |
1703 ] |
1629 ]. |
1704 ]. |
1630 |
1705 |
1631 "class-variables" |
1706 "class-variables" |
1632 classToCompileFor notNil ifTrue:[ |
1707 classToCompileFor notNil ifTrue:[ |
|
1708 prevClassVarNames do:[:classVarName | |
|
1709 names add:classVarName. |
|
1710 dists add:(aString spellAgainst: "levenshteinTo:"classVarName) |
|
1711 ]. |
|
1712 |
|
1713 false ifTrue:[ |
1633 aClass := classToCompileFor. |
1714 aClass := classToCompileFor. |
1634 aClass isMeta ifTrue:[ |
1715 aClass isMeta ifTrue:[ |
1635 className := aClass name. |
1716 className := aClass name. |
1636 className := className copyFrom:1 to:(className size - 5). |
1717 className := className copyFrom:1 to:(className size - 5). |
1637 baseClass := Smalltalk at:(className asSymbol). |
1718 baseClass := Smalltalk at:(className asSymbol). |
1640 ] |
1721 ] |
1641 ]. |
1722 ]. |
1642 [aClass notNil] whileTrue:[ |
1723 [aClass notNil] whileTrue:[ |
1643 (aClass classVarNames) do:[:classVarName | |
1724 (aClass classVarNames) do:[:classVarName | |
1644 names add:classVarName. |
1725 names add:classVarName. |
1645 dists add:(aString levenshteinTo:classVarName) |
1726 dists add:(aString spellAgainst: "levenshteinTo:"classVarName) |
1646 ]. |
1727 ]. |
1647 aClass := aClass superclass |
1728 aClass := aClass superclass |
1648 ] |
1729 ] |
|
1730 ]. |
1649 ]. |
1731 ]. |
1650 |
1732 |
1651 "globals" |
1733 "globals" |
1652 Smalltalk allKeysDo:[:aKey | |
1734 Smalltalk allKeysDo:[:aKey | |
1653 globalVarName := aKey asString. |
1735 globalVarName := aKey asString. |
1654 "only compare strings where length is about right" |
1736 "only compare strings where length is about right" |
1655 ((globalVarName size - aString size) abs < 3) ifTrue:[ |
1737 ((globalVarName size - aString size) abs < 3) ifTrue:[ |
1656 names add:globalVarName. |
1738 names add:globalVarName. |
1657 dists add:(aString levenshteinTo:globalVarName) |
1739 dists add:(aString spellAgainst: "levenshteinTo:"globalVarName) |
1658 ] |
1740 ] |
1659 ]. |
1741 ]. |
1660 |
1742 |
1661 "misc" |
1743 "misc" |
1662 #('self' 'super' 'nil') do:[:name | |
1744 #('self' 'super' 'nil' 'thisContext') do:[:name | |
1663 "only compare strings where length is about right" |
1745 "only compare strings where length is about right" |
1664 ((name size - aString size) abs < 3) ifTrue:[ |
1746 names add:name. |
1665 names add:name. |
1747 dists add:(aString spellAgainst: "levenshteinTo:"name) |
1666 dists add:(aString levenshteinTo:name) |
|
1667 ] |
|
1668 ]. |
1748 ]. |
1669 |
1749 |
1670 (dists size ~~ 0) ifTrue:[ |
1750 (dists size ~~ 0) ifTrue:[ |
1671 dists sortWith:names. |
1751 dists sortWith:names. |
|
1752 dists := dists reverse. |
|
1753 names := names reverse. |
1672 n := names size min:10. |
1754 n := names size min:10. |
1673 ^ names copyFrom:1 to:n |
1755 ^ names copyFrom:1 to:n |
1674 ]. |
1756 ]. |
1675 ^ nil |
1757 ^ nil |
1676 ! |
1758 ! |