2 * Copyright (C) 2019 Nick Downing <nick@ndcode.org>
3 * SPDX-License-Identifier: GPL-2.0-only
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.
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
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
27 /* internal classes */
29 class DeclarationOrStatement;
30 class Statement: DeclarationOrStatement;
32 class InitializerOrExpression;
33 class Expression: InitializerOrExpression;
34 class ExpressionUnary: Expression {
35 str unary_operator = '';
38 class ExpressionBinary: Expression {
39 str binary_operator = '';
41 bool right_to_left = False;
52 class TypeFloat: Type {
57 class TypePointer: Type {
58 ref target_type = None;
60 class TypeArray: Type {
61 ref element_type = None;
62 int element_count = -1;
64 class TypeFunction: Type {
69 ref return_type = None;
72 class TypeStructOrUnion: Type {
79 class TypeStruct: TypeStructOrUnion;
80 class TypeUnion: TypeStructOrUnion;
81 /* storage class analysis */
83 class StorageClassExtern: StorageClass;
84 class StorageClassStatic: StorageClass;
86 class AlignAsExpression;
88 class ArgumentExpressionList;
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 {
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;
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 {
175 class GenericAssociation;
176 class GenericAssociationList;
177 class GenericSelection;
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 {
205 class StructDeclaration;
206 class StructDeclarationList;
207 class StructDeclarator;
208 class StructDeclaratorList;
209 class StructSpecifier: Specifier;
211 class TypeQualifier {
214 class TypeQualifierList;
215 class TypeQualifierOrStaticList;
216 class TypeSpecifier: Specifier {
219 class UnionSpecifier: Specifier;
220 class TranslationUnit;
225 def snake_to_camel(text):
226 return ''.join([i[0].upper() + i[1:] for i in text.split('_')])
234 enclosing_struct = None,
235 enclosing_loop = None,
236 translate_identifier = {
245 self.top_level = top_level
246 self.enclosing_struct = enclosing_struct
247 self.enclosing_loop = enclosing_loop
248 self.translate_identifier = translate_identifier
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()
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()
295 ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09']
298 def factory(tag, *args, **kwargs):
299 return tag_to_class[tag](*args, **kwargs)
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])
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(
321 snake_to_camel(base_type.name),
326 ',\n{0:s} {1:s} = {2:s}'.format(
329 i.type.translate_zero(context)
331 for i in base_type.children
337 '\n{0:s} self.{1:s} = {2:s}'.format(
342 for i in base_type.children
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(
357 type.translate_zero(context)
358 if isinstance(i.children[1], AST.EqualsInitializerEmpty) else
359 i.children[1].translate_initializer_or_expression(context)
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(
373 ', '.join([i.name for i in type.children])
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)
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):
399 enclosing_loop_save.children[1],
400 AST.StatementContinue(),
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(
408 enclosing_loop_save.children[2].translate_statement_expression(context),
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):
418 isinstance(self.children[1], AST.ExpressionIntLiteral) and
419 self.children[1].text[0] == '0'
421 self.children[0].translate_declaration_or_statement(context)
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
432 AST.ExpressionLogicalNot(
436 unary_operator = 'not '
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(
447 self.children[0].translate_statement_expression(context)
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(
456 self.children[1].translate_expression(context, 0)
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(
468 self.children[2].translate_statement_expression(context)
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(
477 self.children[0].text[0]
480 @method(AST.StatementIf)
481 def translate_declaration_or_statement(self, context):
482 context.lines.append(
483 '{0:s}if {1:s}:\n'.format(
485 self.children[0].translate_expression(context, 0)
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(
497 self.children[0].translate_expression(context, 0)
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(
511 self.children[0].translate_expression(context, 0)
514 @method(AST.StatementLabel)
515 def translate_declaration_or_statement(self, context):
516 context.lines.append(
517 '{0:s}{1:s}:\n'.format(
519 self.children[0].text[0]
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 += ' '
528 for i in self.children[1].children[0].children:
530 isinstance(i, AST.StatementCase) or
531 isinstance(i, AST.StatementDefault)
533 if isinstance(i, AST.StatementCase):
534 cond_expr = AST.ExpressionEqual(
539 binary_operator = ' == ',
547 isinstance(j, AST.StatementCase) or
548 isinstance(j, AST.StatementDefault)
550 if isinstance(j, AST.StatementCase):
551 if cond_expr is not None:
552 cond_expr = AST.ExpressionLogicalOr(
560 binary_operator = ' == ',
564 binary_operator = ' or ',
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(
577 cond_expr.translate_expression(context, 0)
582 context.lines.append(
583 '{0:s}else:\n'.format(indent_save)
586 j.translate_declaration_or_statement(context)
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(
595 self.children[0].translate_expression(context, 0)
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):
608 del translate_declaration_or_statement
610 @method(AST.Declarator)
611 def get_type_and_name(self, base_type):
613 raise NotImplementedError
614 @method(AST.DeclaratorAbstract)
615 def get_type_and_name(self, base_type):
617 @method(AST.DeclaratorArray)
618 def get_type_and_name(self, base_type):
619 return self.children[0].get_type_and_name(
621 element_type = base_type,
624 if isinstance(self.children[2], AST.ExpressionEmpty) else
625 # kludgey way, assuming not calculated size
627 self.children[2].text[0],
628 8 if self.children[2].text[0][:2] in octal_prefix else 0
633 @method(AST.DeclaratorFunction)
634 def get_type_and_name(self, base_type):
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(
642 return_type = base_type,
643 varargs = self.varargs,
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)
654 del get_type_and_name
656 @method(AST.InitializerOrExpression)
657 def translate_initializer_or_expression(self, context):
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(
672 i.translate_initializer_or_expression(context)
673 for i in self.children
677 del translate_initializer_or_expression
679 @method(AST.Expression)
680 def translate_expression(self, context, precedence):
681 #return element.to_text(self).strip()
683 raise NotImplementedError
684 @method(AST.ExpressionUnary)
685 def translate_expression(self, context, precedence):
687 text = '{0:s}{1:s}'.format(
688 self.children[0].translate_expression(context, 14),
692 text = '({0:s})'.format(text)
694 text = '{0:s}{1:s}'.format(
696 self.children[0].translate_expression(context, 13)
699 text = '({0:s})'.format(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(
706 self.precedence + int(self.right_to_left)
708 self.binary_operator,
709 self.children[1].translate_expression(
711 self.precedence + int(not self.right_to_left)
714 if self.precedence < precedence:
715 text = '({0:s})'.format(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])
724 text = '({0:s})'.format(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
733 isinstance(type, AST.TypeInt) and
735 isinstance(self.children[1], AST.ExpressionIntLiteral) or
737 isinstance(self.children[1], AST.ExpressionMinus) and
738 isinstance(self.children[1].children[0], AST.ExpressionIntLiteral)
743 isinstance(type, AST.TypeFloat) and
745 isinstance(self.children[1], AST.ExpressionFloatLiteral) or
747 isinstance(self.children[1], AST.ExpressionMinus) and
748 isinstance(self.children[1].children[0], AST.ExpressionFloatLiteral)
753 text = self.children[1].translate_expression(context, precedence)
755 text = '{0:s}({1:s})'.format(
756 type.translate_type(context),
757 self.children[1].translate_expression(context, 0)
760 text = '({0:s})'.format(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)
773 text = '({0:s})'.format(text)
775 @method(AST.ExpressionEmpty)
776 def translate_expression(self, context, precedence):
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)
785 text = '({0:s})'.format(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)
794 text = '({0:s})'.format(text)
796 @method(AST.ExpressionFloatLiteral)
797 def translate_expression(self, context, precedence):
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)
812 text = '({0:s})'.format(text)
814 @method(AST.ExpressionIntLiteral)
815 def translate_expression(self, context, precedence):
817 if text[:2] in octal_prefix:
818 text = '0o' + text[1:]
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):
837 replace('\'', '\\\'')
839 for i in self.children
842 @method(AST.ExpressionFunctionName)
843 def translate_expression(self, context, precedence):
845 del translate_expression
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):
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
868 def translate_size(self, context):
870 raise NotImplementedError
871 @method(AST.TypeVoid)
872 def translate_size(self, context):
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):
883 @method(AST.TypePointer)
884 def translate_size(self, context):
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])
898 def translate_type(self, context):
900 raise NotImplementedError
901 @method(AST.TypeVoid)
902 def translate_type(self, context):
905 def translate_type(self, context):
907 @method(AST.TypeFloat)
908 def translate_type(self, context):
910 @method(AST.TypeBool)
911 def translate_type(self, context):
913 @method(AST.TypePointer)
914 def translate_type(self, context):
918 isinstance(self.target_type, AST.TypeInt) and
919 self.target_type.bits == 8
926 def translate_zero(self, context):
928 raise NotImplementedError
929 @method(AST.TypeVoid)
930 def translate_zero(self, context):
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):
947 isinstance(self.target_type, AST.TypeInt) and
948 self.target_type.bits == 8
952 if context.top_level else
955 @method(AST.TypeArray)
956 def translate_zero(self, context):
957 return '[{0:s}]'.format(
959 [self.element_type.translate_zero(context)] * self.element_count
962 @method(AST.TypeStructOrUnion)
963 def translate_zero(self, context):
964 return '{0:s}()'.format(snake_to_camel(self.name))
967 @method(AST.TypeVoid)
972 return '{0:s}int{1:d}'.format(['u', ''][int(self.signed)], self.bits)
973 @method(AST.TypeFloat)
975 return '{0:s}float{0:d}'.format(
976 ['', 'i', 'c'][int(self.complex)],
979 @method(AST.TypeBool)
982 @method(AST.TypePointer)
984 return 'pointer<{0:s}>'.format(str(self.target_type))
985 @method(AST.TypeArray)
987 return 'array<{0:s}: {1:s}>'.format(
988 str(self.element_type),
991 if self.element_count == -1 else
993 if self.element_count == -2 else
994 str(self.element_count)
997 @method(AST.TypeFunction.Argument)
999 return '{0:s} {1:s}'.format(
1001 'ABSTRACT' if self.name == '' else self.name
1003 @method(AST.TypeFunction)
1005 return 'function<{0:s} -> {1:s}>'.format(
1008 if len(self.children) == 0 else
1010 [str(i) for i in self.children] + (['...'] if self.varargs else [])
1013 str(self.return_type)
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
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
1031 @method(AST.Specifier)
1032 def specifier_get_type(self):
1034 raise NotImplementedError
1035 @method(AST.StructSpecifier)
1036 def specifier_get_type(self):
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],
1045 @method(AST.UnionSpecifier)
1046 def specifier_get_type(self):
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],
1054 del specifier_get_type
1056 @method(AST.SpecifierList)
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):
1065 return i.specifier_get_type()
1066 return type_specifiers_to_type[tuple(type_specifiers)]
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
1078 @method(AST.Identifier)
1079 def translate_identifier(self, context):
1081 return context.translate_identifier.get(text, text)
1082 del translate_identifier
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