Mercurial > lcfOS
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 |