Mercurial > projects > dang
annotate parser/Parser.d @ 45:9bc660cbdbec new_gen
If statements are back
Also fixed a bug in the codegen preventing return in the else branch, now
it is optional.
Also found an issue with the way we are generating our llvm from ifs - it
doesn't mean anything but the code looks ugly.
if (cond_1)
if (cond_2)
statement;
return 0;
Becomes:
br cond_1, then, merge
then:
br cond_2 then2, merge2
merge:
ret 0
then2:
statements
merge2:
br merge
This is because we use appendBasicBlock on the function
author | Anders Halager <halager@gmail.com> |
---|---|
date | Wed, 23 Apr 2008 16:43:42 +0200 |
parents | 495188f9078e |
children | 90fb4fdfefdd |
rev | line source |
---|---|
1 | 1 module parser.Parser; |
2 | |
3 import lexer.Lexer, | |
4 lexer.Token; | |
5 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
6 import parser.Action; |
1 | 7 |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
8 import misc.Error; |
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
9 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
10 import basic.SmallArray; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
11 |
1 | 12 import tango.io.Stdout, |
13 Integer = tango.text.convert.Integer; | |
14 | |
15 class Parser | |
16 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
17 Action action; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
18 alias Object Exp; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
19 alias Object Stmt; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
20 alias Object Decl; |
1 | 21 |
22 public: | |
23 Decl[] parse(Lexer lexer) | |
24 { | |
25 this.lexer = lexer; | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
26 action = new AstAction; |
1 | 27 |
28 | |
29 Decl[] declarations; | |
30 | |
31 while(lexer.peek.type != Tok.EOF) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
32 declarations ~= parseRootDecl(); |
1 | 33 |
34 return declarations; | |
35 } | |
36 | |
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
|
37 Decl parseRootDecl() |
1 | 38 { |
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
|
39 Token t = lexer.peek; |
1 | 40 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
41 if (t.isBasicType || t.isIdentifier) |
1 | 42 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
43 Id type = Id(lexer.next); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
44 Id iden = Id(require(Tok.Identifier)); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
45 Token next = lexer.peek(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
46 if (next.type == Tok.Seperator) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
47 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
48 Token sep = lexer.next(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
49 return action.actOnDeclarator(type, iden, null); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
50 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
51 else if (next.type == Tok.Assign) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
52 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
53 Token assign = lexer.next(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
54 Exp exp = parseExpression(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
55 require(Tok.Seperator); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
56 return action.actOnDeclarator(type, iden, exp); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
57 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
58 else if (next.type == Tok.OpenParentheses) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
59 return parseFunc(type, iden); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
60 else |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
61 throw error(__LINE__, PE.UnexpectedTok) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
62 .tok(next) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
63 .arg(next.getType); |
1 | 64 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
65 else if (t.type == Tok.Struct) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
66 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
67 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
68 char[] c = t.getType; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
69 throw error(__LINE__, PE.UnexpectedTok).tok(t).arg(c); |
1 | 70 } |
71 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
72 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
73 Parse statements. |
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
|
74 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
75 This is the place to attack! |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
76 */ |
1 | 77 Stmt parseStatement() |
78 { | |
79 Token t = lexer.peek; | |
80 | |
81 switch(t.type) | |
82 { | |
83 case Tok.Return: | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
84 Token ret = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
85 Exp exp = parseExpression(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
86 require(Tok.Seperator); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
87 return action.actOnReturnStmt(ret, exp); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
88 |
45 | 89 /* |
90 if (cond) | |
91 single statement | compound statement | |
92 [else | |
93 single statement | compound statement] | |
94 */ | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
95 case Tok.If: |
45 | 96 Token _if = lexer.next(); |
97 | |
98 require(Tok.OpenParentheses); | |
99 Exp cond = parseExpression(); | |
100 require(Tok.CloseParentheses); | |
101 | |
102 Stmt thenB = parseSingleOrCompoundStatement(); | |
103 | |
104 // if there is no else part we use the if as token, to have | |
105 // something than can be passed along | |
106 Token _else = _if; | |
107 Stmt elseB; | |
108 if (lexer.peek.type == Tok.Else) | |
109 { | |
110 _else = lexer.next; | |
111 elseB = parseSingleOrCompoundStatement(); | |
112 } | |
113 | |
114 return action.actOnIfStmt(_if, cond, thenB, _else, elseB); | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
115 |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
116 case Tok.While: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
117 return null; |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
118 |
1 | 119 case Tok.Identifier: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
120 return null; |
1 | 121 |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
122 case Tok.Switch: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
123 return null; |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
124 |
1 | 125 default: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
126 return null; |
1 | 127 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
128 error(__LINE__, "").tok(t); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
129 return null; |
1 | 130 } |
131 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
132 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
133 Parses a function/method given the already parsed |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
134 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
135 Decl parseFunc(ref Id type, ref Id name) |
1 | 136 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
137 Decl func = action.actOnStartOfFunctionDef(type, name); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
138 parseFuncArgs(func); |
1 | 139 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
140 Stmt stmt = parseCompoundStatement(); |
1 | 141 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
142 action.actOnEndOfFunction(func, stmt); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
143 return func; |
1 | 144 } |
145 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
146 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
147 Parse the function arguments, assumes current token is (. |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
148 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
149 Both the intitial paren and the ending paren is consumed. |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
150 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
151 void parseFuncArgs(Decl func) |
1 | 152 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
153 require(Tok.OpenParentheses); // Remove the "(" token. |
1 | 154 |
155 while(lexer.peek.type != Tok.CloseParentheses) | |
156 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
157 auto t = parseType(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
158 auto i = parseIdentifier(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
159 action.addFuncArg(func, t, i); |
1 | 160 |
161 if(lexer.peek.type == Tok.Comma) | |
162 lexer.next; | |
163 } | |
164 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
165 require(Tok.CloseParentheses); // Remove the ")" |
1 | 166 } |
167 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
168 /** |
45 | 169 Parse either a block, or a single statement as allowed after if, while |
170 and for. | |
171 */ | |
172 Stmt parseSingleOrCompoundStatement() | |
173 { | |
174 if (lexer.peek.type == Tok.OpenBrace) | |
175 return parseCompoundStatement(); | |
176 return parseStatement(); | |
177 } | |
178 /** | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
179 Parses a function-body or similar, expects { to be current token. |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
180 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
181 Will consume both the starting { and ending } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
182 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
183 Stmt parseCompoundStatement() |
1 | 184 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
185 Token lbrace = require(Tok.OpenBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
186 SmallArray!(Stmt, 32) stmts; // Try to use the stack only |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
187 while (lexer.peek.type != Tok.CloseBrace) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
188 stmts ~= parseStatement(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
189 Token rbrace = require(Tok.CloseBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
190 return action.actOnCompoundStmt(lbrace, rbrace, stmts.unsafe()); |
1 | 191 } |
192 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
193 Id parseIdentifier() |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
194 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
195 Token tok = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
196 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
197 if (tok.type is Tok.Identifier) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
198 return Id(tok); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
199 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
200 throw error(__LINE__, PE.UnexpectedTokSingle) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
201 .arg(tok.getType) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
202 .arg(Tok.Identifier) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
203 .tok(tok); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
204 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
205 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
206 Id parseType() |
1 | 207 { |
208 Token type = lexer.next; | |
209 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
210 if (type.isBasicType || type.type == Tok.Identifier) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
211 return Id(type); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
212 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
213 char[] c = type.getType; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
214 error(__LINE__, "Unexpected token in Type parsing. Got %0").arg(c); |
1 | 215 } |
216 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
217 private: |
1 | 218 // -- Expression parsing -- // |
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
|
219 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
|
220 { |
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 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
|
222 { |
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 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
|
224 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
|
225 { |
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 case Tok.Identifier: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
227 Token op = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
228 Id member = Id(lexer.next); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
229 Exp exp = action.actOnMemberReference(target, op.location, member); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
230 return parseExpIdentifier(exp); |
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
|
231 default: |
30
3147a52d1247
Ooops.. should have compiled before commit.. now works again
Anders Halager <halager@gmail.com>
parents:
29
diff
changeset
|
232 Token t = lexer.peek(1); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
233 throw error(__LINE__, "Expected identifier after '.'").tok(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
|
234 } |
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
|
235 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
|
236 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
|
237 } |
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
|
238 } |
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
|
239 |
1 | 240 Exp parseExpression(int p = 0) |
241 { | |
242 auto exp = P(); | |
243 Token next = lexer.peek(); | |
244 BinOp* op = null; | |
245 while ((op = binary(next.type)) != null && op.prec >= p) | |
246 { | |
247 lexer.next(); | |
248 int q = op.leftAssoc? 1 + op.prec : op.prec; | |
249 auto exp2 = parseExpression(q); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
250 exp = action.actOnBinaryOp(op.operator, exp, exp2); |
1 | 251 next = lexer.peek(); |
252 } | |
253 | |
254 return exp; | |
255 } | |
256 | |
257 Exp P() | |
258 { | |
259 Token next = lexer.next(); | |
260 if (auto op = unary(next.type)) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
261 return action.actOnUnaryOp(next, parseExpression(op.prec)); |
1 | 262 else if (next.type == Tok.OpenParentheses) |
263 { | |
264 auto e = parseExpression(0); | |
265 require(Tok.CloseParentheses); | |
266 return e; | |
267 } | |
268 else if (next.type == Tok.Identifier) | |
269 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
270 Exp value = action.actOnIdentifierExp(Id(next)); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
271 Exp iden = parseExpIdentifier(value); |
1 | 272 switch(lexer.peek.type) |
273 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
274 // TODO: Function calls are parsed but ignored |
1 | 275 case Tok.OpenParentheses: |
276 lexer.next; | |
277 Exp[] args; | |
278 while(lexer.peek.type != Tok.CloseParentheses) | |
279 { | |
280 if(lexer.peek.type == Tok.Comma) | |
281 { | |
282 lexer.next; | |
283 } | |
284 args ~= parseExpression(); | |
285 } | |
286 | |
287 lexer.next(); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
288 return null;//new CallExp(iden, args); |
1 | 289 |
290 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
|
291 return iden; |
1 | 292 } |
293 } | |
294 else if (next.type == Tok.Integer) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
295 return action.actOnNumericConstant(next); |
1 | 296 |
297 Stdout.formatln("{}", next.getType); | |
298 assert(0, "Should not happen"); | |
299 } | |
300 | |
301 struct UnOp | |
302 { | |
303 Tok tokenType; | |
304 int prec; | |
305 } | |
306 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
307 static const UnOp[] _unary = [{Tok.Sub, 4}]; |
1 | 308 UnOp* unary(Tok t) |
309 { | |
310 foreach (ref op; _unary) | |
311 if (op.tokenType == t) | |
312 return &op; | |
313 return null; | |
314 } | |
315 | |
316 struct BinOp | |
317 { | |
318 Tok tokenType; | |
319 int prec; | |
320 bool leftAssoc; | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
321 Operator operator; |
1 | 322 } |
323 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
324 static const BinOp[] _binary = |
1 | 325 [ |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
326 {Tok.Eq, 2, true, Operator.Eq}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
327 {Tok.Ne, 2, true, Operator.Ne}, |
10
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
328 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
329 {Tok.Lt, 2, true, Operator.Lt}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
330 {Tok.Le, 2, true, Operator.Le}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
331 {Tok.Gt, 2, true, Operator.Gt}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
332 {Tok.Ge, 2, true, Operator.Ge}, |
10
2f493057cf17
Some support for the rest of the boolean operators
Anders Halager <halager@gmail.com>
parents:
7
diff
changeset
|
333 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
334 {Tok.Add, 3, true, Operator.Add}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
335 {Tok.Sub, 3, true, Operator.Sub}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
336 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
337 {Tok.Mul, 5, true, Operator.Mul}, |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
338 {Tok.Div, 5, true, Operator.Div} |
1 | 339 ]; |
340 BinOp* binary(Tok t) | |
341 { | |
342 foreach (ref op; _binary) | |
343 if (op.tokenType == t) | |
344 return &op; | |
345 return null; | |
346 } | |
347 | |
348 private: | |
349 | |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
350 Token require(Tok t) |
1 | 351 { |
352 if (lexer.peek().type != t) | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
353 throw error(__LINE__, PE.UnexpectedTokSingle) |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
354 .arg(lexer.peek.getType) |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
355 .arg(t); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
356 return lexer.next(); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
357 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
358 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
359 bool skip(Tok t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
360 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
361 if (lexer.peek().type != t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
362 return false; |
1 | 363 lexer.next(); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
364 return true; |
1 | 365 } |
366 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
367 Error error(uint line, char[] errMsg) |
1 | 368 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
369 Location loc = lexer.peek.location; |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
370 auto e = |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
371 new Error("Parser.d(" ~ Integer.toString(line) ~ "): " ~errMsg); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
372 e.loc(loc); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
373 return e; |
1 | 374 } |
375 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
376 struct PE |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
377 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
378 static char[] |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
379 UnexpectedTokMulti = "Unexpected token, got %0 expected one of %1", |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
380 UnexpectedTokSingle = "Unexpected token, got %0 expected %1", |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
381 UnexpectedTok = "Unexpected token %0"; |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
382 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
383 static char[] |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
384 CaseValueMustBeInt = "Cases can only be integer literals"; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
385 } |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
386 |
1 | 387 Lexer lexer; |
388 } |