]> gcc.gnu.org Git - gcc.git/blob - gcc/m2/tools-src/array2index.py
1ed1ed3ccfcaa22044a3d4f9bd59680c9cc6421d
[gcc.git] / gcc / m2 / tools-src / array2index.py
1 #!/usr/bin/python3
2
3 # array2index.py utility to convert static arrays into a dynamic equivalent.
4
5 # Copyright (C) 2011-2021 Free Software Foundation, Inc.
6 #
7 # This file is part of GNU Modula-2.
8 #
9 # GNU Modula-2 is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3, or (at your option)
12 # any later version.
13 #
14 # GNU Modula-2 is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with GNU Modula-2; see the file COPYING. If not, write to the
21 # Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
22 # 02110-1301, USA.
23 #
24
25 import sys
26 import os
27 import glob
28 import string
29 import getopt
30
31
32 lines = [] # global copy of the input lines of text.
33
34
35 #
36 # printf - keeps C programmers happy :-)
37 #
38
39 def printf (format, *args):
40 print(str(format) % args, end=' ')
41
42
43 #
44 # fatal - displays a message and exits
45 #
46
47 def fatal (format, *args):
48 print(str(format) % args, end=' ')
49 os.sys.exit(1)
50
51 #
52 # debug
53 #
54
55 def debug(s):
56 print("*", s, "*")
57
58 #
59 # putNext - pushes, i, to be the next line read when
60 # getNext is called.
61 #
62
63 def putNext (i):
64 global lines
65 lines = [i] + lines
66
67 #
68 # getNext - returns the next line of input text.
69 #
70
71 def getNext ():
72 global lines
73
74 if lines==[]:
75 return '<eof>'
76 else:
77 l = lines[0]
78 lines = lines[1:]
79 return l
80
81
82 #
83 # isEof - return True if <eof> is seen.
84 #
85
86 def isEof (i):
87 return i=='<eof>'
88
89
90 #
91 # isProcedure - return True if 'PROCEDURE' is seen.
92 #
93
94 def isProcedure (i):
95 l = i.split()
96 return (len(l)>0) and (l[0]=='PROCEDURE')
97
98
99 #
100 # isVar - return True if 'VAR' is seen.
101 #
102
103 def isVar (i):
104 l = i.split()
105 return (len(l)>0) and (l[0]=='VAR')
106
107
108 #
109 # isBegin - return True if 'BEGIN' is seen.
110 #
111
112 def isBegin (i):
113 l = i.split()
114 return (len(l)>0) and (l[0]=='BEGIN')
115
116
117 #
118 # isEnd - return True if the 'END' to a procedure is seen.
119 #
120
121 def isEnd (i):
122 return (len(i)>3) and (i[0:3]=='END')
123
124
125 #
126 # getVarIndent - return the variable indent (where ':' occurs)
127 #
128
129 def getVarIndent (l):
130 n = 0
131 while len(l)>n:
132 if l[n]==':':
133 return n
134 n += 1
135 return 0
136
137
138 #
139 # getMaxIndent - return the maximum variable indent (where ':' occurs)
140 #
141
142 def getMaxIndent (v):
143 max = 0
144 for l in v:
145 n = getVarIndent(l)
146 if max<n:
147 max = n
148 return max
149
150 #
151 # setVarIndent - sets the indentation to, n, for each variable declared.
152 #
153
154 def setVarIndent (v, n):
155 w = []
156 for l in v:
157 i = l.find(':')
158 if (i>=0) and (i<n):
159 w += [l[0:i] + (' '*(n-i)) + l[i:]]
160 else:
161 w += [l]
162 return w
163
164 #
165 # adjustVar - adds the dictionary contents to the variable list.
166 #
167
168 def adjustVar (v, d):
169 print(v, d)
170 if d != {}:
171 if v == []:
172 h = ['VAR\n']
173 t = []
174 if 'pCall' in d:
175 v = h + [' pCall: PtrToCallFrame ;\n'] + t
176 if 'pSym' in d:
177 v = h + [' pSym: PtrToSymbol ;\n'] + t
178 else:
179 h = v[0]
180 if 'pCall' in d:
181 v = [h] + [' pCall: PtrToCallFrame ;\n'] + v[1:]
182 if 'pSym' in d:
183 v = [h] + [' pSym: PtrToSymbol ;\n'] + v[1:]
184 v = setVarIndent(v, getMaxIndent(v))
185 return v
186
187 #
188 # getIndent - returns the number of spaces before the text.
189 #
190
191 def getIndent (i):
192 n = 0
193 while len(i)>n:
194 if i[n]==' ':
195 n += 1
196 else:
197 return n
198 return n
199
200 #
201 # scanStatements - returns the statements in a procedure after they
202 # have been transformed to use an index rather than
203 # an array.
204 #
205
206 def scanStatements ():
207 debug(scanStatements)
208 s = []
209 d = {}
210 i = getNext()
211 while not isEnd(i):
212 x = i.find('Symbols[')
213 if x>=0:
214 n = getIndent(i)
215 y = i.find('[', x)+1
216 z = i.find(']', y)
217 print("indexing ", i[y:z])
218 d['pSym'] = i[y:z]
219 j = n * ' '
220 j += 'pSym := GetPsym(%s) ;\n' % i[y:z]
221 s += [j]
222 i = i[0:x]+'pSym^'+i[z+1:]
223 else:
224 x = i.find('ScopeCallFrame[')
225 if x>=0:
226 n = getIndent(i)
227 y = i.find('[', x)+1
228 z = i.find(']', y)
229 print("indexing ", i[y:z])
230 d['pCall'] = i[y:z]
231 j = n * ' '
232 j += 'pCall := GetPcall(%s) ;\n' % i[y:z]
233 s += [j]
234 i = i[0:x]+'pCall^'+i[z+1:]
235 s += [i]
236 i = getNext()
237 putNext(i)
238 return s, d
239
240 #
241 # scanVar - returns the list of variable declarations.
242 #
243
244 def scanVar ():
245 v = []
246 i = getNext()
247 while not isBegin(i):
248 v += [i]
249 i = getNext()
250 putNext(i)
251 return v
252
253 #
254 # scanProcedure - returns the list of modified lines within
255 # a procedure.
256 #
257
258 def scanProcedure ():
259 debug("scanProcedure")
260 o = []
261 v = []
262 i = getNext()
263 while (not isEnd(i)):
264 if isVar(i):
265 v = [i]
266 v += scanVar()
267 print(v)
268 elif isBegin(i):
269 s, d = scanStatements()
270 v = adjustVar(v, d)
271 o += v + [i] + s
272 return o
273 else:
274 # const, type, comment
275 o += [i]
276 i = getNext()
277 fatal("internal error")
278
279
280 #
281 # scanLines - scans a list of lines for each procedure
282 #
283
284 def scanLines (l):
285 global lines
286
287 debug("scanLines")
288 lines = l + ['<eof>']
289 o = []
290 i = getNext()
291 while not isEof(i):
292 o += i
293 if isProcedure(i):
294 print(i)
295 o += scanProcedure()
296 i = getNext()
297 return o
298
299
300 #
301 # Usage - display a single line summarising usage.
302 #
303
304 def Usage():
305 print("array2index.py [-h][-o outputfile] inputfile")
306
307
308 #
309 # collectArgs - return inputfile, outputfile.
310 #
311
312 def collectArgs():
313 debug('collectArgs')
314 inputfile="-"
315 outputfile="-"
316 try:
317 optlist, list = getopt.getopt(sys.argv[1:], ':ho:')
318 inputfile = list[0]
319 for opt in optlist:
320 if opt[0] == '-h':
321 Usage()
322 os.sys.exit(0)
323 elif opt[0] == '-o':
324 outputfile = opt[1]
325 except getopt.GetoptError:
326 Usage()
327 os.sys.exit(1)
328 return inputfile, outputfile
329
330
331 #
332 # getFiles - given two strings, input, and, output, open and
333 # return their two respective files.
334 #
335
336 def getFiles (inputfile, outputfile):
337 if inputfile=='-':
338 ip = sys.stdin
339 else:
340 if os.path.exists(inputfile):
341 ip = open(inputfile, 'r')
342 else:
343 fatal('cannot open file %s', inputfile)
344 if outputfile=='-':
345 op = sys.stdout
346 else:
347 op = open(outputfile, 'w')
348 return ip, op
349
350
351 #
352 # main - the main procedure
353 #
354
355 def main():
356 debug('main')
357 inputfile, outputfile = collectArgs()
358 ip, op = getFiles(inputfile, outputfile)
359 op.writelines(scanLines(ip.readlines()))
360 op.close()
361 ip.close()
362
363
364 #
365 # we start here
366 #
367
368 main()
This page took 0.051561 seconds and 4 git commands to generate.