1
0

Compiler-Interpreter.st 3.6 KB

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