/**
  * Branching code generation for == operation.
  *
  * @param output the code emitter (basically an abstraction for producing the .class file).
  * @param targetLabel target for generated branch instruction.
  * @param onTrue should we branch on true?
  */
 public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
   lhs.codegen(output);
   rhs.codegen(output);
   if (lhs.type().isReference()) {
     output.addBranchInstruction(onTrue ? IF_ACMPEQ : IF_ACMPNE, targetLabel);
   } else {
     output.addBranchInstruction(onTrue ? IF_ICMPEQ : IF_ICMPNE, targetLabel);
   }
 }
 /**
  * The semantics of j-- require that we implement short-circuiting branching in implementing the
  * logical AND.
  *
  * @param output the code emitter (basically an abstraction for producing the .class file).
  * @param targetLabel target for generated branch instruction.
  * @param onTrue should we branch on true?
  */
 public void codegen(CLEmitter output, String targetLabel, boolean onTrue) {
   if (onTrue) {
     String falseLabel = output.createLabel();
     lhs.codegen(output, falseLabel, false);
     rhs.codegen(output, targetLabel, true);
     output.addLabel(falseLabel);
   } else {
     lhs.codegen(output, targetLabel, false);
     rhs.codegen(output, targetLabel, false);
   }
 }
 /**
  * Generate code for the case where we actually want a boolean value (true or false) computed onto
  * the stack, eg for assignment to a boolean variable.
  *
  * @param output the code emitter (basically an abstraction for producing the .class file).
  */
 public void codegen(CLEmitter output) {
   String elseLabel = output.createLabel();
   String endIfLabel = output.createLabel();
   this.codegen(output, elseLabel, false);
   output.addNoArgInstruction(ICONST_1); // true
   output.addBranchInstruction(GOTO, endIfLabel);
   output.addLabel(elseLabel);
   output.addNoArgInstruction(ICONST_0); // false
   output.addLabel(endIfLabel);
 }
  /**
   * Declare fields in the parent's (partial) class.
   *
   * @param context the parent (class) context.
   * @param partial the code emitter (basically an abstraction for producing the partial class).
   */
  public void preAnalyze(Context context, CLEmitter partial) {
    // Fields may not be declared abstract.
    if (mods.contains("abstract")) {
      JAST.compilationUnit.reportSemanticError(line(), "Field cannot be declared abstract");
    }

    for (JVariableDeclarator decl : decls) {
      // Add field to (partial) class
      decl.setType(decl.type().resolve(context));
      partial.addField(mods, decl.name(), decl.type().toDescriptor(), false);
    }
  }
 /**
  * Code generation for field declaration involves generate field the header.
  *
  * @param output the code emitter (basically an abstraction for producing the .class file).
  */
 public void codegen(CLEmitter output) {
   for (JVariableDeclarator decl : decls) {
     // Add field to class
     output.addField(mods, decl.name(), decl.type().toDescriptor(), false);
   }
 }