Compiler-AST.st 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  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. isReturnNode
  102. ^false
  103. !
  104. isSendNode
  105. ^false
  106. !
  107. isValueNode
  108. ^false
  109. !
  110. stopOnStepping
  111. ^ false
  112. !
  113. subtreeNeedsAliasing
  114. ^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
  115. (self nodes detect: [ :each | each subtreeNeedsAliasing ] ifNone: [ false ]) ~= false ]
  116. ! !
  117. !Node methodsFor: 'visiting'!
  118. accept: aVisitor
  119. ^ aVisitor visitNode: self
  120. ! !
  121. Node subclass: #AssignmentNode
  122. instanceVariableNames: 'left right'
  123. package: 'Compiler-AST'!
  124. !AssignmentNode commentStamp!
  125. I represent an assignment node.!
  126. !AssignmentNode methodsFor: 'accessing'!
  127. left
  128. ^left
  129. !
  130. left: aNode
  131. left := aNode.
  132. aNode parent: self
  133. !
  134. nodes
  135. ^ Array with: self left with: self right
  136. !
  137. right
  138. ^right
  139. !
  140. right: aNode
  141. right := aNode.
  142. aNode parent: self
  143. ! !
  144. !AssignmentNode methodsFor: 'testing'!
  145. isAssignmentNode
  146. ^ true
  147. ! !
  148. !AssignmentNode methodsFor: 'visiting'!
  149. accept: aVisitor
  150. ^ aVisitor visitAssignmentNode: self
  151. ! !
  152. Node subclass: #BlockNode
  153. instanceVariableNames: 'parameters scope'
  154. package: 'Compiler-AST'!
  155. !BlockNode commentStamp!
  156. I represent an block closure node.!
  157. !BlockNode methodsFor: 'accessing'!
  158. nextChild
  159. "Answer the receiver as we want to avoid eager evaluation"
  160. ^ self
  161. !
  162. nextNode: aNode
  163. "Answer the receiver as we want to avoid eager evaluation"
  164. ^ self
  165. !
  166. parameters
  167. ^parameters ifNil: [parameters := Array new]
  168. !
  169. parameters: aCollection
  170. parameters := aCollection
  171. !
  172. scope
  173. ^ scope
  174. !
  175. scope: aLexicalScope
  176. scope := aLexicalScope
  177. ! !
  178. !BlockNode methodsFor: 'testing'!
  179. isBlockNode
  180. ^true
  181. !
  182. subtreeNeedsAliasing
  183. ^ self shouldBeAliased or: [ self shouldBeInlined ]
  184. ! !
  185. !BlockNode methodsFor: 'visiting'!
  186. accept: aVisitor
  187. ^ aVisitor visitBlockNode: self
  188. ! !
  189. Node subclass: #CascadeNode
  190. instanceVariableNames: 'receiver'
  191. package: 'Compiler-AST'!
  192. !CascadeNode commentStamp!
  193. I represent an cascade node.!
  194. !CascadeNode methodsFor: 'accessing'!
  195. receiver
  196. ^receiver
  197. !
  198. receiver: aNode
  199. receiver := aNode
  200. ! !
  201. !CascadeNode methodsFor: 'testing'!
  202. isCascadeNode
  203. ^ true
  204. ! !
  205. !CascadeNode methodsFor: 'visiting'!
  206. accept: aVisitor
  207. ^ aVisitor visitCascadeNode: self
  208. ! !
  209. Node subclass: #DynamicArrayNode
  210. instanceVariableNames: ''
  211. package: 'Compiler-AST'!
  212. !DynamicArrayNode commentStamp!
  213. I represent an dynamic array node.!
  214. !DynamicArrayNode methodsFor: 'visiting'!
  215. accept: aVisitor
  216. ^ aVisitor visitDynamicArrayNode: self
  217. ! !
  218. Node subclass: #DynamicDictionaryNode
  219. instanceVariableNames: ''
  220. package: 'Compiler-AST'!
  221. !DynamicDictionaryNode commentStamp!
  222. I represent an dynamic dictionary node.!
  223. !DynamicDictionaryNode methodsFor: 'visiting'!
  224. accept: aVisitor
  225. ^ aVisitor visitDynamicDictionaryNode: self
  226. ! !
  227. Node subclass: #JSStatementNode
  228. instanceVariableNames: 'source'
  229. package: 'Compiler-AST'!
  230. !JSStatementNode commentStamp!
  231. I represent an JavaScript statement node.!
  232. !JSStatementNode methodsFor: 'accessing'!
  233. source
  234. ^source ifNil: ['']
  235. !
  236. source: aString
  237. source := aString
  238. ! !
  239. !JSStatementNode methodsFor: 'testing'!
  240. isJSStatementNode
  241. ^ true
  242. ! !
  243. !JSStatementNode methodsFor: 'visiting'!
  244. accept: aVisitor
  245. ^ aVisitor visitJSStatementNode: self
  246. ! !
  247. Node subclass: #MethodNode
  248. instanceVariableNames: 'selector arguments source scope classReferences sendIndexes superSends'
  249. package: 'Compiler-AST'!
  250. !MethodNode commentStamp!
  251. I represent an method node.
  252. A method node must be the root and only method node of a valid AST.!
  253. !MethodNode methodsFor: 'accessing'!
  254. arguments
  255. ^arguments ifNil: [#()]
  256. !
  257. arguments: aCollection
  258. arguments := aCollection
  259. !
  260. classReferences
  261. ^ classReferences
  262. !
  263. classReferences: aCollection
  264. classReferences := aCollection
  265. !
  266. extent
  267. ^ self source lines size @ (self source lines last size + 1)
  268. !
  269. messageSends
  270. ^ self sendIndexes keys
  271. !
  272. method
  273. ^ self
  274. !
  275. scope
  276. ^ scope
  277. !
  278. scope: aMethodScope
  279. scope := aMethodScope
  280. !
  281. selector
  282. ^selector
  283. !
  284. selector: aString
  285. selector := aString
  286. !
  287. sendIndexes
  288. ^ sendIndexes
  289. !
  290. sendIndexes: aDictionary
  291. sendIndexes := aDictionary
  292. !
  293. source
  294. ^source
  295. !
  296. source: aString
  297. source := aString
  298. !
  299. superSends
  300. ^ superSends
  301. !
  302. superSends: aCollection
  303. superSends := aCollection
  304. ! !
  305. !MethodNode methodsFor: 'visiting'!
  306. accept: aVisitor
  307. ^ aVisitor visitMethodNode: self
  308. ! !
  309. Node subclass: #ReturnNode
  310. instanceVariableNames: 'scope'
  311. package: 'Compiler-AST'!
  312. !ReturnNode commentStamp!
  313. I represent an return node. At the AST level, there is not difference between a local return or non-local return.!
  314. !ReturnNode methodsFor: 'accessing'!
  315. scope
  316. ^ scope
  317. !
  318. scope: aLexicalScope
  319. scope := aLexicalScope
  320. ! !
  321. !ReturnNode methodsFor: 'testing'!
  322. isReturnNode
  323. ^ true
  324. !
  325. nonLocalReturn
  326. ^ self scope isMethodScope not
  327. ! !
  328. !ReturnNode methodsFor: 'visiting'!
  329. accept: aVisitor
  330. ^ aVisitor visitReturnNode: self
  331. ! !
  332. Node subclass: #SendNode
  333. instanceVariableNames: 'selector arguments receiver superSend index'
  334. package: 'Compiler-AST'!
  335. !SendNode commentStamp!
  336. I represent an message send node.!
  337. !SendNode methodsFor: 'accessing'!
  338. arguments
  339. ^arguments ifNil: [arguments := #()]
  340. !
  341. arguments: aCollection
  342. arguments := aCollection.
  343. aCollection do: [ :each | each parent: self ]
  344. !
  345. cascadeNodeWithMessages: aCollection
  346. | first |
  347. first := SendNode new
  348. selector: self selector;
  349. arguments: self arguments;
  350. yourself.
  351. ^CascadeNode new
  352. receiver: self receiver;
  353. nodes: (Array with: first), aCollection;
  354. yourself
  355. !
  356. index
  357. ^ index
  358. !
  359. index: anInteger
  360. index := anInteger
  361. !
  362. nodes
  363. self receiver ifNil: [ ^ self arguments copy ].
  364. ^ (Array with: self receiver)
  365. addAll: self arguments;
  366. yourself
  367. !
  368. receiver
  369. ^receiver
  370. !
  371. receiver: aNode
  372. receiver := aNode.
  373. aNode isNode ifTrue: [
  374. aNode parent: self ]
  375. !
  376. selector
  377. ^selector
  378. !
  379. selector: aString
  380. selector := aString
  381. !
  382. superSend
  383. ^ superSend ifNil: [ false ]
  384. !
  385. superSend: aBoolean
  386. superSend := aBoolean
  387. !
  388. valueForReceiver: anObject
  389. ^SendNode new
  390. position: self position;
  391. receiver: (self receiver
  392. ifNil: [anObject]
  393. ifNotNil: [self receiver valueForReceiver: anObject]);
  394. selector: self selector;
  395. arguments: self arguments;
  396. yourself
  397. ! !
  398. !SendNode methodsFor: 'testing'!
  399. isCascadeSendNode
  400. ^ self parent isCascadeNode
  401. !
  402. isSendNode
  403. ^ true
  404. !
  405. shouldBeAliased
  406. ^ super shouldBeAliased or: [
  407. (self method sendIndexes at: self selector) size > 1 ]
  408. !
  409. stopOnStepping
  410. ^ true
  411. ! !
  412. !SendNode methodsFor: 'visiting'!
  413. accept: aVisitor
  414. ^ aVisitor visitSendNode: self
  415. ! !
  416. Node subclass: #SequenceNode
  417. instanceVariableNames: 'temps scope'
  418. package: 'Compiler-AST'!
  419. !SequenceNode commentStamp!
  420. I represent an sequence node. A sequence represent a set of instructions inside the same scope (the method scope or a block scope).!
  421. !SequenceNode methodsFor: 'accessing'!
  422. scope
  423. ^ scope
  424. !
  425. scope: aLexicalScope
  426. scope := aLexicalScope
  427. !
  428. temps
  429. ^temps ifNil: [#()]
  430. !
  431. temps: aCollection
  432. temps := aCollection
  433. ! !
  434. !SequenceNode methodsFor: 'testing'!
  435. asBlockSequenceNode
  436. ^BlockSequenceNode new
  437. position: self position;
  438. nodes: self nodes;
  439. temps: self temps;
  440. yourself
  441. ! !
  442. !SequenceNode methodsFor: 'visiting'!
  443. accept: aVisitor
  444. ^ aVisitor visitSequenceNode: self
  445. ! !
  446. SequenceNode subclass: #BlockSequenceNode
  447. instanceVariableNames: ''
  448. package: 'Compiler-AST'!
  449. !BlockSequenceNode commentStamp!
  450. I represent an special sequence node for block scopes.!
  451. !BlockSequenceNode methodsFor: 'testing'!
  452. isBlockSequenceNode
  453. ^true
  454. ! !
  455. !BlockSequenceNode methodsFor: 'visiting'!
  456. accept: aVisitor
  457. ^ aVisitor visitBlockSequenceNode: self
  458. ! !
  459. Node subclass: #ValueNode
  460. instanceVariableNames: 'value'
  461. package: 'Compiler-AST'!
  462. !ValueNode commentStamp!
  463. I represent a value node.!
  464. !ValueNode methodsFor: 'accessing'!
  465. value
  466. ^value
  467. !
  468. value: anObject
  469. value := anObject
  470. ! !
  471. !ValueNode methodsFor: 'testing'!
  472. isImmutable
  473. ^ self value isImmutable
  474. !
  475. isValueNode
  476. ^true
  477. ! !
  478. !ValueNode methodsFor: 'visiting'!
  479. accept: aVisitor
  480. ^ aVisitor visitValueNode: self
  481. ! !
  482. !ValueNode methodsFor: 'xxxDoIt'!
  483. xxxDoIt ^[self stack] value
  484. ! !
  485. ValueNode subclass: #VariableNode
  486. instanceVariableNames: 'assigned binding'
  487. package: 'Compiler-AST'!
  488. !VariableNode commentStamp!
  489. I represent an variable node.!
  490. !VariableNode methodsFor: 'accessing'!
  491. alias
  492. ^ self binding alias
  493. !
  494. assigned
  495. ^assigned ifNil: [false]
  496. !
  497. assigned: aBoolean
  498. assigned := aBoolean
  499. !
  500. beAssigned
  501. self binding validateAssignment.
  502. assigned := true
  503. !
  504. binding
  505. ^ binding
  506. !
  507. binding: aScopeVar
  508. binding := aScopeVar
  509. ! !
  510. !VariableNode methodsFor: 'testing'!
  511. isImmutable
  512. ^ self binding isPseudoVar
  513. ! !
  514. !VariableNode methodsFor: 'visiting'!
  515. accept: aVisitor
  516. ^ aVisitor visitVariableNode: self
  517. ! !
  518. !Object methodsFor: '*Compiler-AST'!
  519. isNode
  520. ^ false
  521. ! !
  522. !CompiledMethod methodsFor: '*Compiler-AST'!
  523. ast
  524. self source ifEmpty: [ self error: 'Method source is empty' ].
  525. ^ Smalltalk current parse: self source
  526. ! !