diff python/ppci/c3/parser.py @ 354:5477e499b039

Added some sort of string functionality
author Windel Bouwman
date Thu, 13 Mar 2014 18:59:06 +0100
parents d1ecc493384e
children c05ab629976a
line wrap: on
line diff
--- a/python/ppci/c3/parser.py	Sun Mar 09 18:49:10 2014 +0100
+++ b/python/ppci/c3/parser.py	Thu Mar 13 18:59:06 2014 +0100
@@ -1,12 +1,12 @@
 import logging
-from ppci import CompilerError
+from .. import CompilerError
 from .astnodes import Member, Literal, TypeCast, Unop, Binop
 from .astnodes import Assignment, ExpressionStatement, Compound
 from .astnodes import Return, While, If, Empty, For
 from .astnodes import FunctionType, Function, FormalParameter
-from .astnodes import StructureType, DefinedType, PointerType
+from .astnodes import StructureType, DefinedType, PointerType, ArrayType
 from .astnodes import Constant, Variable
-from .astnodes import StructField, Deref
+from .astnodes import StructField, Deref, Index
 from .astnodes import Package
 from .astnodes import Identifier
 from .astnodes import FunctionCall
@@ -105,14 +105,29 @@
         return ids
 
     # Type system
-    def parseTypeSpec(self):
-        # For now, do simple type spec, just parse an ID:
+    def PostFixId(self):
+        pfe = self.PrimaryExpression_Id()
+        while self.Peak in ['.']:
+            if self.hasConsumed('.'):
+                field = self.Consume('ID')
+                pfe = Member(pfe, field.val, field.loc)
+            else:
+                raise Exception()
+        return pfe
+
+    def PrimaryExpression_Id(self):
+        if self.Peak == 'ID':
+            return self.parseDesignator()
+        self.Error('Expected ID, got {0}'.format(self.Peak))
+
+    def parse_type_spec(self):
+        """ Parse type specification """
         if self.Peak == 'struct':
             self.Consume('struct')
             self.Consume('{')
             mems = []
             while self.Peak != '}':
-                mem_t = self.parseTypeSpec()
+                mem_t = self.parse_type_spec()
                 for i in self.parseIdSequence():
                     mems.append(StructField(i.val, mem_t))
                 self.Consume(';')
@@ -122,15 +137,27 @@
             # TODO)
             raise NotImplementedError()
         else:
-            theT = self.PostFixExpression()
-        # Check for pointer suffix:
-        while self.hasConsumed('*'):
-            theT = PointerType(theT)
+            theT = self.PostFixId()
+
+        # Check for pointer or array suffix:
+        while self.Peak in ['*', '[']:
+            if self.hasConsumed('*'):
+                theT = PointerType(theT)
+            elif self.hasConsumed('['):
+                if self.Peak == ']':
+                    size = 0
+                    self.Consume(']')
+                else:
+                    size = self.Expression()
+                    self.Consume(']')
+                theT = ArrayType(theT, size)
+            else:
+                raise Exception()
         return theT
 
     def parseTypeDef(self):
         self.Consume('type')
-        newtype = self.parseTypeSpec()
+        newtype = self.parse_type_spec()
         typename = self.Consume('ID')
         self.Consume(';')
         df = DefinedType(typename.val, newtype, typename.loc)
@@ -139,7 +166,7 @@
     # Variable declarations:
     def parseVarDef(self):
         self.Consume('var')
-        t = self.parseTypeSpec()
+        t = self.parse_type_spec()
         for name in self.parseIdSequence():
             v = Variable(name.val, t)
             v.loc = name.loc
@@ -149,7 +176,7 @@
 
     def parseConstDef(self):
         self.Consume('const')
-        t = self.parseTypeSpec()
+        t = self.parse_type_spec()
         while True:
             name = self.Consume('ID')
             self.Consume('=')
@@ -163,7 +190,7 @@
 
     def parseFunctionDef(self):
         loc = self.Consume('function').loc
-        returntype = self.parseTypeSpec()
+        returntype = self.parse_type_spec()
         fname = self.Consume('ID').val
         f = Function(fname, loc)
         self.addDeclaration(f)
@@ -173,7 +200,7 @@
         parameters = []
         if not self.hasConsumed(')'):
             while True:
-                typ = self.parseTypeSpec()
+                typ = self.parse_type_spec()
                 name = self.Consume('ID')
                 param = FormalParameter(name.val, typ)
                 param.loc = name.loc
@@ -187,7 +214,7 @@
         f.body = self.parseCompound()
         self.currentPart = savePart
 
-    def parseIf(self):
+    def parse_if(self):
         loc = self.Consume('if').loc
         self.Consume('(')
         condition = self.Expression()
@@ -204,7 +231,7 @@
         statements = self.Statement()
         return While(condition, statements, loc)
 
-    def parseFor(self):
+    def parse_for(self):
         loc = self.Consume('for').loc
         self.Consume('(')
         init = self.Statement()
@@ -235,11 +262,11 @@
     def Statement(self):
         # Determine statement type based on the pending token:
         if self.Peak == 'if':
-            return self.parseIf()
+            return self.parse_if()
         elif self.Peak == 'while':
             return self.parseWhile()
         elif self.Peak == 'for':
-            return self.parseFor()
+            return self.parse_for()
         elif self.Peak == '{':
             return self.parseCompound()
         elif self.hasConsumed(';'):
@@ -339,7 +366,7 @@
         if self.Peak == 'cast':
             loc = self.Consume('cast').loc
             self.Consume('<')
-            t = self.parseTypeSpec()
+            t = self.parse_type_spec()
             self.Consume('>')
             self.Consume('(')
             ce = self.Expression()
@@ -363,7 +390,9 @@
         pfe = self.PrimaryExpression()
         while self.Peak in ['[', '.', '->', '(', '++']:
             if self.hasConsumed('['):
-                raise NotImplementedError('Array not yet implemented')
+                i = self.Expression()
+                self.Consume(']')
+                pfe = Index(pfe, i, i.loc)
             elif self.hasConsumed('->'):
                 field = self.Consume('ID')
                 pfe = Deref(pfe, pfe.loc)
@@ -410,3 +439,4 @@
         elif self.Peak == 'ID':
             return self.parseDesignator()
         self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
+