Mercurial > lcfOS
annotate python/c3/parser.py @ 220:3f6c30a5d234
Major change in expression parsing to enable pointers and structs
author | Windel Bouwman |
---|---|
date | Sat, 06 Jul 2013 21:32:20 +0200 |
parents | 1fa3e0050b49 |
children | 848c4b15fd0b |
rev | line source |
---|---|
213 | 1 from . import astnodes, lexer |
152 | 2 from ppci import CompilerError |
148 | 3 |
4 class Parser: | |
213 | 5 """ Parses sourcecode into an abstract syntax tree (AST) """ |
6 def __init__(self, diag): | |
7 self.diag = diag | |
8 | |
9 def parseSource(self, source): | |
148 | 10 self.initLex(source) |
11 try: | |
12 self.parsePackage() | |
213 | 13 return self.mod |
152 | 14 except CompilerError as e: |
15 self.diag.addDiag(e) | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
16 |
213 | 17 def Error(self, msg): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
18 raise CompilerError(msg, self.token.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
19 |
213 | 20 # Lexer helpers: |
21 def Consume(self, typ): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
22 if self.Peak == typ: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
23 return self.NextToken() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
24 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
25 self.Error('Excected: "{0}", got "{1}"'.format(typ, self.Peak)) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
26 |
213 | 27 @property |
28 def Peak(self): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
29 return self.token.typ |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
30 |
213 | 31 def hasConsumed(self, typ): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
32 if self.Peak == typ: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
33 self.Consume(typ) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
34 return True |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
35 return False |
213 | 36 |
37 def NextToken(self): | |
219 | 38 t = self.token |
39 if t.typ != 'END': | |
40 self.token = self.tokens.__next__() | |
41 return t | |
213 | 42 |
43 def initLex(self, source): | |
219 | 44 self.tokens = lexer.tokenize(source) # Lexical stage |
45 self.token = self.tokens.__next__() | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
46 |
215 | 47 def addDeclaration(self, decl): |
48 self.currentPart.declarations.append(decl) | |
213 | 49 |
50 def parseUses(self): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
51 # TODO: parse uses |
213 | 52 pass |
53 | |
54 def parsePackage(self): | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
55 self.Consume('package') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
56 name = self.Consume('ID') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
57 self.Consume(';') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
58 self.mod = astnodes.Package(name.val, name.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
59 self.currentPart = self.mod |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
60 self.parseUses() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
61 while self.Peak != 'END': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
62 self.parseTopLevel() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
63 self.Consume('END') |
148 | 64 |
213 | 65 def parseTopLevel(self): |
148 | 66 if self.Peak == 'function': |
213 | 67 self.parseFunctionDef() |
148 | 68 elif self.Peak == 'var': |
149 | 69 self.parseVarDef() |
163 | 70 elif self.Peak == 'const': |
71 self.parseConstDef() | |
213 | 72 elif self.Peak == 'type': |
73 self.parseTypeDef() | |
149 | 74 else: |
213 | 75 self.Error('Expected function, var, const or type') |
148 | 76 |
213 | 77 def parseDesignator(self): |
148 | 78 """ A designator designates an object """ |
79 name = self.Consume('ID') | |
213 | 80 d = astnodes.Designator(name.val, name.loc) |
148 | 81 return d |
82 | |
213 | 83 # Type system |
84 def parseTypeSpec(self): | |
85 # For now, do simple type spec, just parse an ID: | |
219 | 86 #return self.parseDesignator() |
213 | 87 if self.Peak == 'struct': |
88 self.Consume('struct') | |
89 self.Consume('{') | |
90 mems = [] | |
91 while self.Peak != '}': | |
92 mem_t = self.parseTypeSpec() | |
93 mem_n = self.Consume('ID') | |
94 mems.append((mem_t, mem_n)) | |
95 while self.hasConsumed(','): | |
96 mem_n = self.Consume('ID') | |
97 mems.append((mem_t, mem_n)) | |
98 self.Consume(';') | |
99 self.Consume('}') | |
100 theT = astnodes.StructureType(mems) | |
101 else: | |
102 theT = self.parseDesignator() | |
103 # Check for pointer suffix: | |
104 while self.hasConsumed('*'): | |
105 theT = astnodes.PointerType(theT) | |
106 return theT | |
107 | |
108 def parseTypeDef(self): | |
109 self.Consume('type') | |
110 newtype = self.parseTypeSpec() | |
111 typename = self.Consume('ID') | |
112 # TODO: action here :) | |
113 self.Consume(';') | |
114 return astnodes.DefinedType(typename, newtype) | |
115 | |
116 # Variable declarations: | |
117 def parseVarDef(self): | |
148 | 118 self.Consume('var') |
213 | 119 t = self.parseTypeSpec() |
149 | 120 def parseVar(): |
121 name = self.Consume('ID') | |
213 | 122 v = astnodes.Variable(name.val, t) |
123 v.loc = name.loc | |
149 | 124 if self.hasConsumed('='): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
125 v.ival = self.Expression() |
215 | 126 self.addDeclaration(v) |
149 | 127 parseVar() |
128 while self.hasConsumed(','): | |
129 parseVar() | |
157 | 130 self.Consume(';') |
148 | 131 |
213 | 132 def parseConstDef(self): |
163 | 133 self.Consume('const') |
213 | 134 t = self.parseTypeSpec() |
163 | 135 def parseConst(): |
136 name = self.Consume('ID') | |
137 self.Consume('=') | |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
138 val = self.Expression() |
213 | 139 c = astnodes.Constant(name.val, t, val) |
140 c.loc = name.loc | |
163 | 141 parseConst() |
142 while self.hasConsumed(','): | |
143 parseConst() | |
144 self.Consume(';') | |
145 | |
213 | 146 # Procedures |
147 def parseFunctionDef(self): | |
148 loc = self.Consume('function').loc | |
149 returntype = self.parseTypeSpec() | |
150 fname = self.Consume('ID').val | |
151 f = astnodes.Function(fname, loc) | |
215 | 152 self.addDeclaration(f) |
153 savePart = self.currentPart | |
154 self.currentPart = f | |
148 | 155 self.Consume('(') |
156 parameters = [] | |
157 if not self.hasConsumed(')'): | |
150 | 158 def parseParameter(): |
213 | 159 typ = self.parseTypeSpec() |
148 | 160 name = self.Consume('ID') |
213 | 161 param = astnodes.Variable(name.val, typ) |
162 param.loc = name.loc | |
215 | 163 self.addDeclaration(param) |
213 | 164 parameters.append(param) |
150 | 165 parseParameter() |
166 while self.hasConsumed(','): | |
167 parseParameter() | |
148 | 168 self.Consume(')') |
215 | 169 paramtypes = [p.typ for p in parameters] |
170 f.typ = astnodes.FunctionType(paramtypes, returntype) | |
171 f.body = self.parseCompoundStatement() | |
172 self.currentPart = savePart | |
148 | 173 |
213 | 174 # Statements: |
148 | 175 |
213 | 176 def parseIfStatement(self): |
165 | 177 loc = self.Consume('if').loc |
148 | 178 self.Consume('(') |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
179 condition = self.Expression() |
148 | 180 self.Consume(')') |
149 | 181 yes = self.parseCompoundStatement() |
148 | 182 if self.hasConsumed('else'): |
149 | 183 no = self.parseCompoundStatement() |
165 | 184 else: |
185 no = astnodes.EmptyStatement() | |
213 | 186 return astnodes.IfStatement(condition, yes, no, loc) |
148 | 187 |
213 | 188 def parseWhileStatement(self): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
189 loc = self.Consume('while').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
190 self.Consume('(') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
191 condition = self.Expression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
192 self.Consume(')') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
193 statements = self.parseCompoundStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
194 return astnodes.WhileStatement(condition, statements, loc) |
149 | 195 |
213 | 196 def parseReturnStatement(self): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
197 loc = self.Consume('return').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
198 expr = self.Expression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
199 self.Consume(';') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
200 return astnodes.ReturnStatement(expr, loc) |
148 | 201 |
213 | 202 def parseCompoundStatement(self): |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
203 self.Consume('{') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
204 statements = [] |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
205 while not self.hasConsumed('}'): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
206 s = self.Statement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
207 if type(s) is astnodes.EmptyStatement: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
208 continue |
166 | 209 statements.append(s) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
210 return astnodes.CompoundStatement(statements) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
211 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
212 def Statement(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
213 # Determine statement type based on the pending token: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
214 if self.Peak == 'if': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
215 return self.parseIfStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
216 elif self.Peak == 'while': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
217 return self.parseWhileStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
218 elif self.Peak == '{': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
219 return self.parseCompoundStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
220 elif self.hasConsumed(';'): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
221 return astnodes.EmptyStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
222 elif self.Peak == 'var': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
223 self.parseVarDef() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
224 return astnodes.EmptyStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
225 elif self.Peak == 'return': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
226 return self.parseReturnStatement() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
227 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
228 return self.AssignmentOrCall() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
229 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
230 def AssignmentOrCall(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
231 x = self.UnaryExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
232 if self.Peak == '=': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
233 # We enter assignment mode here. |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
234 loc = self.Consume('=').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
235 rhs = self.Expression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
236 return astnodes.Assignment(x, rhs, loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
237 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
238 return x |
148 | 239 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
240 # Expression section: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
241 # We not implement these C constructs: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
242 # a(2), f = 2 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
243 # and this: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
244 # a = 2 < x : 4 ? 1; |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
245 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
246 def Expression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
247 exp = self.LogicalAndExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
248 while self.Peak == 'or': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
249 loc = self.Consume('or').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
250 e2 = self.LogicalAndExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
251 exp = astnodes.Binop(exp, 'or', e2, loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
252 return exp |
148 | 253 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
254 def LogicalAndExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
255 o = self.EqualityExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
256 while self.Peak == 'and': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
257 loc = self.Consume('and').loc |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
258 o2 = self.EqualityExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
259 o = astnodes.Binop(o, 'and', o2, loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
260 return o |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
261 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
262 def EqualityExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
263 ee = self.SimpleExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
264 while self.Peak in ['<', '==', '>']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
265 op = self.Consume(self.Peak) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
266 ee2 = self.SimpleExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
267 ee = astnodes.Binop(ee, op.typ, ee2, op.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
268 return ee |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
269 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
270 def SimpleExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
271 e = self.Term() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
272 while self.Peak in ['+', '-']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
273 op = self.Consume(self.Peak) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
274 e2 = self.Term() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
275 e = astnodes.Binop(e, op.typ, e2, op.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
276 return e |
213 | 277 |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
278 def Term(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
279 t = self.Factor() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
280 while self.Peak in ['*', '/']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
281 op = self.Consume(self.Peak) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
282 t2 = self.Factor() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
283 t = astnodes.Binop(t, op.typ, t2, op.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
284 return t |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
285 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
286 def Factor(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
287 # TODO: eliminate this step? |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
288 return self.CastExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
289 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
290 # Domain of unary expressions: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
291 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
292 def CastExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
293 # TODO: cast conflicts with '(' expr ')' |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
294 if self.Peak == '(ii': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
295 self.Consume('(') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
296 print('TODO: implement type cast') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
297 #rrrrr |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
298 self.parseTypeSpec() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
299 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
300 # Type |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
301 self.Consume(')') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
302 ce = self.CastExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
303 return ce |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
304 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
305 return self.UnaryExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
306 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
307 def UnaryExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
308 if self.Peak in ['&', '*']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
309 op = self.Consume(self.Peak) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
310 ce = self.CastExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
311 return astnodes.Unop(op.typ, ce, op.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
312 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
313 return self.PostFixExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
314 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
315 def PostFixExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
316 pfe = self.PrimaryExpression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
317 while self.Peak in ['[', '(', '.', '->']: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
318 if self.hasConsumed('['): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
319 pass |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
320 elif self.hasConsumed('('): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
321 # Function call |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
322 args = [] |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
323 if not self.hasConsumed(')'): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
324 args.append(self.Expression()) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
325 while self.hasConsumed(','): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
326 args.append(self.Expression()) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
327 self.Consume(')') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
328 pfe = astnodes.FunctionCall(pfe, args, pfe.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
329 else: |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
330 rrrr |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
331 return pfe |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
332 |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
333 def PrimaryExpression(self): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
334 if self.hasConsumed('('): |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
335 e = self.Expression() |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
336 self.Consume(')') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
337 return e |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
338 elif self.Peak == 'NUMBER': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
339 val = self.Consume('NUMBER') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
340 return astnodes.Literal(val.val, val.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
341 elif self.Peak == 'REAL': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
342 val = self.Consume('REAL') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
343 return astnodes.Literal(val.val, val.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
344 elif self.Peak == 'true': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
345 val = self.Consume('true') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
346 return astnodes.Literal(True, val.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
347 elif self.Peak == 'false': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
348 val = self.Consume('false') |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
349 return astnodes.Literal(False, val.loc) |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
350 elif self.Peak == 'ID': |
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
351 d = self.parseDesignator() |
213 | 352 return astnodes.VariableUse(d, d.loc) |
220
3f6c30a5d234
Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents:
219
diff
changeset
|
353 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak)) |
148 | 354 |
355 |