comparison python/ppci/c3/parser.py @ 307:e609d5296ee9

Massive rewrite of codegenerator
author Windel Bouwman
date Thu, 12 Dec 2013 20:42:56 +0100
parents b145f8e6050b
children 2e7f55319858
comparison
equal deleted inserted replaced
306:b145f8e6050b 307:e609d5296ee9
1 import logging 1 import logging
2 from ppci import CompilerError 2 from ppci import CompilerError
3 from .astnodes import Member, Literal, TypeCast, Unop, Binop 3 from .astnodes import Member, Literal, TypeCast, Unop, Binop
4 from .astnodes import Assignment, ExpressionStatement, CompoundStatement 4 from .astnodes import Assignment, ExpressionStatement, Compound
5 from .astnodes import ReturnStatement, WhileStatement, IfStatement 5 from .astnodes import Return, While, If, Empty
6 from .astnodes import FunctionType, Function, FormalParameter 6 from .astnodes import FunctionType, Function, FormalParameter
7 from .astnodes import StructureType, DefinedType, PointerType 7 from .astnodes import StructureType, DefinedType, PointerType
8 from .astnodes import Constant, Variable 8 from .astnodes import Constant, Variable
9 from .astnodes import StructField, Deref 9 from .astnodes import StructField, Deref
10 from .astnodes import Package 10 from .astnodes import Package
11 from .astnodes import Identifier 11 from .astnodes import Identifier
12 from .astnodes import FunctionCall 12 from .astnodes import FunctionCall
13 from .astnodes import EmptyStatement
14 13
15 14
16 class Parser: 15 class Parser:
17 """ Parses sourcecode into an abstract syntax tree (AST) """ 16 """ Parses sourcecode into an abstract syntax tree (AST) """
18 def __init__(self, diag): 17 def __init__(self, diag):
144 for name in self.parseIdSequence(): 143 for name in self.parseIdSequence():
145 v = Variable(name.val, t) 144 v = Variable(name.val, t)
146 v.loc = name.loc 145 v.loc = name.loc
147 self.addDeclaration(v) 146 self.addDeclaration(v)
148 self.Consume(';') 147 self.Consume(';')
149 return EmptyStatement() 148 return Empty()
150 149
151 def parseConstDef(self): 150 def parseConstDef(self):
152 self.Consume('const') 151 self.Consume('const')
153 t = self.parseTypeSpec() 152 t = self.parseTypeSpec()
154 while True: 153 while True:
182 if not self.hasConsumed(','): 181 if not self.hasConsumed(','):
183 break 182 break
184 self.Consume(')') 183 self.Consume(')')
185 paramtypes = [p.typ for p in parameters] 184 paramtypes = [p.typ for p in parameters]
186 f.typ = FunctionType(paramtypes, returntype) 185 f.typ = FunctionType(paramtypes, returntype)
187 f.body = self.parseCompoundStatement() 186 f.body = self.parseCompound()
188 self.currentPart = savePart 187 self.currentPart = savePart
189 188
190 def parseIfStatement(self): 189 def parseIf(self):
191 loc = self.Consume('if').loc 190 loc = self.Consume('if').loc
192 self.Consume('(') 191 self.Consume('(')
193 condition = self.Expression() 192 condition = self.Expression()
194 self.Consume(')') 193 self.Consume(')')
195 yes = self.Statement() 194 yes = self.Statement()
196 no = self.Statement() if self.hasConsumed('else') else EmptyStatement() 195 no = self.Statement() if self.hasConsumed('else') else Empty()
197 return IfStatement(condition, yes, no, loc) 196 return If(condition, yes, no, loc)
198 197
199 def parseWhileStatement(self): 198 def parseWhile(self):
200 loc = self.Consume('while').loc 199 loc = self.Consume('while').loc
201 self.Consume('(') 200 self.Consume('(')
202 condition = self.Expression() 201 condition = self.Expression()
203 self.Consume(')') 202 self.Consume(')')
204 statements = self.Statement() 203 statements = self.Statement()
205 return WhileStatement(condition, statements, loc) 204 return While(condition, statements, loc)
206 205
207 def parseReturnStatement(self): 206 def parseReturn(self):
208 loc = self.Consume('return').loc 207 loc = self.Consume('return').loc
209 if self.Peak == ';': 208 if self.Peak == ';':
210 expr = Literal(0, loc) 209 expr = Literal(0, loc)
211 else: 210 else:
212 expr = self.Expression() 211 expr = self.Expression()
213 self.Consume(';') 212 self.Consume(';')
214 return ReturnStatement(expr, loc) 213 return Return(expr, loc)
215 214
216 def parseCompoundStatement(self): 215 def parseCompound(self):
217 self.Consume('{') 216 self.Consume('{')
218 statements = [] 217 statements = []
219 while not self.hasConsumed('}'): 218 while not self.hasConsumed('}'):
220 statements.append(self.Statement()) 219 statements.append(self.Statement())
221 return CompoundStatement(statements) 220 return Compound(statements)
222 221
223 def Statement(self): 222 def Statement(self):
224 # Determine statement type based on the pending token: 223 # Determine statement type based on the pending token:
225 if self.Peak == 'if': 224 if self.Peak == 'if':
226 return self.parseIfStatement() 225 return self.parseIf()
227 elif self.Peak == 'while': 226 elif self.Peak == 'while':
228 return self.parseWhileStatement() 227 return self.parseWhile()
229 elif self.Peak == '{': 228 elif self.Peak == '{':
230 return self.parseCompoundStatement() 229 return self.parseCompound()
231 elif self.hasConsumed(';'): 230 elif self.hasConsumed(';'):
232 return EmptyStatement() 231 return Empty()
233 elif self.Peak == 'var': 232 elif self.Peak == 'var':
234 return self.parseVarDef() 233 return self.parseVarDef()
235 elif self.Peak == 'return': 234 elif self.Peak == 'return':
236 return self.parseReturnStatement() 235 return self.parseReturn()
237 else: 236 else:
238 x = self.UnaryExpression() 237 x = self.UnaryExpression()
239 if self.Peak == '=': 238 if self.Peak == '=':
240 # We enter assignment mode here. 239 # We enter assignment mode here.
241 loc = self.Consume('=').loc 240 loc = self.Consume('=').loc