Skip to content

Commit 8993741

Browse files
committed
GIMPLE coversions for ArrayIndexExpr and Arrays with values
This compiles the ArrayIndexExpressions and Arrays such as: let x = [1,2,3]; let a = x[0]; Addresses: gcc-mirror#55
1 parent 3f49161 commit 8993741

File tree

6 files changed

+143
-6
lines changed

6 files changed

+143
-6
lines changed

gcc/rust/analysis/rust-type-resolution.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,17 @@ void
466466
TypeResolution::visit (AST::ArrayExpr &expr)
467467
{
468468
auto elements = expr.get_internal_elements ();
469+
470+
auto before = typeBuffer.size ();
469471
elements->accept_vis (*this);
472+
if (typeBuffer.size () <= before)
473+
{
474+
rust_error_at (expr.get_locus_slow (),
475+
"unable to determine type for ArrayExpr");
476+
return;
477+
}
478+
479+
expr.set_inferred_type (typeBuffer.back ());
470480
}
471481

472482
void

gcc/rust/ast/rust-expr.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,10 @@ class ArrayExpr : public ExprWithoutBlock
10001000

10011001
Location locus;
10021002

1003+
// this is a reference to what the inferred type is based on
1004+
// this init expression
1005+
Type *inferredType;
1006+
10031007
public:
10041008
std::string as_string () const override;
10051009

@@ -1050,6 +1054,9 @@ class ArrayExpr : public ExprWithoutBlock
10501054

10511055
ArrayElems *get_internal_elements () { return internal_elements.get (); };
10521056

1057+
Type *get_inferred_type () { return inferredType; }
1058+
void set_inferred_type (Type *type) { inferredType = type; }
1059+
10531060
protected:
10541061
/* Use covariance to implement clone function as returning this object rather
10551062
* than base */

gcc/rust/ast/rust-type.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,10 @@ class ArrayType : public TypeNoBounds
576576

577577
Type *get_element_type () { return elem_type.get (); }
578578

579+
Expr *get_size_expr () { return size.get (); }
580+
581+
Location &get_locus () { return locus; }
582+
579583
protected:
580584
/* Use covariance to implement clone function as returning this object rather
581585
* than base */

gcc/rust/backend/rust-compile.cc

Lines changed: 113 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -503,19 +503,102 @@ Compilation::visit (AST::CompoundAssignmentExpr &expr)
503503
void
504504
Compilation::visit (AST::GroupedExpr &expr)
505505
{}
506-
// void Compilation::visit(ArrayElems& elems) {}
506+
507507
void
508508
Compilation::visit (AST::ArrayElemsValues &elems)
509-
{}
509+
{
510+
std::vector< ::Bexpression *> elements;
511+
512+
bool failed = false;
513+
elems.iterate ([&] (AST::Expr *expr) mutable -> bool {
514+
Bexpression *value = nullptr;
515+
VISIT_POP (expr.get_locus_slow (), expr, value, exprs);
516+
if (value == nullptr)
517+
{
518+
rust_fatal_error (expr->get_locus_slow (),
519+
"failed to compile value to array initialiser");
520+
return false;
521+
}
522+
elements.push_back (value);
523+
return true;
524+
});
525+
526+
// nothing to do when its failed
527+
if (failed)
528+
return;
529+
530+
arrayConsStack.push_back (elements);
531+
}
532+
510533
void
511534
Compilation::visit (AST::ArrayElemsCopied &elems)
512535
{}
536+
513537
void
514538
Compilation::visit (AST::ArrayExpr &expr)
515-
{}
539+
{
540+
translatedType = nullptr;
541+
expr.get_inferred_type ()->accept_vis (*this);
542+
if (translatedType == nullptr)
543+
{
544+
rust_error_at (expr.get_locus_slow (),
545+
"failed to compile array type for ArrayExpr");
546+
return;
547+
}
548+
549+
::Btype *compiledType = translatedType;
550+
translatedType = nullptr;
551+
552+
auto before = arrayConsStack.size ();
553+
expr.get_internal_elements ()->accept_vis (*this);
554+
if (arrayConsStack.size () <= before)
555+
{
556+
rust_error_at (expr.get_locus_slow (),
557+
"failed to compile the array constructor");
558+
return;
559+
}
560+
std::vector< ::Bexpression *> initializer = arrayConsStack.back ();
561+
arrayConsStack.pop_back ();
562+
563+
std::vector<unsigned long> indexes;
564+
for (unsigned long i = 0; i < initializer.size (); ++i)
565+
indexes.push_back (i);
566+
567+
Bexpression *cons
568+
= backend->array_constructor_expression (compiledType, indexes, initializer,
569+
expr.get_locus_slow ());
570+
exprs.push_back (cons);
571+
}
572+
516573
void
517574
Compilation::visit (AST::ArrayIndexExpr &expr)
518-
{}
575+
{
576+
Bexpression *arrayExpr = nullptr;
577+
VISIT_POP (expr.get_array_expr ()->get_locus_slow (), expr.get_array_expr (),
578+
arrayExpr, exprs);
579+
if (arrayExpr == nullptr)
580+
{
581+
rust_error_at (expr.get_locus_slow (),
582+
"failed to compile value to array expression reference");
583+
return;
584+
}
585+
586+
Bexpression *indexExpr = nullptr;
587+
VISIT_POP (expr.get_index_expr ()->get_locus_slow (), expr.get_index_expr (),
588+
indexExpr, exprs);
589+
if (indexExpr == nullptr)
590+
{
591+
rust_error_at (expr.get_locus_slow (),
592+
"failed to compile value to array index expression");
593+
return;
594+
}
595+
596+
Bexpression *indexExpression
597+
= backend->array_index_expression (arrayExpr, indexExpr,
598+
expr.get_locus_slow ());
599+
exprs.push_back (indexExpression);
600+
}
601+
519602
void
520603
Compilation::visit (AST::TupleExpr &expr)
521604
{}
@@ -1376,9 +1459,34 @@ Compilation::visit (AST::RawPointerType &type)
13761459
void
13771460
Compilation::visit (AST::ReferenceType &type)
13781461
{}
1462+
13791463
void
13801464
Compilation::visit (AST::ArrayType &type)
1381-
{}
1465+
{
1466+
Btype *elementType;
1467+
translatedType = nullptr;
1468+
type.get_element_type ()->accept_vis (*this);
1469+
if (translatedType == nullptr)
1470+
{
1471+
rust_error_at (type.get_locus (),
1472+
"Failed to compile element type for array");
1473+
return;
1474+
}
1475+
elementType = translatedType;
1476+
1477+
Bexpression *length = nullptr;
1478+
VISIT_POP (type.get_size_expr ()->get_locus_slow (), type.get_size_expr (),
1479+
length, exprs);
1480+
if (length == nullptr)
1481+
{
1482+
rust_error_at (type.get_size_expr ()->get_locus_slow (),
1483+
"failed to size for array type");
1484+
return;
1485+
}
1486+
1487+
translatedType = backend->array_type (elementType, length);
1488+
}
1489+
13821490
void
13831491
Compilation::visit (AST::SliceType &type)
13841492
{}

gcc/rust/backend/rust-compile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ class Compilation : public AST::ASTVisitor
243243
std::vector< ::Bexpression *> exprs;
244244
std::vector< ::Bstatement *> stmts;
245245
std::vector< ::Bvariable *> varBuffer;
246-
std::vector<AST::StructStruct*> structBuffer;
246+
std::vector<AST::StructStruct *> structBuffer;
247+
std::vector<std::vector< ::Bexpression *> > arrayConsStack;
247248

248249
// careful these are the vectors we pass into the GCC middle-end
249250
std::vector< ::Btype *> type_decls;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
let xs: [i32; 5] = [1, 2, 3, 4, 5];
3+
let xy = [6, 7, 8];
4+
5+
let a = xs[0];
6+
let b = xy[2];
7+
}

0 commit comments

Comments
 (0)