1
1
#include " rust-resolution.h"
2
2
#include " rust-diagnostics.h"
3
3
4
+ #define ADD_BUILTIN_TYPE (_X, _S ) \
5
+ do \
6
+ { \
7
+ AST::PathIdentSegment seg (_X); \
8
+ auto typePath = ::std::unique_ptr<AST::TypePathSegment> ( \
9
+ new AST::TypePathSegment (::std::move (seg), false , \
10
+ Linemap::unknown_location ())); \
11
+ ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs; \
12
+ segs.push_back (::std::move (typePath)); \
13
+ auto bType = new AST::TypePath (::std::move (segs), \
14
+ Linemap::unknown_location (), false ); \
15
+ _S.Insert (_X, bType); \
16
+ } \
17
+ while (0 )
18
+
4
19
namespace Rust {
5
20
namespace Analysis {
6
21
7
- TypeResolution::TypeResolution (AST::Crate &crate) : scope (), crate (crate)
22
+ TypeResolution::TypeResolution (AST::Crate &crate) : crate (crate)
8
23
{
9
- // push all builtin types
10
- // base is parse_path_ident_segment based up on segments
11
- /* scope.Insert ("u8",
12
- new AST::MaybeNamedParam (Identifier ("u8"),
13
- AST::MaybeNamedParam::IDENTIFIER,
14
- NULL, Location ()));*/
24
+ typeScope.Push ();
25
+ scope.Push ();
26
+
27
+ // push all builtin types - this is probably too basic for future needs
28
+ ADD_BUILTIN_TYPE (" u8" , typeScope);
29
+ ADD_BUILTIN_TYPE (" u16" , typeScope);
30
+ ADD_BUILTIN_TYPE (" u32" , typeScope);
31
+ ADD_BUILTIN_TYPE (" u64" , typeScope);
32
+
33
+ ADD_BUILTIN_TYPE (" i8" , typeScope);
34
+ ADD_BUILTIN_TYPE (" i16" , typeScope);
35
+ ADD_BUILTIN_TYPE (" i32" , typeScope);
36
+ ADD_BUILTIN_TYPE (" i64" , typeScope);
37
+
38
+ ADD_BUILTIN_TYPE (" f32" , typeScope);
39
+ ADD_BUILTIN_TYPE (" f64" , typeScope);
40
+
41
+ ADD_BUILTIN_TYPE (" char" , typeScope);
42
+ ADD_BUILTIN_TYPE (" str" , typeScope);
43
+ ADD_BUILTIN_TYPE (" bool" , typeScope);
15
44
}
16
45
17
- TypeResolution::~TypeResolution () {}
46
+ TypeResolution::~TypeResolution ()
47
+ {
48
+ typeScope.Pop ();
49
+ scope.Pop ();
50
+ }
18
51
19
52
bool
20
53
TypeResolution::ResolveNamesAndTypes (AST::Crate &crate)
@@ -26,12 +59,9 @@ TypeResolution::ResolveNamesAndTypes (AST::Crate &crate)
26
59
bool
27
60
TypeResolution::go ()
28
61
{
29
- scope.Push ();
30
62
for (auto &item : crate.items )
31
- {
32
- item->accept_vis (*this );
33
- }
34
- scope.Pop ();
63
+ item->accept_vis (*this );
64
+
35
65
return true ;
36
66
}
37
67
@@ -50,7 +80,15 @@ TypeResolution::visit (AST::AttrInputMetaItemContainer &input)
50
80
void
51
81
TypeResolution::visit (AST::IdentifierExpr &ident_expr)
52
82
{
53
- printf (" IdentifierExpr %s\n " , ident_expr.as_string ().c_str ());
83
+ AST::Type *type = NULL ;
84
+ bool ok = scope.Lookup (ident_expr.ident , &type);
85
+ if (!ok)
86
+ {
87
+ rust_error_at (ident_expr.locus , " unknown identifier" );
88
+ return ;
89
+ }
90
+
91
+ typeBuffer.push_back (type);
54
92
}
55
93
56
94
void
@@ -68,22 +106,33 @@ TypeResolution::visit (AST::MacroInvocationSemi ¯o)
68
106
// rust-path.h
69
107
void
70
108
TypeResolution::visit (AST::PathInExpression &path)
71
- {}
109
+ {
110
+ printf (" PathInExpression: %s\n " , path.as_string ().c_str ());
111
+ }
112
+
72
113
void
73
114
TypeResolution::visit (AST::TypePathSegment &segment)
74
115
{}
75
116
void
76
117
TypeResolution::visit (AST::TypePathSegmentGeneric &segment)
77
118
{}
119
+
78
120
void
79
121
TypeResolution::visit (AST::TypePathSegmentFunction &segment)
80
122
{}
123
+
81
124
void
82
125
TypeResolution::visit (AST::TypePath &path)
83
- {}
126
+ {
127
+ printf (" TypePath: %s\n " , path.as_string ().c_str ());
128
+ }
129
+
84
130
void
85
131
TypeResolution::visit (AST::QualifiedPathInExpression &path)
86
- {}
132
+ {
133
+ printf (" QualifiedPathInExpression: %s\n " , path.as_string ().c_str ());
134
+ }
135
+
87
136
void
88
137
TypeResolution::visit (AST::QualifiedPathInType &path)
89
138
{}
@@ -92,19 +141,69 @@ TypeResolution::visit (AST::QualifiedPathInType &path)
92
141
void
93
142
TypeResolution::visit (AST::LiteralExpr &expr)
94
143
{
95
- printf (" LiteralExpr: %s\n " , expr.as_string ().c_str ());
96
- // figure out what this type is and push it onto the
144
+ std::string type;
145
+ switch (expr.literal .get_lit_type ())
146
+ {
147
+ case AST::Literal::CHAR:
148
+ type = " char" ;
149
+ break ;
150
+
151
+ case AST::Literal::STRING:
152
+ case AST::Literal::RAW_STRING:
153
+ type = " str" ;
154
+ break ;
155
+
156
+ case AST::Literal::BOOL:
157
+ type = " bool" ;
158
+ break ;
159
+
160
+ case AST::Literal::BYTE:
161
+ type = " u8" ;
162
+ break ;
163
+
164
+ // FIXME these are not always going to be the case
165
+ // eg: suffix on the value can change the type
166
+ case AST::Literal::FLOAT:
167
+ type = " f32" ;
168
+ break ;
169
+
170
+ case AST::Literal::INT:
171
+ type = " i32" ;
172
+ break ;
173
+
174
+ case AST::Literal::BYTE_STRING:
175
+ case AST::Literal::RAW_BYTE_STRING:
176
+ // FIXME
177
+ break ;
178
+ }
179
+
180
+ if (type.empty ())
181
+ {
182
+ rust_error_at (expr.locus , " unknown literal: %s" ,
183
+ expr.literal .as_string ().c_str ());
184
+ return ;
185
+ }
186
+
187
+ AST::Type *val = NULL ;
188
+ bool ok = typeScope.Lookup (type, &val);
189
+ if (ok)
190
+ typeBuffer.push_back (val);
191
+ else
192
+ rust_error_at (expr.locus , " unknown literal type: %s" , type.c_str ());
97
193
}
98
194
99
195
void
100
196
TypeResolution::visit (AST::AttrInputLiteral &attr_input)
101
197
{}
198
+
102
199
void
103
200
TypeResolution::visit (AST::MetaItemLitExpr &meta_item)
104
201
{}
202
+
105
203
void
106
204
TypeResolution::visit (AST::MetaItemPathLit &meta_item)
107
205
{}
206
+
108
207
void
109
208
TypeResolution::visit (AST::BorrowExpr &expr)
110
209
{}
@@ -117,24 +216,64 @@ TypeResolution::visit (AST::ErrorPropagationExpr &expr)
117
216
void
118
217
TypeResolution::visit (AST::NegationExpr &expr)
119
218
{}
219
+
120
220
void
121
221
TypeResolution::visit (AST::ArithmeticOrLogicalExpr &expr)
122
- {}
222
+ {
223
+ size_t before;
224
+ before = typeBuffer.size ();
225
+ expr.visit_lhs (*this );
226
+ if (typeBuffer.size () <= before)
227
+ {
228
+ rust_error_at (expr.locus , " unable to determine lhs type" );
229
+ return ;
230
+ }
231
+
232
+ auto lhsType = typeBuffer.back ();
233
+ typeBuffer.pop_back ();
234
+
235
+ before = typeBuffer.size ();
236
+ expr.visit_rhs (*this );
237
+ if (typeBuffer.size () <= before)
238
+ {
239
+ rust_error_at (expr.locus , " unable to determine rhs type" );
240
+ return ;
241
+ }
242
+
243
+ auto rhsType = typeBuffer.back ();
244
+ // not poping because we will be checking they match and the
245
+ // scope will require knowledge of the type
246
+
247
+ // do the lhsType and the rhsType match
248
+ // TODO
249
+ }
250
+
123
251
void
124
252
TypeResolution::visit (AST::ComparisonExpr &expr)
125
253
{}
254
+
126
255
void
127
256
TypeResolution::visit (AST::LazyBooleanExpr &expr)
128
- {}
257
+ {
258
+ printf (" LazyBooleanExpr: %s\n " , expr.as_string ().c_str ());
259
+ }
260
+
129
261
void
130
262
TypeResolution::visit (AST::TypeCastExpr &expr)
131
263
{}
264
+
132
265
void
133
266
TypeResolution::visit (AST::AssignmentExpr &expr)
134
- {}
267
+ {
268
+ printf (" AssignmentExpr: %s\n " , expr.as_string ().c_str ());
269
+ }
270
+
135
271
void
136
272
TypeResolution::visit (AST::CompoundAssignmentExpr &expr)
137
- {}
273
+ {
274
+ printf (" CompoundAssignmentExpr: %s\n " , expr.as_string ().c_str ());
275
+ }
276
+
138
277
void
139
278
TypeResolution::visit (AST::GroupedExpr &expr)
140
279
{}
@@ -391,9 +530,13 @@ TypeResolution::visit (AST::Enum &enum_item)
391
530
void
392
531
TypeResolution::visit (AST::Union &union_item)
393
532
{}
533
+
394
534
void
395
535
TypeResolution::visit (AST::ConstantItem &const_item)
396
- {}
536
+ {
537
+ printf (" ConstantItem: %s\n " , const_item.as_string ().c_str ());
538
+ }
539
+
397
540
void
398
541
TypeResolution::visit (AST::StaticItem &static_item)
399
542
{}
@@ -474,7 +617,6 @@ TypeResolution::visit (AST::LiteralPattern &pattern)
474
617
void
475
618
TypeResolution::visit (AST::IdentifierPattern &pattern)
476
619
{
477
- printf (" IdentifierPattern: %s\n " , pattern.as_string ().c_str ());
478
620
letPatternBuffer.push_back (pattern);
479
621
}
480
622
@@ -545,12 +687,15 @@ TypeResolution::visit (AST::EmptyStmt &stmt)
545
687
void
546
688
TypeResolution::visit (AST::LetStmt &stmt)
547
689
{
548
- AST::Type *inferedType = NULL ;
549
- if (stmt.has_type ())
690
+ if (!stmt.has_init_expr () && !stmt.has_type ())
550
691
{
551
- inferedType = stmt.type .get ();
692
+ rust_error_at (stmt.locus ,
693
+ " E0282: type annotations or init expression needed" );
694
+ return ;
552
695
}
553
- else if (stmt.has_init_expr ())
696
+
697
+ AST::Type *inferedType = NULL ;
698
+ if (stmt.has_init_expr ())
554
699
{
555
700
stmt.init_expr ->accept_vis (*this );
556
701
@@ -565,13 +710,26 @@ TypeResolution::visit (AST::LetStmt &stmt)
565
710
inferedType = typeBuffer.back ();
566
711
typeBuffer.pop_back ();
567
712
}
568
- else
713
+
714
+ if (stmt.has_type () && stmt.has_init_expr ())
569
715
{
570
- rust_error_at (stmt. locus , " unable to determine type for declaration " );
571
- return ;
716
+ auto declaredTyped = stmt. type . get ( );
717
+ // TODO compare this type to the inferred type to ensure they match
572
718
}
719
+ else if (stmt.has_type () && !stmt.has_init_expr ())
720
+ {
721
+ inferedType = stmt.type .get ();
722
+ }
723
+
724
+ // TODO check we know what the type is in the scope requires the builtins to
725
+ // be defined at the constructor
573
726
574
- // TODO check we know what the type is
727
+ // ensure the decl has the type set for compilation later on
728
+ if (!stmt.has_type ())
729
+ {
730
+ // FIXME
731
+ // stmt.type = inferedType;
732
+ }
575
733
576
734
// get all the names part of this declaration and add the types to the scope
577
735
stmt.variables_pattern ->accept_vis (*this );
0 commit comments