annotate python/c3/parser.py @ 169:ee0d30533dae

Added more tests and improved the diagnostic update
author Windel Bouwman
date Sat, 23 Mar 2013 18:34:41 +0100
parents 0b5b2ee6b435
children 46d62dadd61b
rev   line source
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
1 from . import astnodes, lexer, semantics
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:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
10 """ Parses sourcecode into an abstract syntax tree (AST) """
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
11 def __init__(self, diag):
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
12 self.sema = semantics.Semantics(diag)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
13 self.diag = diag
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
14 def parseSource(self, source):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
15 self.initLex(source)
169
ee0d30533dae Added more tests and improved the diagnostic update
Windel Bouwman
parents: 167
diff changeset
16 self.sema.reinit()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
17 try:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
18 self.parsePackage()
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)
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
21 return self.sema.mod
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
22 def Error(self, msg):
152
b73bc14a3aa3 Light coupling ide and c3 frontend
Windel Bouwman
parents: 150
diff changeset
23 raise CompilerError(msg, self.token.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
24 # Lexer helpers:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
25 def Consume(self, typ):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
26 if self.Peak == typ:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
27 return self.NextToken()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
28 else:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
29 self.Error('Excected: "{0}", got "{1}"'.format(typ, self.Peak))
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
30 @property
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
31 def Peak(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
32 return self.token.typ
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
33 @property
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
34 def PeakPrec(self):
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
35 if self.Peak in binopPrecs:
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
36 return binopPrecs[self.Peak]
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
37 return -1
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
38 def hasConsumed(self, typ):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
39 if self.Peak == typ:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
40 self.Consume(typ)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
41 return True
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
42 return False
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
43 def NextToken(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
44 t = self.token
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
45 if t.typ != 'END':
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
46 self.token = self.tokens.__next__()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
47 return t
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
48 def initLex(self, source):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
49 self.tokens = lexer.tokenize(source) # Lexical stage
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
50 self.token = self.tokens.__next__()
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
51 def skipToSemi(self, tt):
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
52 while self.Peak != tt and self.Peak != 'END':
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
53 self.NextToken()
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
54 if self.Peak == tt:
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
55 self.Consume(tt)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
56
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
57 def parsePackage(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
58 self.Consume('package')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
59 name = self.Consume('ID')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
60 self.Consume(';')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
61 self.sema.handlePackage(name.val, name.loc)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
62 # TODO: parse uses
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
63 while self.Peak != 'END':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
64 self.parseTopLevel()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
65 self.Consume('END')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
66
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
67 def parseTopLevel(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
68 if self.Peak == 'function':
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
69 self.parseFunctionDefinition()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
70 elif self.Peak == 'var':
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
71 self.parseVarDef()
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
72 elif self.Peak == 'const':
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
73 self.parseConstDef()
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
74 else:
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
75 self.Error('Expected function or variable')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
76
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
77 def parseDesignator(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
78 """ A designator designates an object """
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
79 name = self.Consume('ID')
150
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
80 return self.sema.actOnDesignator(name.val, name.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
81
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
82 # Type system
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
83 def parseType(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
84 d = self.parseDesignator()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
85 return d
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
86
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
87 # Variable declarations:
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
88 def parseVarDef(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
89 self.Consume('var')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
90 t = self.parseType()
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
91 def parseVar():
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
92 name = self.Consume('ID')
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
93 ival = None
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
94 if self.hasConsumed('='):
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
95 ival = self.parseExpression()
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
96 self.sema.actOnVarDef(name.val, name.loc, t, ival)
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
97 parseVar()
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
98 while self.hasConsumed(','):
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
99 parseVar()
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
100 self.Consume(';')
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
101
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
102 def parseConstDef(self):
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
103 self.Consume('const')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
104 t = self.parseType()
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
105 def parseConst():
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
106 name = self.Consume('ID')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
107 self.Consume('=')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
108 val = self.parseExpression()
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
109 self.sema.actOnConstDef(name.val, name.loc, t, val)
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
110 parseConst()
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
111 while self.hasConsumed(','):
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
112 parseConst()
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
113 self.Consume(';')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
114
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
115 # Procedures
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
116 def parseFunctionDefinition(self):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
117 self.Consume('function')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
118 returntype = self.parseType()
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
119 pname = self.Consume('ID')
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
120 self.sema.actOnFuncDef1(pname.val, pname.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
121 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
122 parameters = []
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
123 if not self.hasConsumed(')'):
150
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
124 def parseParameter():
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
125 typ = self.parseType()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
126 name = self.Consume('ID')
150
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
127 parameters.append(self.sema.actOnParameter(name.val, name.loc, typ))
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
128 parseParameter()
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
129 while self.hasConsumed(','):
4ae0e02599de Added type check start and analyze phase
Windel Bouwman
parents: 149
diff changeset
130 parseParameter()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
131 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
132 body = self.parseCompoundStatement()
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
133 self.sema.actOnFuncDef2(parameters, returntype, body)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
134
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
135 # Statements:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
136 def parseAssignment(self, lval):
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
137 lval = self.sema.actOnVariableUse(lval, lval.loc)
164
e023d3ce1d63 Fix to loc of assignment
Windel Bouwman
parents: 163
diff changeset
138 loc = self.Consume('=').loc
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
139 rval = self.parseExpression()
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
140 self.Consume(';')
164
e023d3ce1d63 Fix to loc of assignment
Windel Bouwman
parents: 163
diff changeset
141 return self.sema.actOnAssignment(lval, rval, loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
142
167
0b5b2ee6b435 Added 2 unit tests
Windel Bouwman
parents: 166
diff changeset
143 def parseProcedureCall(self, func):
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
144 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
145 args = []
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
146 if not self.hasConsumed(')'):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
147 args.append(self.parseExpression())
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
148 while self.hasConsumed(','):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
149 args.append(self.parseExpression())
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
150 self.Consume(')')
167
0b5b2ee6b435 Added 2 unit tests
Windel Bouwman
parents: 166
diff changeset
151 return self.sema.actOnFunctionCall(func, args, func.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
152
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
153 def parseIfStatement(self):
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
154 loc = self.Consume('if').loc
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
155 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
156 condition = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
157 self.Consume(')')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
158 yes = self.parseCompoundStatement()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
159 if self.hasConsumed('else'):
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
160 no = self.parseCompoundStatement()
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
161 else:
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
162 no = astnodes.EmptyStatement()
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
163 return self.sema.actOnIfStatement(condition, yes, no, loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
164
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
165 def parseWhileStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
166 self.Consume('while')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
167 self.Consume('(')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
168 condition = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
169 self.Consume(')')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
170 statements = self.parseCompoundStatement()
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
171 return astnodes.WhileStatement(condition, statements)
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
172
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
173 def parseReturnStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
174 self.Consume('return')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
175 expr = self.parseExpression()
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
176 self.Consume(';')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
177 return astnodes.ReturnStatement(expr)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
178
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
179 def parseCompoundStatement(self):
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
180 self.Consume('{')
157
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
181 statements = []
8f3924b6076e Added some code generator things
Windel Bouwman
parents: 155
diff changeset
182 while not self.hasConsumed('}'):
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
183 s = self.parseStatement()
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
184 if not type(s) is astnodes.EmptyStatement:
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
185 statements.append(s)
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
186 return astnodes.CompoundStatement(statements)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
187
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
188 def parseStatement(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
189 # Determine statement type based on the pending token:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
190 if self.Peak == 'if':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
191 return self.parseIfStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
192 elif self.Peak == 'while':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
193 return self.parseWhileStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
194 elif self.Peak == '{':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
195 return self.parseCompoundStatement()
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
196 elif self.hasConsumed(';'):
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 152
diff changeset
197 return astnodes.EmptyStatement()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
198 elif self.Peak == 'var':
158
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
199 self.parseVarDef()
9683a4cd848f Added some functions for code generation
Windel Bouwman
parents: 157
diff changeset
200 return astnodes.EmptyStatement()
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
201 elif self.Peak == 'return':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
202 return self.parseReturnStatement()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
203 elif self.Peak == 'ID':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
204 designator = self.parseDesignator()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
205 if self.Peak == '(':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
206 return self.parseProcedureCall(designator)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
207 elif self.Peak == '=':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
208 return self.parseAssignment(designator)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
209 self.Error('Unable to determine statement')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
210
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
211 # Parsing expressions:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
212 def parseExpression(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
213 return self.parseBinopRhs(self.parsePrimary(), 0)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
214 def parsePrimary(self):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
215 if self.hasConsumed('('):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
216 e = self.parseExpression()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
217 self.Consume(')')
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
218 return e
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
219 elif self.Peak == 'NUMBER':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
220 val = self.Consume('NUMBER')
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
221 return self.sema.actOnNumber(val.val, val.loc)
163
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
222 elif self.Peak == 'REAL':
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
223 val = self.Consume('REAL')
8104fc8b5e90 Added visitor to c3
Windel Bouwman
parents: 158
diff changeset
224 return self.sema.actOnNumber(val.val, val.loc)
166
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
225 elif self.Peak == 'true':
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
226 val = self.Consume('true')
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
227 return self.sema.actOnNumber(True, val.loc)
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
228 elif self.Peak == 'false':
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
229 val = self.Consume('false')
da0087b82fbe Improved type checking
Windel Bouwman
parents: 165
diff changeset
230 return self.sema.actOnNumber(False, val.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
231 elif self.Peak == 'ID':
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
232 d = self.parseDesignator()
155
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 152
diff changeset
233 if self.Peak == '(':
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 152
diff changeset
234 return self.parseProcedureCall(d)
b28a11c01dbe Simplified IR classes
Windel Bouwman
parents: 152
diff changeset
235 else:
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents: 164
diff changeset
236 return self.sema.actOnVariableUse(d, d.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
237 self.Error('Expected NUM, ID or (expr), got {0}'.format(self.Peak))
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
238
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
239 def parseBinopRhs(self, lhs, min_prec):
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
240 while self.PeakPrec >= min_prec:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
241 op_prec = self.PeakPrec
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
242 op = self.Consume(self.Peak)
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
243 rhs = self.parsePrimary()
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
244 while self.PeakPrec > op_prec:
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
245 rhs = self.parseBinopRhs(rhs, self.PeakPrec)
149
74241ca312cc Fixes on parser and semantics
Windel Bouwman
parents: 148
diff changeset
246 lhs = self.sema.actOnBinop(lhs, op.typ, rhs, op.loc)
148
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
247 return lhs
e5263f74b287 Added c3 language frontend initial parser
Windel Bouwman
parents:
diff changeset
248