1
0

Compiler-Interpreter.st 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. locals
  16. ^ locals ifNil: [ locals := Dictionary new ]
  17. !
  18. outerContext
  19. ^ outerContext
  20. !
  21. outerContext: anAIContext
  22. outerContext := anAIContext
  23. !
  24. pc
  25. ^ pc ifNil: [ pc := 0 ]
  26. !
  27. pc: anInteger
  28. pc := anInteger
  29. !
  30. receiver
  31. ^ receiver
  32. !
  33. receiver: anObject
  34. receiver := anObject
  35. !
  36. selector
  37. ^ selector
  38. !
  39. selector: aString
  40. selector := aString
  41. ! !
  42. !AIContext class methodsFor: 'instance creation'!
  43. fromMethodContext: aMethodContext
  44. ^ self new
  45. initializeFromMethodContext: aMethodContext;
  46. yourself
  47. ! !
  48. NodeVisitor subclass: #ASTInterpreter
  49. instanceVariableNames: 'currentNode context shouldReturn'
  50. package: 'Compiler-Interpreter'!
  51. !ASTInterpreter methodsFor: 'accessing'!
  52. context
  53. ^ context
  54. !
  55. context: anAIContext
  56. context := anAIContext
  57. ! !
  58. !ASTInterpreter methodsFor: 'initialization'!
  59. initialize
  60. super initialize.
  61. shouldReturn := false
  62. ! !
  63. !ASTInterpreter methodsFor: 'interpreting'!
  64. interpret: aNode
  65. shouldReturn := false.
  66. ^ self interpretNode: aNode
  67. !
  68. interpretNode: aNode
  69. currentNode := aNode.
  70. ^ self visit: aNode
  71. !
  72. messageFromSendNode: aSendNode
  73. ^ Message new
  74. selector: aSendNode selector;
  75. arguments: (aSendNode arguments collect: [ :each |
  76. self interpretNode: each ]);
  77. yourself
  78. ! !
  79. !ASTInterpreter methodsFor: 'visiting'!
  80. visitBlockNode: aNode
  81. ^ [ self interpretNode: aNode nodes first ]
  82. !
  83. visitCascadeNode: aNode
  84. "TODO: Handle super sends"
  85. | receiver |
  86. receiver := self interpretNode: aNode receiver.
  87. aNode nodes allButLast
  88. do: [ :each |
  89. (self messageFromSendNode: each)
  90. sendTo: receiver ].
  91. ^ (self messageFromSendNode: aNode nodes last)
  92. sendTo: receiver
  93. !
  94. visitClassReferenceNode: aNode
  95. ^ Smalltalk current at: aNode value
  96. !
  97. visitJSStatementNode: aNode
  98. self halt
  99. !
  100. visitReturnNode: aNode
  101. shouldReturn := true.
  102. ^ self interpretNode: aNode nodes first
  103. !
  104. visitSendNode: aNode
  105. "TODO: Handle super sends"
  106. ^ (self messageFromSendNode: aNode)
  107. sendTo: (self interpretNode: aNode receiver)
  108. !
  109. visitSequenceNode: aNode
  110. aNode nodes allButLast do: [ :each | | value |
  111. value := self interpretNode: each.
  112. shouldReturn ifTrue: [ ^ value ] ].
  113. ^ self interpretNode: aNode nodes last
  114. !
  115. visitValueNode: aNode
  116. ^ aNode value
  117. ! !
  118. TestCase subclass: #ASTInterpreterTest
  119. instanceVariableNames: ''
  120. package: 'Compiler-Interpreter'!
  121. !ASTInterpreterTest methodsFor: 'accessing'!
  122. analyze: aNode forClass: aClass
  123. (SemanticAnalyzer on: aClass) visit: aNode.
  124. ^ aNode
  125. !
  126. interpret: aString
  127. "the food is a methodNode. Interpret the sequenceNode only"
  128. ^ ASTInterpreter new
  129. interpret: (self parse: aString forClass: Object)
  130. nodes first
  131. !
  132. parse: aString
  133. ^ Smalltalk current parse: aString
  134. !
  135. parse: aString forClass: aClass
  136. ^ self analyze: (self parse: aString) forClass: aClass
  137. ! !
  138. !ASTInterpreterTest methodsFor: 'tests'!
  139. testBinarySend
  140. self assert: (self interpret: 'foo 2+3+4') equals: 9
  141. !
  142. testBlockLiteral
  143. self assert: (self interpret: 'foo ^ true ifTrue: [ 1 ] ifFalse: [ 2 ]') equals: 1.
  144. self assert: (self interpret: 'foo true ifTrue: [ ^ 1 ] ifFalse: [ 2 ]') equals: 1.
  145. self assert: (self interpret: 'foo ^ false ifTrue: [ 1 ] ifFalse: [ 2 ]') equals: 2
  146. !
  147. testCascade
  148. self assert: (self interpret: 'foo ^ OrderedCollection new add: 2; add: 3; yourself') equals: (OrderedCollection with: 2 with: 3)
  149. ! !