package nebula.vm;
/***
* 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<Address> 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, int offset, boolean forward) {
this(name);
isForwardRef = forward;
if (forward) {
// if forward reference, then address is address to update
addForwardReference(address, offset);
} else {
this.address = address;
}
}
class Address {
int ip;
int offset;
Address(int ip, int offset) {
this.ip = ip;
this.offset = offset;
}
}
public void addForwardReference(int address, int offset) {
if (forwardReferences == null) {
forwardReferences = new Vector<Address>();
}
forwardReferences.addElement(new Address(address, offset));
}
public void resolveForwardReferences(int[] code) {
isForwardRef = false;
// need to patch up all references to this symbol
Vector<Address> opndsToPatch = forwardReferences;
for (Address addrToPatch : opndsToPatch) {
/*
* System.out.println("updating operand at addr "+
* addr+" to be "+getAddress());
*/
code[addrToPatch.ip] = code[addrToPatch.ip] | (address << addrToPatch.offset);
// BytecodeAssembler2.writeInt(code, addrToPatch, address);
}
}
public String toString() {
String refs = "";
if (forwardReferences != null) {
refs = "[refs=" + forwardReferences.toString() + "]";
}
return name + "@" + address + refs;
}
}