1
0

Compiler-Interpreter.st 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. Smalltalk current createPackage: 'Compiler-Interpreter' properties: #{}!
  2. NodeVisitor subclass: #ASTInterpreter
  3. instanceVariableNames: 'currentNode context shouldReturn'
  4. package: 'Compiler-Interpreter'!
  5. !ASTInterpreter methodsFor: 'accessing'!
  6. context
  7. ^ context
  8. !
  9. context: aMethodContext
  10. context := aMethodContext
  11. ! !
  12. !ASTInterpreter methodsFor: 'initialization'!
  13. initialize
  14. super initialize.
  15. shouldReturn := false
  16. ! !
  17. !ASTInterpreter methodsFor: 'interpreting'!
  18. interpret: aNode
  19. shouldReturn := false.
  20. ^ self interpretNode: aNode
  21. !
  22. interpretNode: aNode
  23. currentNode := aNode.
  24. ^ self visit: aNode
  25. !
  26. messageFromSendNode: aSendNode
  27. ^ Message new
  28. selector: aSendNode selector;
  29. arguments: (aSendNode arguments collect: [ :each |
  30. self interpretNode: each ]);
  31. yourself
  32. ! !
  33. !ASTInterpreter methodsFor: 'visiting'!
  34. visitBlockNode: aNode
  35. ^ [ self interpretNode: aNode nodes first ]
  36. !
  37. visitCascadeNode: aNode
  38. "TODO: Handle super sends"
  39. | receiver |
  40. receiver := self interpretNode: aNode receiver.
  41. aNode nodes allButLast
  42. do: [ :each |
  43. (self messageFromSendNode: each)
  44. sendTo: receiver ].
  45. ^ (self messageFromSendNode: aNode nodes last)
  46. sendTo: receiver
  47. !
  48. visitClassReferenceNode: aNode
  49. ^ Smalltalk current at: aNode value
  50. !
  51. visitJSStatementNode: aNode
  52. self halt
  53. !
  54. visitReturnNode: aNode
  55. shouldReturn := true.
  56. ^ self interpretNode: aNode nodes first
  57. !
  58. visitSendNode: aNode
  59. "TODO: Handle super sends"
  60. ^ (self messageFromSendNode: aNode)
  61. sendTo: (self interpretNode: aNode receiver)
  62. !
  63. visitSequenceNode: aNode
  64. aNode nodes allButLast do: [ :each | | value |
  65. value := self interpretNode: each.
  66. shouldReturn ifTrue: [ ^ value ] ].
  67. ^ self interpretNode: aNode nodes last
  68. !
  69. visitValueNode: aNode
  70. ^ aNode value
  71. ! !
  72. TestCase subclass: #ASTInterpreterTest
  73. instanceVariableNames: ''
  74. package: 'Compiler-Interpreter'!
  75. !ASTInterpreterTest methodsFor: 'accessing'!
  76. analyze: aNode forClass: aClass
  77. (SemanticAnalyzer on: aClass) visit: aNode.
  78. ^ aNode
  79. !
  80. interpret: aString
  81. "the food is a methodNode. Interpret the sequenceNode only"
  82. ^ ASTInterpreter new
  83. interpret: (self parse: aString forClass: Object)
  84. nodes first
  85. !
  86. parse: aString
  87. ^ Smalltalk current parse: aString
  88. !
  89. parse: aString forClass: aClass
  90. ^ self analyze: (self parse: aString) forClass: aClass
  91. ! !
  92. !ASTInterpreterTest methodsFor: 'tests'!
  93. testBinarySend
  94. self assert: (self interpret: 'foo 2+3+4') equals: 9
  95. !
  96. testBlockLiteral
  97. self assert: (self interpret: 'foo ^ true ifTrue: [ 1 ] ifFalse: [ 2 ]') equals: 1.
  98. self assert: (self interpret: 'foo true ifTrue: [ ^ 1 ] ifFalse: [ 2 ]') equals: 1.
  99. self assert: (self interpret: 'foo ^ false ifTrue: [ 1 ] ifFalse: [ 2 ]') equals: 2
  100. !
  101. testCascade
  102. self assert: (self interpret: 'foo ^ OrderedCollection new add: 2; add: 3; yourself') equals: (OrderedCollection with: 2 with: 3)
  103. ! !