From c1f2d98b0246b6b9c2b7237559d8dba7de81f0c3 Mon Sep 17 00:00:00 2001 From: Nick Downing Date: Sun, 19 Jan 2020 17:49:23 +1100 Subject: [PATCH] Implement storage classes --- ansi_c.l | 2 +- ansi_c.t | 75 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/ansi_c.l b/ansi_c.l index e037240..c394660 100644 --- a/ansi_c.l +++ b/ansi_c.l @@ -80,7 +80,7 @@ WS [ \t\v\n\f] "_Thread_local" return y_tab.THREAD_LOCAL "__func__" return y_tab.FUNC_NAME -FILE|GRAM_STYPE|YYLTYPE|assoc|bool|boundary|code_props|code_props_type|location|muscle_kind|named_ref|param_type|scanflags_t|size_t|symbol|symbol_class|symbol_list|uniqstr|variant|warnings|u?int(8|16|32|64)_t { +FILE|GRAM_STYPE|YYLTYPE|assoc|bool|boundary|code_props|code_props_type|location|muscle_kind|named_ref|param_type|scanflags_t|size_t|symbol|symbol_class|symbol_list|uniqstr|variant|warnings|u?int(8|16|32|64)_t|BaseType_t { # THIS IS A HACK FOR NOW return y_tab.TYPEDEF_NAME } diff --git a/ansi_c.t b/ansi_c.t index f7d1811..2eae663 100644 --- a/ansi_c.t +++ b/ansi_c.t @@ -41,6 +41,7 @@ class AST { bool right_to_left = False; }; class Specifier; + class SpecifierList; /* type analysis */ class Type; class TypeVoid: Type; @@ -77,6 +78,10 @@ class AST { }; class TypeStruct: TypeStructOrUnion; class TypeUnion: TypeStructOrUnion; + /* storage class analysis */ + class StorageClass; + class StorageClassExtern: StorageClass; + class StorageClassStatic: StorageClass; /* syntax classes */ class AlignAsExpression; class AlignAsType; @@ -84,7 +89,7 @@ class AST { class BlockItemList; class Declaration: DeclarationOrStatement; class DeclarationList; - class DeclarationSpecifierList; + class DeclarationSpecifierList: SpecifierList; class DeclaratorAbstract: Declarator; class DeclaratorArray: Declarator; class DeclaratorEmpty: Declarator; @@ -177,7 +182,7 @@ class AST { class InitDeclaratorList; class ParameterDeclaration; class ParameterDeclarationList; - class SpecifierQualifierList; + class SpecifierQualifierList: SpecifierList; class StatementBlock: Statement; class StatementBreak: Statement; class StatementCase: Statement; @@ -280,6 +285,12 @@ type_specifiers_to_type = { (0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1): AST.TypeFloat(complex = 2, bits = 64), (0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0): AST.TypeBool() } +# typedef extern static thread_local auto register +storage_class_specifiers_to_storage_class = { + (0, 0, 0, 0, 0): AST.StorageClass(), + (0, 1, 0, 0, 0): AST.StorageClassExtern(), + (0, 0, 1, 0, 0): AST.StorageClassStatic() +} octal_prefix = set( ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'] ) @@ -333,20 +344,22 @@ def translate_declaration_or_statement(self, context): ) ) ) - for i in self.children[1].children: - type, name = i.children[0].get_type_and_name(base_type) - if not isinstance(type, AST.TypeFunction): - context.lines.append( - '{0:s}{1:s} = {2:s}\n'.format( - context.indent, - name, - ( - type.translate_zero(context) - if isinstance(i.children[1], AST.EqualsInitializerEmpty) else - i.children[1].translate_initializer_or_expression(context) + storage_class = self.children[0].get_storage_class() + if not isinstance(storage_class, AST.StorageClassExtern): + for i in self.children[1].children: + type, name = i.children[0].get_type_and_name(base_type) + if not isinstance(type, AST.TypeFunction): + context.lines.append( + '{0:s}{1:s} = {2:s}\n'.format( + context.indent, + name, + ( + type.translate_zero(context) + if isinstance(i.children[1], AST.EqualsInitializerEmpty) else + i.children[1].translate_initializer_or_expression(context) + ) ) ) - ) @method(AST.FunctionDefinition) def translate_declaration_or_statement(self, context): type, name = self.children[1].get_type_and_name(self.children[0].get_type()) @@ -803,9 +816,11 @@ 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': + if text[-1:] == 'L': + text = text[:-1] + if text[-1:] == 'L': + text = text[:-1] + if text[-1:] == 'U': text = text[:-1] return text @method(AST.ExpressionSizeOfType) @@ -1038,24 +1053,28 @@ def specifier_get_type(self): ) del specifier_get_type -@method(AST.DeclarationSpecifierList) +@method(AST.SpecifierList) def get_type(self): type_specifiers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] for i in self.children: - if not isinstance(i, AST.TypeSpecifier): - return i.specifier_get_type() - type_specifiers[i.n] += 1 - return type_specifiers_to_type[tuple(type_specifiers)] -@method(AST.SpecifierQualifierList) -def get_type(self): - type_specifiers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - for i in self.children: - if not isinstance(i, AST.TypeSpecifier): + if isinstance(i, AST.TypeSpecifier): + type_specifiers[i.n] += 1 + elif isinstance(i, AST.StorageClassSpecifier): + pass + else: return i.specifier_get_type() - type_specifiers[i.n] += 1 return type_specifiers_to_type[tuple(type_specifiers)] del get_type +@method(AST.SpecifierList) +def get_storage_class(self): + storage_class_specifiers = [0, 0, 0, 0, 0] + for i in self.children: + if isinstance(i, AST.StorageClassSpecifier): + storage_class_specifiers[i.n] += 1 + return storage_class_specifiers_to_storage_class[tuple(storage_class_specifiers)] +del get_storage_class + @method(AST.Identifier) def translate_identifier(self, context): text = self.text[0] -- 2.34.1