package test.antlr.assembler; /*** * Excerpted from "Language Implementation Patterns", * published by The Pragmatic Bookshelf. * Copyrights apply to this code. It may not be used to create training material, * courses, books, articles, and the like. Contact us if you are in doubt. * We make no guarantees that this code is fit for any purpose. * Visit http://www.pragmaticprogrammer.com/titles/tpdsl for more book information. ***/ import java.util.*; public class LabelSymbol { String name; /** Address in code memory */ int address; /** Is this ref'd before def'd. */ boolean isForwardRef = false; /** Set when we see actual ID: definition */ boolean isDefined = true; /** List of operands in memory we need to update after seeing def */ Vector<Integer> forwardReferences = null; public LabelSymbol(String name) { this.name = name; } public LabelSymbol(String name, int address) { this(name); this.address = address; } public LabelSymbol(String name, int address, boolean forward) { this(name); isForwardRef = forward; if ( forward ) { // if forward reference, then address is address to update addForwardReference(address); } else { this.address = address; } } public void addForwardReference(int address) { if ( forwardReferences==null ) { forwardReferences = new Vector<Integer>(); } forwardReferences.addElement(new Integer(address)); } public void resolveForwardReferences(byte[] code) { isForwardRef = false; // need to patch up all references to this symbol Vector<Integer> opndsToPatch = forwardReferences; for (int addrToPatch : opndsToPatch) { /* System.out.println("updating operand at addr "+ addr+" to be "+getAddress()); */ BytecodeAssembler.writeInt(code, addrToPatch, address); } } public String toString() { String refs = ""; if ( forwardReferences!=null ) { refs = "[refs="+forwardReferences.toString()+"]"; } return name+"@"+address+refs; } }