Skip to content

Commit edf53ee

Browse files
authored
Merge pull request #23 from philberty/phil/compilation-simple
WIP more type inferencing
2 parents 966e522 + 57019a0 commit edf53ee

File tree

4 files changed

+200
-36
lines changed

4 files changed

+200
-36
lines changed

gcc/rust/analysis/rust-resolution.cc

+191-33
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,53 @@
11
#include "rust-resolution.h"
22
#include "rust-diagnostics.h"
33

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+
419
namespace Rust {
520
namespace Analysis {
621

7-
TypeResolution::TypeResolution (AST::Crate &crate) : scope (), crate (crate)
22+
TypeResolution::TypeResolution (AST::Crate &crate) : crate (crate)
823
{
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);
1544
}
1645

17-
TypeResolution::~TypeResolution () {}
46+
TypeResolution::~TypeResolution ()
47+
{
48+
typeScope.Pop ();
49+
scope.Pop ();
50+
}
1851

1952
bool
2053
TypeResolution::ResolveNamesAndTypes (AST::Crate &crate)
@@ -26,12 +59,9 @@ TypeResolution::ResolveNamesAndTypes (AST::Crate &crate)
2659
bool
2760
TypeResolution::go ()
2861
{
29-
scope.Push ();
3062
for (auto &item : crate.items)
31-
{
32-
item->accept_vis (*this);
33-
}
34-
scope.Pop ();
63+
item->accept_vis (*this);
64+
3565
return true;
3666
}
3767

@@ -50,7 +80,15 @@ TypeResolution::visit (AST::AttrInputMetaItemContainer &input)
5080
void
5181
TypeResolution::visit (AST::IdentifierExpr &ident_expr)
5282
{
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);
5492
}
5593

5694
void
@@ -68,22 +106,33 @@ TypeResolution::visit (AST::MacroInvocationSemi &macro)
68106
// rust-path.h
69107
void
70108
TypeResolution::visit (AST::PathInExpression &path)
71-
{}
109+
{
110+
printf ("PathInExpression: %s\n", path.as_string ().c_str ());
111+
}
112+
72113
void
73114
TypeResolution::visit (AST::TypePathSegment &segment)
74115
{}
75116
void
76117
TypeResolution::visit (AST::TypePathSegmentGeneric &segment)
77118
{}
119+
78120
void
79121
TypeResolution::visit (AST::TypePathSegmentFunction &segment)
80122
{}
123+
81124
void
82125
TypeResolution::visit (AST::TypePath &path)
83-
{}
126+
{
127+
printf ("TypePath: %s\n", path.as_string ().c_str ());
128+
}
129+
84130
void
85131
TypeResolution::visit (AST::QualifiedPathInExpression &path)
86-
{}
132+
{
133+
printf ("QualifiedPathInExpression: %s\n", path.as_string ().c_str ());
134+
}
135+
87136
void
88137
TypeResolution::visit (AST::QualifiedPathInType &path)
89138
{}
@@ -92,19 +141,69 @@ TypeResolution::visit (AST::QualifiedPathInType &path)
92141
void
93142
TypeResolution::visit (AST::LiteralExpr &expr)
94143
{
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 ());
97193
}
98194

99195
void
100196
TypeResolution::visit (AST::AttrInputLiteral &attr_input)
101197
{}
198+
102199
void
103200
TypeResolution::visit (AST::MetaItemLitExpr &meta_item)
104201
{}
202+
105203
void
106204
TypeResolution::visit (AST::MetaItemPathLit &meta_item)
107205
{}
206+
108207
void
109208
TypeResolution::visit (AST::BorrowExpr &expr)
110209
{}
@@ -117,24 +216,64 @@ TypeResolution::visit (AST::ErrorPropagationExpr &expr)
117216
void
118217
TypeResolution::visit (AST::NegationExpr &expr)
119218
{}
219+
120220
void
121221
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+
123251
void
124252
TypeResolution::visit (AST::ComparisonExpr &expr)
125253
{}
254+
126255
void
127256
TypeResolution::visit (AST::LazyBooleanExpr &expr)
128-
{}
257+
{
258+
printf ("LazyBooleanExpr: %s\n", expr.as_string ().c_str ());
259+
}
260+
129261
void
130262
TypeResolution::visit (AST::TypeCastExpr &expr)
131263
{}
264+
132265
void
133266
TypeResolution::visit (AST::AssignmentExpr &expr)
134-
{}
267+
{
268+
printf ("AssignmentExpr: %s\n", expr.as_string ().c_str ());
269+
}
270+
135271
void
136272
TypeResolution::visit (AST::CompoundAssignmentExpr &expr)
137-
{}
273+
{
274+
printf ("CompoundAssignmentExpr: %s\n", expr.as_string ().c_str ());
275+
}
276+
138277
void
139278
TypeResolution::visit (AST::GroupedExpr &expr)
140279
{}
@@ -391,9 +530,13 @@ TypeResolution::visit (AST::Enum &enum_item)
391530
void
392531
TypeResolution::visit (AST::Union &union_item)
393532
{}
533+
394534
void
395535
TypeResolution::visit (AST::ConstantItem &const_item)
396-
{}
536+
{
537+
printf ("ConstantItem: %s\n", const_item.as_string ().c_str ());
538+
}
539+
397540
void
398541
TypeResolution::visit (AST::StaticItem &static_item)
399542
{}
@@ -474,7 +617,6 @@ TypeResolution::visit (AST::LiteralPattern &pattern)
474617
void
475618
TypeResolution::visit (AST::IdentifierPattern &pattern)
476619
{
477-
printf ("IdentifierPattern: %s\n", pattern.as_string ().c_str ());
478620
letPatternBuffer.push_back (pattern);
479621
}
480622

@@ -545,12 +687,15 @@ TypeResolution::visit (AST::EmptyStmt &stmt)
545687
void
546688
TypeResolution::visit (AST::LetStmt &stmt)
547689
{
548-
AST::Type *inferedType = NULL;
549-
if (stmt.has_type ())
690+
if (!stmt.has_init_expr () && !stmt.has_type ())
550691
{
551-
inferedType = stmt.type.get ();
692+
rust_error_at (stmt.locus,
693+
"E0282: type annotations or init expression needed");
694+
return;
552695
}
553-
else if (stmt.has_init_expr ())
696+
697+
AST::Type *inferedType = NULL;
698+
if (stmt.has_init_expr ())
554699
{
555700
stmt.init_expr->accept_vis (*this);
556701

@@ -565,13 +710,26 @@ TypeResolution::visit (AST::LetStmt &stmt)
565710
inferedType = typeBuffer.back ();
566711
typeBuffer.pop_back ();
567712
}
568-
else
713+
714+
if (stmt.has_type () && stmt.has_init_expr ())
569715
{
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
572718
}
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
573726

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+
}
575733

576734
// get all the names part of this declaration and add the types to the scope
577735
stmt.variables_pattern->accept_vis (*this);

gcc/rust/analysis/rust-resolution.h

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ class TypeResolution : public AST::ASTVisitor
226226
bool go ();
227227

228228
Scope scope;
229+
Scope typeScope;
229230
AST::Crate &crate;
230231

231232
std::vector<AST::IdentifierPattern> letPatternBuffer;

gcc/rust/ast/rust-ast.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -960,11 +960,11 @@ class ExprWithoutBlock : public Expr
960960
// single-segment paths
961961
class IdentifierExpr : public ExprWithoutBlock
962962
{
963+
public:
963964
Identifier ident;
964965

965966
Location locus;
966967

967-
public:
968968
IdentifierExpr (Identifier ident, Location locus = Location (),
969969
::std::vector<Attribute> outer_attrs
970970
= ::std::vector<Attribute> ())

0 commit comments

Comments
 (0)