1
0

Compiler-Interpreter.st 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. Smalltalk current createPackage: 'Compiler-Interpreter' properties: #{}!
  2. NodeVisitor subclass: #AIContext
  3. instanceVariableNames: 'outerContext pc locals selector'
  4. package: 'Compiler-Interpreter'!
  5. !AIContext methodsFor: 'accessing'!
  6. localAt: aString
  7. ^ self locals at: aString ifAbsent: [ nil ]
  8. !
  9. localAt: aString put: anObject
  10. self locals at: aString put: anObject
  11. !
  12. locals
  13. ^ locals ifNil: [ locals := Dictionary new ]
  14. !
  15. outerContext
  16. ^ outerContext
  17. !
  18. outerContext: anAIContext
  19. outerContext := anAIContext
  20. !
  21. pc
  22. ^ pc ifNil: [ pc := 0 ]
  23. !
  24. pc: anInteger
  25. pc := anInteger
  26. !
  27. receiver
  28. ^ self localAt: 'self'
  29. !
  30. receiver: anObject
  31. self localAt: 'self' put: anObject
  32. ! !
  33. !AIContext methodsFor: 'initialization'!
  34. initializeFromMethodContext: aMethodContext
  35. self pc: aMethodContext pc.
  36. self receiver: aMethodContext receiver.
  37. self selector: aMethodContext selector.
  38. aMethodContext outerContext ifNotNil: [
  39. self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
  40. aMethodContext locals keysAndValuesDo: [ :key :value |
  41. self locals at: key put: value ]
  42. ! !
  43. Object subclass: #ASTInterpreter
  44. instanceVariableNames: 'currentNode context shouldReturn result'
  45. package: 'Compiler-Interpreter'!
  46. !ASTInterpreter commentStamp!
  47. ASTIntepreter is like a `NodeVisitor`, interpreting nodes one after each other.
  48. It is built using Continuation Passing Style for stepping purposes.!
  49. !ASTInterpreter methodsFor: 'accessing'!
  50. context
  51. ^ context ifNil: [ context := AIContext new ]
  52. !
  53. context: anAIContext
  54. context := anAIContext
  55. !
  56. result
  57. ^ result
  58. ! !
  59. !ASTInterpreter methodsFor: 'initialization'!
  60. initialize
  61. super initialize.
  62. shouldReturn := false
  63. ! !
  64. !ASTInterpreter methodsFor: 'interpreting'!
  65. interpret: aNode
  66. shouldReturn := false.
  67. self interpret: aNode continue: [ :value |
  68. result := value ]
  69. !
  70. interpret: aNode continue: aBlock
  71. shouldReturn ifTrue: [ ^ self ].
  72. aNode isNode
  73. ifTrue: [
  74. currentNode := aNode.
  75. self interpretNode: aNode continue: [ :value |
  76. self continue: aBlock value: value] ]
  77. ifFalse: [ self continue: aBlock value: aNode ]
  78. !
  79. interpretAssignmentNode: aNode continue: aBlock
  80. self interpret: aNode right continue: [ :value |
  81. self
  82. continue: aBlock
  83. value: (self assign: aNode left to: value) ]
  84. !
  85. interpretBlockNode: aNode continue: aBlock
  86. "TODO: Context should be set"
  87. self
  88. continue: aBlock
  89. value: [ self interpret: aNode nodes first; result ]
  90. !
  91. interpretBlockSequenceNode: aNode continue: aBlock
  92. self interpretSequenceNode: aNode continue: aBlock
  93. !
  94. interpretCascadeNode: aNode continue: aBlock
  95. "TODO: Handle super sends"
  96. self interpret: aNode receiver continue: [ :receiver |
  97. "Only interpret the receiver once"
  98. aNode nodes do: [ :each | each receiver: receiver ].
  99. self
  100. interpretAll: aNode nodes allButLast
  101. continue: [
  102. self
  103. interpret: aNode nodes last
  104. continue: [ :val | self continue: aBlock value: val ] ] ]
  105. !
  106. interpretClassReferenceNode: aNode continue: aBlock
  107. self continue: aBlock value: (Smalltalk current at: aNode value)
  108. !
  109. interpretDynamicArrayNode: aNode continue: aBlock
  110. self interpretAll: aNode nodes continue: [ :array |
  111. self
  112. continue: aBlock
  113. value: array ]
  114. !
  115. interpretDynamicDictionaryNode: aNode continue: aBlock
  116. self interpretAll: aNode nodes continue: [ :array | | hashedCollection |
  117. hashedCollection := HashedCollection new.
  118. array do: [ :each | hashedCollection add: each ].
  119. self
  120. continue: aBlock
  121. value: hashedCollection ]
  122. !
  123. interpretJSStatementNode: aNode continue: aBlock
  124. shouldReturn := true.
  125. self continue: aBlock value: (self eval: aNode source)
  126. !
  127. interpretMethodNode: aNode continue: aBlock
  128. self interpretAll: aNode nodes continue: [ :array |
  129. self continue: aBlock value: array first ]
  130. !
  131. interpretNode: aNode continue: aBlock
  132. aNode interpreter: self continue: aBlock
  133. !
  134. interpretReturnNode: aNode continue: aBlock
  135. self interpret: aNode nodes first continue: [ :value |
  136. shouldReturn := true.
  137. self continue: aBlock value: value ]
  138. !
  139. interpretSendNode: aNode continue: aBlock
  140. "TODO: Handle super sends"
  141. self interpret: aNode receiver continue: [ :receiver |
  142. self messageFromSendNode: aNode do: [ :message |
  143. self context pc: self context pc + 1.
  144. self
  145. continue: aBlock
  146. value: (message sendTo: receiver) ] ]
  147. !
  148. interpretSequenceNode: aNode continue: aBlock
  149. self interpretAll: aNode nodes continue: [ :array |
  150. self continue: aBlock value: array last ]
  151. !
  152. interpretValueNode: aNode continue: aBlock
  153. self continue: aBlock value: aNode value
  154. !
  155. interpretVariableNode: aNode continue: aBlock
  156. self
  157. continue: aBlock
  158. value: (aNode binding isInstanceVar
  159. ifTrue: [ self context receiver instVarAt: aNode value ]
  160. ifFalse: [ self context localAt: aNode value ])
  161. ! !
  162. !ASTInterpreter methodsFor: 'private'!
  163. assign: aNode to: anObject
  164. ^ aNode binding isInstanceVar
  165. ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]
  166. ifFalse: [ self context localAt: aNode value put: anObject ]
  167. !
  168. continue: aBlock value: anObject
  169. result := anObject.
  170. aBlock value: anObject
  171. !
  172. eval: aString
  173. "Evaluate aString as JS source inside an JS function.
  174. aString is not sandboxed."
  175. | source function |
  176. source := String streamContents: [ :str |
  177. str nextPutAll: '(function('.
  178. self context locals keys
  179. do: [ :each | str nextPutAll: each ]
  180. separatedBy: [ str nextPutAll: ',' ].
  181. str
  182. nextPutAll: '){ return (function() {';
  183. nextPutAll: aString;
  184. nextPutAll: '})() })' ].
  185. function := Compiler new eval: source.
  186. ^ function valueWithPossibleArguments: self context locals values
  187. !
  188. interpretAll: aCollection continue: aBlock
  189. self
  190. interpretAll: aCollection
  191. continue: aBlock
  192. result: OrderedCollection new
  193. !
  194. interpretAll: nodes continue: aBlock result: aCollection
  195. nodes isEmpty
  196. ifTrue: [ aBlock value: aCollection ]
  197. ifFalse: [
  198. self interpret: nodes first continue: [:value |
  199. self
  200. interpretAll: nodes allButFirst
  201. continue: aBlock
  202. result: aCollection, { value } ] ]
  203. !
  204. messageFromSendNode: aSendNode do: aBlock
  205. self interpretAll: aSendNode arguments continue: [ :args |
  206. aBlock value: (Message new
  207. selector: aSendNode selector;
  208. arguments: args;
  209. yourself) ]
  210. ! !
  211. ASTInterpreter subclass: #ASTDebugger
  212. instanceVariableNames: 'continuation'
  213. package: 'Compiler-Interpreter'!
  214. !ASTDebugger methodsFor: 'initialization'!
  215. initialize
  216. super initialize.
  217. continuation := [ ]
  218. ! !
  219. !ASTDebugger methodsFor: 'interpreting'!
  220. interpret: aNode continue: aBlock
  221. continuation := [ super interpret: aNode continue: aBlock ]
  222. ! !
  223. !ASTDebugger methodsFor: 'stepping'!
  224. stepOver
  225. continuation value
  226. ! !
  227. !Node methodsFor: '*Compiler-Interpreter'!
  228. interpreter: anInterpreter continue: aBlock
  229. ^ anInterpreter interpretNode: self continue: aBlock
  230. ! !
  231. !AssignmentNode methodsFor: '*Compiler-Interpreter'!
  232. interpreter: anInterpreter continue: aBlock
  233. ^ anInterpreter interpretAssignmentNode: self continue: aBlock
  234. ! !
  235. !BlockNode methodsFor: '*Compiler-Interpreter'!
  236. interpreter: anInterpreter continue: aBlock
  237. ^ anInterpreter interpretBlockNode: self continue: aBlock
  238. ! !
  239. !CascadeNode methodsFor: '*Compiler-Interpreter'!
  240. interpreter: anInterpreter continue: aBlock
  241. ^ anInterpreter interpretCascadeNode: self continue: aBlock
  242. ! !
  243. !DynamicArrayNode methodsFor: '*Compiler-Interpreter'!
  244. interpreter: anInterpreter continue: aBlock
  245. ^ anInterpreter interpretDynamicArrayNode: self continue: aBlock
  246. ! !
  247. !DynamicDictionaryNode methodsFor: '*Compiler-Interpreter'!
  248. interpreter: anInterpreter continue: aBlock
  249. ^ anInterpreter interpretDynamicDictionaryNode: self continue: aBlock
  250. ! !
  251. !JSStatementNode methodsFor: '*Compiler-Interpreter'!
  252. interpreter: anInterpreter continue: aBlock
  253. ^ anInterpreter interpretJSStatementNode: self continue: aBlock
  254. ! !
  255. !MethodNode methodsFor: '*Compiler-Interpreter'!
  256. interpreter: anInterpreter continue: aBlock
  257. ^ anInterpreter interpretMethodNode: self continue: aBlock
  258. ! !
  259. !ReturnNode methodsFor: '*Compiler-Interpreter'!
  260. interpreter: anInterpreter continue: aBlock
  261. ^ anInterpreter interpretReturnNode: self continue: aBlock
  262. ! !
  263. !SendNode methodsFor: '*Compiler-Interpreter'!
  264. interpreter: anInterpreter continue: aBlock
  265. ^ anInterpreter interpretSendNode: self continue: aBlock
  266. ! !
  267. !SequenceNode methodsFor: '*Compiler-Interpreter'!
  268. interpreter: anInterpreter continue: aBlock
  269. ^ anInterpreter interpretSequenceNode: self continue: aBlock
  270. ! !
  271. !BlockSequenceNode methodsFor: '*Compiler-Interpreter'!
  272. interpreter: anInterpreter continue: aBlock
  273. ^ anInterpreter interpretBlockSequenceNode: self continue: aBlock
  274. ! !
  275. !ValueNode methodsFor: '*Compiler-Interpreter'!
  276. interpreter: anInterpreter continue: aBlock
  277. ^ anInterpreter interpretValueNode: self continue: aBlock
  278. ! !
  279. !VariableNode methodsFor: '*Compiler-Interpreter'!
  280. interpreter: anInterpreter continue: aBlock
  281. ^ anInterpreter interpretVariableNode: self continue: aBlock
  282. ! !
  283. !ClassReferenceNode methodsFor: '*Compiler-Interpreter'!
  284. interpreter: anInterpreter continue: aBlock
  285. ^ anInterpreter interpretClassReferenceNode: self continue: aBlock
  286. ! !