Compiler-AST.st 11 KB

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