1 "{ Package: 'stx:goodies/petitparser/compiler' }" |
1 "{ Package: 'stx:goodies/petitparser/compiler' }" |
2 |
2 |
3 "{ NameSpace: Smalltalk }" |
3 "{ NameSpace: Smalltalk }" |
4 |
4 |
5 Object subclass:#PPCMethod |
5 Object subclass:#PPCMethod |
6 instanceVariableNames:'buffer variables indentation id profile variableForReturn |
6 instanceVariableNames:'buffer id variableForReturn category profile' |
7 category' |
|
8 classVariableNames:'' |
7 classVariableNames:'' |
9 poolDictionaries:'' |
8 poolDictionaries:'' |
10 category:'PetitCompiler-Core' |
9 category:'PetitCompiler-Compiler-Codegen' |
11 ! |
10 ! |
12 |
11 |
13 |
12 |
14 !PPCMethod class methodsFor:'as yet unclassified'! |
13 !PPCMethod class methodsFor:'as yet unclassified'! |
15 |
14 |
39 category: value |
38 category: value |
40 category := value |
39 category := value |
41 ! |
40 ! |
42 |
41 |
43 code |
42 code |
44 ^ self methodName, Character cr asString, |
43 ^ String streamContents: [ :s | |
45 self variables, Character cr asString, |
44 s nextPutAll: self methodName; cr. |
46 self profilingBegin, Character cr asString, |
45 buffer codeOn: s. |
47 self body, Character cr asString |
46 ] |
48 " self profilingEnd" |
47 |
49 |
48 "Modified: / 01-06-2015 / 21:24:47 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
50 "Modified: / 23-04-2015 / 19:26:39 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
51 ! |
49 ! |
52 |
50 |
53 id: value |
51 id: value |
54 id := value |
52 id := value |
55 ! |
53 ! |
56 |
54 |
|
55 indentationLevel |
|
56 ^ buffer indentationLevel |
|
57 |
|
58 "Created: / 01-06-2015 / 21:38:31 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
59 ! |
|
60 |
|
61 indentationLevel: anInteger |
|
62 buffer indentationLevel: anInteger |
|
63 |
|
64 "Created: / 01-06-2015 / 21:38:58 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
65 ! |
|
66 |
57 methodName |
67 methodName |
58 ^ id |
68 ^ id |
59 ! |
69 ! |
60 |
70 |
61 profile |
71 profile |
67 ! ! |
77 ! ! |
68 |
78 |
69 !PPCMethod methodsFor:'as yet unclassified'! |
79 !PPCMethod methodsFor:'as yet unclassified'! |
70 |
80 |
71 add: string |
81 add: string |
72 self nl. |
82 buffer add: string |
73 indentation timesRepeat: [ buffer nextPut: Character tab ]. |
83 |
74 self addOnLine: string. |
84 "Modified: / 01-06-2015 / 21:09:06 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
75 ! |
85 ! |
76 |
86 |
77 addOnLine: string |
87 addOnLine: string |
78 buffer nextPutAll: string. |
88 buffer addOnLine: string |
|
89 |
|
90 "Modified: / 01-06-2015 / 21:09:20 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
79 ! |
91 ! |
80 |
92 |
81 call |
93 call |
82 ^ 'self ', self methodName, '.'. |
94 ^ 'self ', self methodName, '.'. |
83 ! |
95 ! |
84 |
96 |
85 nl |
|
86 ^ buffer nextPut: Character cr |
|
87 ! |
|
88 |
|
89 profilingBegin |
97 profilingBegin |
90 self profile ifTrue: [ |
98 self profile ifTrue: [ |
91 ^ ' context methodInvoked: #', id, '.' |
99 ^ ' context methodInvoked: #', id, '.' |
92 ]. |
100 ]. |
93 ^ '' |
101 ^ '' |
94 ! |
102 ! |
95 |
103 |
96 profilingEnd |
104 profilingEnd |
97 self profile ifTrue: [ |
105 self profile ifTrue: [ |
98 ^ ' context methodFinished: #', id, '.' |
106 ^ ' context methodFinished: #', id, '.' |
99 ]. |
107 ]. |
100 ^ '' |
108 ^ '' |
101 ! ! |
109 ! ! |
102 |
110 |
|
111 !PPCMethod methodsFor:'code generation'! |
|
112 |
|
113 code: aStringOrBlockOrRBParseNode |
|
114 buffer code: aStringOrBlockOrRBParseNode. |
|
115 |
|
116 "Created: / 01-06-2015 / 22:31:16 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
117 "Modified (format): / 01-06-2015 / 23:50:26 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
118 ! |
|
119 |
|
120 codeBlock: contents |
|
121 | outerBlock innerBlock | |
|
122 |
|
123 outerBlock := buffer. |
|
124 innerBlock := PPCCodeBlock new. |
|
125 innerBlock indentationLevel: outerBlock indentationLevel + 1. |
|
126 [ |
|
127 outerBlock addOnLine:'['. |
|
128 buffer := innerBlock. |
|
129 self code: contents. |
|
130 ] ensure:[ |
|
131 outerBlock |
|
132 code: (String streamContents:[:s | innerBlock codeOn: s]); |
|
133 add:']'. |
|
134 buffer := outerBlock. |
|
135 ] |
|
136 |
|
137 "Created: / 01-06-2015 / 22:33:21 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
138 "Modified: / 03-06-2015 / 06:11:32 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
139 ! ! |
|
140 |
|
141 !PPCMethod methodsFor:'code generation - indenting'! |
|
142 |
|
143 dedent |
|
144 buffer dedent |
|
145 |
|
146 "Created: / 01-06-2015 / 21:32:28 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
147 ! |
|
148 |
|
149 indent |
|
150 buffer indent |
|
151 |
|
152 "Created: / 01-06-2015 / 21:32:22 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
153 ! |
|
154 |
|
155 nl |
|
156 |
|
157 buffer nl |
|
158 |
|
159 "Created: / 01-06-2015 / 21:52:31 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
160 ! ! |
|
161 |
103 !PPCMethod methodsFor:'code generation - variables'! |
162 !PPCMethod methodsFor:'code generation - variables'! |
104 |
|
105 addVariable: name |
|
106 (variables includes: name) ifTrue:[ |
|
107 self error:'Duplicate variable name, must rename'. |
|
108 ]. |
|
109 variables add: name. |
|
110 |
|
111 "Modified: / 23-04-2015 / 12:29:58 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
112 ! |
|
113 |
163 |
114 allocateReturnVariable |
164 allocateReturnVariable |
115 |
165 |
116 ^ variableForReturn isNil ifTrue:[ |
166 ^ variableForReturn isNil ifTrue:[ |
117 variableForReturn := self allocateTemporaryVariableNamed: 'retval' |
167 variableForReturn := self allocateTemporaryVariableNamed: 'retval' |
120 ]. |
170 ]. |
121 |
171 |
122 "Created: / 23-04-2015 / 18:03:40 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
172 "Created: / 23-04-2015 / 18:03:40 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
123 ! |
173 ! |
124 |
174 |
|
175 allocateReturnVariableNamed: name |
|
176 "Allocate temporary variable used for storing a parser's return value (the parsed object)" |
|
177 |
|
178 variableForReturn notNil ifTrue:[ |
|
179 self error: 'Return variable already allocated!!'. |
|
180 ^ self. |
|
181 ]. |
|
182 variableForReturn := self allocateTemporaryVariableNamed: name. |
|
183 ^ variableForReturn |
|
184 |
|
185 "Created: / 15-06-2015 / 17:52:14 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
186 ! |
|
187 |
125 allocateTemporaryVariableNamed:preferredName |
188 allocateTemporaryVariableNamed:preferredName |
126 "Allocate a new variable with (preferably) given name. |
189 "Allocate a new variable with (preferably) given name. |
127 Returns a real variable name that should be used." |
190 Returns a real variable name that should be used." |
128 |
191 |
129 (variables includes:preferredName) ifFalse:[ |
192 ^ buffer allocateTemporaryVariableNamed: preferredName |
130 variables add:preferredName. |
193 |
131 ^ preferredName |
194 "Created: / 23-04-2015 / 17:37:55 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
132 ] ifTrue:[ |
195 "Modified: / 01-06-2015 / 21:04:02 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
133 | name | |
196 ! |
134 |
197 |
135 name := preferredName , '_' , (variables size + 1) printString. |
198 returnVariable |
136 variables add:name. |
199 ^ variableForReturn |
137 ^ name |
200 |
|
201 "Created: / 23-04-2015 / 20:50:50 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
202 "Modified (format): / 15-06-2015 / 18:12:28 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
203 ! |
|
204 |
|
205 returnVariable: aString |
|
206 (variableForReturn notNil and:[variableForReturn ~= aString]) ifTrue:[ |
|
207 self error: 'Return variable already allocated with different name (''', variableForReturn , ''' vs ''', aString,''')'. |
138 ]. |
208 ]. |
139 |
209 variableForReturn := aString |
140 "Created: / 23-04-2015 / 17:37:55 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
141 ! |
|
142 |
|
143 returnVariable |
|
144 ^ variableForReturn |
|
145 |
|
146 "Created: / 23-04-2015 / 20:50:50 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
|
147 ! |
|
148 |
|
149 returnVariable: aString |
|
150 ^ variableForReturn := aString |
|
151 |
210 |
152 "Created: / 23-04-2015 / 18:23:47 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
211 "Created: / 23-04-2015 / 18:23:47 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
153 "Modified: / 23-04-2015 / 21:08:54 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
212 "Modified: / 15-06-2015 / 18:14:02 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
154 ! |
|
155 |
|
156 variables |
|
157 ^ ' | ', (variables inject: '' into: [ :s :e | s, ' ', e]), ' |' |
|
158 ! ! |
|
159 |
|
160 !PPCMethod methodsFor:'indentation'! |
|
161 |
|
162 dedent |
|
163 indentation := indentation - 1 |
|
164 ! |
|
165 |
|
166 indent |
|
167 indentation := indentation + 1 |
|
168 ! |
|
169 |
|
170 indentationLevel |
|
171 ^ indentation |
|
172 ! |
|
173 |
|
174 indentationLevel: value |
|
175 indentation := value |
|
176 ! ! |
213 ! ! |
177 |
214 |
178 !PPCMethod methodsFor:'initialization'! |
215 !PPCMethod methodsFor:'initialization'! |
179 |
216 |
180 initialize |
217 initialize |
181 buffer := WriteStream on: ''. |
218 buffer := PPCCodeBlock new. |
182 indentation := 1. |
219 |
183 variables := OrderedCollection new. |
220 "Modified: / 01-06-2015 / 21:33:36 / Jan Vrany <jan.vrany@fit.cvut.cz>" |
184 ! ! |
221 ! ! |
185 |
222 |
186 !PPCMethod methodsFor:'printing'! |
223 !PPCMethod methodsFor:'printing'! |
187 |
224 |
188 printOn:aStream |
225 printOn:aStream |