Skip to content

Commit

Permalink
GIMPLE coversions for ArrayIndexExpr and Arrays with values
Browse files Browse the repository at this point in the history
This compiles the ArrayIndexExpressions and Arrays such as:
  let x = [1,2,3];
  let a = x[0];

Addresses: gcc-mirror#55
  • Loading branch information
philberty committed Dec 1, 2020
1 parent 3f49161 commit 8993741
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 6 deletions.
10 changes: 10 additions & 0 deletions gcc/rust/analysis/rust-type-resolution.cc
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,17 @@ void
TypeResolution::visit (AST::ArrayExpr &expr)
{
auto elements = expr.get_internal_elements ();

auto before = typeBuffer.size ();
elements->accept_vis (*this);
if (typeBuffer.size () <= before)
{
rust_error_at (expr.get_locus_slow (),
"unable to determine type for ArrayExpr");
return;
}

expr.set_inferred_type (typeBuffer.back ());
}

void
Expand Down
7 changes: 7 additions & 0 deletions gcc/rust/ast/rust-expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,10 @@ class ArrayExpr : public ExprWithoutBlock

Location locus;

// this is a reference to what the inferred type is based on
// this init expression
Type *inferredType;

public:
std::string as_string () const override;

Expand Down Expand Up @@ -1050,6 +1054,9 @@ class ArrayExpr : public ExprWithoutBlock

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

Type *get_inferred_type () { return inferredType; }
void set_inferred_type (Type *type) { inferredType = type; }

protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
Expand Down
4 changes: 4 additions & 0 deletions gcc/rust/ast/rust-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,10 @@ class ArrayType : public TypeNoBounds

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

Expr *get_size_expr () { return size.get (); }

Location &get_locus () { return locus; }

protected:
/* Use covariance to implement clone function as returning this object rather
* than base */
Expand Down
118 changes: 113 additions & 5 deletions gcc/rust/backend/rust-compile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -503,19 +503,102 @@ Compilation::visit (AST::CompoundAssignmentExpr &expr)
void
Compilation::visit (AST::GroupedExpr &expr)
{}
// void Compilation::visit(ArrayElems& elems) {}

void
Compilation::visit (AST::ArrayElemsValues &elems)
{}
{
std::vector< ::Bexpression *> elements;

bool failed = false;
elems.iterate ([&] (AST::Expr *expr) mutable -> bool {
Bexpression *value = nullptr;
VISIT_POP (expr.get_locus_slow (), expr, value, exprs);
if (value == nullptr)
{
rust_fatal_error (expr->get_locus_slow (),
"failed to compile value to array initialiser");
return false;
}
elements.push_back (value);
return true;
});

// nothing to do when its failed
if (failed)
return;

arrayConsStack.push_back (elements);
}

void
Compilation::visit (AST::ArrayElemsCopied &elems)
{}

void
Compilation::visit (AST::ArrayExpr &expr)
{}
{
translatedType = nullptr;
expr.get_inferred_type ()->accept_vis (*this);
if (translatedType == nullptr)
{
rust_error_at (expr.get_locus_slow (),
"failed to compile array type for ArrayExpr");
return;
}

::Btype *compiledType = translatedType;
translatedType = nullptr;

auto before = arrayConsStack.size ();
expr.get_internal_elements ()->accept_vis (*this);
if (arrayConsStack.size () <= before)
{
rust_error_at (expr.get_locus_slow (),
"failed to compile the array constructor");
return;
}
std::vector< ::Bexpression *> initializer = arrayConsStack.back ();
arrayConsStack.pop_back ();

std::vector<unsigned long> indexes;
for (unsigned long i = 0; i < initializer.size (); ++i)
indexes.push_back (i);

Bexpression *cons
= backend->array_constructor_expression (compiledType, indexes, initializer,
expr.get_locus_slow ());
exprs.push_back (cons);
}

void
Compilation::visit (AST::ArrayIndexExpr &expr)
{}
{
Bexpression *arrayExpr = nullptr;
VISIT_POP (expr.get_array_expr ()->get_locus_slow (), expr.get_array_expr (),
arrayExpr, exprs);
if (arrayExpr == nullptr)
{
rust_error_at (expr.get_locus_slow (),
"failed to compile value to array expression reference");
return;
}

Bexpression *indexExpr = nullptr;
VISIT_POP (expr.get_index_expr ()->get_locus_slow (), expr.get_index_expr (),
indexExpr, exprs);
if (indexExpr == nullptr)
{
rust_error_at (expr.get_locus_slow (),
"failed to compile value to array index expression");
return;
}

Bexpression *indexExpression
= backend->array_index_expression (arrayExpr, indexExpr,
expr.get_locus_slow ());
exprs.push_back (indexExpression);
}

void
Compilation::visit (AST::TupleExpr &expr)
{}
Expand Down Expand Up @@ -1376,9 +1459,34 @@ Compilation::visit (AST::RawPointerType &type)
void
Compilation::visit (AST::ReferenceType &type)
{}

void
Compilation::visit (AST::ArrayType &type)
{}
{
Btype *elementType;
translatedType = nullptr;
type.get_element_type ()->accept_vis (*this);
if (translatedType == nullptr)
{
rust_error_at (type.get_locus (),
"Failed to compile element type for array");
return;
}
elementType = translatedType;

Bexpression *length = nullptr;
VISIT_POP (type.get_size_expr ()->get_locus_slow (), type.get_size_expr (),
length, exprs);
if (length == nullptr)
{
rust_error_at (type.get_size_expr ()->get_locus_slow (),
"failed to size for array type");
return;
}

translatedType = backend->array_type (elementType, length);
}

void
Compilation::visit (AST::SliceType &type)
{}
Expand Down
3 changes: 2 additions & 1 deletion gcc/rust/backend/rust-compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,8 @@ class Compilation : public AST::ASTVisitor
std::vector< ::Bexpression *> exprs;
std::vector< ::Bstatement *> stmts;
std::vector< ::Bvariable *> varBuffer;
std::vector<AST::StructStruct*> structBuffer;
std::vector<AST::StructStruct *> structBuffer;
std::vector<std::vector< ::Bexpression *> > arrayConsStack;

// careful these are the vectors we pass into the GCC middle-end
std::vector< ::Btype *> type_decls;
Expand Down
7 changes: 7 additions & 0 deletions gcc/testsuite/rust.test/compilable/arrays1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
fn main() {
let xs: [i32; 5] = [1, 2, 3, 4, 5];
let xy = [6, 7, 8];

let a = xs[0];
let b = xy[2];
}

0 comments on commit 8993741

Please sign in to comment.