Update Makefile to make it compile with recent pilex
[c_to_python.git] / ansi_c.t
1 /*
2  * Copyright (C) 2019 Nick Downing <nick@ndcode.org>
3  * SPDX-License-Identifier: GPL-2.0-only
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the Free
7  * Software Foundation; version 2.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 %{
20   import element
21   import sys
22 %}
23
24 %%
25
26 class AST {
27   /* internal classes */
28   class Text;
29   class DeclarationOrStatement;
30   class Statement: DeclarationOrStatement;
31   class Declarator;
32   class InitializerOrExpression;
33   class Expression: InitializerOrExpression;
34   class ExpressionUnary: Expression {
35     str unary_operator = '';
36     bool postfix = False;
37   };
38   class ExpressionBinary: Expression {
39     str binary_operator = '';
40     int precedence = -1;
41     bool right_to_left = False;
42   };
43   class Specifier;
44   class SpecifierList;
45   /* type analysis */
46   class Type;
47   class TypeVoid: Type;
48   class TypeInt: Type {
49     bool signed = False;
50     int bits = -1;
51   };
52   class TypeFloat: Type {
53     int complex = -1;
54     int bits = -1;
55   };
56   class TypeBool: Type;
57   class TypePointer: Type {
58     ref target_type = None;
59   };
60   class TypeArray: Type {
61     ref element_type = None;
62     int element_count = -1;
63   };
64   class TypeFunction: Type {
65     class Argument {
66       ref type = None;
67       str name = '';
68     };
69     ref return_type = None;
70     bool varargs = False;
71   };
72   class TypeStructOrUnion: Type {
73     class Member {
74       ref type = None;
75       str name = '';
76     };
77     str name = '';
78   };
79   class TypeStruct: TypeStructOrUnion;
80   class TypeUnion: TypeStructOrUnion;
81   /* storage class analysis */
82   class StorageClass;
83   class StorageClassExtern: StorageClass;
84   class StorageClassStatic: StorageClass;
85   /* syntax classes */
86   class AlignAsExpression;
87   class AlignAsType;
88   class ArgumentExpressionList;
89   class BlockItemList;
90   class Declaration: DeclarationOrStatement;
91   class DeclarationList;
92   class DeclarationSpecifierList: SpecifierList;
93   class DeclaratorAbstract: Declarator;
94   class DeclaratorArray: Declarator;
95   class DeclaratorEmpty: Declarator;
96   class DeclaratorFunction: Declarator {
97     bool varargs = False;
98   };
99   class DeclaratorFunctionOldStyle: Declarator;
100   class DeclaratorIdentifier: Declarator;
101   class DeclaratorPointer: Declarator;
102   class DefaultTypeName;
103   class DesignatorField;
104   class DesignatorIndex;
105   class DesignatorInitializer: InitializerOrExpression;
106   class DesignatorInitializerList: InitializerOrExpression;
107   class DesignatorListEqualsEmpty;
108   class DesignatorList;
109   class EnumSpecifier: Specifier;
110   class Enumerator;
111   class EnumeratorList;
112   class EqualsInitializerEmpty;
113   class ExpressionAdd: ExpressionBinary;
114   class ExpressionAddAssignment: ExpressionBinary;
115   class ExpressionAddressOf: ExpressionUnary;
116   class ExpressionAlignOfType: ExpressionUnary;
117   class ExpressionArray: Expression;
118   class ExpressionAssignment: ExpressionBinary;
119   class ExpressionAsterisk: Expression;
120   class ExpressionBitwiseAnd: ExpressionBinary;
121   class ExpressionBitwiseAndAssignment: ExpressionBinary;
122   class ExpressionBitwiseNot: ExpressionUnary;
123   class ExpressionBitwiseOr: ExpressionBinary;
124   class ExpressionBitwiseOrAssignment: ExpressionBinary;
125   class ExpressionCall: Expression;
126   class ExpressionCast: Expression;
127   class ExpressionCharConstant: Expression;
128   class ExpressionComma: ExpressionBinary;
129   class ExpressionConditional: Expression;
130   class ExpressionDereference: ExpressionUnary;
131   class ExpressionDivide: ExpressionBinary;
132   class ExpressionDivideAssignment: ExpressionBinary;
133   class ExpressionEmpty: Expression;
134   class ExpressionEqual: ExpressionBinary;
135   class ExpressionExclusiveOr: ExpressionBinary;
136   class ExpressionExclusiveOrAssignment: ExpressionBinary;
137   class ExpressionField: Expression;
138   class ExpressionFieldDereference: Expression;
139   class ExpressionFloatLiteral: Expression;
140   class ExpressionFunctionName: Expression;
141   class ExpressionGreaterThan: ExpressionBinary;
142   class ExpressionGreaterThanOrEqual: ExpressionBinary;
143   class ExpressionIdentifier: Expression;
144   class ExpressionIndex: Expression;
145   class ExpressionIntLiteral: Expression;
146   class ExpressionLeftShiftAssignment: ExpressionBinary;
147   class ExpressionLessThan: ExpressionBinary;
148   class ExpressionLessThanOrEqual: ExpressionBinary;
149   class ExpressionLogicalAnd: ExpressionBinary;
150   class ExpressionLogicalNot: ExpressionUnary;
151   class ExpressionLogicalOr: ExpressionBinary;
152   class ExpressionMinus: ExpressionUnary;
153   class ExpressionModulo: ExpressionBinary;
154   class ExpressionModuloAssignment: ExpressionBinary;
155   class ExpressionMultiply: ExpressionBinary;
156   class ExpressionMultiplyAssignment: ExpressionBinary;
157   class ExpressionNotEqual: ExpressionBinary;
158   class ExpressionPlus: ExpressionUnary;
159   class ExpressionPostDecrement: ExpressionUnary;
160   class ExpressionPostIncrement: ExpressionUnary;
161   class ExpressionPreDecrement: ExpressionUnary;
162   class ExpressionPreIncrement: ExpressionUnary;
163   class ExpressionRightShiftAssignment: ExpressionBinary;
164   class ExpressionShiftLeft: ExpressionBinary;
165   class ExpressionShiftRight: ExpressionBinary;
166   class ExpressionSizeOfExpression: ExpressionUnary;
167   class ExpressionSizeOfType: ExpressionUnary;
168   class ExpressionStringLiteral: Expression;
169   class ExpressionSubtract: ExpressionBinary;
170   class ExpressionSubtractAssignment: ExpressionBinary;
171   class FunctionDefinition: DeclarationOrStatement;
172   class FunctionSpecifier: Specifier {
173     int n = -1;
174   };
175   class GenericAssociation;
176   class GenericAssociationList;
177   class GenericSelection;
178   class Identifier;
179   class IdentifierEmpty;
180   class IdentifierList;
181   class InitDeclarator;
182   class InitDeclaratorList;
183   class ParameterDeclaration;
184   class ParameterDeclarationList;
185   class SpecifierQualifierList: SpecifierList;
186   class StatementBlock: Statement;
187   class StatementBreak: Statement;
188   class StatementCase: Statement;
189   class StatementContinue: Statement;
190   class StatementDefault: Statement;
191   class StatementDoWhile: Statement;
192   class StatementExpression: Statement;
193   class StatementFor: Statement;
194   class StatementGoto: Statement;
195   class StatementIf: Statement;
196   class StatementIfElse: Statement;
197   class StatementLabel: Statement;
198   class StatementReturn: Statement;
199   class StatementSwitch: Statement;
200   class StatementWhile: Statement;
201   class StaticAssertDeclaration: DeclarationOrStatement;
202   class StorageClassSpecifier: Specifier {
203     int n = -1;
204   };
205   class StructDeclaration;
206   class StructDeclarationList;
207   class StructDeclarator;
208   class StructDeclaratorList;
209   class StructSpecifier: Specifier;
210   class TypeName;
211   class TypeQualifier {
212     int n = -1;
213   };
214   class TypeQualifierList;
215   class TypeQualifierOrStaticList;
216   class TypeSpecifier: Specifier {
217     int n = -1;
218   };
219   class UnionSpecifier: Specifier;
220   class TranslationUnit;
221 };
222
223 %%
224
225 def snake_to_camel(text):
226   return ''.join([i[0].upper() + i[1:] for i in text.split('_')])
227
228 class Context:
229   def __init__(
230     self,
231     indent = '',
232     lines = [],
233     top_level = True,
234     enclosing_struct = None,
235     enclosing_loop = None,
236     translate_identifier = {
237       'NULL': 'None',
238       'false': 'False',
239       'strlen': 'len',
240       'true': 'True'
241     }
242   ):
243     self.indent = indent
244     self.lines = lines
245     self.top_level = top_level
246     self.enclosing_struct = enclosing_struct
247     self.enclosing_loop = enclosing_loop
248     self.translate_identifier = translate_identifier
249
250 # void char short int long float double signed unsigned bool complex imaginary
251 type_specifiers_to_type = {
252   (1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeVoid(),
253   (0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 8),
254   (0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 8),
255   (0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 8),
256   (0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 16),
257   (0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 16),
258   (0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 16),
259   (0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 16),
260   (0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 16),
261   (0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 16),
262   (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
263   (0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
264   (0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 32),
265   (0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
266   (0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
267   (0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 32),
268   (0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
269   (0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
270   (0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 32),
271   (0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
272   (0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 32),
273   (0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 32),
274   (0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 64),
275   (0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 64),
276   (0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 64),
277   (0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 64),
278   (0, 0, 0, 1, 2, 0, 0, 1, 0, 0, 0, 0): AST.TypeInt(signed = True, bits = 64),
279   (0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0): AST.TypeInt(signed = False, bits = 64),
280   (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0): AST.TypeFloat(complex = 0, bits = 32),
281   (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0): AST.TypeFloat(complex = 2, bits = 32),
282   (0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1): AST.TypeFloat(complex = 1, bits = 32),
283   (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0): AST.TypeFloat(complex = 0, bits = 64),
284   (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0): AST.TypeFloat(complex = 1, bits = 64),
285   (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1): AST.TypeFloat(complex = 2, bits = 64),
286   (0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0): AST.TypeBool()
287 }
288 # typedef extern static thread_local auto register
289 storage_class_specifiers_to_storage_class = {
290   (0, 0, 0, 0, 0): AST.StorageClass(),
291   (0, 1, 0, 0, 0): AST.StorageClassExtern(),
292   (0, 0, 1, 0, 0): AST.StorageClassStatic()
293 }
294 octal_prefix = set(
295   ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09']
296 )
297
298 def factory(tag, *args, **kwargs):
299   return tag_to_class[tag](*args, **kwargs)
300
301 @method(AST.DeclarationOrStatement)
302 def translate_declaration_or_statement(self, context):
303   #text = element.to_text(self).strip()
304   #assert text[-1] == ';'
305   #context.lines.append(
306   #  '{0:s}{1:s}\n'.format(context.indent, text[:-1])
307   #)
308   print(self)
309   raise NotImplementedError
310 @method(AST.Declaration)
311 def translate_declaration_or_statement(self, context):
312   base_type = self.children[0].get_type()
313   if isinstance(base_type, AST.TypeStructOrUnion) and len(base_type.children):
314     context.lines.append(
315       '''{0:s}class {1:s}:
316 {2:s}  def __init__(
317 {3:s}    self{4:s}
318 {5:s}  ):{6:s}
319 '''.format(
320         context.indent,
321         snake_to_camel(base_type.name),
322         context.indent,
323         context.indent,
324         ''.join(
325           [
326             ',\n{0:s}    {1:s} = {2:s}'.format(
327               context.indent,
328               i.name,
329               i.type.translate_zero(context)
330             )
331             for i in base_type.children
332           ]
333         ),
334         context.indent,
335         ''.join(
336           [
337             '\n{0:s}    self.{1:s} = {2:s}'.format(
338               context.indent,
339               i.name,
340               i.name
341             )
342             for i in base_type.children
343           ]
344         )
345       )
346     )
347   storage_class = self.children[0].get_storage_class()
348   if not isinstance(storage_class, AST.StorageClassExtern):
349     for i in self.children[1].children:
350       type, name = i.children[0].get_type_and_name(base_type)
351       if not isinstance(type, AST.TypeFunction):
352         context.lines.append(
353           '{0:s}{1:s} = {2:s}\n'.format(
354             context.indent,
355             name,
356             (
357               type.translate_zero(context)
358             if isinstance(i.children[1], AST.EqualsInitializerEmpty) else
359               i.children[1].translate_initializer_or_expression(context)
360             )
361           )
362         )
363 @method(AST.FunctionDefinition)
364 def translate_declaration_or_statement(self, context):
365   type, name = self.children[1].get_type_and_name(self.children[0].get_type())
366   assert isinstance(type, AST.TypeFunction)
367   if len(context.lines):
368     context.lines.append('\n')
369   context.lines.append(
370     '{0:s}def {1:s}({2:s}):\n'.format(
371       context.indent,
372       name,
373       ', '.join([i.name for i in type.children])
374     )
375   )
376   indent_save = context.indent
377   context.indent += '  '
378   assert context.top_level
379   context.top_level = False
380   self.children[3].translate_block_item_list(context)
381   context.top_level = True
382   context.indent = indent_save
383 @method(AST.StatementBlock)
384 def translate_declaration_or_statement(self, context):
385   if len(self.children[0].children):
386     self.children[0].translate_block_item_list(context)
387   else:
388     context.lines.append('{0:s}pass\n'.format(context.indent))
389 @method(AST.StatementBreak)
390 def translate_declaration_or_statement(self, context):
391   context.lines.append('{0:s}break\n'.format(context.indent))
392 @method(AST.StatementContinue)
393 def translate_declaration_or_statement(self, context):
394   enclosing_loop_save = context.enclosing_loop
395   context.enclosing_loop = None
396   if isinstance(enclosing_loop_save, AST.StatementDoWhile):
397     AST.StatementIfElse(
398       children = [
399         enclosing_loop_save.children[1],
400         AST.StatementContinue(),
401         AST.StatementBreak()
402       ]
403     ).translate_declaration_or_statement(context)
404   elif isinstance(enclosing_loop_save, AST.StatementFor):
405     context.lines.append(
406       '{0:s}{1:s}\n{2:s}continue\n'.format(
407         context.indent,
408         enclosing_loop_save.children[2].translate_statement_expression(context),
409         context.indent
410       )
411     )
412   else:
413     context.lines.append('{0:s}continue\n'.format(context.indent))
414   context.enclosing_loop = enclosing_loop_save
415 @method(AST.StatementDoWhile)
416 def translate_declaration_or_statement(self, context):
417   if (
418     isinstance(self.children[1], AST.ExpressionIntLiteral) and
419     self.children[1].text[0] == '0'
420   ):
421     self.children[0].translate_declaration_or_statement(context)
422     return
423   context.lines.append('{0:s}while True:\n'.format(context.indent))
424   indent_save = context.indent
425   context.indent += '  '
426   enclosing_loop_save = context.enclosing_loop
427   context.enclosing_loop = self
428   self.children[0].translate_declaration_or_statement(context)
429   context.enclosing_loop = enclosing_loop_save
430   AST.StatementIf(
431     children = [
432       AST.ExpressionLogicalNot(
433         children = [
434           self.children[1]
435         ],
436         unary_operator = 'not '
437       ),
438       AST.StatementBreak()
439     ]
440   ).translate_declaration_or_statement(context)
441   context.indent = indent_save
442 @method(AST.StatementExpression)
443 def translate_declaration_or_statement(self, context):
444   context.lines.append(
445     '{0:s}{1:s}\n'.format(
446       context.indent,
447       self.children[0].translate_statement_expression(context)
448     )
449   )
450 @method(AST.StatementFor)
451 def translate_declaration_or_statement(self, context):
452   self.children[0].translate_declaration_or_statement(context)
453   context.lines.append(
454     '{0:s}while {1:s}:\n'.format(
455       context.indent,
456       self.children[1].translate_expression(context, 0)
457     )
458   )
459   indent_save = context.indent
460   context.indent += '  '
461   enclosing_loop_save = context.enclosing_loop
462   context.enclosing_loop = self
463   self.children[3].translate_declaration_or_statement(context)
464   context.enclosing_loop = enclosing_loop_save
465   context.lines.append(
466     '{0:s}{1:s}\n'.format(
467       context.indent,
468       self.children[2].translate_statement_expression(context)
469     )
470   )
471   context.indent = indent_save
472 @method(AST.StatementGoto)
473 def translate_declaration_or_statement(self, context):
474   context.lines.append(
475     '{0:s}goto {1:s}\n'.format(
476       context.indent,
477       self.children[0].text[0]
478     )
479   )
480 @method(AST.StatementIf)
481 def translate_declaration_or_statement(self, context):
482   context.lines.append(
483     '{0:s}if {1:s}:\n'.format(
484       context.indent,
485       self.children[0].translate_expression(context, 0)
486     )
487   )
488   indent_save = context.indent
489   context.indent += '  '
490   self.children[1].translate_declaration_or_statement(context)
491   context.indent = indent_save
492 @method(AST.StatementIfElse)
493 def translate_declaration_or_statement(self, context):
494   context.lines.append(
495     '{0:s}if {1:s}:\n'.format(
496       context.indent,
497       self.children[0].translate_expression(context, 0)
498     )
499   )
500   indent_save = context.indent
501   context.indent += '  '
502   self.children[1].translate_declaration_or_statement(context)
503   context.lines.append('{0:s}else:\n'.format(indent_save))
504   self.children[2].translate_declaration_or_statement(context)
505   context.indent = indent_save
506 @method(AST.StatementReturn)
507 def translate_declaration_or_statement(self, context):
508   context.lines.append(
509     '{0:s}return {1:s}\n'.format(
510       context.indent,
511       self.children[0].translate_expression(context, 0)
512     )
513   )
514 @method(AST.StatementLabel)
515 def translate_declaration_or_statement(self, context):
516   context.lines.append(
517     '{0:s}{1:s}:\n'.format(
518       context.indent,
519       self.children[0].text[0]
520     )
521   )
522 @method(AST.StatementSwitch)
523 def translate_declaration_or_statement(self, context):
524   assert isinstance(self.children[1], AST.StatementBlock)
525   indent_save = context.indent
526   context.indent += '  '
527   if_text = 'if'
528   for i in self.children[1].children[0].children:
529     if (
530       isinstance(i, AST.StatementCase) or
531       isinstance(i, AST.StatementDefault)
532     ):
533       if isinstance(i, AST.StatementCase):
534         cond_expr = AST.ExpressionEqual(
535           children = [
536             self.children[0],
537             i.children[0]
538           ],
539           binary_operator = ' == ',
540           precedence = 8
541         )
542         j = i.children[1]
543       else:
544         cond_expr = None
545         j = i.children[0]
546       if (
547         isinstance(j, AST.StatementCase) or
548         isinstance(j, AST.StatementDefault)
549       ):
550         if isinstance(j, AST.StatementCase):
551           if cond_expr is not None:
552             cond_expr = AST.ExpressionLogicalOr(
553               children = [
554                 cond_expr,
555                 AST.ExpressionEqual(
556                   children = [
557                     self.children[0],
558                     j.children[0]
559                   ],
560                   binary_operator = ' == ',
561                   precedence = 8
562                 )
563               ],
564               binary_operator = ' or ',
565               precedence = 3
566             )
567           j = j.children[1]
568         else:
569           cond_expr = None
570           j = j.children[0]
571       if cond_expr is not None:
572         assert if_text is not None
573         context.lines.append(
574           '{0:s}{1:s} {2:s}:\n'.format(
575             indent_save,
576             if_text,
577             cond_expr.translate_expression(context, 0)
578           )
579         )
580         if_text = 'elif'
581       else:
582         context.lines.append(
583           '{0:s}else:\n'.format(indent_save)
584         )
585         if_text = None
586       j.translate_declaration_or_statement(context)
587     else:
588       i.translate_declaration_or_statement(context)
589   context.indent = indent_save
590 @method(AST.StatementWhile)
591 def translate_declaration_or_statement(self, context):
592   context.lines.append(
593     '{0:s}while {1:s}:\n'.format(
594       context.indent,
595       self.children[0].translate_expression(context, 0)
596     )
597   )
598   indent_save = context.indent
599   context.indent += '  '
600   enclosing_loop_save = context.enclosing_loop
601   context.enclosing_loop = self
602   self.children[1].translate_declaration_or_statement(context)
603   context.enclosing_loop = enclosing_loop_save
604   context.indent = indent_save
605 @method(AST.StaticAssertDeclaration)
606 def translate_declaration_or_statement(self, context):
607   pass
608 del translate_declaration_or_statement
609
610 @method(AST.Declarator)
611 def get_type_and_name(self, base_type):
612   print(self)
613   raise NotImplementedError
614 @method(AST.DeclaratorAbstract)
615 def get_type_and_name(self, base_type):
616   return base_type, ''
617 @method(AST.DeclaratorArray)
618 def get_type_and_name(self, base_type):
619   return self.children[0].get_type_and_name(
620     AST.TypeArray(
621       element_type = base_type,
622       element_count = (
623         -1
624       if isinstance(self.children[2], AST.ExpressionEmpty) else
625         # kludgey way, assuming not calculated size
626         int(
627           self.children[2].text[0],
628           8 if self.children[2].text[0][:2] in octal_prefix else 0
629         )
630       )
631     )
632   )
633 @method(AST.DeclaratorFunction)
634 def get_type_and_name(self, base_type):
635   children = []
636   for i in self.children[1].children:
637     type, name = i.children[1].get_type_and_name(i.children[0].get_type())
638     children.append(AST.TypeFunction.Argument(type = type, name = name))
639   return self.children[0].get_type_and_name(
640     AST.TypeFunction(
641       children = children,
642       return_type = base_type,
643       varargs = self.varargs,
644     )
645   )
646 @method(AST.DeclaratorIdentifier)
647 def get_type_and_name(self, base_type):
648   return base_type, self.children[0].text[0]
649 @method(AST.DeclaratorPointer)
650 def get_type_and_name(self, base_type):
651   return self.children[1].get_type_and_name(
652     AST.TypePointer(target_type = base_type)
653   )
654 del get_type_and_name
655
656 @method(AST.InitializerOrExpression)
657 def translate_initializer_or_expression(self, context):
658   print(self)
659   raise NotImplementedError
660 @method(AST.Expression)
661 def translate_initializer_or_expression(self, context):
662   return self.translate_expression(context, 0)
663 @method(AST.DesignatorInitializer)
664 def translate_initializer_or_expression(self, context):
665   assert isinstance(self.children[0], AST.DesignatorListEqualsEmpty)
666   return self.children[1].translate_initializer_or_expression(context)
667 @method(AST.DesignatorInitializerList)
668 def translate_initializer_or_expression(self, context):
669   return '[{0:s}]'.format(
670     ', '.join(
671       [
672         i.translate_initializer_or_expression(context)
673         for i in self.children
674       ]
675     )
676   )
677 del translate_initializer_or_expression
678
679 @method(AST.Expression)
680 def translate_expression(self, context, precedence):
681   #return element.to_text(self).strip()
682   print(self)
683   raise NotImplementedError
684 @method(AST.ExpressionUnary)
685 def translate_expression(self, context, precedence):
686   if self.postfix:
687     text = '{0:s}{1:s}'.format(
688       self.children[0].translate_expression(context, 14),
689       self.unary_operator
690     )
691     if 14 < precedence:
692       text = '({0:s})'.format(text)
693   else:
694     text = '{0:s}{1:s}'.format(
695       self.unary_operator,
696       self.children[0].translate_expression(context, 13)
697     )
698     if 13 < precedence:
699       text = '({0:s})'.format(text)
700   return text
701 @method(AST.ExpressionBinary)
702 def translate_expression(self, context, precedence):
703   text = '{0:s}{1:s}{2:s}'.format(
704     self.children[0].translate_expression(
705       context,
706       self.precedence + int(self.right_to_left)
707     ),
708     self.binary_operator,
709     self.children[1].translate_expression(
710       context,
711       self.precedence + int(not self.right_to_left)
712     )
713   )
714   if self.precedence < precedence:
715     text = '({0:s})'.format(text)
716   return text
717 @method(AST.ExpressionCall)
718 def translate_expression(self, context, precedence):
719   text = '{0:s}({1:s})'.format(
720     self.children[0].translate_expression(context, 14),
721     ', '.join([i.translate_expression(context, 1) for i in self.children[1].children])
722   )
723   if 14 < precedence:
724     text = '({0:s})'.format(text)
725   return text
726 @method(AST.ExpressionCast)
727 def translate_expression(self, context, precedence):
728   type, _ = self.children[0].children[1].get_type_and_name(self.children[0].children[0].get_type())
729   # python unifies the different int types and the different float types,
730   # therefore a lot of casting of constants etc needed in C is not in python
731   if (
732     (
733       isinstance(type, AST.TypeInt) and
734       (
735         isinstance(self.children[1], AST.ExpressionIntLiteral) or
736         (
737           isinstance(self.children[1], AST.ExpressionMinus) and
738           isinstance(self.children[1].children[0], AST.ExpressionIntLiteral)
739         )
740       )
741     ) or
742     (
743       isinstance(type, AST.TypeFloat) and
744       (
745         isinstance(self.children[1], AST.ExpressionFloatLiteral) or
746         (
747           isinstance(self.children[1], AST.ExpressionMinus) and
748           isinstance(self.children[1].children[0], AST.ExpressionFloatLiteral)
749         )
750       )
751     )
752   ):
753     text = self.children[1].translate_expression(context, precedence)
754   else:
755     text = '{0:s}({1:s})'.format(
756       type.translate_type(context),
757       self.children[1].translate_expression(context, 0)
758     )
759     if 14 < precedence:
760       text = '({0:s})'.format(text)
761   return text
762 @method(AST.ExpressionCharConstant)
763 def translate_expression(self, context, precedence):
764   return 'ord(\'{0:s}\')'.format(self.children[0].text[0])
765 @method(AST.ExpressionConditional)
766 def translate_expression(self, context, precedence):
767   text = '{0:s} if {1:s} else {2:s}'.format(
768     self.children[1].translate_expression(context, 3),
769     self.children[0].translate_expression(context, 0),
770     self.children[2].translate_expression(context, 2)
771   )
772   if 2 < precedence:
773     text = '({0:s})'.format(text)
774   return text
775 @method(AST.ExpressionEmpty)
776 def translate_expression(self, context, precedence):
777   return 'True'
778 @method(AST.ExpressionField)
779 def translate_expression(self, context, precedence):
780   text = '{0:s}.{1:s}'.format(
781     self.children[0].translate_expression(context, 14),
782     self.children[1].translate_identifier(context)
783   )
784   if 14 < precedence:
785     text = '({0:s})'.format(text)
786   return text
787 @method(AST.ExpressionFieldDereference)
788 def translate_expression(self, context, precedence):
789   text = '{0:s}->{1:s}'.format(
790     self.children[0].translate_expression(context, 14),
791     self.children[1].translate_identifier(context)
792   )
793   if 14 < precedence:
794     text = '({0:s})'.format(text)
795   return text
796 @method(AST.ExpressionFloatLiteral)
797 def translate_expression(self, context, precedence):
798   text = self.text[0]
799   if text[-1:] == 'f':
800     text = text[:-1]
801   return text
802 @method(AST.ExpressionIdentifier)
803 def translate_expression(self, context, precedence):
804   return self.children[0].translate_identifier(context)
805 @method(AST.ExpressionIndex)
806 def translate_expression(self, context, precedence):
807   text = '{0:s}[{1:s}]'.format(
808     self.children[0].translate_expression(context, 14),
809     self.children[1].translate_expression(context, 0)
810   )
811   if 14 < precedence:
812     text = '({0:s})'.format(text)
813   return text
814 @method(AST.ExpressionIntLiteral)
815 def translate_expression(self, context, precedence):
816   text = self.text[0]
817   if text[:2] in octal_prefix:
818     text = '0o' + text[1:]
819   if text[-1:] == 'L':
820     text = text[:-1]
821   if text[-1:] == 'L':
822     text = text[:-1]
823   if text[-1:] == 'U':
824     text = text[:-1]
825   return text
826 @method(AST.ExpressionSizeOfType)
827 def translate_expression(self, context, precedence):
828   type, _ = self.children[0].children[1].get_type_and_name(self.children[0].children[0].get_type())
829   return str(type.translate_size(context))
830 @method(AST.ExpressionStringLiteral)
831 def translate_expression(self, context, precedence):
832   return ' '.join(
833     [
834       '\'{0:s}\''.format(
835         i.text[0].
836         replace('\\"', '"').
837         replace('\'', '\\\'')
838       )
839       for i in self.children
840     ]
841   )
842 @method(AST.ExpressionFunctionName)
843 def translate_expression(self, context, precedence):
844   return '__func__'
845 del translate_expression
846
847 @method(AST.Expression)
848 def translate_statement_expression(self, context):
849   return self.translate_expression(context, 0)
850 @method(AST.ExpressionEmpty)
851 def translate_statement_expression(self, context):
852   return 'pass'
853 @method(AST.ExpressionPostDecrement)
854 def translate_statement_expression(self, context):
855   return '{0:s} -= 1'.format(self.children[0].translate_expression(context, 0))
856 @method(AST.ExpressionPostIncrement)
857 def translate_statement_expression(self, context):
858   return '{0:s} += 1'.format(self.children[0].translate_expression(context, 0))
859 @method(AST.ExpressionPreDecrement)
860 def translate_statement_expression(self, context):
861   return '{0:s} -= 1'.format(self.children[0].translate_expression(context, 0))
862 @method(AST.ExpressionPreIncrement)
863 def translate_statement_expression(self, context):
864   return '{0:s} += 1'.format(self.children[0].translate_expression(context, 0))
865 del translate_statement_expression
866
867 @method(AST.Type)
868 def translate_size(self, context):
869   print(self)
870   raise NotImplementedError
871 @method(AST.TypeVoid)
872 def translate_size(self, context):
873   return 0
874 @method(AST.TypeInt)
875 def translate_size(self, context):
876   return (self.bits + 7) // 8
877 @method(AST.TypeFloat)
878 def translate_size(self, context):
879   return (self.bits + 7) // 8
880 @method(AST.TypeBool)
881 def translate_size(self, context):
882   return 1
883 @method(AST.TypePointer)
884 def translate_size(self, context):
885   return 4
886 @method(AST.TypeArray)
887 def translate_size(self, context):
888   return self.element_type.translate_type(context) * self.element_count 
889 @method(AST.TypeStruct)
890 def translate_size(self, context):
891   return sum([i.type.translate_size(context) for i in self.children])
892 @method(AST.TypeUnion)
893 def translate_size(self, context):
894   return max([i.type.translate_size(context) for i in self.children])
895 del translate_size
896
897 @method(AST.Type)
898 def translate_type(self, context):
899   print(self)
900   raise NotImplementedError
901 @method(AST.TypeVoid)
902 def translate_type(self, context):
903   return 'NoneType'
904 @method(AST.TypeInt)
905 def translate_type(self, context):
906   return 'int'
907 @method(AST.TypeFloat)
908 def translate_type(self, context):
909   return 'float'
910 @method(AST.TypeBool)
911 def translate_type(self, context):
912   return 'bool'
913 @method(AST.TypePointer)
914 def translate_type(self, context):
915   return (
916     'str'
917   if (
918     isinstance(self.target_type, AST.TypeInt) and
919     self.target_type.bits == 8
920   ) else
921     'list'
922   )
923 del translate_type
924
925 @method(AST.Type)
926 def translate_zero(self, context):
927   print(self)
928   raise NotImplementedError
929 @method(AST.TypeVoid)
930 def translate_zero(self, context):
931   return 'None'
932 @method(AST.TypeInt)
933 def translate_zero(self, context):
934   return '0' if context.top_level else 'None'
935 @method(AST.TypeFloat)
936 def translate_zero(self, context):
937   return '0.' if context.top_level else 'None'
938 @method(AST.TypeBool)
939 def translate_zero(self, context):
940   return 'False' if context.top_level else 'None'
941 @method(AST.TypePointer)
942 def translate_zero(self, context):
943   return (
944     (
945       '\'\''
946     if (
947       isinstance(self.target_type, AST.TypeInt) and
948       self.target_type.bits == 8
949     ) else
950       '[]'
951     )
952   if context.top_level else
953     'None'
954   )
955 @method(AST.TypeArray)
956 def translate_zero(self, context):
957   return '[{0:s}]'.format(
958     ', '.join(
959       [self.element_type.translate_zero(context)] * self.element_count
960     )
961   )
962 @method(AST.TypeStructOrUnion)
963 def translate_zero(self, context):
964   return '{0:s}()'.format(snake_to_camel(self.name))
965 del translate_zero
966
967 @method(AST.TypeVoid)
968 def __str__(self):
969   return 'void'
970 @method(AST.TypeInt)
971 def __str__(self):
972   return '{0:s}int{1:d}'.format(['u', ''][int(self.signed)], self.bits)
973 @method(AST.TypeFloat)
974 def __str__(self):
975   return '{0:s}float{0:d}'.format(
976     ['', 'i', 'c'][int(self.complex)],
977     self.bits
978   )
979 @method(AST.TypeBool)
980 def __str__(self):
981   return 'bool'
982 @method(AST.TypePointer)
983 def __str__(self):
984   return 'pointer<{0:s}>'.format(str(self.target_type))
985 @method(AST.TypeArray)
986 def __str__(self):
987   return 'array<{0:s}: {1:s}>'.format(
988     str(self.element_type),
989     (
990       'UNSPECIFIED'
991     if self.element_count == -1 else
992       'C99_FLEXIBLE'
993     if self.element_count == -2 else
994       str(self.element_count)
995     )
996   )
997 @method(AST.TypeFunction.Argument)
998 def __str__(self):
999   return '{0:s} {1:s}'.format(
1000     str(self.type),
1001     'ABSTRACT' if self.name == '' else self.name
1002   )
1003 @method(AST.TypeFunction)
1004 def __str__(self):
1005   return 'function<{0:s} -> {1:s}>'.format(
1006     (
1007       'void'
1008     if len(self.children) == 0 else
1009       ', '.join(
1010         [str(i) for i in self.children] + (['...'] if self.varargs else [])
1011       )
1012     ),
1013     str(self.return_type)
1014   )
1015 del __str__
1016
1017 @method(AST.BlockItemList)
1018 def translate_block_item_list(self, context):
1019   for i in self.children:
1020     i.translate_declaration_or_statement(context)
1021 del translate_block_item_list
1022
1023 @method(AST.StructDeclaration)
1024 def struct_get_members(self, children):
1025   base_type = self.children[0].get_type()
1026   for i in self.children[1].children:
1027     type, name = i.get_type_and_name(base_type)
1028     children.append(AST.TypeStructOrUnion.Member(type = type, name = name))
1029 del struct_get_members
1030
1031 @method(AST.Specifier)
1032 def specifier_get_type(self):
1033   print(self)
1034   raise NotImplementedError
1035 @method(AST.StructSpecifier)
1036 def specifier_get_type(self):
1037   children = []
1038   if len(self.children) >= 2:
1039     for i in self.children[1].children:
1040       i.struct_get_members(children)
1041   return AST.TypeStruct(
1042     name = self.children[0].text[0],
1043     children = children
1044   )
1045 @method(AST.UnionSpecifier)
1046 def specifier_get_type(self):
1047   children = []
1048   for i in self.children[1].children:
1049     i.struct_get_members(children)
1050   return AST.TypeUnion(
1051     name = self.children[0].text[0],
1052     children = children
1053   )
1054 del specifier_get_type
1055
1056 @method(AST.SpecifierList)
1057 def get_type(self):
1058   type_specifiers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
1059   for i in self.children:
1060     if isinstance(i, AST.TypeSpecifier):
1061       type_specifiers[i.n] += 1
1062     elif isinstance(i, AST.StorageClassSpecifier):
1063       pass
1064     else:
1065       return i.specifier_get_type()
1066   return type_specifiers_to_type[tuple(type_specifiers)]
1067 del get_type
1068
1069 @method(AST.SpecifierList)
1070 def get_storage_class(self):
1071   storage_class_specifiers = [0, 0, 0, 0, 0]
1072   for i in self.children:
1073     if isinstance(i, AST.StorageClassSpecifier):
1074       storage_class_specifiers[i.n] += 1
1075   return storage_class_specifiers_to_storage_class[tuple(storage_class_specifiers)]
1076 del get_storage_class
1077
1078 @method(AST.Identifier)
1079 def translate_identifier(self, context):
1080   text = self.text[0]
1081   return context.translate_identifier.get(text, text)
1082 del translate_identifier
1083
1084 @method(AST.TranslationUnit)
1085 def translate_translation_unit(self, context):
1086   for i in self.children:
1087     i.translate_declaration_or_statement(context)
1088 del translate_translation_unit