Mercurial > projects > dang
annotate parser/Parser.d @ 28:69464d465284 new_gen
Now supporting structs - both read and write. Still a few errors though, so watch out.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Sun, 20 Apr 2008 11:20:28 +0200 |
parents | e331e4e816e4 |
children | 41d23f2762c3 |
rev | line source |
---|---|
1 | 1 module parser.Parser; |
2 | |
3 import lexer.Lexer, | |
4 lexer.Token; | |
5 | |
6 import ast.Exp, | |
7 ast.Stmt, | |
8 ast.Decl; | |
9 | |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
10 import misc.Error; |
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
11 |
1 | 12 import tango.io.Stdout, |
13 Integer = tango.text.convert.Integer; | |
14 | |
15 class Parser | |
16 { | |
17 | |
18 public: | |
19 Decl[] parse(Lexer lexer) | |
20 { | |
21 this.lexer = lexer; | |
22 | |
23 | |
24 Decl[] declarations; | |
25 | |
26 while(lexer.peek.type != Tok.EOF) | |
27 { | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
28 declarations ~= parseRootDecl; |
1 | 29 } |
30 | |
31 return declarations; | |
32 } | |
33 | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
34 Decl parseRootDecl() |
1 | 35 { |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
36 Token t = lexer.peek; |
1 | 37 |
38 switch(t.type) | |
39 { | |
40 case Tok.Byte, Tok.Ubyte, | |
41 Tok.Short, Tok.Ushort, | |
42 Tok.Int, Tok.Uint, | |
43 Tok.Long, Tok.Ulong, | |
44 Tok.Float, Tok.Double, | |
12
6282db07115f
Added some ekstra tests, and allowed bool as a type
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
45 Tok.Bool, |
1 | 46 Tok.Identifier: |
47 Identifier type = new Identifier(t); | |
48 | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
49 Token iden = lexer.peek(1); |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
50 |
1 | 51 switch(iden.type) |
52 { | |
53 case Tok.Identifier: | |
54 Identifier identifier = new Identifier(iden); | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
55 Token p = lexer.peek(2); |
1 | 56 switch(p.type) |
57 { | |
58 case Tok.OpenParentheses: | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
59 lexer.next; lexer.next; |
1 | 60 return parseFunc(type, identifier); |
61 case Tok.Seperator: | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
62 lexer.next; lexer.next; |
1 | 63 require(Tok.Seperator); |
64 return new VarDecl(type, identifier, null); | |
65 case Tok.Assign: | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
66 lexer.next; lexer.next; |
1 | 67 lexer.next(); |
68 auto exp = parseExpression(); | |
69 require(Tok.Seperator); | |
70 return new VarDecl(type, identifier, exp); | |
71 default: | |
72 char[] c = t.getType; | |
73 error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__)); | |
74 } | |
75 break; | |
76 default: | |
77 char[] c = t.getType; | |
78 error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__)); | |
79 } | |
80 break; | |
22 | 81 case Tok.Struct: |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
82 lexer.next; |
22 | 83 Token iden = lexer.next; |
84 switch(iden.type) | |
85 { | |
86 case Tok.Identifier: | |
87 Identifier identifier = new Identifier(iden); | |
88 return new StructDecl (identifier, parseStruct()); | |
89 default: | |
90 throw new Error("Expected struct identifier, but got "~iden.getType, | |
91 iden.location); | |
92 } | |
1 | 93 case Tok.EOF: |
94 return null; | |
95 default: | |
96 char[] c = t.getType; | |
97 error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__)); | |
98 } | |
99 } | |
100 | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
101 Decl parseDecl() |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
102 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
103 Token t = lexer.peek; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
104 |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
105 switch(t.type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
106 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
107 case Tok.Byte, Tok.Ubyte, |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
108 Tok.Short, Tok.Ushort, |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
109 Tok.Int, Tok.Uint, |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
110 Tok.Long, Tok.Ulong, |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
111 Tok.Float, Tok.Double, |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
112 Tok.Bool, |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
113 Tok.Identifier: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
114 Identifier type = new Identifier(t); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
115 |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
116 Token iden = lexer.peek(1); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
117 |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
118 switch(iden.type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
119 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
120 case Tok.Identifier: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
121 Identifier identifier = new Identifier(iden); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
122 Token p = lexer.peek(2); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
123 switch(p.type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
124 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
125 case Tok.OpenParentheses: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
126 lexer.next; lexer.next; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
127 return parseFunc(type, identifier); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
128 case Tok.Seperator: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
129 lexer.next; lexer.next; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
130 require(Tok.Seperator); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
131 return new VarDecl(type, identifier, null); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
132 case Tok.Assign: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
133 lexer.next; lexer.next; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
134 lexer.next(); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
135 auto exp = parseExpression(); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
136 require(Tok.Seperator); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
137 return new VarDecl(type, identifier, exp); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
138 default: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
139 char[] c = t.getType; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
140 error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__)); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
141 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
142 break; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
143 default: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
144 char[] c = t.getType; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
145 error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__)); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
146 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
147 break; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
148 case Tok.EOF: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
149 return null; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
150 default: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
151 char[] c = t.getType; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
152 error("Unexpexted token "~c~" at line "~Integer.toString(__LINE__)); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
153 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
154 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
155 |
22 | 156 VarDecl[] parseStruct() |
157 { | |
158 VarDecl[] varDecls; | |
159 require(Tok.OpenBrace); | |
160 while(lexer.peek.type != Tok.CloseBrace) | |
161 { | |
162 varDecls ~= cast(VarDecl)parseDecl; | |
163 } | |
164 | |
165 require(Tok.CloseBrace); | |
166 return varDecls; | |
167 } | |
168 | |
1 | 169 Stmt parseStatement() |
170 { | |
171 Token t = lexer.peek; | |
172 | |
173 switch(t.type) | |
174 { | |
175 case Tok.Return: | |
176 lexer.next; | |
177 auto ret = new ReturnStmt(); | |
178 ret.exp = parseExpression(); | |
179 require(Tok.Seperator); | |
180 return ret; | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
181 |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
182 case Tok.If: |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
183 lexer.next; |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
184 require(Tok.OpenParentheses); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
185 auto condition = parseExpression(); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
186 require(Tok.CloseParentheses); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
187 |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
188 auto then_body = parseBlockOrSingleStmt(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
189 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
190 Stmt[] else_body; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
191 if (lexer.peek.type == Tok.Else) |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
192 { |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
193 lexer.next; |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
194 else_body = parseBlockOrSingleStmt(); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
195 } |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
196 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
197 return new IfStmt(condition, then_body, else_body); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
198 |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
199 case Tok.While: |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
200 lexer.next; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
201 require(Tok.OpenParentheses); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
202 auto condition = parseExpression(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
203 require(Tok.CloseParentheses); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
204 return new WhileStmt(condition, parseBlockOrSingleStmt()); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
205 |
1 | 206 case Tok.Identifier: |
207 Token n = lexer.peek(1); | |
208 switch(n.type) | |
209 { | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
210 case Tok.Dot: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
211 Exp iden = parseExpIdentifier(new Identifier(lexer.next)); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
212 switch(lexer.peek.type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
213 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
214 case Tok.Assign: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
215 lexer.next; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
216 auto stmt = new ExpStmt(new AssignExp(iden , parseExpression())); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
217 require(Tok.Seperator); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
218 return stmt; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
219 break; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
220 } |
1 | 221 case Tok.Assign: |
222 lexer.next; | |
223 lexer.next; | |
224 auto stmt = new ExpStmt(new AssignExp(new Identifier(t), parseExpression())); | |
225 require(Tok.Seperator); | |
226 return stmt; | |
227 break; | |
22 | 228 case Tok.Identifier: |
229 auto decl = new DeclStmt(parseDecl()); | |
230 return decl; | |
1 | 231 |
232 default: | |
233 auto e = new ExpStmt(parseExpression()); | |
234 require(Tok.Seperator); | |
235 return e; | |
236 | |
237 } | |
238 break; | |
239 | |
240 default: | |
241 auto decl = new DeclStmt(parseDecl()); | |
242 //require(Tok.Seperator); | |
243 return decl; | |
244 } | |
245 return new Stmt(); | |
246 } | |
247 | |
248 FuncDecl parseFunc(Identifier type, Identifier identifier) | |
249 { | |
250 VarDecl[] funcArgs = parseFuncArgs(); | |
251 | |
252 lexer.next; // Remove the "{" | |
253 | |
254 Stmt[] statements; | |
255 | |
256 while(lexer.peek.type != Tok.CloseBrace) | |
257 statements ~= parseStatement(); | |
258 | |
259 lexer.next; // Remove "}" | |
260 | |
261 return new FuncDecl(type, identifier, funcArgs, statements); | |
262 } | |
263 | |
264 VarDecl[] parseFuncArgs() | |
265 { | |
266 lexer.next; // Remove the "(" token. | |
267 | |
268 VarDecl[] funcArgs; | |
269 | |
270 while(lexer.peek.type != Tok.CloseParentheses) | |
271 { | |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
272 auto t = parseType; |
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
273 auto i = parseIdentifier; |
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
274 funcArgs ~= new VarDecl(t, i); |
1 | 275 |
276 if(lexer.peek.type == Tok.Comma) | |
277 lexer.next; | |
278 } | |
279 | |
280 lexer.next; // Remove the ")" | |
281 | |
282 return funcArgs; | |
283 } | |
284 | |
285 Identifier parseIdentifier() | |
286 { | |
287 Token identifier = lexer.next; | |
288 | |
289 switch(identifier.type) | |
290 { | |
291 case Tok.Identifier: | |
292 return new Identifier(identifier); | |
293 break; | |
294 default: | |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
295 throw new Error("Unexpexted token in Identifier parsing. Got "~identifier.getType, identifier.location); |
1 | 296 } |
297 } | |
298 | |
299 Identifier parseType() | |
300 { | |
301 Token type = lexer.next; | |
302 | |
303 switch(type.type) | |
304 { | |
305 case Tok.Byte, Tok.Ubyte, | |
306 Tok.Short, Tok.Ushort, | |
307 Tok.Int, Tok.Uint, | |
308 Tok.Long, Tok.Ulong, | |
309 Tok.Float, Tok.Double, | |
12
6282db07115f
Added some ekstra tests, and allowed bool as a type
Anders Halager <halager@gmail.com>
parents:
11
diff
changeset
|
310 Tok.Bool, |
1 | 311 Tok.Identifier: |
312 return new Identifier(type); | |
313 break; | |
314 default: | |
315 char[] c = type.getType; | |
316 error("Unexpexted token in Type parsing. Got "~c); | |
317 } | |
318 } | |
319 | |
320 // -- Expression parsing -- // | |
321 private: | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
322 Exp parseExpIdentifier(Exp target) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
323 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
324 switch(lexer.peek.type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
325 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
326 case Tok.Dot: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
327 switch(lexer.peek(1).type) |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
328 { |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
329 case Tok.Identifier: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
330 lexer.next; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
331 return parseExpIdentifier( |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
332 new MemberLookup(target, new Identifier(lexer.next))); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
333 default: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
334 throw new Error("Expected identifier after '.'", lexer.peek(1).location); |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
335 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
336 default: |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
337 return target; |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
338 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
339 } |
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
340 |
1 | 341 Exp parseExpression(int p = 0) |
342 { | |
343 auto exp = P(); | |
344 Token next = lexer.peek(); | |
345 BinOp* op = null; | |
346 while ((op = binary(next.type)) != null && op.prec >= p) | |
347 { | |
348 lexer.next(); | |
349 int q = op.leftAssoc? 1 + op.prec : op.prec; | |
350 auto exp2 = parseExpression(q); | |
351 exp = new BinaryExp(op.operator, exp, exp2); | |
352 next = lexer.peek(); | |
353 } | |
354 | |
355 return exp; | |
356 } | |
357 | |
358 Exp P() | |
359 { | |
360 Token next = lexer.next(); | |
361 if (auto op = unary(next.type)) | |
362 return new NegateExp(parseExpression(op.prec)); | |
363 else if (next.type == Tok.OpenParentheses) | |
364 { | |
365 auto e = parseExpression(0); | |
366 require(Tok.CloseParentheses); | |
367 return e; | |
368 } | |
369 else if (next.type == Tok.Identifier) | |
370 { | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
371 Exp iden = parseExpIdentifier(new Identifier(next)); |
1 | 372 switch(lexer.peek.type) |
373 { | |
374 case Tok.OpenParentheses: | |
375 lexer.next; | |
376 Exp[] args; | |
377 while(lexer.peek.type != Tok.CloseParentheses) | |
378 { | |
379 if(lexer.peek.type == Tok.Comma) | |
380 { | |
381 lexer.next; | |
382 } | |
383 args ~= parseExpression(); | |
384 } | |
385 | |
386 lexer.next(); | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
387 return new CallExp(iden, args); |
1 | 388 |
389 default: | |
28
69464d465284
Now supporting structs - both read and write. Still a few errors though, so watch out.
Anders Johnsen <skabet@gmail.com>
parents:
22
diff
changeset
|
390 return iden; |
1 | 391 } |
392 } | |
393 else if (next.type == Tok.Integer) | |
394 return new IntegerLit(next); | |
395 | |
396 Stdout.formatln("{}", next.getType); | |
397 assert(0, "Should not happen"); | |
398 } | |
399 | |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
400 private Stmt[] parseBlockOrSingleStmt() |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
401 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
402 Stmt[] stmts; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
403 if (lexer.peek.type == Tok.OpenBrace) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
404 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
405 lexer.next; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
406 while(lexer.peek.type != Tok.CloseBrace) |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
407 stmts ~= parseStatement(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
408 lexer.next; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
409 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
410 else |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
411 stmts ~= parseStatement(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
412 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
413 return stmts; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
414 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
415 |
1 | 416 struct UnOp |
417 { | |
418 Tok tokenType; | |
419 int prec; | |
420 } | |
421 | |
422 static UnOp[] _unary = [{Tok.Sub, 4}]; | |
423 UnOp* unary(Tok t) | |
424 { | |
425 foreach (ref op; _unary) | |
426 if (op.tokenType == t) | |
427 return &op; | |
428 return null; | |
429 } | |
430 | |
431 struct BinOp | |
432 { | |
433 Tok tokenType; | |
434 int prec; | |
435 bool leftAssoc; | |
436 BinaryExp.Operator operator; | |
437 } | |
438 | |
439 static BinOp[] _binary = | |
440 [ | |
10
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
441 {Tok.Eq, 2, true, BinaryExp.Operator.Eq}, |
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
442 {Tok.Ne, 2, true, BinaryExp.Operator.Ne}, |
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
443 {Tok.Lt, 2, true, BinaryExp.Operator.Lt}, |
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
444 {Tok.Le, 2, true, BinaryExp.Operator.Le}, |
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
445 {Tok.Gt, 2, true, BinaryExp.Operator.Gt}, |
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
446 {Tok.Ge, 2, true, BinaryExp.Operator.Ge}, |
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
447 |
7
2ce5209f1954
Starting to work on bool support, for now == works
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
448 {Tok.Add, 3, true, BinaryExp.Operator.Add}, |
2ce5209f1954
Starting to work on bool support, for now == works
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
449 {Tok.Sub, 3, true, BinaryExp.Operator.Sub}, |
10
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
450 |
7
2ce5209f1954
Starting to work on bool support, for now == works
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
451 {Tok.Mul, 5, true, BinaryExp.Operator.Mul}, |
2ce5209f1954
Starting to work on bool support, for now == works
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
452 {Tok.Div, 5, true, BinaryExp.Operator.Div} |
1 | 453 ]; |
454 BinOp* binary(Tok t) | |
455 { | |
456 foreach (ref op; _binary) | |
457 if (op.tokenType == t) | |
458 return &op; | |
459 return null; | |
460 } | |
461 | |
462 private: | |
463 | |
464 void require(Tok t) | |
465 { | |
466 if (lexer.peek().type != t) | |
467 error("Unexpexted token: Got '"~lexer.peek.getType~"' Expected '"~typeToString[t]~"'"); | |
468 lexer.next(); | |
469 } | |
470 | |
471 void error(char[] errMsg) | |
472 { | |
473 throw new Exception("Parser error: " ~errMsg); | |
474 } | |
475 | |
476 Lexer lexer; | |
477 } |