-
-
Notifications
You must be signed in to change notification settings - Fork 346
/
RFSemanticAnalyzer.class.st
121 lines (99 loc) · 3.54 KB
/
RFSemanticAnalyzer.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
"
I add Reflectivity link analysis to the Semantic analyzer.
I add #beforeHooks and #afterHooks anotation and make sure to visit them for semantic analysis.
"
Class {
#name : #RFSemanticAnalyzer,
#superclass : #OCASTSemanticAnalyzer,
#category : #'Reflectivity-Compiler'
}
{ #category : #visiting }
RFSemanticAnalyzer >> analyseForLinks: aNode generator: aGenerator [
aNode propertyAt: #preambles put: aGenerator preamble.
aNode preambles do: [:each | self visitNode: each].
aNode hasMetalinkBefore ifTrue: [
aNode propertyAt: #beforeHooks put: aGenerator beforeHooks.
aNode beforeHooks do: [:each | self visitNode: each]].
aNode hasMetalinkAfter ifTrue: [
aNode propertyAt: #postambles put: aGenerator postamble.
aNode postambles do: [:each | self visitNode: each].
aNode propertyAt: #afterHooks put: aGenerator afterHooks.
aNode afterHooks do: [:each | self visitNode: each]].
aNode hasMetalinkInstead ifTrue: [
aNode propertyAt: #insteadHooks put: aGenerator insteadHooks.
aNode insteadHooks do: [:each | self visitNode: each]].
]
{ #category : #visiting }
RFSemanticAnalyzer >> analyseForLinksForNodes: aNode [
| generator |
aNode hasMetalink
ifFalse: [ ^ self ].
generator := HookGenerator node: aNode.
self analyseForLinks: aNode generator: generator.
]
{ #category : #visiting }
RFSemanticAnalyzer >> analyseForLinksForVariables: aVariableNode [
| variable generator |
variable := aVariableNode binding variable.
variable hasMetalink
ifFalse: [ ^ self ].
generator := HookGeneratorForVariables entity: variable node: aVariableNode.
self analyseForLinks: variable generator: generator.
]
{ #category : #api }
RFSemanticAnalyzer >> analyze: aNode [
self visitNode: aNode.
RFASTClosureAnalyzer new visitNode: aNode
]
{ #category : #visiting }
RFSemanticAnalyzer >> visitAssignmentNode: aNode [
self visitVarWrite: aNode variable.
super visitAssignmentNode: aNode
]
{ #category : #visiting }
RFSemanticAnalyzer >> visitMethodNode: aMethodNode [
scope := compilationContext scope newMethodScope.
aMethodNode scope: scope. scope node: aMethodNode.
aMethodNode arguments do: [:node | self declareArgumentNode: node ].
aMethodNode pragmas do: [:each | self visitNode: each].
self declareVariableNode: (RBVariableNode named: #RFValueReificationVar).
self analyseForLinksForNodes: aMethodNode.
self visitNode: aMethodNode body.
]
{ #category : #visiting }
RFSemanticAnalyzer >> visitNode: aNode [
"here we add the hook anotations and visit those AST parts for semantic analysis"
super visitNode: aNode.
aNode isMethod ifFalse: [self analyseForLinksForNodes: aNode]
]
{ #category : #visiting }
RFSemanticAnalyzer >> visitStoreIntoTempNode: aNode [
| name var |
name := aNode name.
var := scope lookupVarForDeclaration: name.
var ifNil: [
var := scope addTemp: name ].
aNode binding: var.
]
{ #category : #visiting }
RFSemanticAnalyzer >> visitStorePopIntoTempNode: aNode [
| name var |
name := aNode name.
var := scope lookupVarForDeclaration: name.
var ifNil: [
var := scope addTemp: name ].
aNode binding: var.
]
{ #category : #visiting }
RFSemanticAnalyzer >> visitVarWrite: aNode [
self analyseForLinksForNodes: aNode
]
{ #category : #visiting }
RFSemanticAnalyzer >> visitVariableNode: aVariableNode [
super visitVariableNode: aVariableNode.
self flag: #TBD. "needs to be extendend to other kinds of variables and cleaned"
aVariableNode isGlobal ifTrue: [
self analyseForLinksForVariables: aVariableNode ].
(aVariableNode isInstance) ifTrue: [
self analyseForLinksForVariables: aVariableNode ]
]