Skip to content

Commit

Permalink
Merge pull request #1214 from MarcusDenker/21726-add-a-first-version-…
Browse files Browse the repository at this point in the history
…of-evaluate-and-evaluateInContext-to-RBValueNode-and-use-it-in-RBBlockPatternNode

21726-add-a-first-version-of-evaluate-and-evaluateInContext-to-RBValueNode-and-use-it-in-RBBlockPatternNode
  • Loading branch information
MarcusDenker committed Apr 18, 2018
2 parents b73eddd + 19fa2a4 commit a299844
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 12 deletions.
14 changes: 2 additions & 12 deletions src/AST-Core/RBPatternBlockNode.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,6 @@ RBPatternBlockNode >> copyInContext: aDictionary [
^ self replacingBlock value: aDictionary
]

{ #category : #matching }
RBPatternBlockNode >> createBlockFor: aRBBlockNode [
aRBBlockNode left: self left; right:self right.
self replacePatternNodesIn: aRBBlockNode.
^Smalltalk compiler
source: aRBBlockNode formattedCode;
receiver: self;
evaluate
]

{ #category : #matching }
RBPatternBlockNode >> createMatchingBlock [
| newBlock |
Expand All @@ -71,7 +61,7 @@ RBPatternBlockNode >> createMatchingBlock [
ifTrue: [self addArgumentWithNameBasedOn: 'aNode' to: newBlock].
newBlock arguments size = 1
ifTrue: [self addArgumentWithNameBasedOn: 'aDictionary' to: newBlock].
^self createBlockFor: newBlock
^newBlock evaluateForReceiver: self.
]

{ #category : #matching }
Expand All @@ -84,7 +74,7 @@ RBPatternBlockNode >> createReplacingBlock [
newBlock := RBBlockNode arguments: arguments body: body.
self arguments isEmpty
ifTrue: [self addArgumentWithNameBasedOn: 'aDictionary' to: newBlock].
^self createBlockFor: newBlock
^newBlock evaluateForReceiver: self.
]

{ #category : #'testing-matching' }
Expand Down
46 changes: 46 additions & 0 deletions src/AST-Core/RBValueNode.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,52 @@ RBValueNode >> containedBy: anInterval [
and: [anInterval last >= self stopWithoutParentheses]
]

{ #category : #evaluating }
RBValueNode >> evaluate [
"evaluate the AST without taking variables into account"
| methodNode |

methodNode := RBMethodNode
selector: #DoIt
body: (RBReturnNode value: self) asSequenceNode.

^methodNode generateWithSource valueWithReceiver: nil arguments: #().


]

{ #category : #evaluating }
RBValueNode >> evaluateForContext: aContext [
"evaluate the AST taking variables from the context"
| methodNode |

methodNode := RBMethodNode
selector: #DoItIn:
arguments: { RBVariableNode named: 'ThisContext' }
body: (RBReturnNode value: self) asSequenceNode.

methodNode methodClass: aContext receiver class.
methodNode rewriteTempsForContext: aContext.
^methodNode generateWithSource valueWithReceiver: aContext receiver arguments: {aContext}.


]

{ #category : #evaluating }
RBValueNode >> evaluateForReceiver: aReceicer [
"evaluate the AST without taking variables into account"
| methodNode |

methodNode := RBMethodNode
selector: #DoIt
body: (RBReturnNode value: self) asSequenceNode.

methodNode methodClass: aReceicer class.
^methodNode generateWithSource valueWithReceiver: aReceicer arguments: #().


]

{ #category : #testing }
RBValueNode >> hasParentheses [
^self parentheses notEmpty
Expand Down
49 changes: 49 additions & 0 deletions src/AST-Tests-Core/ASTEvaluationTest.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
"
I am testing AST evaluation
"
Class {
#name : #ASTEvaluationTest,
#superclass : #TestCase,
#category : #'AST-Tests-Core'
}

{ #category : #tests }
ASTEvaluationTest >> testEvaluate [
self assert: (RBLiteralNode value: 5) evaluate equals: 5
]

{ #category : #tests }
ASTEvaluationTest >> testEvaluateForContext [
| varForTesting node |
varForTesting := 4@5.

"first we test if we can read the temp varForTesting"
node := thisContext method variableNodes first.
self assert: (node evaluateForContext: thisContext) equals: varForTesting.

"lets check self, super"
node := RBVariableNode named: 'self'.
self assert: (node evaluateForContext: thisContext) equals: thisContext receiver.
node := RBVariableNode named: 'super'.
self assert: (node evaluateForContext: thisContext) equals: thisContext receiver.

"thisContext is not the thisContext of this method though... it is the context of the evaluating doit"
node := RBVariableNode named: 'thisContext'.
self deny: (node evaluateForContext: thisContext) equals: thisContext.

"reading ivars works, too"
node := RBVariableNode named: 'testSelector'.
self assert: (node evaluateForContext: thisContext) equals: #testEvaluateForContext.
]

{ #category : #tests }
ASTEvaluationTest >> testEvaluateForReceiver [
| receiver node |
receiver := 4@5.
node := (receiver class>>#x) variableNodes first.
self assert: (node evaluateForReceiver: receiver) equals: 4.
node := RBVariableNode named: 'self'.
self assert: (node evaluateForReceiver: receiver) equals: receiver.
node := RBVariableNode named: 'super'.
self assert: (node evaluateForReceiver: receiver) equals: receiver.
]

0 comments on commit a299844

Please sign in to comment.