-
Notifications
You must be signed in to change notification settings - Fork 64
/
TConstantNode.class.st
148 lines (118 loc) · 3.18 KB
/
TConstantNode.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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
Class {
#name : #TConstantNode,
#superclass : #TParseNode,
#instVars : [
'value'
],
#category : #'Slang-AST'
}
{ #category : #'instance creation' }
TConstantNode class >> value: aValue [
^ self new
setValue: aValue;
yourself
]
{ #category : #comparing }
TConstantNode >> = aNode [
^ aNode isConstant and: [ value = aNode value ]
]
{ #category : #visiting }
TConstantNode >> accept: aVisitor [
^ aVisitor visitConstantNode: self
]
{ #category : #tranforming }
TConstantNode >> asCASTIn: aBuilder [
^ CConstantNode value: (aBuilder cLiteralFor: value)
]
{ #category : #transformations }
TConstantNode >> asPrintfFormatStringNode [
^TPrintfFormatStringNode new
setValue: value;
comment: comment;
yourself
]
{ #category : #accessing }
TConstantNode >> children [
^ #()
]
{ #category : #accessing }
TConstantNode >> constantNumbericValueIfAtAllPossibleOrNilIn: aCCodeGen [
"This is a version of constantNumbericValueOrNil for type checking rather than code generation.
It aims to yield a value if at all possible. This should /not/ be overridden in TDefineNode."
^value isNumber ifTrue: [value]
]
{ #category : #accessing }
TConstantNode >> constantNumbericValueOrNil [
^value isNumber ifTrue: [value]
]
{ #category : #testing }
TConstantNode >> hasSideEffect [
"Answer if the parse tree rooted at this node has a side-effect or not."
^false
]
{ #category : #testing }
TConstantNode >> isConstant [
^true
]
{ #category : #testing }
TConstantNode >> isLeaf [
^true
]
{ #category : #comparing }
TConstantNode >> isSameAs: aTParseNode [
^aTParseNode isConstant
and: [value class == aTParseNode value class
and: [value = aTParseNode value]]
]
{ #category : #accessing }
TConstantNode >> name [
^''
]
{ #category : #accessing }
TConstantNode >> nameOrValue [
^value
]
{ #category : #enumerating }
TConstantNode >> nodesDo: aBlock parent: parent [
"Apply aBlock to all nodes in the receiver with each node's parent.
N.B. This is assumed to be bottom-up, leaves first."
aBlock value: self value: parent
]
{ #category : #printing }
TConstantNode >> printOn: aStream level: level [
value isSymbol
ifTrue: [aStream nextPutAll: (value copyWithout: $:)]
ifFalse: [value storeOn: aStream]
]
{ #category : #accessing }
TConstantNode >> setValue: anObject [
value := anObject.
]
{ #category : #'type inference' }
TConstantNode >> typeOrNilFrom: aCodeGenerator in: aTMethod [
"For integers, answer int unless the value does not fit into a 32bits signed int.
In that case, answer the shortest architecture independant integer type that could hold the constant.
This method must be consistent with CCodeGenerator>>cLiteralFor:"
| hb |
value isInteger
ifTrue:
[value positive
ifTrue:
[hb := value highBit.
hb < 32 ifTrue: [^#int].
hb = 32 ifTrue: [^#'unsigned int'].
hb = 64 ifTrue: [^#'unsigned long long'].
^#'long long']
ifFalse:
[hb := value bitInvert highBit.
hb < 32 ifTrue: [^#int].
^#'long long']].
value isFloat ifTrue: [^#double].
(#(nil true false) includes: value) ifTrue: [^#int].
(value isString and: [value isSymbol not]) ifTrue: [^#'char *'].
^nil
]
{ #category : #accessing }
TConstantNode >> value [
^value
]