forked from pharo-project/pharo
/
OCASTTranslatorForEffect.class.st
123 lines (94 loc) · 3.47 KB
/
OCASTTranslatorForEffect.class.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"
I override some methods in my super to generate instructions for effect only.
"
Class {
#name : #OCASTTranslatorForEffect,
#superclass : #OCASTTranslator,
#category : #'OpalCompiler-Core-Translator'
}
{ #category : #'inline messages' }
OCASTTranslatorForEffect >> emitAnd: aMessageNode [
super emitAnd: aMessageNode.
methodBuilder popTop.
]
{ #category : #'inline messages' }
OCASTTranslatorForEffect >> emitIfFalse: aMessageNode [
valueTranslator visitNode: aMessageNode receiver.
methodBuilder jumpAheadTo: #else if: true.
self visitInlinedBlockNode: aMessageNode arguments first.
methodBuilder jumpAheadTarget: #else.
]
{ #category : #'inline messages' }
OCASTTranslatorForEffect >> emitIfNotNil: aMessageNode [
| args |
valueTranslator visitNode: aMessageNode receiver.
args := aMessageNode arguments.
args first arguments ifNotEmpty: [ args first arguments first variable emitStore: methodBuilder ].
methodBuilder pushLiteral: nil.
methodBuilder send: #==.
methodBuilder jumpAheadTo: #end if: true.
self visitInlinedBlockNode: args first.
methodBuilder jumpAheadTarget: #end.
]
{ #category : #'inline messages' }
OCASTTranslatorForEffect >> emitIfTrue: aMessageNode [
valueTranslator visitNode: aMessageNode receiver.
methodBuilder jumpAheadTo: #else if: false.
self visitInlinedBlockNode: aMessageNode arguments first.
methodBuilder jumpAheadTarget: #else.
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> emitMessageNode: aMessageNode [
super emitMessageNode: aMessageNode.
methodBuilder popTop.
]
{ #category : #'inline messages' }
OCASTTranslatorForEffect >> emitOr: aMessageNode [
super emitOr: aMessageNode.
methodBuilder popTop.
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitArrayNode: anArrayNode [
"An arrayNode may have side effect, for example: '{self foo}'. So we cannot just generate nothing for this node."
super visitArrayNode: anArrayNode.
methodBuilder popTop.
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitAssignmentNode: anAssignmentNode [
super visitAssignmentNode: anAssignmentNode .
methodBuilder popTop.
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitBlockNode: aBlockNode [
"even though the code is never executed, we generate it to make sure that we
can map bytecode and access temps"
super visitBlockNode: aBlockNode.
methodBuilder popTop
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitLiteralArrayNode: aLiteralNode [
super visitLiteralArrayNode: aLiteralNode.
methodBuilder popTop
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitLiteralNode: aLiteralNode [
super visitLiteralNode: aLiteralNode.
methodBuilder popTop
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitParseErrorNode: anErrorNode [
super visitParseErrorNode: anErrorNode.
methodBuilder popTop.
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitSequenceNode: aSequenceNode [
aSequenceNode statements do: [:each | self visitNode: each].
]
{ #category : #'visitor-double dispatching' }
OCASTTranslatorForEffect >> visitVariableNode: aVariableNode [
"when visiting a variable for effect, we could push it and then pop it, but we do nothing"
| variable |
variable := aVariableNode variable.
(variable isLiteralVariable or: [ variable isUndeclaredVariable ])
ifTrue: [ methodBuilder addLiteral: variable ]
]