CommonFunctionMacro.java
package edu.udel.cis.vsl.abc.token.common;
import java.util.HashMap;
import java.util.Map;
import org.antlr.runtime.Token;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.Tree;
import edu.udel.cis.vsl.abc.front.c.preproc.PreprocessorLexer;
import edu.udel.cis.vsl.abc.token.IF.FunctionMacro;
import edu.udel.cis.vsl.abc.token.IF.SourceFile;
public class CommonFunctionMacro extends CommonMacro implements FunctionMacro {
private boolean variadic = false;
public CommonFunctionMacro(Tree definitionNode, SourceFile file) {
super(definitionNode, file);
initialize();
}
private void initialize() {
int numFormals = getNumFormals();
int numReplacements = getNumReplacements();
Map<String, Integer> nameMap = new HashMap<String, Integer>(numFormals);
for (int i = 0; i < numFormals; i++) {
Token formal = getFormal(i);
String formalName;
if (i == numFormals - 1 && "...".equals(formal.getText())) {
formalName = "__VA_ARGS__";
variadic = true;
} else
formalName = formal.getText();
nameMap.put(formalName, i);
}
for (int j = 0; j < numReplacements; j++) {
FunctionReplacementUnit unit = getReplacementUnit(j);
Token token = unit.token;
if (token.getType() == PreprocessorLexer.IDENTIFIER) {
String name = token.getText();
Integer lookup = nameMap.get(name);
if (lookup != null) {
unit.formalIndex = lookup;
continue;
}
}
unit.formalIndex = -1;
}
}
@Override
public Tree getBodyNode() {
return definitionNode.getChild(2);
}
public int getNumFormals() {
return definitionNode.getChild(1).getChildCount();
}
public Token getFormal(int index) {
return ((CommonTree) definitionNode.getChild(1).getChild(index))
.getToken();
}
@Override
public String toString() {
StringBuffer buf = new StringBuffer("FunctionMacro[" + getName() + "(");
int numFormals = getNumFormals();
int numReplacements = getNumReplacements();
for (int j = 0; j < numFormals; j++) {
if (j > 0)
buf.append(',');
buf.append(getFormal(j).getText());
}
buf.append(") =");
for (int i = 0; i < numReplacements; i++) {
ReplacementUnit unit = getReplacementUnit(i);
buf.append(unit.token.getText());
for (Token t : unit.whitespace)
buf.append(t.getText());
}
buf.append("]");
return buf.toString();
}
@Override
public boolean equals(Object object) {
if (this == object)
return true;
if (object instanceof CommonFunctionMacro) {
CommonFunctionMacro that = (CommonFunctionMacro) object;
if (!super.equals(that))
return false;
int numFormals = getNumFormals();
if (numFormals != that.getNumFormals())
return false;
for (int i = 0; i < numFormals; i++) {
Token t1 = getFormal(i);
Token t2 = that.getFormal(i);
if (t1.getType() != t2.getType()
|| !t1.getText().equals(t2.getText()))
return false;
}
return true;
}
return false;
}
@Override
public FunctionReplacementUnit getReplacementUnit(int index) {
return (FunctionReplacementUnit) super.getReplacementUnit(index);
}
@Override
protected ReplacementUnit makeReplacement(int index, Token token,
Token[] whitespace) {
return new FunctionReplacementUnit(index, token, whitespace);
}
@Override
public boolean isVariadic() {
return variadic;
}
}