Update hacky hard coded paths to pilex/piyacc/pitree, add struct translation
authorNick Downing <nick.downing@lifx.co>
Sun, 19 Jan 2020 03:08:36 +0000 (14:08 +1100)
committerNick Downing <nick.downing@lifx.co>
Sun, 19 Jan 2020 03:22:20 +0000 (14:22 +1100)
Makefile
ansi_c.l
ansi_c.t
ansi_c.y

index e35fcf9..ccbb7dd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,16 @@
 all: element.py lex_yy.py t_def.py y_tab.py
 
-element.py: ../pitree.git/skel/element.py
+element.py: ../pitree/ndcode/pitree/skel/element.py
        cat $< >$@
 
 lex_yy.py: ansi_c.l
-       ../pilex.git/pilex.py --element --python $<
+       ../pilex/pilex.py --element --python $<
 
 t_def.py: ansi_c.t
-       ../pitree.git/pitree.py --python $<
+       PYTHONPATH=../pitree ../pitree/ndcode/pitree/cli.py --python $<
 
 y_tab.py: ansi_c.y
-       ../piyacc.git/piyacc.py --element --python $<
+       ../piyacc/piyacc.py --element --python $<
 
 clean:
        rm -f element.py lex_yy.py t_def.py y_tab.py
index 099f1b1..e037240 100644 (file)
--- a/ansi_c.l
+++ b/ansi_c.l
@@ -22,8 +22,8 @@ ES  (\\(['"\?\\abfnrtv]|[0-7]{1,3}|x[a-fA-F0-9]+))
 WS  [ \t\v\n\f]
 
 %{
-import t_def
-import y_tab
+  import t_def
+  import y_tab
 %}
 
 %%
@@ -80,7 +80,7 @@ import y_tab
 "_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" {
+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 {
   # THIS IS A HACK FOR NOW
   return y_tab.TYPEDEF_NAME
 }
index 3083146..4937513 100644 (file)
--- a/ansi_c.t
+++ b/ansi_c.t
  * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+%{
+  import element
+  import sys
+%}
+
 %%
 
 class AST {
@@ -35,6 +40,7 @@ class AST {
     int precedence = -1;
     bool right_to_left = False;
   };
+  class Specifier;
   /* type analysis */
   class Type;
   class TypeVoid: Type;
@@ -62,6 +68,15 @@ class AST {
     ref return_type = None;
     bool varargs = False;
   };
+  class TypeStructOrUnion: Type {
+    class Member {
+      ref type = None;
+      str name = '';
+    };
+    str name = '';
+  };
+  class TypeStruct: TypeStructOrUnion;
+  class TypeUnion: TypeStructOrUnion;
   /* syntax classes */
   class AlignAsExpression;
   class AlignAsType;
@@ -86,7 +101,7 @@ class AST {
   class DesignatorInitializerList: InitializerOrExpression;
   class DesignatorListEqualsEmpty;
   class DesignatorList;
-  class EnumSpecifier;
+  class EnumSpecifier: Specifier;
   class Enumerator;
   class EnumeratorList;
   class EqualsInitializerEmpty;
@@ -149,7 +164,7 @@ class AST {
   class ExpressionSubtract: ExpressionBinary;
   class ExpressionSubtractAssignment: ExpressionBinary;
   class FunctionDefinition: DeclarationOrStatement;
-  class FunctionSpecifier {
+  class FunctionSpecifier: Specifier {
     int n = -1;
   };
   class GenericAssociation;
@@ -179,35 +194,39 @@ class AST {
   class StatementSwitch: Statement;
   class StatementWhile: Statement;
   class StaticAssertDeclaration: DeclarationOrStatement;
-  class StorageClassSpecifier {
+  class StorageClassSpecifier: Specifier {
     int n = -1;
   };
   class StructDeclaration;
   class StructDeclarationList;
   class StructDeclarator;
   class StructDeclaratorList;
-  class StructSpecifier;
+  class StructSpecifier: Specifier;
   class TypeName;
   class TypeQualifier {
     int n = -1;
   };
   class TypeQualifierList;
   class TypeQualifierOrStaticList;
-  class TypeSpecifier {
+  class TypeSpecifier: Specifier {
     int n = -1;
   };
-  class UnionSpecifier;
+  class UnionSpecifier: Specifier;
   class TranslationUnit;
 };
 
 %%
 
+def snake_to_camel(text):
+  return ''.join([i[0].upper() + i[1:] for i in text.split('_')])
+
 class Context:
   def __init__(
     self,
     indent = '',
     lines = [],
     top_level = True,
+    enclosing_struct = None,
     enclosing_loop = None,
     translate_identifier = {
       'NULL': 'None',
@@ -219,6 +238,7 @@ class Context:
     self.indent = indent
     self.lines = lines
     self.top_level = top_level
+    self.enclosing_struct = enclosing_struct
     self.enclosing_loop = enclosing_loop
     self.translate_identifier = translate_identifier
 
@@ -265,7 +285,7 @@ octal_prefix = set(
 )
 
 def factory(tag, *args, **kwargs):
-  return tag_to_class.get(tag, element.Element)(tag, *args, **kwargs)
+  return tag_to_class[tag](*args, **kwargs)
 
 @method(AST.DeclarationOrStatement)
 def translate_declaration_or_statement(self, context):
@@ -279,6 +299,40 @@ def translate_declaration_or_statement(self, context):
 @method(AST.Declaration)
 def translate_declaration_or_statement(self, context):
   base_type = self.children[0].get_type()
+  if isinstance(base_type, AST.TypeStructOrUnion) and len(base_type.children):
+    context.lines.append(
+      '''{0:s}class {1:s}:
+{2:s}  def __init__(
+{3:s}    self{4:s}
+{5:s}  ):{6:s}
+'''.format(
+        context.indent,
+        snake_to_camel(base_type.name),
+        context.indent,
+        context.indent,
+        ''.join(
+          [
+            ',\n{0:s}    {1:s} = {2:s}'.format(
+              context.indent,
+              i.name,
+              i.type.translate_zero(context)
+            )
+            for i in base_type.children
+          ]
+        ),
+        context.indent,
+        ''.join(
+          [
+            '\n{0:s}    self.{1:s} = {2:s}'.format(
+              context.indent,
+              i.name,
+              i.name
+            )
+            for i in base_type.children
+          ]
+        )
+      )
+    )
   for i in self.children[1].children:
     type, name = i.children[0].get_type_and_name(base_type)
     if not isinstance(type, AST.TypeFunction):
@@ -829,6 +883,9 @@ def translate_zero(self, context):
       [self.element_type.translate_zero(context)] * self.element_count
     )
   )
+@method(AST.TypeStructOrUnion)
+def translate_zero(self, context):
+  return '{0:s}()'.format(snake_to_camel(self.name))
 del translate_zero
 
 @method(AST.TypeVoid)
@@ -887,19 +944,54 @@ def translate_block_item_list(self, context):
     i.translate_declaration_or_statement(context)
 del translate_block_item_list
 
+@method(AST.StructDeclaration)
+def struct_get_members(self, children):
+  base_type = self.children[0].get_type()
+  for i in self.children[1].children:
+    type, name = i.get_type_and_name(base_type)
+    children.append(AST.TypeStructOrUnion.Member(type = type, name = name))
+del struct_get_members
+
+@method(AST.Specifier)
+def specifier_get_type(self):
+  print(self)
+  raise NotImplementedError
+@method(AST.StructSpecifier)
+def specifier_get_type(self):
+  children = []
+  if len(self.children) >= 2:
+    for i in self.children[1].children:
+      i.struct_get_members(children)
+  return AST.TypeStruct(
+    name = self.children[0].text[0],
+    children = children
+  )
+@method(AST.UnionSpecifier)
+def specifier_get_type(self):
+  children = []
+  for i in self.children[1].children:
+    i.struct_get_members(children)
+  return AST.TypeUnion(
+    name = self.children[0].text[0],
+    children = children
+  )
+del specifier_get_type
+
 @method(AST.DeclarationSpecifierList)
 def get_type(self):
   type_specifiers = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
   for i in self.children:
-    if isinstance(i, AST.TypeSpecifier):
-      type_specifiers[i.n] += 1
+    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 isinstance(i, AST.TypeSpecifier):
-      type_specifiers[i.n] += 1
+    if not isinstance(i, AST.TypeSpecifier):
+      return i.specifier_get_type()
+    type_specifiers[i.n] += 1
   return type_specifiers_to_type[tuple(type_specifiers)]
 del get_type
 
index 11dd954..7eb80d8 100644 (file)
--- a/ansi_c.y
+++ b/ansi_c.y
@@ -20,7 +20,7 @@
 %expect 2
 
 %{
-import t_def
+  import t_def
 %}
 
 %%