コード例 #1
0
    public override void TraverseChildren(IArrayIndexer arrayIndexer) {

      //if (!IsAtomicInstance(arrayIndexer.IndexedObject)) {
      //  // Simplify the BE so that all nested dereferences and method calls are broken up into separate assignments to locals.
      //  var se = ExpressionSimplifier.Simplify(this.sink, arrayIndexer);
      //  this.Traverse(se);
      //  return;
      //}

      this.Traverse(arrayIndexer.IndexedObject);
      Bpl.Expr arrayExpr = TranslatedExpressions.Pop();

      var be = arrayIndexer.IndexedObject as IBoundExpression;
      if (be != null && be.Instance != null) {
        var l = this.sink.CreateFreshLocal(be.Type);
        var lhs = Bpl.Expr.Ident(l);
        var cmd = Bpl.Cmd.SimpleAssign(arrayIndexer.Token(), lhs, arrayExpr);
        this.StmtTraverser.StmtBuilder.Add(cmd);
        arrayExpr = lhs;
      }

      this.Traverse(arrayIndexer.Indices);
      int count = arrayIndexer.Indices.Count();
      Bpl.Expr[] indexExprs = new Bpl.Expr[count];
      for (int i = count; i > 0; i--) {
        indexExprs[i - 1] = TranslatedExpressions.Pop();
      }
      Bpl.Expr indexExpr;
      if (indexExprs.Length == 1) {
        indexExpr = indexExprs[0];
      }
      else {
        Bpl.Function f = this.sink.FindOrCreateNaryIntFunction(indexExprs.Length);
        indexExpr = new Bpl.NAryExpr(arrayIndexer.Token(), new Bpl.FunctionCall(f), new List<Bpl.Expr>(indexExprs));
      }

      AssertOrAssumeNonNull(arrayIndexer.Token(), arrayExpr);
      this.TranslatedExpressions.Push(this.sink.Heap.ReadHeap(arrayExpr, indexExpr, AccessType.Array, this.sink.CciTypeToBoogie(arrayIndexer.Type)));
    }