Mercurial > projects > dang
annotate parser/Parser.d @ 84:cc05c041e6a3 new_gen
Assign stuff to arrays.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Fri, 02 May 2008 20:17:22 +0200 |
parents | 9e90694f5da0 |
children | eb5b2c719a39 |
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: | |
51
c96cdcbdb9d6
Rearranged some stuff, and renamed LLVMGen -> CodeGen
Anders Halager <halager@gmail.com>
parents:
48
diff
changeset
|
23 Decl[] parse(Lexer lexer, Action act) |
1 | 24 { |
25 this.lexer = lexer; | |
51
c96cdcbdb9d6
Rearranged some stuff, and renamed LLVMGen -> CodeGen
Anders Halager <halager@gmail.com>
parents:
48
diff
changeset
|
26 action = act; |
1 | 27 |
28 Decl[] declarations; | |
29 | |
30 while(lexer.peek.type != Tok.EOF) | |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
31 declarations ~= parseDecl(); |
1 | 32 |
33 return declarations; | |
34 } | |
35 | |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
36 Decl parseDecl() |
1 | 37 { |
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
|
38 Token t = lexer.peek; |
1 | 39 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
40 if (t.isBasicType || t.isIdentifier) |
1 | 41 { |
76
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
42 Id type = Id(lexer.next); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
43 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
|
44 Token next = lexer.peek(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
45 if (next.type == Tok.Seperator) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
46 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
47 Token sep = lexer.next(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
48 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
|
49 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
50 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
|
51 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
52 Token assign = lexer.next(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
53 Exp exp = parseExpression(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
54 require(Tok.Seperator); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
55 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
|
56 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
57 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
|
58 return parseFunc(type, iden); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
59 else |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
60 throw error(__LINE__, PE.UnexpectedTok) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
61 .tok(next) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
62 .arg(next.getType); |
1 | 63 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
64 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
|
65 { |
53
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
66 Id type = Id(lexer.next); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
67 Id iden = Id(require(Tok.Identifier)); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
68 |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
69 return parseStruct(type, iden); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
70 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
71 char[] c = t.getType; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
72 throw error(__LINE__, PE.UnexpectedTok).tok(t).arg(c); |
1 | 73 } |
74 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
75 /** |
53
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
76 Parse struct |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
77 */ |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
78 Decl parseStruct(Id type, Id iden) |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
79 { |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
80 auto decl = action.actOnDeclarator(type, iden, null); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
81 |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
82 require(Tok.OpenBrace); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
83 |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
84 while(lexer.peek.isBasicType || lexer.peek.isIdentifier) |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
85 { |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
86 Id var_type = Id(lexer.next); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
87 Id var_iden = Id(require(Tok.Identifier)); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
88 Token next = lexer.peek(); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
89 if (next.type == Tok.Seperator) |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
90 { |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
91 Token sep = lexer.next(); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
92 action.actOnStructMember(decl, var_type, var_iden, null); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
93 continue; |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
94 } |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
95 else if (next.type == Tok.Assign) |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
96 { |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
97 Token assign = lexer.next(); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
98 Exp exp = parseExpression(); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
99 require(Tok.Seperator); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
100 action.actOnStructMember(decl, var_type, var_iden, exp); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
101 continue; |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
102 } |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
103 throw error(__LINE__, PE.UnexpectedTok) |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
104 .tok(next).arg(next.getType); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
105 } |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
106 |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
107 require(Tok.CloseBrace); |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
108 |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
109 return decl; |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
110 } |
da551f90e03f
Added struct decl and forward ref. A note on structs: they need to make a new scope when declared. Otherwise you could access struct members as globals
Anders Johnsen <skabet@gmail.com>
parents:
51
diff
changeset
|
111 /** |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
112 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
|
113 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
114 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
|
115 */ |
1 | 116 Stmt parseStatement() |
117 { | |
118 Token t = lexer.peek; | |
119 | |
120 switch(t.type) | |
121 { | |
122 case Tok.Return: | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
123 Token ret = lexer.next; |
46 | 124 Exp exp; |
125 if (lexer.peek.type != Tok.Seperator) | |
126 exp = parseExpression(); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
127 require(Tok.Seperator); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
128 return action.actOnReturnStmt(ret, exp); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
129 |
45 | 130 /* |
131 if (cond) | |
132 single statement | compound statement | |
133 [else | |
134 single statement | compound statement] | |
135 */ | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
136 case Tok.If: |
45 | 137 Token _if = lexer.next(); |
138 | |
139 require(Tok.OpenParentheses); | |
140 Exp cond = parseExpression(); | |
141 require(Tok.CloseParentheses); | |
142 | |
143 Stmt thenB = parseSingleOrCompoundStatement(); | |
144 | |
145 // if there is no else part we use the if as token, to have | |
146 // something than can be passed along | |
147 Token _else = _if; | |
148 Stmt elseB; | |
149 if (lexer.peek.type == Tok.Else) | |
150 { | |
151 _else = lexer.next; | |
152 elseB = parseSingleOrCompoundStatement(); | |
153 } | |
154 | |
155 return action.actOnIfStmt(_if, cond, thenB, _else, elseB); | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
156 |
47
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
157 /* |
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
158 while (cond) |
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
159 single statement | compound statement |
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
160 */ |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
161 case Tok.While: |
46 | 162 Token _while = lexer.next; |
47
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
163 require(Tok.OpenParentheses); |
46 | 164 Exp cond = parseExpression(); |
47
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
165 require(Tok.CloseParentheses); |
46 | 166 Stmt bodyStmt = parseSingleOrCompoundStatement(); |
167 return action.actOnWhileStmt(_while, cond, bodyStmt); | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
168 |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
169 /* |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
170 One of four things: |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
171 A declaration of a function/variable `type id ...` |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
172 A direct assignment `id = exp;` |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
173 An indirect assignment `id.id = exp` |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
174 Some sort of free standing expression |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
175 |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
176 The assignments should be handled as binary expressions? |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
177 */ |
1 | 178 case Tok.Identifier: |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
179 Token iden = lexer.peek; |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
180 Token n = lexer.peek(1); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
181 // Must be an decl, if we start with a basic type, or two |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
182 // identifiers in a row |
75 | 183 if (iden.isBasicType() || iden.isIdentifier()) |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
184 { |
81 | 185 if ( n.type == Tok.Star || n.type == Tok.OpenBracket) |
84 | 186 { |
187 int len = peekParseType; | |
188 if(lexer.peek(len).type == Tok.Identifier || len == 0) | |
189 return action.actOnDeclStmt(parseVarDecl()); | |
190 | |
191 Exp exp = parseExpression(); | |
192 require(Tok.Seperator); | |
193 return action.actOnExprStmt(exp); | |
194 } | |
76
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
195 |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
196 if ( n.isIdentifier()) |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
197 return action.actOnDeclStmt(parseVarDecl()); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
198 |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
199 // Expression: a.b, a = b, a(b) etc. |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
200 Exp exp = parseExpression(); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
201 require(Tok.Seperator); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
202 return action.actOnExprStmt(exp); |
76
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
203 break; |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
204 } |
1 | 205 |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
206 case Tok.Switch: |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
207 throw error(__LINE__, ":(").tok(lexer.peek); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
208 return null; |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
209 |
1 | 210 default: |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
211 if (t.isBasicType()) |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
212 goto case Tok.Identifier; |
80
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
213 if (t.type == Tok.Star) |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
214 { |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
215 auto exp = parseExpression(); |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
216 require(Tok.Seperator); |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
217 return action.actOnExprStmt(exp); |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
218 } |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
219 |
71
010f46b6641c
Handled a few more error cases on input.
Anders Johnsen <skabet@gmail.com>
parents:
68
diff
changeset
|
220 throw error(__LINE__, "Unexpexted begining of statement.").tok(lexer.peek); |
1 | 221 } |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
222 throw error(__LINE__, "").tok(t); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
223 return null; |
1 | 224 } |
225 | |
76
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
226 Decl parseVarDecl() |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
227 { |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
228 // manually hardcoded to only support "type id [= exp];" |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
229 // as that is the only thing the codegen understands |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
230 Id type = parseType; |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
231 Id id = Id(lexer.next); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
232 Exp init; |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
233 if (skip(Tok.Assign)) |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
234 init = parseExpression(); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
235 require(Tok.Seperator); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
236 Decl d = action.actOnDeclarator(type, id, init); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
237 return d; |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
238 } |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
239 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
240 /** |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
241 Parses a function/method given the already parsed return type and name |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
242 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
243 Decl parseFunc(ref Id type, ref Id name) |
1 | 244 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
245 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
|
246 parseFuncArgs(func); |
1 | 247 |
82
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
248 if(lexer.peek.type == Tok.Seperator) |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
249 { |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
250 lexer.next; |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
251 return func; |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
252 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
253 Stmt stmt = parseCompoundStatement(); |
1 | 254 |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
255 return action.actOnEndOfFunction(func, stmt); |
1 | 256 } |
257 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
258 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
259 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
|
260 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
261 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
|
262 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
263 void parseFuncArgs(Decl func) |
1 | 264 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
265 require(Tok.OpenParentheses); // Remove the "(" token. |
1 | 266 |
267 while(lexer.peek.type != Tok.CloseParentheses) | |
268 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
269 auto t = parseType(); |
82
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
270 Id i; |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
271 if(lexer.peek.type == Tok.Identifier) |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
272 i = parseIdentifier(); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
273 action.addFuncArg(func, t, i); |
1 | 274 |
275 if(lexer.peek.type == Tok.Comma) | |
276 lexer.next; | |
277 } | |
278 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
279 require(Tok.CloseParentheses); // Remove the ")" |
1 | 280 } |
281 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
282 /** |
45 | 283 Parse either a block, or a single statement as allowed after if, while |
284 and for. | |
285 */ | |
286 Stmt parseSingleOrCompoundStatement() | |
287 { | |
288 if (lexer.peek.type == Tok.OpenBrace) | |
289 return parseCompoundStatement(); | |
290 return parseStatement(); | |
291 } | |
292 /** | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
293 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
|
294 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
295 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
|
296 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
297 Stmt parseCompoundStatement() |
1 | 298 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
299 Token lbrace = require(Tok.OpenBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
300 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
|
301 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
|
302 stmts ~= parseStatement(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
303 Token rbrace = require(Tok.CloseBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
304 return action.actOnCompoundStmt(lbrace, rbrace, stmts.unsafe()); |
1 | 305 } |
306 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
307 Id parseIdentifier() |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
308 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
309 Token tok = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
310 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
311 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
|
312 return Id(tok); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
313 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
314 throw error(__LINE__, PE.UnexpectedTokSingle) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
315 .arg(tok.getType) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
316 .arg(Tok.Identifier) |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
317 .tok(tok); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
318 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
319 |
75 | 320 /** |
321 Parse a type - this includes pointer and array(at some point) types. | |
322 */ | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
323 Id parseType() |
1 | 324 { |
325 Token type = lexer.next; | |
326 | |
75 | 327 Id currentType; |
328 | |
329 if ( !(type.isBasicType || type.type == Tok.Identifier) ) | |
330 throw error(__LINE__, "Unexpected token in Type parsing. Got %0") | |
331 .arg(type.getType) | |
332 .tok(type); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
333 |
75 | 334 currentType = Id(type); |
335 type = lexer.peek; | |
336 | |
81 | 337 while(type.type == Tok.Star || type.type == Tok.OpenBracket) |
75 | 338 { |
81 | 339 if(type.type == Tok.Star) |
340 { | |
341 currentType = PointerId(currentType); | |
342 lexer.next; | |
343 } | |
344 else | |
345 { | |
346 lexer.next; | |
347 currentType = ArrayId(currentType, action.actOnNumericConstant(require(Tok.Integer))); | |
348 require(Tok.CloseBracket); | |
349 | |
350 } | |
75 | 351 type = lexer.peek; |
352 } | |
353 | |
354 return currentType; | |
1 | 355 } |
356 | |
84 | 357 int peekParseType() |
358 { | |
359 int i; | |
360 Token type = lexer.peek(i); | |
361 | |
362 Id currentType; | |
363 | |
364 if ( !(type.isBasicType || type.type == Tok.Identifier) ) | |
365 return i; | |
366 | |
367 currentType = Id(type); | |
368 type = lexer.peek(++i); | |
369 | |
370 while(type.type == Tok.Star || type.type == Tok.OpenBracket) | |
371 { | |
372 if(type.type == Tok.Star) | |
373 { | |
374 i++; | |
375 } | |
376 else | |
377 { | |
378 if(lexer.peek(i++).type != Tok.OpenBracket) | |
379 return 0; | |
380 if(lexer.peek(i++).type != Tok.Integer) | |
381 return 0; | |
382 if(lexer.peek(i++).type != Tok.CloseBracket) | |
383 return 0; | |
384 | |
385 } | |
386 type = lexer.peek(i); | |
387 } | |
388 | |
389 return i; | |
390 } | |
391 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
392 private: |
1 | 393 // -- Expression parsing -- // |
83
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
394 Exp parsePostfixExp(Exp target) |
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
|
395 { |
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
|
396 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
|
397 { |
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 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
|
399 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
|
400 { |
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 case Tok.Identifier: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
402 Token op = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
403 Id member = Id(lexer.next); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
404 Exp exp = action.actOnMemberReference(target, op.location, member); |
83
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
405 return parsePostfixExp(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
|
406 default: |
30
3147a52d1247
Ooops.. should have compiled before commit.. now works again
Anders Halager <halager@gmail.com>
parents:
29
diff
changeset
|
407 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
|
408 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
|
409 } |
83
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
410 case Tok.OpenBracket: |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
411 Token open = lexer.next; |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
412 Exp index = parseExpression(); |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
413 Token close = require(Tok.CloseBracket); |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
414 return action.actOnIndexEpr(target, open, index, close); |
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
|
415 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
|
416 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
|
417 } |
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
|
418 } |
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
|
419 |
1 | 420 Exp parseExpression(int p = 0) |
421 { | |
422 auto exp = P(); | |
423 Token next = lexer.peek(); | |
424 BinOp* op = null; | |
425 while ((op = binary(next.type)) != null && op.prec >= p) | |
426 { | |
427 lexer.next(); | |
428 int q = op.leftAssoc? 1 + op.prec : op.prec; | |
429 auto exp2 = parseExpression(q); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
430 exp = action.actOnBinaryOp(op.operator, exp, exp2); |
1 | 431 next = lexer.peek(); |
432 } | |
433 | |
434 return exp; | |
435 } | |
436 | |
437 Exp P() | |
438 { | |
439 Token next = lexer.next(); | |
440 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
|
441 return action.actOnUnaryOp(next, parseExpression(op.prec)); |
1 | 442 else if (next.type == Tok.OpenParentheses) |
443 { | |
444 auto e = parseExpression(0); | |
445 require(Tok.CloseParentheses); | |
446 return e; | |
447 } | |
448 else if (next.type == Tok.Identifier) | |
449 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
450 Exp value = action.actOnIdentifierExp(Id(next)); |
83
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
451 Exp iden = parsePostfixExp(value); |
1 | 452 switch(lexer.peek.type) |
453 { | |
454 case Tok.OpenParentheses: | |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
455 Token lp = lexer.next; |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
456 SmallArray!(Exp, 8) args; |
1 | 457 while(lexer.peek.type != Tok.CloseParentheses) |
458 { | |
459 if(lexer.peek.type == Tok.Comma) | |
460 lexer.next; | |
461 args ~= parseExpression(); | |
462 } | |
463 | |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
464 Token rp = lexer.next(); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
465 return action.actOnCallExpr(iden, lp, args.unsafe(), rp); |
1 | 466 |
467 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
|
468 return iden; |
1 | 469 } |
470 } | |
68
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
471 else if (next.type == Tok.Cast) |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
472 return parseCast(); |
1 | 473 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
|
474 return action.actOnNumericConstant(next); |
1 | 475 |
71
010f46b6641c
Handled a few more error cases on input.
Anders Johnsen <skabet@gmail.com>
parents:
68
diff
changeset
|
476 throw error(__LINE__, "Expected expression, not '"~next.getType~"'").tok(next); |
1 | 477 assert(0, "Should not happen"); |
478 } | |
479 | |
68
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
480 Exp parseCast() |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
481 { |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
482 require(Tok.OpenParentheses); |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
483 auto next = lexer.next; |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
484 if(!next.isBasicType && !next.isIdentifier) |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
485 throw error(__LINE__, "Expected cast type, not "~next.get).tok(next); |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
486 |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
487 require(Tok.CloseParentheses); |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
488 auto exp = P(); |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
489 return action.actOnCastExpr(Id(next), exp); |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
490 } |
381975d76baf
A LOT of bug fixing - also implemented implicit casts. If you do a --ast-dump-code on a target with some algebra of differant types, you should now see the type casts being made. Also, Tests are again back with only switches failing...
Anders Johnsen <skabet@gmail.com>
parents:
62
diff
changeset
|
491 |
1 | 492 struct UnOp |
493 { | |
494 Tok tokenType; | |
495 int prec; | |
496 } | |
497 | |
78
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
498 static const UnOp[] _unary = |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
499 [ |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
500 {Tok.Minus, 4}, |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
501 {Tok.Star, 4} |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
502 ]; |
1 | 503 UnOp* unary(Tok t) |
504 { | |
505 foreach (ref op; _unary) | |
506 if (op.tokenType == t) | |
507 return &op; | |
508 return null; | |
509 } | |
510 | |
511 struct BinOp | |
512 { | |
513 Tok tokenType; | |
514 int prec; | |
515 bool leftAssoc; | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
516 Operator operator; |
1 | 517 } |
518 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
519 static const BinOp[] _binary = |
1 | 520 [ |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
521 {Tok.Assign, 1, false, Operator.Assign}, |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
522 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
523 {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
|
524 {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
|
525 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
526 {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
|
527 {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
|
528 {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
|
529 {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
|
530 |
74
192da4976daa
Renamed Add, Sub, Mul, Div and Mod in lexer to what they are (Plus, Minus....)
johnsen@johnsen-laptop
parents:
71
diff
changeset
|
531 {Tok.Plus, 3, true, Operator.Add}, |
192da4976daa
Renamed Add, Sub, Mul, Div and Mod in lexer to what they are (Plus, Minus....)
johnsen@johnsen-laptop
parents:
71
diff
changeset
|
532 {Tok.Minus, 3, true, Operator.Sub}, |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
533 |
74
192da4976daa
Renamed Add, Sub, Mul, Div and Mod in lexer to what they are (Plus, Minus....)
johnsen@johnsen-laptop
parents:
71
diff
changeset
|
534 {Tok.Star, 5, true, Operator.Mul}, |
192da4976daa
Renamed Add, Sub, Mul, Div and Mod in lexer to what they are (Plus, Minus....)
johnsen@johnsen-laptop
parents:
71
diff
changeset
|
535 {Tok.Slash, 5, true, Operator.Div}, |
192da4976daa
Renamed Add, Sub, Mul, Div and Mod in lexer to what they are (Plus, Minus....)
johnsen@johnsen-laptop
parents:
71
diff
changeset
|
536 {Tok.Percent, 5, true, Operator.Mod} |
1 | 537 ]; |
538 BinOp* binary(Tok t) | |
539 { | |
540 foreach (ref op; _binary) | |
541 if (op.tokenType == t) | |
542 return &op; | |
543 return null; | |
544 } | |
545 | |
546 private: | |
547 | |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
548 Token require(Tok t) |
1 | 549 { |
550 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
|
551 throw error(__LINE__, PE.UnexpectedTokSingle) |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
552 .arg(lexer.peek.getType) |
71
010f46b6641c
Handled a few more error cases on input.
Anders Johnsen <skabet@gmail.com>
parents:
68
diff
changeset
|
553 .arg(t) |
010f46b6641c
Handled a few more error cases on input.
Anders Johnsen <skabet@gmail.com>
parents:
68
diff
changeset
|
554 .tok(lexer.peek); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
555 return lexer.next(); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
556 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
557 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
558 bool skip(Tok t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
559 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
560 if (lexer.peek().type != t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
561 return false; |
1 | 562 lexer.next(); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
563 return true; |
1 | 564 } |
565 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
566 Error error(uint line, char[] errMsg) |
1 | 567 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
568 Location loc = lexer.peek.location; |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
569 auto e = |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
570 new Error("Parser.d(" ~ Integer.toString(line) ~ "): " ~errMsg); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
571 e.loc(loc); |
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
572 return e; |
1 | 573 } |
574 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
575 struct PE |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
576 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
577 static char[] |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
578 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
|
579 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
|
580 UnexpectedTok = "Unexpected token %0"; |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
581 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
582 static char[] |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
583 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
|
584 } |
33
084c2c147c4f
Improvements to the Error class.
Anders Halager <halager@gmail.com>
parents:
30
diff
changeset
|
585 |
1 | 586 Lexer lexer; |
587 } |