Compiler-AST.st 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. Smalltalk createPackage: 'Compiler-AST'!
  2. Object subclass: #Node
  3. instanceVariableNames: 'parent position source nodes shouldBeInlined shouldBeAliased'
  4. package: 'Compiler-AST'!
  5. !Node commentStamp!
  6. I am the abstract root class of the abstract syntax tree.
  7. Concrete classes should implement `#accept:` to allow visiting.
  8. `position` holds a point containing line and column number of the symbol location in the original source file.!
  9. !Node methodsFor: 'accessing'!
  10. addNode: aNode
  11. self nodes add: aNode.
  12. aNode parent: self
  13. !
  14. allNodes
  15. | allNodes |
  16. allNodes := self nodes asSet.
  17. self nodes do: [ :each |
  18. allNodes addAll: each allNodes ].
  19. ^ allNodes
  20. !
  21. method
  22. ^ self parent ifNotNil: [ :node | node method ]
  23. !
  24. navigationNodeAt: aPoint ifAbsent: aBlock
  25. "Answer the navigation node in the receiver's tree at aPoint
  26. or nil if no navigation node was found.
  27. See `node >> isNaviationNode`"
  28. | children |
  29. children := self allNodes select: [ :each |
  30. each isNavigationNode and: [ each inPosition: aPoint ] ].
  31. children ifEmpty: [ ^ aBlock value ].
  32. ^ (children asArray sort: [ :a :b |
  33. (a positionStart dist: aPoint) <=
  34. (b positionStart dist: aPoint) ]) first
  35. !
  36. nextChild
  37. "Answer the next node after aNode.
  38. Recurse into the possible children of the receiver to answer the next node to be evaluated"
  39. ^ self nodes isEmpty
  40. ifTrue: [ self ]
  41. ifFalse: [ self nodes first nextChild ]
  42. !
  43. nextNode
  44. ^ self parent ifNotNil: [ :node |
  45. node nextNode: self ]
  46. !
  47. nextNode: aNode
  48. "Answer the next node after aNode.
  49. Recurse into the possible children of the next node to answer the next node to be evaluated"
  50. | next |
  51. next := self nodes
  52. at: (self nodes indexOf: aNode) + 1
  53. ifAbsent: [ ^ self ].
  54. ^ next nextChild
  55. !
  56. nodes
  57. ^ nodes ifNil: [ nodes := Array new ]
  58. !
  59. parent
  60. ^ parent
  61. !
  62. parent: aNode
  63. parent := aNode
  64. !
  65. position
  66. "answer the line and column of the receiver in the source code"
  67. ^ position ifNil: [
  68. self parent ifNotNil: [ :node | node position ] ]
  69. !
  70. position: aPosition
  71. position := aPosition
  72. !
  73. positionEnd
  74. ^ self positionStart + ((self source lines size - 1) @ (self source lines last size - 1))
  75. !
  76. positionStart
  77. ^ self position
  78. !
  79. shouldBeAliased
  80. ^ shouldBeAliased ifNil: [ false ]
  81. !
  82. shouldBeAliased: aBoolean
  83. shouldBeAliased := aBoolean
  84. !
  85. shouldBeInlined
  86. ^ shouldBeInlined ifNil: [ false ]
  87. !
  88. shouldBeInlined: aBoolean
  89. shouldBeInlined := aBoolean
  90. !
  91. size
  92. ^ self source size
  93. !
  94. source
  95. ^ source ifNil: [ '' ]
  96. !
  97. source: aString
  98. source := aString
  99. ! !
  100. !Node methodsFor: 'building'!
  101. nodes: aCollection
  102. nodes := aCollection.
  103. aCollection do: [ :each | each parent: self ]
  104. ! !
  105. !Node methodsFor: 'copying'!
  106. postCopy
  107. super postCopy.
  108. self nodes do: [ :each | each parent: self ]
  109. ! !
  110. !Node methodsFor: 'testing'!
  111. inPosition: aPoint
  112. ^ (self positionStart <= aPoint and: [
  113. self positionEnd >= aPoint ])
  114. !
  115. isAssignmentNode
  116. ^ false
  117. !
  118. isBlockNode
  119. ^ false
  120. !
  121. isBlockSequenceNode
  122. ^ false
  123. !
  124. isCascadeNode
  125. ^ false
  126. !
  127. isImmutable
  128. ^ false
  129. !
  130. isJSStatementNode
  131. ^ false
  132. !
  133. isLastChild
  134. ^ self parent nodes last = self
  135. !
  136. isNavigationNode
  137. "Answer true if the node can be navigated to"
  138. ^ false
  139. !
  140. isNode
  141. ^ true
  142. !
  143. isReferenced
  144. "Answer true if the receiver is referenced by other nodes.
  145. Do not take sequences or assignments into account"
  146. ^ (self parent isSequenceNode or: [
  147. self parent isAssignmentNode ]) not
  148. !
  149. isReturnNode
  150. ^ false
  151. !
  152. isSendNode
  153. ^ false
  154. !
  155. isSequenceNode
  156. ^ false
  157. !
  158. isValueNode
  159. ^ false
  160. !
  161. isVariableNode
  162. ^ false
  163. !
  164. requiresSmalltalkContext
  165. "Answer true if the receiver requires a smalltalk context.
  166. Only send nodes require a context.
  167. If no node requires a context, the method will be compiled without one.
  168. See `IRJSTranslator` and `JSStream` for context creation"
  169. ^ (self nodes
  170. detect: [ :each | each requiresSmalltalkContext ]
  171. ifNone: [ nil ]) notNil
  172. !
  173. stopOnStepping
  174. ^ false
  175. !
  176. subtreeNeedsAliasing
  177. ^ (self shouldBeAliased or: [ self shouldBeInlined ]) or: [
  178. self nodes anySatisfy: [ :each | each subtreeNeedsAliasing ] ]
  179. ! !
  180. !Node methodsFor: 'visiting'!
  181. accept: aVisitor
  182. ^ aVisitor visitNode: self
  183. ! !
  184. Node subclass: #AssignmentNode
  185. instanceVariableNames: 'left right'
  186. package: 'Compiler-AST'!
  187. !AssignmentNode commentStamp!
  188. I represent an assignment node.!
  189. !AssignmentNode methodsFor: 'accessing'!
  190. left
  191. ^ left
  192. !
  193. left: aNode
  194. left := aNode.
  195. aNode parent: self
  196. !
  197. nodes
  198. ^ Array with: self left with: self right
  199. !
  200. right
  201. ^ right
  202. !
  203. right: aNode
  204. right := aNode.
  205. aNode parent: self
  206. ! !
  207. !AssignmentNode methodsFor: 'testing'!
  208. isAssignmentNode
  209. ^ true
  210. !
  211. shouldBeAliased
  212. ^ super shouldBeAliased or: [ self isReferenced ]
  213. ! !
  214. !AssignmentNode methodsFor: 'visiting'!
  215. accept: aVisitor
  216. ^ aVisitor visitAssignmentNode: self
  217. ! !
  218. Node subclass: #BlockNode
  219. instanceVariableNames: 'parameters scope'
  220. package: 'Compiler-AST'!
  221. !BlockNode commentStamp!
  222. I represent an block closure node.!
  223. !BlockNode methodsFor: 'accessing'!
  224. nextChild
  225. "Answer the receiver as we want to avoid eager evaluation"
  226. ^ self
  227. !
  228. nextNode: aNode
  229. "Answer the receiver as we want to avoid eager evaluation"
  230. ^ self
  231. !
  232. parameters
  233. ^ parameters ifNil: [ parameters := Array new ]
  234. !
  235. parameters: aCollection
  236. parameters := aCollection
  237. !
  238. scope
  239. ^ scope
  240. !
  241. scope: aLexicalScope
  242. scope := aLexicalScope
  243. ! !
  244. !BlockNode methodsFor: 'testing'!
  245. isBlockNode
  246. ^ true
  247. !
  248. subtreeNeedsAliasing
  249. ^ self shouldBeAliased or: [ self shouldBeInlined ]
  250. ! !
  251. !BlockNode methodsFor: 'visiting'!
  252. accept: aVisitor
  253. ^ aVisitor visitBlockNode: self
  254. ! !
  255. Node subclass: #CascadeNode
  256. instanceVariableNames: 'receiver'
  257. package: 'Compiler-AST'!
  258. !CascadeNode commentStamp!
  259. I represent an cascade node.!
  260. !CascadeNode methodsFor: 'accessing'!
  261. receiver
  262. ^ receiver
  263. !
  264. receiver: aNode
  265. receiver := aNode
  266. ! !
  267. !CascadeNode methodsFor: 'testing'!
  268. isCascadeNode
  269. ^ true
  270. ! !
  271. !CascadeNode methodsFor: 'visiting'!
  272. accept: aVisitor
  273. ^ aVisitor visitCascadeNode: self
  274. ! !
  275. Node subclass: #DynamicArrayNode
  276. instanceVariableNames: ''
  277. package: 'Compiler-AST'!
  278. !DynamicArrayNode commentStamp!
  279. I represent an dynamic array node.!
  280. !DynamicArrayNode methodsFor: 'visiting'!
  281. accept: aVisitor
  282. ^ aVisitor visitDynamicArrayNode: self
  283. ! !
  284. Node subclass: #DynamicDictionaryNode
  285. instanceVariableNames: ''
  286. package: 'Compiler-AST'!
  287. !DynamicDictionaryNode commentStamp!
  288. I represent an dynamic dictionary node.!
  289. !DynamicDictionaryNode methodsFor: 'visiting'!
  290. accept: aVisitor
  291. ^ aVisitor visitDynamicDictionaryNode: self
  292. ! !
  293. Node subclass: #JSStatementNode
  294. instanceVariableNames: ''
  295. package: 'Compiler-AST'!
  296. !JSStatementNode commentStamp!
  297. I represent an JavaScript statement node.!
  298. !JSStatementNode methodsFor: 'testing'!
  299. isJSStatementNode
  300. ^ true
  301. !
  302. requiresSmalltalkContext
  303. ^ true
  304. ! !
  305. !JSStatementNode methodsFor: 'visiting'!
  306. accept: aVisitor
  307. ^ aVisitor visitJSStatementNode: self
  308. ! !
  309. Node subclass: #MethodNode
  310. instanceVariableNames: 'selector arguments source scope classReferences sendIndexes superSends'
  311. package: 'Compiler-AST'!
  312. !MethodNode commentStamp!
  313. I represent an method node.
  314. A method node must be the root and only method node of a valid AST.!
  315. !MethodNode methodsFor: 'accessing'!
  316. arguments
  317. ^ arguments ifNil: [ #() ]
  318. !
  319. arguments: aCollection
  320. arguments := aCollection
  321. !
  322. classReferences
  323. ^ classReferences
  324. !
  325. classReferences: aCollection
  326. classReferences := aCollection
  327. !
  328. messageSends
  329. ^ self sendIndexes keys
  330. !
  331. method
  332. ^ self
  333. !
  334. scope
  335. ^ scope
  336. !
  337. scope: aMethodScope
  338. scope := aMethodScope
  339. !
  340. selector
  341. ^ selector
  342. !
  343. selector: aString
  344. selector := aString
  345. !
  346. sendIndexes
  347. ^ sendIndexes
  348. !
  349. sendIndexes: aDictionary
  350. sendIndexes := aDictionary
  351. !
  352. sequenceNode
  353. self nodes do: [ :each |
  354. each isSequenceNode ifTrue: [ ^ each ] ].
  355. ^ nil
  356. !
  357. source
  358. ^ source
  359. !
  360. source: aString
  361. source := aString
  362. !
  363. superSends
  364. ^ superSends
  365. !
  366. superSends: aCollection
  367. superSends := aCollection
  368. ! !
  369. !MethodNode methodsFor: 'visiting'!
  370. accept: aVisitor
  371. ^ aVisitor visitMethodNode: self
  372. ! !
  373. Node subclass: #ReturnNode
  374. instanceVariableNames: 'scope'
  375. package: 'Compiler-AST'!
  376. !ReturnNode commentStamp!
  377. I represent an return node. At the AST level, there is not difference between a local return or non-local return.!
  378. !ReturnNode methodsFor: 'accessing'!
  379. scope
  380. ^ scope
  381. !
  382. scope: aLexicalScope
  383. scope := aLexicalScope
  384. ! !
  385. !ReturnNode methodsFor: 'testing'!
  386. isReturnNode
  387. ^ true
  388. !
  389. nonLocalReturn
  390. ^ self scope isMethodScope not
  391. ! !
  392. !ReturnNode methodsFor: 'visiting'!
  393. accept: aVisitor
  394. ^ aVisitor visitReturnNode: self
  395. ! !
  396. Node subclass: #SendNode
  397. instanceVariableNames: 'selector arguments receiver superSend index'
  398. package: 'Compiler-AST'!
  399. !SendNode commentStamp!
  400. I represent an message send node.!
  401. !SendNode methodsFor: 'accessing'!
  402. arguments
  403. ^ arguments ifNil: [ arguments := #() ]
  404. !
  405. arguments: aCollection
  406. arguments := aCollection.
  407. aCollection do: [ :each | each parent: self ]
  408. !
  409. cascadeNodeWithMessages: aCollection
  410. | first |
  411. first := SendNode new
  412. selector: self selector;
  413. arguments: self arguments;
  414. yourself.
  415. ^ CascadeNode new
  416. receiver: self receiver;
  417. nodes: (Array with: first), aCollection;
  418. yourself
  419. !
  420. index
  421. ^ index
  422. !
  423. index: anInteger
  424. index := anInteger
  425. !
  426. navigationLink
  427. ^ self selector
  428. !
  429. nodes
  430. self receiver ifNil: [ ^ self arguments copy ].
  431. ^ (Array with: self receiver)
  432. addAll: self arguments;
  433. yourself
  434. !
  435. receiver
  436. ^ receiver
  437. !
  438. receiver: aNode
  439. receiver := aNode.
  440. aNode isNode ifTrue: [
  441. aNode parent: self ]
  442. !
  443. selector
  444. ^ selector
  445. !
  446. selector: aString
  447. selector := aString
  448. !
  449. superSend
  450. ^ superSend ifNil: [ false ]
  451. !
  452. superSend: aBoolean
  453. superSend := aBoolean
  454. !
  455. valueForReceiver: anObject
  456. ^ SendNode new
  457. position: self position;
  458. source: self source;
  459. receiver: (self receiver
  460. ifNil: [ anObject ]
  461. ifNotNil: [ self receiver valueForReceiver: anObject ]);
  462. selector: self selector;
  463. arguments: self arguments;
  464. yourself
  465. ! !
  466. !SendNode methodsFor: 'testing'!
  467. isCascadeSendNode
  468. ^ self parent isCascadeNode
  469. !
  470. isNavigationNode
  471. ^ true
  472. !
  473. isSendNode
  474. ^ true
  475. !
  476. requiresSmalltalkContext
  477. ^ true
  478. !
  479. shouldBeAliased
  480. "Because we keep track of send indexes, some send nodes need additional care for aliasing.
  481. See IRJSVisitor >> visitIRSend:"
  482. | sends |
  483. sends := (self method sendIndexes at: self selector) size.
  484. ^ (super shouldBeAliased or: [
  485. self isReferenced and: [
  486. (sends > 1 and: [ self index < sends ])
  487. or: [ self superSend ] ] ])
  488. !
  489. stopOnStepping
  490. ^ true
  491. ! !
  492. !SendNode methodsFor: 'visiting'!
  493. accept: aVisitor
  494. ^ aVisitor visitSendNode: self
  495. ! !
  496. Node subclass: #SequenceNode
  497. instanceVariableNames: 'temps scope'
  498. package: 'Compiler-AST'!
  499. !SequenceNode commentStamp!
  500. I represent an sequence node. A sequence represent a set of instructions inside the same scope (the method scope or a block scope).!
  501. !SequenceNode methodsFor: 'accessing'!
  502. scope
  503. ^ scope
  504. !
  505. scope: aLexicalScope
  506. scope := aLexicalScope
  507. !
  508. temps
  509. ^ temps ifNil: [ #() ]
  510. !
  511. temps: aCollection
  512. temps := aCollection
  513. ! !
  514. !SequenceNode methodsFor: 'converting'!
  515. asBlockSequenceNode
  516. ^ BlockSequenceNode new
  517. position: self position;
  518. source: self source;
  519. nodes: self nodes;
  520. temps: self temps;
  521. yourself
  522. ! !
  523. !SequenceNode methodsFor: 'testing'!
  524. isSequenceNode
  525. ^ true
  526. ! !
  527. !SequenceNode methodsFor: 'visiting'!
  528. accept: aVisitor
  529. ^ aVisitor visitSequenceNode: self
  530. ! !
  531. SequenceNode subclass: #BlockSequenceNode
  532. instanceVariableNames: ''
  533. package: 'Compiler-AST'!
  534. !BlockSequenceNode commentStamp!
  535. I represent an special sequence node for block scopes.!
  536. !BlockSequenceNode methodsFor: 'testing'!
  537. isBlockSequenceNode
  538. ^ true
  539. ! !
  540. !BlockSequenceNode methodsFor: 'visiting'!
  541. accept: aVisitor
  542. ^ aVisitor visitBlockSequenceNode: self
  543. ! !
  544. Node subclass: #ValueNode
  545. instanceVariableNames: 'value'
  546. package: 'Compiler-AST'!
  547. !ValueNode commentStamp!
  548. I represent a value node.!
  549. !ValueNode methodsFor: 'accessing'!
  550. value
  551. ^ value
  552. !
  553. value: anObject
  554. value := anObject
  555. ! !
  556. !ValueNode methodsFor: 'testing'!
  557. isImmutable
  558. ^ self value isImmutable
  559. !
  560. isValueNode
  561. ^ true
  562. ! !
  563. !ValueNode methodsFor: 'visiting'!
  564. accept: aVisitor
  565. ^ aVisitor visitValueNode: self
  566. ! !
  567. ValueNode subclass: #VariableNode
  568. instanceVariableNames: 'assigned binding'
  569. package: 'Compiler-AST'!
  570. !VariableNode commentStamp!
  571. I represent an variable node.!
  572. !VariableNode methodsFor: 'accessing'!
  573. alias
  574. ^ self binding alias
  575. !
  576. assigned
  577. ^ assigned ifNil: [ false ]
  578. !
  579. assigned: aBoolean
  580. assigned := aBoolean
  581. !
  582. beAssigned
  583. self binding validateAssignment.
  584. assigned := true
  585. !
  586. binding
  587. ^ binding
  588. !
  589. binding: aScopeVar
  590. binding := aScopeVar
  591. !
  592. navigationLink
  593. ^ self value
  594. ! !
  595. !VariableNode methodsFor: 'testing'!
  596. isArgument
  597. ^ self binding isArgVar
  598. !
  599. isImmutable
  600. ^ self binding isImmutable
  601. !
  602. isNavigationNode
  603. ^ true
  604. !
  605. isVariableNode
  606. ^ true
  607. ! !
  608. !VariableNode methodsFor: 'visiting'!
  609. accept: aVisitor
  610. ^ aVisitor visitVariableNode: self
  611. ! !
  612. !CompiledMethod methodsFor: '*Compiler-AST'!
  613. ast
  614. self source ifEmpty: [ self error: 'Method source is empty' ].
  615. ^ Smalltalk parse: self source
  616. ! !
  617. !Object methodsFor: '*Compiler-AST'!
  618. isNode
  619. ^ false
  620. ! !