/** Flatten complex expressions within the AST */
  public Node leave(Node old, Node n, NodeVisitor v) {
    if (n == noFlatten) {
      noFlatten = null;
      return n;
    }

    if (n instanceof Block) {
      List l = (List) stack.removeFirst();
      return ((Block) n).statements(l);
    } else if (n instanceof Stmt && !(n instanceof LocalDecl)) {
      List l = (List) stack.getFirst();
      l.add(n);
      return n;
    } else if (n instanceof Expr
        && !(n instanceof Lit)
        && !(n instanceof Special)
        && !(n instanceof Local)) {

      Expr e = (Expr) n;

      if (e instanceof Assign) {
        return n;
      }

      // create a local temp, initialized to the value of the complex
      // expression

      String name = newID();
      LocalDecl def =
          nf.LocalDecl(
              e.position(), Flags.FINAL, nf.CanonicalTypeNode(e.position(), e.type()), name, e);
      def = def.localInstance(ts.localInstance(e.position(), Flags.FINAL, e.type(), name));

      List l = (List) stack.getFirst();
      l.add(def);

      // return the local temp instead of the complex expression
      Local use = nf.Local(e.position(), name);
      use = (Local) use.type(e.type());
      use = use.localInstance(ts.localInstance(e.position(), Flags.FINAL, e.type(), name));
      return use;
    }

    return n;
  }
Beispiel #2
0
  /** Type check the statement. */
  public Node typeCheck(TypeChecker tc) throws SemanticException {
    TypeSystem ts = tc.typeSystem();

    // Check that all initializers have the same type.
    // This should be enforced by the parser, but check again here,
    // just to be sure.
    Type t = null;

    for (Iterator i = inits.iterator(); i.hasNext(); ) {
      ForInit s = (ForInit) i.next();

      if (s instanceof LocalDecl) {
        LocalDecl d = (LocalDecl) s;
        Type dt = d.type().type();
        if (t == null) {
          t = dt;
        } else if (!t.equals(dt)) {
          throw new InternalCompilerError(
              "Local variable "
                  + "declarations in a for loop initializer must all "
                  + "be the same type, in this case "
                  + t
                  + ", not "
                  + dt
                  + ".",
              d.position());
        }
      }
    }

    if (cond != null && !ts.isImplicitCastValid(cond.type(), ts.Boolean())) {
      throw new SemanticException(
          "The condition of a for statement must have boolean type.", cond.position());
    }

    return this;
  }