Beispiel #1
0
  /** Perform the appropriate flow operations for declaration of a local variable */
  protected Map flowLocalDecl(
      DataFlowItem inItem, FlowGraph graph, LocalDecl ld, Set succEdgeKeys) {
    Map m = new HashMap(inItem.initStatus);
    MinMaxInitCount initCount = (MinMaxInitCount) m.get(ld.localInstance());
    // if (initCount == null) {
    if (ld.init() != null) {
      // declaration of local var with initialization.
      initCount = new MinMaxInitCount(InitCount.ONE, InitCount.ONE);
    } else {
      // declaration of local var with no initialization.
      initCount = new MinMaxInitCount(InitCount.ZERO, InitCount.ZERO);
    }

    m.put(ld.localInstance(), initCount);
    //        }
    //        else {
    // the initCount is not null. We now have a problem. Why is the
    // initCount not null? Has this variable been assigned in its own
    // initialization, or is this a declaration inside a loop body?
    // XXX@@@ THIS IS A BUG THAT NEEDS TO BE FIXED.
    // Currently, the declaration "final int i = (i=5);" will
    // not be rejected, as we cannot distinguish between that and
    // "while (true) {final int i = 4;}"
    //        }

    // record the fact that we have seen a local declaration
    currCBI.localDeclarations.add(ld.localInstance());

    return itemToMap(new DataFlowItem(m), succEdgeKeys);
  }
  @Override
  public Node typeCheck(ContextVisitor tc) throws SemanticException {
    RuleDef sym = null;

    MethodInstance mi = call.methodInstance();
    IbexClassType ct = (IbexClassType) mi.container();
    for (RuleInstance rule : ct.rules()) {
      if (rule.name() == mi.name()) sym = rule.def();
    }

    if (sym == null) throw new SemanticException("Cannot find rule for " + mi);

    RhsInvoke n = (RhsInvoke) symbol(sym.asNonterminal()).type(call.type());

    if (assocTag) {
      Context c = tc.context();
      CodeDef code = c.currentCode();
      if (code instanceof RuleDef) {
        RuleDef rd = (RuleDef) code;
        if (rd != sym)
          throw new SemanticException(
              "Associativity annotation must be self-recursive.", position());
      }
    }

    if (!call.type().isVoid()) {
      TypeSystem ts = tc.typeSystem();
      LocalDef li = ts.localDef(position(), Flags.FINAL, Types.ref(call.type()), call.name().id());
      // Formal parameters are never compile-time constants.
      li.setNotConstant();

      IbexNodeFactory nf = (IbexNodeFactory) tc.nodeFactory();
      LocalDecl ld =
          nf.LocalDecl(
              position(),
              nf.FlagsNode(position(), li.flags()),
              nf.CanonicalTypeNode(position(), li.type()),
              nf.Id(position(), li.name()));
      ld = ld.localDef(li);
      ld = ld.init(n);

      return nf.RhsSyntheticBind(position(), ld).type(n.type());
    }

    return n;
  }
  private Node translateExtForArray(ExtendedFor n, List<String> labels) throws SemanticException {
    Position pos = Position.compilerGenerated();
    Type iteratedType = n.decl().type().type();
    // translate "L1,...,Ln: for (C x: e) b" to
    // "{ C[] arr = e; int iter = 0;  L1,...,Ln: while (iter < arr.length)  { C x = arr[iter]; b ;
    // iter = iter + 1; }"
    List<Stmt> stmts = new ArrayList<Stmt>();

    // add the declaration of arr: "C[] arr = e"
    Id arrID = freshName("arr");
    LocalInstance arrLI = ts.localInstance(pos, Flags.NONE, n.expr().type(), arrID.id());
    {
      LocalDecl ld =
          nodeFactory()
              .LocalDecl(
                  pos, Flags.NONE, nodeFactory().CanonicalTypeNode(pos, arrLI.type()), arrID);
      ld = ld.localInstance(arrLI);
      ld = ld.init(n.expr());
      stmts.add(ld);
    }

    // add the declaration of iterator: "int iter = 0"
    Id iterID = freshName("iter");
    LocalInstance iterLI = ts.localInstance(pos, Flags.NONE, ts.Int(), iterID.id());
    {
      LocalDecl ld =
          nodeFactory()
              .LocalDecl(
                  pos, Flags.NONE, nodeFactory().CanonicalTypeNode(pos, iterLI.type()), iterID);
      ld = ld.localInstance(iterLI);
      ld = ld.init(nodeFactory().IntLit(pos, IntLit.INT, 0).type(ts.Int()));
      stmts.add(ld);
    }

    // build the conditional "iter < arr.length"
    Expr cond;
    {
      Local iterLocal =
          (Local) nodeFactory().Local(pos, iterID).localInstance(iterLI).type(ts.Int());
      Local arrLocal =
          (Local) nodeFactory().Local(pos, arrID).localInstance(arrLI).type(arrLI.type());
      Id id = nodeFactory().Id(pos, "length");
      Field field = (Field) nodeFactory().Field(pos, arrLocal, id).type(ts.Int());
      field = field.fieldInstance(ts.findField(arrLI.type().toReference(), "length"));

      cond = nodeFactory().Binary(pos, iterLocal, Binary.LT, field).type(ts.Boolean());
    }

    // build the initlizer for the local decl: arr[iter]
    Expr init;
    {
      Local iterLocal =
          (Local) nodeFactory().Local(pos, iterID).localInstance(iterLI).type(ts.Int());
      Local arrLocal =
          (Local) nodeFactory().Local(pos, arrID).localInstance(arrLI).type(arrLI.type());
      init = nodeFactory().ArrayAccess(pos, arrLocal, iterLocal);
      init = init.type(iteratedType);
    }

    // build the increment for iter (iter = iter + 1;)
    Stmt inc;
    {
      Local iterLocal =
          (Local) nodeFactory().Local(pos, iterID).localInstance(iterLI).type(ts.Int());
      Expr incExpr =
          nodeFactory()
              .Binary(
                  pos,
                  iterLocal.type(ts.Int()),
                  Binary.ADD,
                  nodeFactory().IntLit(pos, IntLit.INT, 1).type(ts.Int()))
              .type(ts.Int());
      Assign incStore =
          (Assign) nodeFactory().Assign(pos, iterLocal, Assign.ASSIGN, incExpr).type(ts.Int());
      inc = nodeFactory().Eval(pos, incStore);
    }

    // build the while loop
    {
      // Create a new loop body from the old body followed by the increment
      Block loopBody = nodeFactory().Block(pos, n.decl().init(init), n.body(), inc);
      While loop = nodeFactory().While(pos, cond, loopBody);
      stmts.add(labelStmt(loop, labels));
    }
    return nodeFactory().Block(pos, stmts);
  }