Compiler-Interpreter.st 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. Smalltalk current createPackage: 'Compiler-Interpreter' properties: #{}!
  2. NodeVisitor subclass: #AIContext
  3. instanceVariableNames: 'outerContext pc locals receiver selector'
  4. package: 'Compiler-Interpreter'!
  5. !AIContext methodsFor: 'accessing'!
  6. initializeFromMethodContext: aMethodContext
  7. self pc: aMethodContext pc.
  8. self receiver: aMethodContext receiver.
  9. self selector: aMethodContext selector.
  10. aMethodContext outerContext ifNotNil: [
  11. self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].
  12. aMethodContext locals keysAndValuesDo: [ :key :value |
  13. self locals at: key put: value ]
  14. !
  15. localAt: aString
  16. ^ self locals at: aString ifAbsent: [ nil ]
  17. !
  18. localAt: aString put: anObject
  19. self locals at: aString put: anObject
  20. !
  21. locals
  22. ^ locals ifNil: [ locals := Dictionary new ]
  23. !
  24. outerContext
  25. ^ outerContext
  26. !
  27. outerContext: anAIContext
  28. outerContext := anAIContext
  29. !
  30. pc
  31. ^ pc ifNil: [ pc := 0 ]
  32. !
  33. pc: anInteger
  34. pc := anInteger
  35. !
  36. receiver
  37. ^ receiver
  38. !
  39. receiver: anObject
  40. receiver := anObject
  41. !
  42. selector
  43. ^ selector
  44. !
  45. selector: aString
  46. selector := aString
  47. ! !
  48. !AIContext class methodsFor: 'instance creation'!
  49. fromMethodContext: aMethodContext
  50. ^ self new
  51. initializeFromMethodContext: aMethodContext;
  52. yourself
  53. ! !
  54. NodeVisitor subclass: #ASTInterpreter
  55. instanceVariableNames: 'currentNode context shouldReturn'
  56. package: 'Compiler-Interpreter'!
  57. !ASTInterpreter methodsFor: 'accessing'!
  58. context
  59. ^ context ifNil: [ context := AIContext new ]
  60. !
  61. context: anAIContext
  62. context := anAIContext
  63. ! !
  64. !ASTInterpreter methodsFor: 'initialization'!
  65. initialize
  66. super initialize.
  67. shouldReturn := false
  68. ! !
  69. !ASTInterpreter methodsFor: 'interpreting'!
  70. assign: aNode to: anObject
  71. ^ aNode binding isInstanceVar
  72. ifTrue: [ self context receiver instVarAt: aNode value put: anObject ]
  73. ifFalse: [ self context localAt: aNode value put: anObject ]
  74. !
  75. eval: aString
  76. "Evaluate aString as JS source inside an JS function.
  77. aString is not sandboxed."
  78. | source function |
  79. source := String streamContents: [ :str |
  80. str nextPutAll: '(function('.
  81. self context locals keys
  82. do: [ :each | str nextPutAll: each ]
  83. separatedBy: [ str nextPutAll: ',' ].
  84. str
  85. nextPutAll: '){ return (function() {';
  86. nextPutAll: aString;
  87. nextPutAll: '})() })' ].
  88. function := Compiler new eval: source.
  89. ^ function valueWithPossibleArguments: self context locals values
  90. !
  91. interpret: aNode
  92. shouldReturn := false.
  93. ^ self interpretNode: aNode
  94. !
  95. interpretNode: aNode
  96. currentNode := aNode.
  97. ^ self visit: aNode
  98. !
  99. messageFromSendNode: aSendNode
  100. ^ Message new
  101. selector: aSendNode selector;
  102. arguments: (aSendNode arguments collect: [ :each |
  103. self interpretNode: each ]);
  104. yourself
  105. ! !
  106. !ASTInterpreter methodsFor: 'visiting'!
  107. visitAssignmentNode: aNode
  108. ^ self assign: aNode left to: (self interpretNode: aNode right)
  109. !
  110. visitBlockNode: aNode
  111. ^ [ self interpretNode: aNode nodes first ]
  112. !
  113. visitCascadeNode: aNode
  114. "TODO: Handle super sends"
  115. | receiver |
  116. receiver := self interpretNode: aNode receiver.
  117. aNode nodes allButLast
  118. do: [ :each |
  119. (self messageFromSendNode: each)
  120. sendTo: receiver ].
  121. ^ (self messageFromSendNode: aNode nodes last)
  122. sendTo: receiver
  123. !
  124. visitClassReferenceNode: aNode
  125. ^ Smalltalk current at: aNode value
  126. !
  127. visitJSStatementNode: aNode
  128. shouldReturn := true.
  129. ^ self eval: aNode source
  130. !
  131. visitReturnNode: aNode
  132. shouldReturn := true.
  133. ^ self interpretNode: aNode nodes first
  134. !
  135. visitSendNode: aNode
  136. "TODO: Handle super sends"
  137. ^ (self messageFromSendNode: aNode)
  138. sendTo: (self interpretNode: aNode receiver)
  139. !
  140. visitSequenceNode: aNode
  141. aNode nodes allButLast do: [ :each | | value |
  142. value := self interpretNode: each.
  143. shouldReturn ifTrue: [ ^ value ] ].
  144. ^ self interpretNode: aNode nodes last
  145. !
  146. visitValueNode: aNode
  147. ^ aNode value
  148. !
  149. visitVariableNode: aNode
  150. ^ aNode binding isInstanceVar
  151. ifTrue: [ self context receiver instVarAt: aNode value ]
  152. ifFalse: [ self context localAt: aNode value ]
  153. ! !