Mercurial > projects > dang
annotate parser/Parser.d @ 33:084c2c147c4f new_gen
Improvements to the Error class.
* Now takes tokens instead of locations (a single loc can still be given)
* Some of the arg functions take arrays now
* Output is much better. Will print the line with all tokens given marked
author | Anders Halager <halager@gmail.com> |
---|---|
date | Sun, 20 Apr 2008 13:59:20 +0200 |
parents | 3147a52d1247 |
children | ce17bea8e9bd |
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: | |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
72 char[] c = p.getType; |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
73 throw error(__LINE__, UnexpextedTokMulti) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
74 .tok(p) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
75 .arg(c) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
76 .arg(Tok.OpenParentheses, Tok.Seperator, Tok.Assign); |
1 | 77 } |
78 break; | |
79 default: | |
80 char[] c = t.getType; | |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
81 throw error(__LINE__, UnexpextedTok).tok(iden).arg(c); |
1 | 82 } |
83 break; | |
22 | 84 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
|
85 lexer.next; |
22 | 86 Token iden = lexer.next; |
87 switch(iden.type) | |
88 { | |
89 case Tok.Identifier: | |
90 Identifier identifier = new Identifier(iden); | |
91 return new StructDecl (identifier, parseStruct()); | |
92 default: | |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
93 throw error(__LINE__, "Expected struct identifier, but got %0").arg(iden.getType); |
22 | 94 } |
1 | 95 case Tok.EOF: |
96 return null; | |
97 default: | |
98 char[] c = t.getType; | |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
99 throw error(__LINE__, UnexpextedTok).tok(t).arg(c); |
1 | 100 } |
101 } | |
102 | |
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
|
103 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
|
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 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
|
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 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
|
108 { |
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 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
|
110 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
|
111 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
|
112 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
|
113 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
|
114 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
|
115 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
|
116 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
|
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 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
|
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 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
|
121 { |
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 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
|
123 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
|
124 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
|
125 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
|
126 { |
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 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
|
128 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
|
129 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
|
130 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
|
131 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
|
132 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
|
133 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
|
134 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
|
135 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
|
136 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
|
137 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
|
138 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
|
139 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
|
140 default: |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
141 char[] c = p.getType; |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
142 throw error(__LINE__, UnexpextedTokMulti) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
143 .tok(p) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
144 .arg(c) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
145 .arg(Tok.OpenParentheses, Tok.Seperator, 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
|
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 default: |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
149 char[] c = iden.getType; |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
150 throw error(__LINE__, UnexpextedTokSingle) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
151 .tok(iden) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
152 .arg(c) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
153 .arg(Tok.Identifier); |
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
|
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 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
|
156 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
|
157 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
|
158 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
|
159 char[] c = t.getType; |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
160 throw error(__LINE__, UnexpextedTok).arg(c); |
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
|
161 } |
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
|
162 } |
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
|
163 |
22 | 164 VarDecl[] parseStruct() |
165 { | |
166 VarDecl[] varDecls; | |
167 require(Tok.OpenBrace); | |
168 while(lexer.peek.type != Tok.CloseBrace) | |
169 { | |
170 varDecls ~= cast(VarDecl)parseDecl; | |
171 } | |
172 | |
173 require(Tok.CloseBrace); | |
174 return varDecls; | |
175 } | |
176 | |
1 | 177 Stmt parseStatement() |
178 { | |
179 Token t = lexer.peek; | |
180 | |
181 switch(t.type) | |
182 { | |
183 case Tok.Return: | |
184 lexer.next; | |
185 auto ret = new ReturnStmt(); | |
186 ret.exp = parseExpression(); | |
187 require(Tok.Seperator); | |
188 return ret; | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
189 |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
190 case Tok.If: |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
191 lexer.next; |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
192 require(Tok.OpenParentheses); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
193 auto condition = parseExpression(); |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
194 require(Tok.CloseParentheses); |
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 auto then_body = parseBlockOrSingleStmt(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
197 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
198 Stmt[] else_body; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
199 if (lexer.peek.type == Tok.Else) |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
200 { |
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
201 lexer.next; |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
202 else_body = parseBlockOrSingleStmt(); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
203 } |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
204 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
205 return new IfStmt(condition, then_body, else_body); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
206 |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
207 case Tok.While: |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
208 lexer.next; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
209 require(Tok.OpenParentheses); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
210 auto condition = parseExpression(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
211 require(Tok.CloseParentheses); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
212 return new WhileStmt(condition, parseBlockOrSingleStmt()); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
213 |
1 | 214 case Tok.Identifier: |
215 Token n = lexer.peek(1); | |
216 switch(n.type) | |
217 { | |
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
|
218 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
|
219 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
|
220 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
|
221 { |
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
|
222 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
|
223 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
|
224 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
|
225 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
|
226 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
|
227 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
|
228 } |
1 | 229 case Tok.Assign: |
230 lexer.next; | |
231 lexer.next; | |
232 auto stmt = new ExpStmt(new AssignExp(new Identifier(t), parseExpression())); | |
233 require(Tok.Seperator); | |
234 return stmt; | |
235 break; | |
22 | 236 case Tok.Identifier: |
237 auto decl = new DeclStmt(parseDecl()); | |
238 return decl; | |
1 | 239 |
240 default: | |
241 auto e = new ExpStmt(parseExpression()); | |
242 require(Tok.Seperator); | |
243 return e; | |
244 | |
245 } | |
246 break; | |
247 | |
248 default: | |
249 auto decl = new DeclStmt(parseDecl()); | |
250 //require(Tok.Seperator); | |
251 return decl; | |
252 } | |
253 return new Stmt(); | |
254 } | |
255 | |
256 FuncDecl parseFunc(Identifier type, Identifier identifier) | |
257 { | |
258 VarDecl[] funcArgs = parseFuncArgs(); | |
259 | |
260 lexer.next; // Remove the "{" | |
261 | |
262 Stmt[] statements; | |
263 | |
264 while(lexer.peek.type != Tok.CloseBrace) | |
265 statements ~= parseStatement(); | |
266 | |
267 lexer.next; // Remove "}" | |
268 | |
269 return new FuncDecl(type, identifier, funcArgs, statements); | |
270 } | |
271 | |
272 VarDecl[] parseFuncArgs() | |
273 { | |
274 lexer.next; // Remove the "(" token. | |
275 | |
276 VarDecl[] funcArgs; | |
277 | |
278 while(lexer.peek.type != Tok.CloseParentheses) | |
279 { | |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
280 auto t = parseType; |
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
281 auto i = parseIdentifier; |
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
282 funcArgs ~= new VarDecl(t, i); |
1 | 283 |
284 if(lexer.peek.type == Tok.Comma) | |
285 lexer.next; | |
286 } | |
287 | |
288 lexer.next; // Remove the ")" | |
289 | |
290 return funcArgs; | |
291 } | |
292 | |
293 Identifier parseIdentifier() | |
294 { | |
295 Token identifier = lexer.next; | |
296 | |
297 switch(identifier.type) | |
298 { | |
299 case Tok.Identifier: | |
300 return new Identifier(identifier); | |
301 break; | |
302 default: | |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
303 throw error(__LINE__, "Unexpexted token in Identifier parsing. Got %0") |
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
304 .arg(identifier.getType) |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
305 .tok(identifier); |
1 | 306 } |
307 } | |
308 | |
309 Identifier parseType() | |
310 { | |
311 Token type = lexer.next; | |
312 | |
313 switch(type.type) | |
314 { | |
315 case Tok.Byte, Tok.Ubyte, | |
316 Tok.Short, Tok.Ushort, | |
317 Tok.Int, Tok.Uint, | |
318 Tok.Long, Tok.Ulong, | |
319 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
|
320 Tok.Bool, |
1 | 321 Tok.Identifier: |
322 return new Identifier(type); | |
323 break; | |
324 default: | |
325 char[] c = type.getType; | |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
326 error(__LINE__, "Unexpexted token in Type parsing. Got %0").arg(c); |
1 | 327 } |
328 } | |
329 | |
330 // -- Expression parsing -- // | |
331 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
|
332 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
|
333 { |
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 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
|
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 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
|
337 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
|
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 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
|
340 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
|
341 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
|
342 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
|
343 default: |
30
3147a52d1247
Ooops.. should have compiled before commit.. now works again
Anders Halager <halager@gmail.com>
parents:
29
diff
changeset
|
344 Token t = lexer.peek(1); |
3147a52d1247
Ooops.. should have compiled before commit.. now works again
Anders Halager <halager@gmail.com>
parents:
29
diff
changeset
|
345 throw error(__LINE__, "Expected identifier after '.'", &t); |
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
|
346 } |
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
|
347 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
|
348 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
|
349 } |
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
|
350 } |
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
|
351 |
1 | 352 Exp parseExpression(int p = 0) |
353 { | |
354 auto exp = P(); | |
355 Token next = lexer.peek(); | |
356 BinOp* op = null; | |
357 while ((op = binary(next.type)) != null && op.prec >= p) | |
358 { | |
359 lexer.next(); | |
360 int q = op.leftAssoc? 1 + op.prec : op.prec; | |
361 auto exp2 = parseExpression(q); | |
362 exp = new BinaryExp(op.operator, exp, exp2); | |
363 next = lexer.peek(); | |
364 } | |
365 | |
366 return exp; | |
367 } | |
368 | |
369 Exp P() | |
370 { | |
371 Token next = lexer.next(); | |
372 if (auto op = unary(next.type)) | |
373 return new NegateExp(parseExpression(op.prec)); | |
374 else if (next.type == Tok.OpenParentheses) | |
375 { | |
376 auto e = parseExpression(0); | |
377 require(Tok.CloseParentheses); | |
378 return e; | |
379 } | |
380 else if (next.type == Tok.Identifier) | |
381 { | |
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
|
382 Exp iden = parseExpIdentifier(new Identifier(next)); |
1 | 383 switch(lexer.peek.type) |
384 { | |
385 case Tok.OpenParentheses: | |
386 lexer.next; | |
387 Exp[] args; | |
388 while(lexer.peek.type != Tok.CloseParentheses) | |
389 { | |
390 if(lexer.peek.type == Tok.Comma) | |
391 { | |
392 lexer.next; | |
393 } | |
394 args ~= parseExpression(); | |
395 } | |
396 | |
397 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
|
398 return new CallExp(iden, args); |
1 | 399 |
400 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
|
401 return iden; |
1 | 402 } |
403 } | |
404 else if (next.type == Tok.Integer) | |
405 return new IntegerLit(next); | |
406 | |
407 Stdout.formatln("{}", next.getType); | |
408 assert(0, "Should not happen"); | |
409 } | |
410 | |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
411 private Stmt[] parseBlockOrSingleStmt() |
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 Stmt[] stmts; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
414 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
|
415 { |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
416 lexer.next; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
417 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
|
418 stmts ~= parseStatement(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
419 lexer.next; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
420 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
421 else |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
422 stmts ~= parseStatement(); |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
423 |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
424 return stmts; |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
425 } |
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
426 |
1 | 427 struct UnOp |
428 { | |
429 Tok tokenType; | |
430 int prec; | |
431 } | |
432 | |
433 static UnOp[] _unary = [{Tok.Sub, 4}]; | |
434 UnOp* unary(Tok t) | |
435 { | |
436 foreach (ref op; _unary) | |
437 if (op.tokenType == t) | |
438 return &op; | |
439 return null; | |
440 } | |
441 | |
442 struct BinOp | |
443 { | |
444 Tok tokenType; | |
445 int prec; | |
446 bool leftAssoc; | |
447 BinaryExp.Operator operator; | |
448 } | |
449 | |
450 static BinOp[] _binary = | |
451 [ | |
10
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
452 {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
|
453 {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
|
454 {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
|
455 {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
|
456 {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
|
457 {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
|
458 |
7
2ce5209f1954
Starting to work on bool support, for now == works
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
459 {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
|
460 {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
|
461 |
7
2ce5209f1954
Starting to work on bool support, for now == works
Anders Halager <halager@gmail.com>
parents:
5
diff
changeset
|
462 {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
|
463 {Tok.Div, 5, true, BinaryExp.Operator.Div} |
1 | 464 ]; |
465 BinOp* binary(Tok t) | |
466 { | |
467 foreach (ref op; _binary) | |
468 if (op.tokenType == t) | |
469 return &op; | |
470 return null; | |
471 } | |
472 | |
473 private: | |
474 | |
475 void require(Tok t) | |
476 { | |
477 if (lexer.peek().type != t) | |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
478 error(__LINE__, UnexpextedTokSingle) |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
479 .arg(lexer.peek.getType) |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
480 .arg(t); |
1 | 481 lexer.next(); |
482 } | |
483 | |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
484 Error error(uint line, char[] errMsg, Token* tok = null) |
1 | 485 { |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
486 Location loc; |
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
487 if (tok is null) |
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
488 loc = lexer.peek.location; |
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
489 else |
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
490 loc = tok.location; |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
491 auto e = |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
492 new Error("Parser.d(" ~ Integer.toString(line) ~ "): " ~errMsg); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
493 e.loc(loc); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
494 if (tok !is null) |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
495 e.tok(*tok); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
496 return e; |
1 | 497 } |
498 | |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
499 static char[] |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
500 UnexpextedTokMulti = "Unexpexted token, got %0 expected one of %1", |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
501 UnexpextedTokSingle = "Unexpexted token, got %0 expected %1", |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
502 UnexpextedTok = "Unexpexted token %0"; |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
503 |
1 | 504 Lexer lexer; |
505 } |