From 242d941d57a4cc3683a974a3af7bf0e4e6d7cf2b Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Sun, 19 Jan 2020 14:54:17 +1100 Subject: [PATCH] Handle some more expressions and statements, add cpp "# line file" extractor --- ansi_c.t | 73 ++++++++++++++++++++++++++++++++++++++++++++++++----- hashline.py | 19 ++++++++++++++ 2 files changed, 86 insertions(+), 6 deletions(-) create mode 100755 hashline.py diff --git a/ansi_c.t b/ansi_c.t index 4937513..f7d1811 100644 --- a/ansi_c.t +++ b/ansi_c.t @@ -456,6 +456,14 @@ def translate_declaration_or_statement(self, context): ) ) context.indent = indent_save +@method(AST.StatementGoto) +def translate_declaration_or_statement(self, context): + context.lines.append( + '{0:s}goto {1:s}\n'.format( + context.indent, + self.children[0].text[0] + ) + ) @method(AST.StatementIf) def translate_declaration_or_statement(self, context): context.lines.append( @@ -490,6 +498,14 @@ def translate_declaration_or_statement(self, context): self.children[0].translate_expression(context, 0) ) ) +@method(AST.StatementLabel) +def translate_declaration_or_statement(self, context): + context.lines.append( + '{0:s}{1:s}:\n'.format( + context.indent, + self.children[0].text[0] + ) + ) @method(AST.StatementSwitch) def translate_declaration_or_statement(self, context): assert isinstance(self.children[1], AST.StatementBlock) @@ -697,12 +713,38 @@ def translate_expression(self, context, precedence): @method(AST.ExpressionCast) def translate_expression(self, context, precedence): type, _ = self.children[0].children[1].get_type_and_name(self.children[0].children[0].get_type()) - text = '{0:s}({1:s})'.format( - type.translate_type(context), - self.children[1].translate_expression(context, 0) - ) - if 14 < precedence: - text = '({0:s})'.format(text) + # python unifies the different int types and the different float types, + # therefore a lot of casting of constants etc needed in C is not in python + if ( + ( + isinstance(type, AST.TypeInt) and + ( + isinstance(self.children[1], AST.ExpressionIntLiteral) or + ( + isinstance(self.children[1], AST.ExpressionMinus) and + isinstance(self.children[1].children[0], AST.ExpressionIntLiteral) + ) + ) + ) or + ( + isinstance(type, AST.TypeFloat) and + ( + isinstance(self.children[1], AST.ExpressionFloatLiteral) or + ( + isinstance(self.children[1], AST.ExpressionMinus) and + isinstance(self.children[1].children[0], AST.ExpressionFloatLiteral) + ) + ) + ) + ): + text = self.children[1].translate_expression(context, precedence) + else: + text = '{0:s}({1:s})'.format( + type.translate_type(context), + self.children[1].translate_expression(context, 0) + ) + if 14 < precedence: + text = '({0:s})'.format(text) return text @method(AST.ExpressionCharConstant) def translate_expression(self, context, precedence): @@ -738,6 +780,12 @@ def translate_expression(self, context, precedence): if 14 < precedence: text = '({0:s})'.format(text) return text +@method(AST.ExpressionFloatLiteral) +def translate_expression(self, context, precedence): + text = self.text[0] + if text[-1:] == 'f': + text = text[:-1] + return text @method(AST.ExpressionIdentifier) def translate_expression(self, context, precedence): return self.children[0].translate_identifier(context) @@ -755,6 +803,10 @@ def translate_expression(self, context, precedence): text = self.text[0] if text[:2] in octal_prefix: text = '0o' + text[1:] + if text[-2:] == 'LL': + text = text[:-2] + elif text[-1:] == 'L': + text = text[:-1] return text @method(AST.ExpressionSizeOfType) def translate_expression(self, context, precedence): @@ -772,6 +824,9 @@ def translate_expression(self, context, precedence): for i in self.children ] ) +@method(AST.ExpressionFunctionName) +def translate_expression(self, context, precedence): + return '__func__' del translate_expression @method(AST.Expression) @@ -816,6 +871,12 @@ def translate_size(self, context): @method(AST.TypeArray) def translate_size(self, context): return self.element_type.translate_type(context) * self.element_count +@method(AST.TypeStruct) +def translate_size(self, context): + return sum([i.type.translate_size(context) for i in self.children]) +@method(AST.TypeUnion) +def translate_size(self, context): + return max([i.type.translate_size(context) for i in self.children]) del translate_size @method(AST.Type) diff --git a/hashline.py b/hashline.py new file mode 100755 index 0000000..0614a3e --- /dev/null +++ b/hashline.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 + +import sys + +EXIT_SUCCESS = 0 +EXIT_FAILURE = 1 + +if len(sys.argv) < 2: + print(f'usage: {sys.argv[0]:s} filename') + sys.exit(EXIT_FAILURE) +filename = sys.argv[1] + +output = True +for line in sys.stdin: + if line[:1] == '#': + fields = line.split() + output = len(fields) >= 3 and fields[2] == f'"{filename:s}"' + elif output: + sys.stdout.write(line) -- 2.34.1