Mercurial > projects > dang
annotate parser/Parser.d @ 100:5f258eaf9517 new_gen
Loading modules in. Just need to add them to the scope of the "main" Module now.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Tue, 06 May 2008 22:49:43 +0200 |
parents | 857f0d530789 |
children | cd066f3b539a |
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 |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
8 import basic.Message; |
21
0fb2d13dce37
Now working with gdc also (gdc use reverse paremeter validating on function calls)
johnsen@johnsen-laptop
parents:
12
diff
changeset
|
9 |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
10 import basic.SmallArray, |
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
11 basic.SourceManager; |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
12 |
1 | 13 import tango.io.Stdout, |
14 Integer = tango.text.convert.Integer; | |
15 | |
16 class Parser | |
17 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
18 Action action; |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
19 MessageHandler messages; |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
20 alias Object Exp; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
21 alias Object Stmt; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
22 alias Object Decl; |
94
48bb2287c035
Added Modules. Right now it's very simple - will grow with time and need.
Anders Johnsen <skabet@gmail.com>
parents:
92
diff
changeset
|
23 alias Object Module; |
1 | 24 |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
25 this(MessageHandler messages) |
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
26 { |
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
27 this.messages = messages; |
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
28 } |
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
29 |
94
48bb2287c035
Added Modules. Right now it's very simple - will grow with time and need.
Anders Johnsen <skabet@gmail.com>
parents:
92
diff
changeset
|
30 Module parse(SourceManager sm, Lexer lexer, Action act) |
1 | 31 { |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
32 this.sm = sm; |
1 | 33 this.lexer = lexer; |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
34 this.action = act; |
1 | 35 |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
36 Module m; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
37 if (lexer.peek.type == Tok.Module) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
38 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
39 Token _module = lexer.next; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
40 ModuleName name = parseModuleName(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
41 m = action.actOnModule(_module, sm.getText(name.asRange())); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
42 require(Tok.Seperator); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
43 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
44 else |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
45 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
46 SLoc loc = lexer.peek.location; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
47 m = action.actOnImplicitModule(loc, sm.getFile(loc)); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
48 } |
1 | 49 |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
50 while (lexer.peek.type != Tok.EOF) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
51 foreach (d; parseDeclDef()) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
52 action.actOnModuleDecl(m, d); |
94
48bb2287c035
Added Modules. Right now it's very simple - will grow with time and need.
Anders Johnsen <skabet@gmail.com>
parents:
92
diff
changeset
|
53 |
48bb2287c035
Added Modules. Right now it's very simple - will grow with time and need.
Anders Johnsen <skabet@gmail.com>
parents:
92
diff
changeset
|
54 return m; |
48bb2287c035
Added Modules. Right now it's very simple - will grow with time and need.
Anders Johnsen <skabet@gmail.com>
parents:
92
diff
changeset
|
55 } |
1 | 56 |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
57 private: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
58 Decl[] parseDeclDef() |
94
48bb2287c035
Added Modules. Right now it's very simple - will grow with time and need.
Anders Johnsen <skabet@gmail.com>
parents:
92
diff
changeset
|
59 { |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
60 Token t = lexer.peek; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
61 if (t.type == Tok.Import) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
62 return parseImports(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
63 else |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
64 return [parseDecl()]; |
1 | 65 } |
66 | |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
67 Decl parseDecl() |
1 | 68 { |
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
|
69 Token t = lexer.peek; |
1 | 70 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
71 if (t.isBasicType || t.isIdentifier) |
1 | 72 { |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
73 Id type; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
74 Id iden; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
75 int len = peekParseType; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
76 if(lexer.peek(len).type == Tok.Identifier && len != 0) |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
77 { |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
78 type = parseType; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
79 parseDeclAfterInvalidType: |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
80 iden = Id(require(Tok.Identifier)); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
81 Token next = lexer.peek(); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
82 if (next.type == Tok.Seperator) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
83 { |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
84 Token sep = lexer.next(); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
85 return action.actOnDeclarator(type, iden, null); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
86 } |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
87 else if (next.type == Tok.Assign) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
88 { |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
89 Token assign = lexer.next(); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
90 Exp exp = parseExpression(); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
91 require(Tok.Seperator); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
92 return action.actOnDeclarator(type, iden, exp); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
93 } |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
94 else if (next.type == Tok.OpenParentheses) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
95 return parseFunc(type, iden); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
96 else |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
97 messages.report(UnexpectedTok, next.location).arg(next.getType); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
98 } |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
99 t = lexer.peek(len); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
100 messages.report(InvalidDeclType, t.location) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
101 .arg(sm.getText(t.asRange)); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
102 while(len--) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
103 lexer.next; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
104 while(lexer.peek.type != Tok.Identifier) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
105 lexer.next; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
106 type = Id(lexer.peek); |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
107 goto parseDeclAfterInvalidType; |
1 | 108 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
109 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
|
110 { |
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
|
111 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
|
112 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
|
113 |
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
|
114 return parseStruct(type, iden); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
115 } |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
116 messages.report(UnexpectedTok, t.location) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
117 .arg(t.getType) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
118 .arg(Tok.Identifier) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
119 .fatal(ExitLevel.Parser); |
1 | 120 } |
121 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
122 /** |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
123 Parse a series of imports belonging to a single import token. |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
124 */ |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
125 Decl[] parseImports() |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
126 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
127 Token _import = require(Tok.Import); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
128 SmallArray!(Decl) res; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
129 void addToRes(Decl d) { res ~= d; } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
130 |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
131 bool done = false; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
132 while (!done && !on_a(Tok.Seperator)) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
133 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
134 ModuleName mod = parseModuleName(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
135 Token tok = lexer.peek; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
136 switch (tok.type) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
137 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
138 case Tok.Comma: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
139 // import A, B.C; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
140 // parse another module-name |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
141 lexer.next(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
142 res ~= action.actOnImport(_import, mod, null); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
143 break; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
144 case Tok.Assign: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
145 // import B = A.A; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
146 // ^- must be a single identifier |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
147 // renamed import |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
148 if (mod.packages.length != 0) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
149 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
150 SLoc loc = mod.packages[0].tok.location; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
151 messages.report(RenameMustBeSingleIdent, loc); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
152 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
153 //if (isStatic) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
154 // error("Static imports cannot be renamed"); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
155 lexer.next(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
156 Id name = mod.id; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
157 mod = parseModuleName(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
158 // create from mod and rename to `name` |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
159 res ~= action.actOnImport(_import, mod, &name); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
160 break; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
161 case Tok.Colon: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
162 // import A : a; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
163 // selective imports, potentially import A : print = a |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
164 lexer.next(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
165 Decl d = action.actOnImport(_import, mod, null); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
166 // do-while on a comma: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
167 // add explicit symbol |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
168 do |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
169 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
170 Id sym = parseIdentifier(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
171 Id dummy; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
172 Id* name = null; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
173 if (skip(Tok.Assign)) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
174 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
175 dummy = sym; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
176 name = &dummy; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
177 sym = parseIdentifier(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
178 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
179 action.addSelectiveImport(d, sym, name); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
180 |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
181 } while (skip(Tok.Comma)); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
182 require(Tok.Seperator); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
183 res ~= d; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
184 return res.safe(); |
100
5f258eaf9517
Loading modules in. Just need to add them to the scope of the "main" Module now.
Anders Johnsen <skabet@gmail.com>
parents:
99
diff
changeset
|
185 case Tok.Seperator: |
5f258eaf9517
Loading modules in. Just need to add them to the scope of the "main" Module now.
Anders Johnsen <skabet@gmail.com>
parents:
99
diff
changeset
|
186 done = true; |
5f258eaf9517
Loading modules in. Just need to add them to the scope of the "main" Module now.
Anders Johnsen <skabet@gmail.com>
parents:
99
diff
changeset
|
187 break; |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
188 default: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
189 goto Lerror; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
190 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
191 res ~= action.actOnImport(_import, mod, null); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
192 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
193 |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
194 require(Tok.Seperator); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
195 return res.safe(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
196 Lerror: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
197 while (!on_a (Tok.Seperator)) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
198 lexer.next(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
199 return res.safe(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
200 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
201 |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
202 /** |
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
|
203 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
|
204 */ |
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
|
205 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
|
206 { |
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
|
207 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
|
208 |
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
|
209 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
|
210 |
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
|
211 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
|
212 { |
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
|
213 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
|
214 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
|
215 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
|
216 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
|
217 { |
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
|
218 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
|
219 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
|
220 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
|
221 } |
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
|
222 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
|
223 { |
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
|
224 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
|
225 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
|
226 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
|
227 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
|
228 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
|
229 } |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
230 messages.report(UnexpectedTok, next.location).arg(next.getType); |
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
|
231 } |
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
|
232 |
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
|
233 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
|
234 |
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
|
235 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
|
236 } |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
237 |
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
|
238 /** |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
239 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
|
240 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
241 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
|
242 */ |
1 | 243 Stmt parseStatement() |
244 { | |
245 Token t = lexer.peek; | |
246 | |
247 switch(t.type) | |
248 { | |
249 case Tok.Return: | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
250 Token ret = lexer.next; |
46 | 251 Exp exp; |
252 if (lexer.peek.type != Tok.Seperator) | |
253 exp = parseExpression(); | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
254 require(Tok.Seperator); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
255 return action.actOnReturnStmt(ret, exp); |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
256 |
45 | 257 /* |
258 if (cond) | |
259 single statement | compound statement | |
260 [else | |
261 single statement | compound statement] | |
262 */ | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
263 case Tok.If: |
45 | 264 Token _if = lexer.next(); |
265 | |
266 require(Tok.OpenParentheses); | |
267 Exp cond = parseExpression(); | |
268 require(Tok.CloseParentheses); | |
269 | |
270 Stmt thenB = parseSingleOrCompoundStatement(); | |
271 | |
272 // if there is no else part we use the if as token, to have | |
273 // something than can be passed along | |
274 Token _else = _if; | |
275 Stmt elseB; | |
276 if (lexer.peek.type == Tok.Else) | |
277 { | |
278 _else = lexer.next; | |
279 elseB = parseSingleOrCompoundStatement(); | |
280 } | |
281 | |
282 return action.actOnIfStmt(_if, cond, thenB, _else, elseB); | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
283 |
47
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
284 /* |
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
285 while (cond) |
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
286 single statement | compound statement |
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
287 */ |
11
642c6a998fd9
Support for while statements and fixed scope for if
Anders Halager <halager@gmail.com>
parents:
10
diff
changeset
|
288 case Tok.While: |
46 | 289 Token _while = lexer.next; |
47
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
290 require(Tok.OpenParentheses); |
46 | 291 Exp cond = parseExpression(); |
47
b0a691727a0c
Stricter while - the () was optional before
Anders Halager <halager@gmail.com>
parents:
46
diff
changeset
|
292 require(Tok.CloseParentheses); |
46 | 293 Stmt bodyStmt = parseSingleOrCompoundStatement(); |
294 return action.actOnWhileStmt(_while, cond, bodyStmt); | |
5
2c5a8f4c254a
Added very simple if support.
Anders Halager <halager@gmail.com>
parents:
1
diff
changeset
|
295 |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
296 /* |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
297 One of four things: |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
298 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
|
299 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
|
300 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
|
301 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
|
302 |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
303 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
|
304 */ |
1 | 305 case Tok.Identifier: |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
306 Token iden = lexer.peek; |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
307 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
|
308 // 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
|
309 // identifiers in a row |
75 | 310 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
|
311 { |
81 | 312 if ( n.type == Tok.Star || n.type == Tok.OpenBracket) |
84 | 313 { |
314 int len = peekParseType; | |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
315 if(lexer.peek(len).type == Tok.Identifier && len != 0) |
84 | 316 return action.actOnDeclStmt(parseVarDecl()); |
317 | |
318 Exp exp = parseExpression(); | |
319 require(Tok.Seperator); | |
320 return action.actOnExprStmt(exp); | |
321 } | |
76
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
322 |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
323 if (n.isIdentifier()) |
76
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
324 return action.actOnDeclStmt(parseVarDecl()); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
325 |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
326 // 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
|
327 Exp exp = parseExpression(); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
328 require(Tok.Seperator); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
329 return action.actOnExprStmt(exp); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
330 } |
1 | 331 |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
332 case Tok.Switch: |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
333 messages.report(UnexpectedTok, lexer.peek.location).arg(lexer.next.getType); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
334 return null; |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
335 |
1 | 336 default: |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
337 if (t.isBasicType()) |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
338 goto case Tok.Identifier; |
80
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
339 if (t.type == Tok.Star) |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
340 { |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
341 auto exp = parseExpression(); |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
342 require(Tok.Seperator); |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
343 return action.actOnExprStmt(exp); |
682e20aa224f
Pointers working now - big YAY
Anders Johnsen <skabet@gmail.com>
parents:
78
diff
changeset
|
344 } |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
345 messages.report(UnexpectedBeginStmt, lexer.peek.location).arg(lexer.next.getType); |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
346 return null; |
1 | 347 } |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
348 messages.report(UnexpectedTok, t.location); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
349 return null; |
1 | 350 } |
351 | |
76
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
352 Decl parseVarDecl() |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
353 { |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
354 // manually hardcoded to only support "type id [= exp];" |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
355 // 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
|
356 Id type = parseType; |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
357 Id id = Id(lexer.next); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
358 Exp init; |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
359 if (skip(Tok.Assign)) |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
360 init = parseExpression(); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
361 require(Tok.Seperator); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
362 Decl d = action.actOnDeclarator(type, id, init); |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
363 return d; |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
364 } |
9171f04dd9ee
Now parsing varDecls a lot nicer!
Anders Johnsen <skabet@gmail.com>
parents:
75
diff
changeset
|
365 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
366 /** |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
367 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
|
368 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
369 Decl parseFunc(ref Id type, ref Id name) |
1 | 370 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
371 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
|
372 parseFuncArgs(func); |
1 | 373 |
82
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
374 if(lexer.peek.type == Tok.Seperator) |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
375 { |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
376 lexer.next; |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
377 return func; |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
378 } |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
379 Stmt stmt = parseCompoundStatement(); |
1 | 380 |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
381 return action.actOnEndOfFunction(func, stmt); |
1 | 382 } |
383 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
384 /** |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
385 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
|
386 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
387 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
|
388 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
389 void parseFuncArgs(Decl func) |
1 | 390 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
391 require(Tok.OpenParentheses); // Remove the "(" token. |
1 | 392 |
393 while(lexer.peek.type != Tok.CloseParentheses) | |
394 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
395 auto t = parseType(); |
82
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
396 Id i; |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
397 if(lexer.peek.type == Tok.Identifier) |
06dda301ea61
Can declare outside functions and call c-functions
Anders Johnsen <skabet@gmail.com>
parents:
81
diff
changeset
|
398 i = parseIdentifier(); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
399 action.addFuncArg(func, t, i); |
1 | 400 |
401 if(lexer.peek.type == Tok.Comma) | |
402 lexer.next; | |
403 } | |
404 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
405 require(Tok.CloseParentheses); // Remove the ")" |
1 | 406 } |
407 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
408 /** |
45 | 409 Parse either a block, or a single statement as allowed after if, while |
410 and for. | |
411 */ | |
412 Stmt parseSingleOrCompoundStatement() | |
413 { | |
414 if (lexer.peek.type == Tok.OpenBrace) | |
415 return parseCompoundStatement(); | |
416 return parseStatement(); | |
417 } | |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
418 |
45 | 419 /** |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
420 Parses a function-body or similar, expects an opening brace to be the |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
421 current token. |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
422 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
423 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
|
424 */ |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
425 Stmt parseCompoundStatement() |
1 | 426 { |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
427 Token lbrace = require(Tok.OpenBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
428 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
|
429 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
|
430 stmts ~= parseStatement(); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
431 Token rbrace = require(Tok.CloseBrace); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
432 return action.actOnCompoundStmt(lbrace, rbrace, stmts.unsafe()); |
1 | 433 } |
434 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
435 Id parseIdentifier() |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
436 { |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
437 Token tok = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
438 |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
439 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
|
440 return Id(tok); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
441 |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
442 messages.report(UnexpectedTokSingle, tok.location) |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
443 .arg(tok.getType) |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
444 .arg(Tok.Identifier); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
445 } |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
446 |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
447 ModuleName parseModuleName() |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
448 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
449 auto id = parseIdentifier(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
450 ModuleName mod; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
451 while (skip(Tok.Dot)) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
452 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
453 mod.packages ~= id; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
454 if (lexer.peek.type != Tok.Identifier) { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
455 messages.report(ExpectedIdAfterPackage, lexer.peek.location); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
456 goto Lerror; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
457 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
458 id = parseIdentifier(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
459 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
460 mod.id = id; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
461 return mod; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
462 Lerror: |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
463 while (!skip(Tok.Seperator)) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
464 lexer.next(); |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
465 return mod; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
466 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
467 |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
468 |
75 | 469 /** |
470 Parse a type - this includes pointer and array(at some point) types. | |
471 */ | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
472 Id parseType() |
1 | 473 { |
474 Token type = lexer.next; | |
475 | |
75 | 476 Id currentType; |
477 | |
478 if ( !(type.isBasicType || type.type == Tok.Identifier) ) | |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
479 messages.report(InvalidType, type.location); |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
480 |
75 | 481 currentType = Id(type); |
482 type = lexer.peek; | |
483 | |
81 | 484 while(type.type == Tok.Star || type.type == Tok.OpenBracket) |
75 | 485 { |
81 | 486 if(type.type == Tok.Star) |
487 { | |
488 currentType = PointerId(currentType); | |
489 lexer.next; | |
490 } | |
491 else | |
492 { | |
493 lexer.next; | |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
494 if(lexer.peek.type == Tok.Integer) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
495 currentType = ArrayId(currentType, action.actOnNumericConstant(require(Tok.Integer))); |
81 | 496 require(Tok.CloseBracket); |
497 | |
498 } | |
75 | 499 type = lexer.peek; |
500 } | |
501 | |
502 return currentType; | |
1 | 503 } |
504 | |
84 | 505 int peekParseType() |
506 { | |
507 int i; | |
508 Token type = lexer.peek(i); | |
509 | |
510 Id currentType; | |
511 | |
512 if ( !(type.isBasicType || type.type == Tok.Identifier) ) | |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
513 return 0; |
84 | 514 |
515 currentType = Id(type); | |
516 type = lexer.peek(++i); | |
517 | |
518 while(type.type == Tok.Star || type.type == Tok.OpenBracket) | |
519 { | |
520 if(type.type == Tok.Star) | |
521 { | |
522 i++; | |
523 } | |
524 else | |
525 { | |
526 if(lexer.peek(i++).type != Tok.OpenBracket) | |
527 return 0; | |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
528 if(lexer.peek(i).type == Tok.Integer) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
529 { |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
530 i++; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
531 if(lexer.peek(i++).type != Tok.CloseBracket) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
532 return 0; |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
533 } |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
534 else |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
535 if(lexer.peek(i++).type != Tok.CloseBracket) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
536 return 0; |
84 | 537 |
538 } | |
539 type = lexer.peek(i); | |
540 } | |
541 | |
542 return i; | |
543 } | |
544 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
545 private: |
1 | 546 // -- Expression parsing -- // |
83
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
547 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
|
548 { |
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
|
549 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
|
550 { |
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
|
551 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
|
552 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
|
553 { |
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
|
554 case Tok.Identifier: |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
555 Token op = lexer.next; |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
556 Id member = Id(lexer.next); |
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
557 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
|
558 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
|
559 default: |
30
3147a52d1247
Ooops.. should have compiled before commit.. now works again
Anders Halager <halager@gmail.com>
parents:
29
diff
changeset
|
560 Token t = lexer.peek(1); |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
561 messages.report(ExpectedIdAfterDot, t.location); |
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
|
562 } |
83
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
563 case Tok.OpenBracket: |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
564 Token open = lexer.next; |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
565 Exp index = parseExpression(); |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
566 Token close = require(Tok.CloseBracket); |
9e90694f5da0
Parse array indexing, and allow reading from arrays
Anders Halager <halager@gmail.com>
parents:
82
diff
changeset
|
567 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
|
568 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
|
569 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
|
570 } |
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
|
571 } |
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
|
572 |
1 | 573 Exp parseExpression(int p = 0) |
574 { | |
575 auto exp = P(); | |
576 Token next = lexer.peek(); | |
577 BinOp* op = null; | |
578 while ((op = binary(next.type)) != null && op.prec >= p) | |
579 { | |
580 lexer.next(); | |
581 int q = op.leftAssoc? 1 + op.prec : op.prec; | |
582 auto exp2 = parseExpression(q); | |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
583 exp = action.actOnBinaryOp(next.location, op.operator, exp, exp2); |
1 | 584 next = lexer.peek(); |
585 } | |
586 | |
587 return exp; | |
588 } | |
589 | |
590 Exp P() | |
591 { | |
592 Token next = lexer.next(); | |
593 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
|
594 return action.actOnUnaryOp(next, parseExpression(op.prec)); |
1 | 595 else if (next.type == Tok.OpenParentheses) |
596 { | |
597 auto e = parseExpression(0); | |
598 require(Tok.CloseParentheses); | |
599 return e; | |
600 } | |
601 else if (next.type == Tok.Identifier) | |
602 { | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
603 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
|
604 Exp iden = parsePostfixExp(value); |
1 | 605 switch(lexer.peek.type) |
606 { | |
607 case Tok.OpenParentheses: | |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
608 Token lp = lexer.next; |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
609 SmallArray!(Exp, 8) args; |
1 | 610 while(lexer.peek.type != Tok.CloseParentheses) |
611 { | |
612 if(lexer.peek.type == Tok.Comma) | |
613 lexer.next; | |
614 args ~= parseExpression(); | |
615 } | |
616 | |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
617 Token rp = lexer.next(); |
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
618 return action.actOnCallExpr(iden, lp, args.unsafe(), rp); |
1 | 619 |
620 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
|
621 return iden; |
1 | 622 } |
623 } | |
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
|
624 else if (next.type == Tok.Cast) |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
625 return parseCast(next); |
1 | 626 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
|
627 return action.actOnNumericConstant(next); |
1 | 628 |
92
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
629 messages.report(ExpectedExp, next.location) |
771ac63898e2
A few better parser errors plus renaming most of the sema classes to match that they do now. Some have changes a lot.
Anders Johnsen <skabet@gmail.com>
parents:
89
diff
changeset
|
630 .fatal(ExitLevel.Parser); |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
631 return null; |
1 | 632 } |
633 | |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
634 Exp parseCast(ref Token _cast) |
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
|
635 { |
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
|
636 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
|
637 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
|
638 if(!next.isBasicType && !next.isIdentifier) |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
639 messages.report(ExpectedCastType, next.location); |
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
|
640 |
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
|
641 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
|
642 auto exp = P(); |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
643 return action.actOnCastExpr(_cast, Id(next), exp); |
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
|
644 } |
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
|
645 |
1 | 646 struct UnOp |
647 { | |
648 Tok tokenType; | |
649 int prec; | |
650 } | |
651 | |
78
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
652 static const UnOp[] _unary = |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
653 [ |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
654 {Tok.Minus, 4}, |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
655 {Tok.Star, 4} |
ad956143dcdc
Parse and gen for dereferences
Anders Halager <halager@gmail.com>
parents:
76
diff
changeset
|
656 ]; |
1 | 657 UnOp* unary(Tok t) |
658 { | |
659 foreach (ref op; _unary) | |
660 if (op.tokenType == t) | |
661 return &op; | |
662 return null; | |
663 } | |
664 | |
665 struct BinOp | |
666 { | |
667 Tok tokenType; | |
668 int prec; | |
669 bool leftAssoc; | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
670 Operator operator; |
1 | 671 } |
672 | |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
673 static const BinOp[] _binary = |
1 | 674 [ |
48
b6c1dc30ca4b
Only tests that dont pass now are structs and switches
Anders Halager <halager@gmail.com>
parents:
47
diff
changeset
|
675 {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
|
676 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
677 {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
|
678 {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
|
679 |
44
495188f9078e
Big update - Moving towards a better, more seperated parser
Anders Halager <halager@gmail.com>
parents:
37
diff
changeset
|
680 {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
|
681 {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
|
682 {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
|
683 {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
|
684 |
74
192da4976daa
Renamed Add, Sub, Mul, Div and Mod in lexer to what they are (Plus, Minus....)
johnsen@johnsen-laptop
parents:
71
diff
changeset
|
685 {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
|
686 {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
|
687 |
74
192da4976daa
Renamed Add, Sub, Mul, Div and Mod in lexer to what they are (Plus, Minus....)
johnsen@johnsen-laptop
parents:
71
diff
changeset
|
688 {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
|
689 {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
|
690 {Tok.Percent, 5, true, Operator.Mod} |
1 | 691 ]; |
692 BinOp* binary(Tok t) | |
693 { | |
694 foreach (ref op; _binary) | |
695 if (op.tokenType == t) | |
696 return &op; | |
697 return null; | |
698 } | |
699 | |
700 private: | |
701 | |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
702 Token require(Tok t) |
1 | 703 { |
704 if (lexer.peek().type != t) | |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
705 messages.report(UnexpectedTokSingle, lexer.peek.location) |
29
41d23f2762c3
Merge, and updated Error class
Anders Halager <halager@gmail.com>
parents:
28
diff
changeset
|
706 .arg(lexer.peek.getType) |
89
a49bb982a7b0
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
Anders Johnsen <skabet@gmail.com>
parents:
88
diff
changeset
|
707 .arg(t); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
708 return lexer.next(); |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
709 } |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
710 |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
711 bool skip(Tok t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
712 { |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
713 if (lexer.peek().type != t) |
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
714 return false; |
1 | 715 lexer.next(); |
36
ce17bea8e9bd
Switch statements support
Anders Halager <halager@gmail.com>
parents:
33
diff
changeset
|
716 return true; |
1 | 717 } |
718 | |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
719 bool on_a(Tok t) |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
720 { |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
721 return lexer.peek.type == t; |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
722 } |
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
723 |
1 | 724 Lexer lexer; |
88
eb5b2c719a39
Major change to locations, tokens and expressions.
Anders Halager <halager@gmail.com>
parents:
84
diff
changeset
|
725 SourceManager sm; |
1 | 726 } |
99
857f0d530789
Imports and improved module statement
Anders Halager <halager@gmail.com>
parents:
94
diff
changeset
|
727 |