Compiler-AST.st 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  1. Smalltalk current createPackage: 'Compiler-AST'!
  2. Object subclass: #Node
  3. instanceVariableNames: '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. !
  13. nodes
  14. ^nodes ifNil: [nodes := Array new]
  15. !
  16. position
  17. ^position ifNil: [position := 0@0]
  18. !
  19. shouldBeAliased
  20. ^ shouldBeAliased ifNil: [ false ]
  21. !
  22. shouldBeAliased: aBoolean
  23. shouldBeAliased := aBoolean
  24. !
  25. shouldBeInlined
  26. ^ shouldBeInlined ifNil: [ false ]
  27. !
  28. shouldBeInlined: aBoolean
  29. shouldBeInlined := aBoolean
  30. ! !
  31. !Node methodsFor: 'building'!
  32. nodes: aCollection
  33. nodes := aCollection
  34. !
  35. position: aPosition
  36. position := aPosition
  37. ! !
  38. !Node methodsFor: 'testing'!
  39. isAssignmentNode
  40. ^ false
  41. !
  42. isBlockNode
  43. ^false
  44. !
  45. isBlockSequenceNode
  46. ^false
  47. !
  48. isImmutable
  49. ^false
  50. !
  51. isNode
  52. ^ true
  53. !
  54. isReturnNode
  55. ^false
  56. !
  57. isSendNode
  58. ^false
  59. !
  60. isValueNode
  61. ^false
  62. !
  63. stopOnStepping
  64. ^ false
  65. !
  66. subtreeNeedsAliasing
  67. ^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
  68. (self nodes detect: [ :each | each subtreeNeedsAliasing ] ifNone: [ false ]) ~= false ]
  69. ! !
  70. !Node methodsFor: 'visiting'!
  71. accept: aVisitor
  72. ^ aVisitor visitNode: self
  73. ! !
  74. Node subclass: #AssignmentNode
  75. instanceVariableNames: 'left right'
  76. package: 'Compiler-AST'!
  77. !AssignmentNode commentStamp!
  78. I represent an assignment node.!
  79. !AssignmentNode methodsFor: 'accessing'!
  80. left
  81. ^left
  82. !
  83. left: aNode
  84. left := aNode
  85. !
  86. nodes
  87. ^ Array with: self left with: self right
  88. !
  89. right
  90. ^right
  91. !
  92. right: aNode
  93. right := aNode
  94. ! !
  95. !AssignmentNode methodsFor: 'testing'!
  96. isAssignmentNode
  97. ^ true
  98. ! !
  99. !AssignmentNode methodsFor: 'visiting'!
  100. accept: aVisitor
  101. ^ aVisitor visitAssignmentNode: self
  102. ! !
  103. Node subclass: #BlockNode
  104. instanceVariableNames: 'parameters scope'
  105. package: 'Compiler-AST'!
  106. !BlockNode commentStamp!
  107. I represent an block closure node.!
  108. !BlockNode methodsFor: 'accessing'!
  109. parameters
  110. ^parameters ifNil: [parameters := Array new]
  111. !
  112. parameters: aCollection
  113. parameters := aCollection
  114. !
  115. scope
  116. ^ scope
  117. !
  118. scope: aLexicalScope
  119. scope := aLexicalScope
  120. ! !
  121. !BlockNode methodsFor: 'testing'!
  122. isBlockNode
  123. ^true
  124. !
  125. subtreeNeedsAliasing
  126. ^ self shouldBeAliased or: [ self shouldBeInlined ]
  127. ! !
  128. !BlockNode methodsFor: 'visiting'!
  129. accept: aVisitor
  130. ^ aVisitor visitBlockNode: self
  131. ! !
  132. Node subclass: #CascadeNode
  133. instanceVariableNames: 'receiver'
  134. package: 'Compiler-AST'!
  135. !CascadeNode commentStamp!
  136. I represent an cascade node.!
  137. !CascadeNode methodsFor: 'accessing'!
  138. receiver
  139. ^receiver
  140. !
  141. receiver: aNode
  142. receiver := aNode
  143. ! !
  144. !CascadeNode methodsFor: 'visiting'!
  145. accept: aVisitor
  146. ^ aVisitor visitCascadeNode: self
  147. ! !
  148. Node subclass: #DynamicArrayNode
  149. instanceVariableNames: ''
  150. package: 'Compiler-AST'!
  151. !DynamicArrayNode commentStamp!
  152. I represent an dynamic array node.!
  153. !DynamicArrayNode methodsFor: 'visiting'!
  154. accept: aVisitor
  155. ^ aVisitor visitDynamicArrayNode: self
  156. ! !
  157. Node subclass: #DynamicDictionaryNode
  158. instanceVariableNames: ''
  159. package: 'Compiler-AST'!
  160. !DynamicDictionaryNode commentStamp!
  161. I represent an dynamic dictionary node.!
  162. !DynamicDictionaryNode methodsFor: 'visiting'!
  163. accept: aVisitor
  164. ^ aVisitor visitDynamicDictionaryNode: self
  165. ! !
  166. Node subclass: #JSStatementNode
  167. instanceVariableNames: 'source'
  168. package: 'Compiler-AST'!
  169. !JSStatementNode commentStamp!
  170. I represent an JavaScript statement node.!
  171. !JSStatementNode methodsFor: 'accessing'!
  172. source
  173. ^source ifNil: ['']
  174. !
  175. source: aString
  176. source := aString
  177. ! !
  178. !JSStatementNode methodsFor: 'visiting'!
  179. accept: aVisitor
  180. ^ aVisitor visitJSStatementNode: self
  181. ! !
  182. Node subclass: #MethodNode
  183. instanceVariableNames: 'selector arguments source scope classReferences messageSends superSends'
  184. package: 'Compiler-AST'!
  185. !MethodNode commentStamp!
  186. I represent an method node.
  187. A method node must be the root and only method node of a valid AST.!
  188. !MethodNode methodsFor: 'accessing'!
  189. arguments
  190. ^arguments ifNil: [#()]
  191. !
  192. arguments: aCollection
  193. arguments := aCollection
  194. !
  195. classReferences
  196. ^ classReferences
  197. !
  198. classReferences: aCollection
  199. classReferences := aCollection
  200. !
  201. messageSends
  202. ^ messageSends
  203. !
  204. messageSends: aCollection
  205. messageSends := aCollection
  206. !
  207. scope
  208. ^ scope
  209. !
  210. scope: aMethodScope
  211. scope := aMethodScope
  212. !
  213. selector
  214. ^selector
  215. !
  216. selector: aString
  217. selector := aString
  218. !
  219. source
  220. ^source
  221. !
  222. source: aString
  223. source := aString
  224. !
  225. superSends
  226. ^ superSends
  227. !
  228. superSends: aCollection
  229. superSends := aCollection
  230. ! !
  231. !MethodNode methodsFor: 'visiting'!
  232. accept: aVisitor
  233. ^ aVisitor visitMethodNode: self
  234. ! !
  235. Node subclass: #ReturnNode
  236. instanceVariableNames: 'scope'
  237. package: 'Compiler-AST'!
  238. !ReturnNode commentStamp!
  239. I represent an return node. At the AST level, there is not difference between a local return or non-local return.!
  240. !ReturnNode methodsFor: 'accessing'!
  241. scope
  242. ^ scope
  243. !
  244. scope: aLexicalScope
  245. scope := aLexicalScope
  246. ! !
  247. !ReturnNode methodsFor: 'testing'!
  248. isReturnNode
  249. ^ true
  250. !
  251. nonLocalReturn
  252. ^ self scope isMethodScope not
  253. ! !
  254. !ReturnNode methodsFor: 'visiting'!
  255. accept: aVisitor
  256. ^ aVisitor visitReturnNode: self
  257. ! !
  258. Node subclass: #SendNode
  259. instanceVariableNames: 'selector arguments receiver superSend index'
  260. package: 'Compiler-AST'!
  261. !SendNode commentStamp!
  262. I represent an message send node.!
  263. !SendNode methodsFor: 'accessing'!
  264. arguments
  265. ^arguments ifNil: [arguments := #()]
  266. !
  267. arguments: aCollection
  268. arguments := aCollection
  269. !
  270. cascadeNodeWithMessages: aCollection
  271. | first |
  272. first := SendNode new
  273. selector: self selector;
  274. arguments: self arguments;
  275. yourself.
  276. ^CascadeNode new
  277. receiver: self receiver;
  278. nodes: (Array with: first), aCollection;
  279. yourself
  280. !
  281. index
  282. ^ index
  283. !
  284. index: anInteger
  285. index := anInteger
  286. !
  287. nodes
  288. ^ (Array withAll: self arguments)
  289. add: self receiver;
  290. yourself
  291. !
  292. receiver
  293. ^receiver
  294. !
  295. receiver: aNode
  296. receiver := aNode
  297. !
  298. selector
  299. ^selector
  300. !
  301. selector: aString
  302. selector := aString
  303. !
  304. superSend
  305. ^ superSend ifNil: [ false ]
  306. !
  307. superSend: aBoolean
  308. superSend := aBoolean
  309. !
  310. valueForReceiver: anObject
  311. ^SendNode new
  312. receiver: (self receiver
  313. ifNil: [anObject]
  314. ifNotNil: [self receiver valueForReceiver: anObject]);
  315. selector: self selector;
  316. arguments: self arguments;
  317. yourself
  318. ! !
  319. !SendNode methodsFor: 'testing'!
  320. isSendNode
  321. ^ true
  322. !
  323. stopOnStepping
  324. ^ true
  325. ! !
  326. !SendNode methodsFor: 'visiting'!
  327. accept: aVisitor
  328. ^ aVisitor visitSendNode: self
  329. ! !
  330. Node subclass: #SequenceNode
  331. instanceVariableNames: 'temps scope'
  332. package: 'Compiler-AST'!
  333. !SequenceNode commentStamp!
  334. I represent an sequence node. A sequence represent a set of instructions inside the same scope (the method scope or a block scope).!
  335. !SequenceNode methodsFor: 'accessing'!
  336. scope
  337. ^ scope
  338. !
  339. scope: aLexicalScope
  340. scope := aLexicalScope
  341. !
  342. temps
  343. ^temps ifNil: [#()]
  344. !
  345. temps: aCollection
  346. temps := aCollection
  347. ! !
  348. !SequenceNode methodsFor: 'testing'!
  349. asBlockSequenceNode
  350. ^BlockSequenceNode new
  351. nodes: self nodes;
  352. temps: self temps;
  353. yourself
  354. ! !
  355. !SequenceNode methodsFor: 'visiting'!
  356. accept: aVisitor
  357. ^ aVisitor visitSequenceNode: self
  358. ! !
  359. SequenceNode subclass: #BlockSequenceNode
  360. instanceVariableNames: ''
  361. package: 'Compiler-AST'!
  362. !BlockSequenceNode commentStamp!
  363. I represent an special sequence node for block scopes.!
  364. !BlockSequenceNode methodsFor: 'testing'!
  365. isBlockSequenceNode
  366. ^true
  367. ! !
  368. !BlockSequenceNode methodsFor: 'visiting'!
  369. accept: aVisitor
  370. ^ aVisitor visitBlockSequenceNode: self
  371. ! !
  372. Node subclass: #ValueNode
  373. instanceVariableNames: 'value'
  374. package: 'Compiler-AST'!
  375. !ValueNode commentStamp!
  376. I represent a value node.!
  377. !ValueNode methodsFor: 'accessing'!
  378. value
  379. ^value
  380. !
  381. value: anObject
  382. value := anObject
  383. ! !
  384. !ValueNode methodsFor: 'testing'!
  385. isImmutable
  386. ^ self value isImmutable
  387. !
  388. isValueNode
  389. ^true
  390. ! !
  391. !ValueNode methodsFor: 'visiting'!
  392. accept: aVisitor
  393. ^ aVisitor visitValueNode: self
  394. ! !
  395. ValueNode subclass: #VariableNode
  396. instanceVariableNames: 'assigned binding'
  397. package: 'Compiler-AST'!
  398. !VariableNode commentStamp!
  399. I represent an variable node.!
  400. !VariableNode methodsFor: 'accessing'!
  401. alias
  402. ^ self binding alias
  403. !
  404. assigned
  405. ^assigned ifNil: [false]
  406. !
  407. assigned: aBoolean
  408. assigned := aBoolean
  409. !
  410. beAssigned
  411. self binding validateAssignment.
  412. assigned := true
  413. !
  414. binding
  415. ^ binding
  416. !
  417. binding: aScopeVar
  418. binding := aScopeVar
  419. ! !
  420. !VariableNode methodsFor: 'testing'!
  421. isImmutable
  422. ^false
  423. ! !
  424. !VariableNode methodsFor: 'visiting'!
  425. accept: aVisitor
  426. ^ aVisitor visitVariableNode: self
  427. ! !
  428. VariableNode subclass: #ClassReferenceNode
  429. instanceVariableNames: ''
  430. package: 'Compiler-AST'!
  431. !ClassReferenceNode commentStamp!
  432. I represent an class reference node.!
  433. !ClassReferenceNode methodsFor: 'visiting'!
  434. accept: aVisitor
  435. ^ aVisitor visitClassReferenceNode: self
  436. ! !
  437. !Object methodsFor: '*Compiler-AST'!
  438. isNode
  439. ^ false
  440. ! !