annotate python/c3/parser.py @ 219:1fa3e0050b49

Expanded ad hoc code generator
author Windel Bouwman
date Sat, 06 Jul 2013 12:38:09 +0200
parents c1ccb1cb4cef
children 3f6c30a5d234
rev   line source
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
1 from . import astnodes, lexer
152
b73bc14a3aa3 Light coupling ide and c3 frontend
Windel Bouwman
parents: 150
diff changeset
2 from ppci import CompilerError
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
3
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
4 # binop precedence for expressions:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
5 binopPrecs = {'or': 5, 'and': 10, \
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
6 '<': 20, '>': 20, '==': 20, '<=': 20, '>=': 20, '!=': 20, \
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
7 '+': 30, '-': 30, '*': 40, '/': 40 }
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
8
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
9 class Parser:
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
10 """ Parses sourcecode into an abstract syntax tree (AST) """
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
11 def __init__(self, diag):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
12 self.diag = diag
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
13
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
14 def parseSource(self, source):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
15 self.initLex(source)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
16 try:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
17 self.parsePackage()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
18 return self.mod
152
b73bc14a3aa3 Light coupling ide and c3 frontend
Windel Bouwman
parents: 150
diff changeset
19 except CompilerError as e:
b73bc14a3aa3 Light coupling ide and c3 frontend
Windel Bouwman
parents: 150
diff changeset
20 self.diag.addDiag(e)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
21 def Error(self, msg):
152
b73bc14a3aa3 Light coupling ide and c3 frontend
Windel Bouwman
parents: 150
diff changeset
22 raise CompilerError(msg, self.token.loc)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
23 # Lexer helpers:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
24 def Consume(self, typ):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
25 if self.Peak == typ:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
26 return self.NextToken()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
27 else:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
28 self.Error('Excected: "{0}", got "{1}"'.format(typ, self.Peak))
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
29 @property
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
30 def Peak(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
31 return self.token.typ
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
32 @property
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
33 def PeakPrec(self):
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
34 if self.Peak in binopPrecs:
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
35 return binopPrecs[self.Peak]
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
36 return -1
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
37 def hasConsumed(self, typ):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
38 if self.Peak == typ:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
39 self.Consume(typ)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
40 return True
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
41 return False
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
42
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
43 def NextToken(self):
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
44 t = self.token
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
45 if t.typ != 'END':
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
46 self.token = self.tokens.__next__()
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
47 return t
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
48
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
49 def initLex(self, source):
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
50 self.tokens = lexer.tokenize(source) # Lexical stage
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
51 self.token = self.tokens.__next__()
215
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
52 def addDeclaration(self, decl):
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
53 self.currentPart.declarations.append(decl)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
54
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
55 def parseUses(self):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
56 pass
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
57
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
58 def parsePackage(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
59 self.Consume('package')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
60 name = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
61 self.Consume(';')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
62 self.mod = astnodes.Package(name.val, name.loc)
215
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
63 self.currentPart = self.mod
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
64 self.parseUses()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
65 # TODO: parse uses
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
66 while self.Peak != 'END':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
67 self.parseTopLevel()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
68 self.Consume('END')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
69
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
70 def parseTopLevel(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
71 if self.Peak == 'function':
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
72 self.parseFunctionDef()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
73 elif self.Peak == 'var':
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
74 self.parseVarDef()
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
75 elif self.Peak == 'const':
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
76 self.parseConstDef()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
77 elif self.Peak == 'type':
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
78 self.parseTypeDef()
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
79 else:
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
80 self.Error('Expected function, var, const or type')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
81
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
82 def parseDesignator(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
83 """ A designator designates an object """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
84 name = self.Consume('ID')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
85 d = astnodes.Designator(name.val, name.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
86 return d
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
87
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
88 # Type system
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
89 def parseTypeSpec(self):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
90 # For now, do simple type spec, just parse an ID:
219
1fa3e0050b49 Expanded ad hoc code generator
Windel Bouwman
parents: 215
diff changeset
91 #return self.parseDesignator()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
92 if self.Peak == 'struct':
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
93 self.Consume('struct')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
94 self.Consume('{')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
95 mems = []
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
96 while self.Peak != '}':
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
97 mem_t = self.parseTypeSpec()
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
98 mem_n = self.Consume('ID')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
99 mems.append((mem_t, mem_n))
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
100 while self.hasConsumed(','):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
101 mem_n = self.Consume('ID')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
102 mems.append((mem_t, mem_n))
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
103 self.Consume(';')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
104 self.Consume('}')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
105 theT = astnodes.StructureType(mems)
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
106 else:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
107 theT = self.parseDesignator()
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
108 # Check for pointer suffix:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
109 while self.hasConsumed('*'):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
110 theT = astnodes.PointerType(theT)
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
111 return theT
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
112
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
113 def parseTypeDef(self):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
114 self.Consume('type')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
115 newtype = self.parseTypeSpec()
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
116 typename = self.Consume('ID')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
117 # TODO: action here :)
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
118 self.Consume(';')
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
119 return astnodes.DefinedType(typename, newtype)
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
120
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
121 # Variable declarations:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
122 def parseVarDef(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
123 self.Consume('var')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
124 t = self.parseTypeSpec()
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
125 def parseVar():
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
126 name = self.Consume('ID')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
127 v = astnodes.Variable(name.val, t)
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
128 v.loc = name.loc
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
129 if self.hasConsumed('='):
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
130 v.ival = self.parseExpression()
215
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
131 self.addDeclaration(v)
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
132 parseVar()
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
133 while self.hasConsumed(','):
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
134 parseVar()
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
135 self.Consume(';')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
136
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
137 def parseConstDef(self):
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
138 self.Consume('const')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
139 t = self.parseTypeSpec()
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
140 def parseConst():
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
141 name = self.Consume('ID')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
142 self.Consume('=')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
143 val = self.parseExpression()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
144 c = astnodes.Constant(name.val, t, val)
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
145 c.loc = name.loc
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
146 parseConst()
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
147 while self.hasConsumed(','):
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
148 parseConst()
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
149 self.Consume(';')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
150
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
151 # Procedures
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
152 def parseFunctionDef(self):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
153 loc = self.Consume('function').loc
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
154 returntype = self.parseTypeSpec()
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
155 fname = self.Consume('ID').val
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
156 f = astnodes.Function(fname, loc)
215
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
157 self.addDeclaration(f)
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
158 savePart = self.currentPart
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
159 self.currentPart = f
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
160 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
161 parameters = []
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
162 if not self.hasConsumed(')'):
150
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
163 def parseParameter():
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
164 typ = self.parseTypeSpec()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
165 name = self.Consume('ID')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
166 param = astnodes.Variable(name.val, typ)
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
167 param.loc = name.loc
215
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
168 self.addDeclaration(param)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
169 parameters.append(param)
150
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
170 parseParameter()
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
171 while self.hasConsumed(','):
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
172 parseParameter()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
173 self.Consume(')')
215
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
174 paramtypes = [p.typ for p in parameters]
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
175 f.typ = astnodes.FunctionType(paramtypes, returntype)
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
176 f.body = self.parseCompoundStatement()
c1ccb1cb4cef Major changes in c3 frontend
Windel Bouwman
parents: 213
diff changeset
177 self.currentPart = savePart
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 # Statements:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
180 def parseAssignment(self, lval):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
181 lval = astnodes.VariableUse(lval, lval.loc)
164
e023d3ce1d63 Fix to loc of assignment
Windel Bouwman
parents: 163
diff changeset
182 loc = self.Consume('=').loc
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
183 rval = self.parseExpression()
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
184 self.Consume(';')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
185 return astnodes.Assignment(lval, rval, loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
186
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
187 def parseCall(self, func):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
188 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
189 args = []
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
190 if not self.hasConsumed(')'):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
191 args.append(self.parseExpression())
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
192 while self.hasConsumed(','):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
193 args.append(self.parseExpression())
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
194 self.Consume(')')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
195 return astnodes.FunctionCall(func, args, func.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
196
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
197 def parseIfStatement(self):
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
198 loc = self.Consume('if').loc
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
199 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
200 condition = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
201 self.Consume(')')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
202 yes = self.parseCompoundStatement()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
203 if self.hasConsumed('else'):
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
204 no = self.parseCompoundStatement()
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
205 else:
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
206 no = astnodes.EmptyStatement()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
207 return astnodes.IfStatement(condition, yes, no, loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
208
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
209 def parseWhileStatement(self):
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
210 loc = self.Consume('while').loc
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
211 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
212 condition = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
213 self.Consume(')')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
214 statements = self.parseCompoundStatement()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
215 return astnodes.WhileStatement(condition, statements, loc)
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
216
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
217 def parseReturnStatement(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
218 self.Consume('return')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
219 expr = self.parseExpression()
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
220 self.Consume(';')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
221 return astnodes.ReturnStatement(expr)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
222
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
223 def parseCompoundStatement(self):
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
224 self.Consume('{')
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
225 statements = []
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
226 while not self.hasConsumed('}'):
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
227 s = self.parseStatement()
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
228 if not type(s) is astnodes.EmptyStatement:
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
229 statements.append(s)
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
230 return astnodes.CompoundStatement(statements)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
231
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
232 def parseStatement(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
233 # Determine statement type based on the pending token:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
234 if self.Peak == 'if':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
235 return self.parseIfStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
236 elif self.Peak == 'while':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
237 return self.parseWhileStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
238 elif self.Peak == '{':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
239 return self.parseCompoundStatement()
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
240 elif self.hasConsumed(';'):
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 152
diff changeset
241 return astnodes.EmptyStatement()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
242 elif self.Peak == 'var':
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
243 self.parseVarDef()
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
244 return astnodes.EmptyStatement()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
245 elif self.Peak == 'return':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
246 return self.parseReturnStatement()
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
247 else:
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
248 designator = self.parseDesignator()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
249 if self.Peak == '(':
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
250 return self.parseCall(designator)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
251 elif self.Peak == '=':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
252 return self.parseAssignment(designator)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
253 else:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
254 self.Error('Unable to determine statement')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
255
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
256 # Parsing expressions:
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
257 def parseExpression(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
258 return self.parseBinopRhs(self.parsePrimary(), 0)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
259
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
260 def parsePrimary(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
261 if self.hasConsumed('('):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
262 e = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
263 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
264 return e
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
265 elif self.Peak == 'NUMBER':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
266 val = self.Consume('NUMBER')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
267 return astnodes.Literal(val.val, val.loc)
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
268 elif self.Peak == 'REAL':
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
269 val = self.Consume('REAL')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
270 return astnodes.Literal(val.val, val.loc)
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
271 elif self.Peak == 'true':
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
272 val = self.Consume('true')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
273 return astnodes.Literal(True, val.loc)
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
274 elif self.Peak == 'false':
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
275 val = self.Consume('false')
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
276 return astnodes.Literal(False, val.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
277 elif self.Peak == 'ID':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
278 d = self.parseDesignator()
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 152
diff changeset
279 if self.Peak == '(':
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
280 return self.parseCall(d)
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 152
diff changeset
281 else:
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
282 return astnodes.VariableUse(d, d.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
283 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
284
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
285 def parseBinopRhs(self, lhs, min_prec):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
286 while self.PeakPrec >= min_prec:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
287 op_prec = self.PeakPrec
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
288 op = self.Consume(self.Peak)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
289 rhs = self.parsePrimary()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
290 while self.PeakPrec > op_prec:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
291 rhs = self.parseBinopRhs(rhs, self.PeakPrec)
213
003c8a976fff Merge of semantics and parser again ..
Windel Bouwman
parents: 186
diff changeset
292 lhs = astnodes.Binop(lhs, op.typ, rhs, op.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
293 return lhs
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
294