annotate python/ppci/c3/parser.py @ 395:3b0c495e3008

Speed improvements
author Windel Bouwman
date Fri, 23 May 2014 14:28:03 +0200
parents 988f3fb861e4
children fb3c1f029b30
rev   line source
254
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
1 import logging
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
2 from .. import CompilerError
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
3 from .astnodes import Member, Literal, TypeCast, Unop, Binop
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
4 from .astnodes import Assignment, ExpressionStatement, Compound
315
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
5 from .astnodes import Return, While, If, Empty, For
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
6 from .astnodes import FunctionType, Function, FormalParameter
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
7 from .astnodes import StructureType, DefinedType, PointerType, ArrayType
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
8 from .astnodes import Constant, Variable, Sizeof
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
9 from .astnodes import StructField, Deref, Index
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
10 from .astnodes import Package
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
11 from .astnodes import Identifier
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
12 from .astnodes import FunctionCall
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
13
288
a747a45dcd78 Various styling work
Windel Bouwman
parents: 284
diff changeset
14
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
15 class Parser:
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
16 """ Parses sourcecode into an abstract syntax tree (AST) """
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
17 def __init__(self, diag):
254
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
18 self.logger = logging.getLogger('c3')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
19 self.diag = diag
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
20
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
21 def parseSource(self, tokens):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 315
diff changeset
22 self.logger.debug('Parsing source')
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
23 self.tokens = tokens
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
24 self.token = self.tokens.__next__()
254
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
25 try:
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
26 self.parse_package()
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
27 self.mod.ok = True # Valid until proven wrong :)
254
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
28 return self.mod
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
29 except CompilerError as e:
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
30 self.diag.addDiag(e)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
31
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
32 def Error(self, msg):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
33 raise CompilerError(msg, self.token.loc)
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
34
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
35 # Lexer helpers:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
36 def Consume(self, typ):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
37 if self.Peak == typ:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
38 return self.NextToken()
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
39 else:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
40 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
41
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
42 @property
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
43 def Peak(self):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
44 return self.token.typ
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
45
228
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
46 @property
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
47 def CurLoc(self):
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
48 return self.token.loc
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
49
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
50 def hasConsumed(self, typ):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
51 if self.Peak == typ:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
52 self.Consume(typ)
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
53 return True
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
54 return False
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
55
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
56 def NextToken(self):
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
57 t = self.token
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
58 if t.typ != 'END':
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
59 self.token = self.tokens.__next__()
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
60 return t
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
61
215
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
62 def addDeclaration(self, decl):
336
d1ecc493384e Added spiffy armtoken class for bit fiddeling. Added cool test that checks for build repeatability
Windel Bouwman
parents: 334
diff changeset
63 self.currentPart.add_declaration(decl)
288
a747a45dcd78 Various styling work
Windel Bouwman
parents: 284
diff changeset
64
251
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
65 def parseImport(self):
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
66 self.Consume('import')
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
67 name = self.Consume('ID').val
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
68 self.mod.imports.append(name)
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
69 self.Consume(';')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
70
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
71 def parse_package(self):
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
72 """ Parse a package definition """
284
05184b95fa16 Moved tests to seperate folder
Windel Bouwman
parents: 280
diff changeset
73 self.Consume('module')
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
74 name = self.Consume('ID')
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
75 self.Consume(';')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
76 self.mod = Package(name.val, name.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
77 self.currentPart = self.mod
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
78 while self.Peak != 'END':
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
79 self.parse_top_level()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
80 self.Consume('END')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
81
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
82 def parse_top_level(self):
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
83 """ Parse toplevel declaration """
251
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
84 if self.Peak == 'function':
362
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
85 self.parse_function_def()
251
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
86 elif self.Peak == 'var':
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
87 self.parse_variable_def()
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
88 # TODO handle variable initialization
251
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
89 elif self.Peak == 'const':
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
90 self.parseConstDef()
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
91 elif self.Peak == 'type':
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
92 self.parse_type_def()
251
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
93 elif self.Peak == 'import':
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
94 self.parseImport()
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
95 else:
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 232
diff changeset
96 self.Error('Expected function, var, const or type')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
97
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
98 def parseDesignator(self):
301
6753763d3bec merge codegen into ppci package
Windel Bouwman
parents: 300
diff changeset
99 """ A designator designates an object with a name. """
225
1c7364bd74c7 Fixed pointer deref
Windel Bouwman
parents: 222
diff changeset
100 name = self.Consume('ID')
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
101 return Identifier(name.val, name.loc)
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
102
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
103 def parseIdSequence(self):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
104 ids = [self.Consume('ID')]
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
105 while self.hasConsumed(','):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
106 ids.append(self.Consume('ID'))
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
107 return ids
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
108
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
109 # Type system
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
110 def PostFixId(self):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
111 pfe = self.PrimaryExpression_Id()
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
112 while self.Peak in ['.']:
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
113 if self.hasConsumed('.'):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
114 field = self.Consume('ID')
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
115 pfe = Member(pfe, field.val, field.loc)
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
116 else:
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
117 raise Exception()
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
118 return pfe
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
119
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
120 def PrimaryExpression_Id(self):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
121 if self.Peak == 'ID':
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
122 return self.parseDesignator()
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
123 self.Error('Expected ID, got {0}'.format(self.Peak))
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
124
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
125 def parse_type_spec(self):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
126 """ Parse type specification """
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
127 if self.Peak == 'struct':
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
128 self.Consume('struct')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
129 self.Consume('{')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
130 mems = []
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
131 while self.Peak != '}':
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
132 mem_t = self.parse_type_spec()
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
133 for i in self.parseIdSequence():
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
134 mems.append(StructField(i.val, mem_t))
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
135 self.Consume(';')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
136 self.Consume('}')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
137 theT = StructureType(mems)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
138 elif self.Peak == 'enum':
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
139 # TODO)
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
140 raise NotImplementedError()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
141 else:
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
142 theT = self.PostFixId()
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
143
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
144 # Check for pointer or array suffix:
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
145 while self.Peak in ['*', '[']:
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
146 if self.hasConsumed('*'):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
147 theT = PointerType(theT)
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
148 elif self.hasConsumed('['):
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
149 if self.Peak == ']':
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
150 size = 0
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
151 self.Consume(']')
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
152 else:
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
153 size = self.Expression()
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
154 self.Consume(']')
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
155 theT = ArrayType(theT, size)
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
156 else:
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
157 raise Exception()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
158 return theT
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
159
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
160 def parse_type_def(self):
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
161 self.Consume('type')
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
162 newtype = self.parse_type_spec()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
163 typename = self.Consume('ID')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
164 self.Consume(';')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
165 df = DefinedType(typename.val, newtype, typename.loc)
225
1c7364bd74c7 Fixed pointer deref
Windel Bouwman
parents: 222
diff changeset
166 self.addDeclaration(df)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
167
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
168 # Variable declarations:
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
169 def parse_variable_def(self):
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
170 """ Parse variable declaration """
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
171 self.Consume('var')
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
172 t = self.parse_type_spec()
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
173 for name in self.parseIdSequence():
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
174 v = Variable(name.val, t)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
175 v.loc = name.loc
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
176 self.addDeclaration(v)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
177 self.Consume(';')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
178
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
179 def parseConstDef(self):
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
180 self.Consume('const')
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
181 t = self.parse_type_spec()
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
182 while True:
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
183 name = self.Consume('ID')
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
184 self.Consume('=')
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
185 val = self.Expression()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
186 c = Constant(name.val, t, val)
313
04cf4d26a3bc Added constant function
Windel Bouwman
parents: 311
diff changeset
187 self.addDeclaration(c)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
188 c.loc = name.loc
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
189 if not self.hasConsumed(','):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
190 break
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
191 self.Consume(';')
288
a747a45dcd78 Various styling work
Windel Bouwman
parents: 284
diff changeset
192
362
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
193 def parse_function_def(self):
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
194 loc = self.Consume('function').loc
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
195 returntype = self.parse_type_spec()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
196 fname = self.Consume('ID').val
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
197 f = Function(fname, loc)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
198 self.addDeclaration(f)
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
199 savePart = self.currentPart
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
200 self.currentPart = f
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
201 self.Consume('(')
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
202 parameters = []
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
203 if not self.hasConsumed(')'):
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
204 while True:
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
205 typ = self.parse_type_spec()
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
206 name = self.Consume('ID')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
207 param = FormalParameter(name.val, typ)
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
208 param.loc = name.loc
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
209 self.addDeclaration(param)
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
210 parameters.append(param)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
211 if not self.hasConsumed(','):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
212 break
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
213 self.Consume(')')
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
214 paramtypes = [p.typ for p in parameters]
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
215 f.typ = FunctionType(paramtypes, returntype)
362
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
216 if self.Peak == ';':
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
217 self.Consume(';')
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
218 f.body = None
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
219 else:
c05ab629976a Added CPUID for arm
Windel Bouwman
parents: 354
diff changeset
220 f.body = self.parseCompound()
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
221 self.currentPart = savePart
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
222
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
223 def parse_if(self):
272
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
224 loc = self.Consume('if').loc
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
225 self.Consume('(')
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
226 condition = self.Expression()
e64bae57cda8 refactor ir
Windel Bouwman
parents: 254
diff changeset
227 self.Consume(')')
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
228 yes = self.Statement()
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
229 no = self.Statement() if self.hasConsumed('else') else Empty()
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
230 return If(condition, yes, no, loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
231
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
232 def parse_switch(self):
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
233 loc = self.Consume('switch').loc
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
234 self.Consume('(')
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
235 condition = self.Expression()
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
236 self.Consume(')')
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
237 return Switch(condition, loc)
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
238
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
239 def parse_while(self):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
240 loc = self.Consume('while').loc
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
241 self.Consume('(')
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
242 condition = self.Expression()
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
243 self.Consume(')')
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
244 statements = self.Statement()
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
245 return While(condition, statements, loc)
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
246
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
247 def parse_for(self):
315
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
248 loc = self.Consume('for').loc
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
249 self.Consume('(')
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
250 init = self.Statement()
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
251 self.Consume(';')
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
252 condition = self.Expression()
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
253 self.Consume(';')
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
254 final = self.Statement()
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
255 self.Consume(')')
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
256 statements = self.Statement()
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
257 return For(init, condition, final, statements, loc)
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
258
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
259 def parseReturn(self):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
260 loc = self.Consume('return').loc
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
261 if self.Peak == ';':
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
262 expr = Literal(0, loc)
280
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
263 else:
02385f62f250 Rework from str interface to Instruction interface
Windel Bouwman
parents: 272
diff changeset
264 expr = self.Expression()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
265 self.Consume(';')
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
266 return Return(expr, loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
267
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
268 def parseCompound(self):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
269 self.Consume('{')
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
270 statements = []
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
271 while not self.hasConsumed('}'):
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
272 statements.append(self.Statement())
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
273 return Compound(statements)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
274
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
275 def Statement(self):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
276 # 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
277 if self.Peak == 'if':
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
278 return self.parse_if()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
279 elif self.Peak == 'while':
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
280 return self.parse_while()
315
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
281 elif self.Peak == 'for':
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
282 return self.parse_for()
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
283 elif self.Peak == 'switch':
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
284 return self.parse_switch()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
285 elif self.Peak == '{':
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
286 return self.parseCompound()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
287 elif self.hasConsumed(';'):
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
288 return Empty()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
289 elif self.Peak == 'var':
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
290 self.parse_variable_def()
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
291 return Empty()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
292 elif self.Peak == 'return':
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
293 return self.parseReturn()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
294 else:
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
295 x = self.UnaryExpression()
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
296 if self.Peak == '=':
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
297 # We enter assignment mode here.
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
298 loc = self.Consume('=').loc
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
299 rhs = self.Expression()
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
300 return Assignment(x, rhs, loc)
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
301 else:
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
302 return ExpressionStatement(x, x.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
303
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
304 # Expression section:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
305 # We not implement these C constructs:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
306 # a(2), f = 2
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
307 # and this:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
308 # a = 2 < x : 4 ? 1;
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
309
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
310 def Expression(self):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
311 exp = self.LogicalAndExpression()
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
312 while self.Peak == 'or':
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
313 loc = self.Consume('or').loc
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
314 e2 = self.LogicalAndExpression()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
315 exp = Binop(exp, 'or', e2, loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
316 return exp
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
317
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
318 def LogicalAndExpression(self):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
319 o = self.EqualityExpression()
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
320 while self.Peak == 'and':
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
321 loc = self.Consume('and').loc
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
322 o2 = self.EqualityExpression()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
323 o = Binop(o, 'and', o2, loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
324 return o
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
325
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
326 def EqualityExpression(self):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
327 ee = self.SimpleExpression()
300
Windel Bouwman
parents: 296
diff changeset
328 while self.Peak in ['<', '==', '>', '>=', '<=', '!=']:
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
329 op = self.Consume(self.Peak)
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
330 ee2 = self.SimpleExpression()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
331 ee = Binop(ee, op.typ, ee2, op.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
332 return ee
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
333
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
334 def SimpleExpression(self):
232
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
335 """ Shift operations before + and - ? """
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
336 e = self.AddExpression()
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
337 while self.Peak in ['>>', '<<']:
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
338 op = self.Consume(self.Peak)
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
339 e2 = self.AddExpression()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
340 e = Binop(e, op.typ, e2, op.loc)
232
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
341 return e
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
342
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
343 def AddExpression(self):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
344 e = self.Term()
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
345 while self.Peak in ['+', '-']:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
346 op = self.Consume(self.Peak)
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
347 e2 = self.Term()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
348 e = Binop(e, op.typ, e2, op.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
349 return e
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
350
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
351 def Term(self):
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
352 t = self.BitwiseOr()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
353 while self.Peak in ['*', '/']:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
354 op = self.Consume(self.Peak)
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
355 t2 = self.BitwiseOr()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
356 t = Binop(t, op.typ, t2, op.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
357 return t
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
358
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
359 def BitwiseOr(self):
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
360 a = self.BitwiseAnd()
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
361 while self.Peak == '|':
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
362 op = self.Consume(self.Peak)
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
363 b = self.BitwiseAnd()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
364 a = Binop(a, op.typ, b, op.loc)
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
365 return a
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
366
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
367 def BitwiseAnd(self):
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
368 a = self.CastExpression()
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
369 while self.Peak == '&':
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
370 op = self.Consume(self.Peak)
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
371 b = self.CastExpression()
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
372 a = Binop(a, op.typ, b, op.loc)
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
373 return a
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
374
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
375 # Domain of unary expressions:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
376
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
377 def CastExpression(self):
228
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
378 """
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
379 the C-style type cast conflicts with '(' expr ')'
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
380 so introduce extra keyword 'cast'
7f18ed9b6b7e Removal of emptystatement class
Windel Bouwman
parents: 227
diff changeset
381 """
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
382 if self.Peak == 'cast':
230
88a1e0baef65 Added some tests for IR-code
Windel Bouwman
parents: 228
diff changeset
383 loc = self.Consume('cast').loc
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
384 self.Consume('<')
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
385 t = self.parse_type_spec()
221
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
386 self.Consume('>')
848c4b15fd0b pointers
Windel Bouwman
parents: 220
diff changeset
387 self.Consume('(')
232
e621e3ba78d2 Added left shift instruction
Windel Bouwman
parents: 230
diff changeset
388 ce = self.Expression()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
389 self.Consume(')')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
390 return TypeCast(t, ce, loc)
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
391 elif self.Peak == 'sizeof':
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
392 return self.sizeof_expression()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
393 else:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
394 return self.UnaryExpression()
230
88a1e0baef65 Added some tests for IR-code
Windel Bouwman
parents: 228
diff changeset
395
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
396 def sizeof_expression(self):
394
988f3fb861e4 c3 code generator rewrite
Windel Bouwman
parents: 393
diff changeset
397 """ Compiler internal function to determine size of a type """
393
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
398 loc = self.Consume('sizeof').loc
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
399 self.Consume('(')
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
400 typ = self.parse_type_spec()
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
401 self.Consume(')')
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
402 return Sizeof(typ, loc)
6ae782a085e0 Added init program
Windel Bouwman
parents: 362
diff changeset
403
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
404 def UnaryExpression(self):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
405 if self.Peak in ['&', '*']:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
406 op = self.Consume(self.Peak)
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
407 ce = self.CastExpression()
225
1c7364bd74c7 Fixed pointer deref
Windel Bouwman
parents: 222
diff changeset
408 if op.val == '*':
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
409 return Deref(ce, op.loc)
225
1c7364bd74c7 Fixed pointer deref
Windel Bouwman
parents: 222
diff changeset
410 else:
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
411 return Unop(op.typ, ce, op.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
412 else:
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
413 return self.PostFixExpression()
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
414
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
415 def PostFixExpression(self):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
416 pfe = self.PrimaryExpression()
315
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
417 while self.Peak in ['[', '.', '->', '(', '++']:
308
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
418 if self.hasConsumed('['):
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
419 i = self.Expression()
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
420 self.Consume(']')
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
421 pfe = Index(pfe, i, i.loc)
308
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
422 elif self.hasConsumed('->'):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
423 field = self.Consume('ID')
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
424 pfe = Deref(pfe, pfe.loc)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
425 pfe = Member(pfe, field.val, field.loc)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
426 elif self.hasConsumed('.'):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
427 field = self.Consume('ID')
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
428 pfe = Member(pfe, field.val, field.loc)
315
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
429 elif self.Peak == '++':
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
430 loc = self.Consume('++').loc
084cccaa5deb Added console and screen
Windel Bouwman
parents: 313
diff changeset
431 pfe = Unop('++', pfe, loc)
308
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
432 elif self.hasConsumed('('):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
433 # Function call
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
434 args = []
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
435 if not self.hasConsumed(')'):
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
436 args.append(self.Expression())
308
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
437 while self.hasConsumed(','):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
438 args.append(self.Expression())
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
439 self.Consume(')')
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
440 pfe = FunctionCall(pfe, args, pfe.loc)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
441 else:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
442 raise Exception()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
443 return pfe
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
444
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
445 def PrimaryExpression(self):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
446 if self.hasConsumed('('):
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
447 e = self.Expression()
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
448 self.Consume(')')
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
449 return e
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
450 elif self.Peak == 'NUMBER':
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
451 val = self.Consume('NUMBER')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
452 return Literal(val.val, val.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
453 elif self.Peak == 'REAL':
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
454 val = self.Consume('REAL')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
455 return Literal(val.val, val.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
456 elif self.Peak == 'true':
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
457 val = self.Consume('true')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
458 return Literal(True, val.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
459 elif self.Peak == 'false':
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
460 val = self.Consume('false')
296
9417caea2eb3 Directorized some backend files
Windel Bouwman
parents: 293
diff changeset
461 return Literal(False, val.loc)
311
ff665880a6b0 Added testcase for kernel and userspace
Windel Bouwman
parents: 308
diff changeset
462 elif self.Peak == 'STRING':
ff665880a6b0 Added testcase for kernel and userspace
Windel Bouwman
parents: 308
diff changeset
463 val = self.Consume('STRING')
ff665880a6b0 Added testcase for kernel and userspace
Windel Bouwman
parents: 308
diff changeset
464 return Literal(val.val, val.loc)
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
465 elif self.Peak == 'ID':
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 301
diff changeset
466 return self.parseDesignator()
220
3f6c30a5d234 Major change in expression parsing to enable pointers and structs
Windel Bouwman
parents: 219
diff changeset
467 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
354
5477e499b039 Added some sort of string functionality
Windel Bouwman
parents: 336
diff changeset
468