CommonMacroExpansion.java
package dev.civl.abc.token.common;
import org.antlr.runtime.Token;
import dev.civl.abc.token.IF.CivlcToken;
import dev.civl.abc.token.IF.Formation;
import dev.civl.abc.token.IF.FunctionMacro;
import dev.civl.abc.token.IF.FunctionMacro.FunctionReplacementUnit;
import dev.civl.abc.token.IF.Macro;
import dev.civl.abc.token.IF.MacroExpansion;
import dev.civl.abc.token.IF.SourceFile;
import dev.civl.abc.token.IF.SourceFormatter;
public class CommonMacroExpansion implements MacroExpansion {
/**
* The start token, a token from the macro invocation. See comments in the
* interface MacroExpansion explaining this concept.
*/
private CivlcToken startToken;
/**
* The macro doing the expanding. Its name should be the same as the text of
* the startToken.
*/
private Macro macro;
/**
* The index of the token resulting from the expansion in the list of
* replacement tokens for the macro. In other words, the end token is the
* index-th replacement token from macro's replacement list.
*/
private int index;
CommonMacroExpansion(CivlcToken startToken, Macro macro, int index) {
this.startToken = startToken;
this.macro = macro;
this.index = index;
}
@Override
public String suffix() {
if (macro instanceof FunctionMacro) {
FunctionMacro fm = (FunctionMacro) macro;
FunctionReplacementUnit unit = fm.getReplacementUnit(index);
if (unit.formalIndex >= 0) { // a formal parameter
Token token = unit.token;
String macroDefFile = macro.getFile().getName();
int line = token.getLine();
String text = token.getText();
int startCol = token.getCharPositionInLine();
int stopCol = startCol + text.length() - 1;
return " substituted for "
+ SourceFormatter.locator(macroDefFile, line, startCol,
stopCol)
+ " " + SourceFormatter.quoteSource(text, true);
}
}
return " expanded from " + startToken.toString();
}
@Override
public String toString() {
return "MacroExpansion[" + startToken.getText() + ", " + macro.getName()
+ ", " + index + "]";
}
@Override
public CivlcToken getStartToken() {
return startToken;
}
@Override
public Macro getMacro() {
return macro;
}
@Override
public int getReplacementTokenIndex() {
return index;
}
@Override
public SourceFile getLastFile() {
if (macro instanceof FunctionMacro) {
FunctionReplacementUnit unit = ((FunctionMacro) macro)
.getReplacementUnit(index);
if (unit.formalIndex >= 0) // a formal parameter
return startToken.getSourceFile();
}
return macro.getFile();
}
public boolean similar(Formation form) {
if (this == form)
return true;
if (!(form instanceof CommonMacroExpansion))
return false;
CommonMacroExpansion that = (CommonMacroExpansion) form;
if (macro == null) {
if (that.macro != null)
return false;
} else if (!macro.equals(that.macro)) {
return false;
}
if (macro instanceof FunctionMacro) {
FunctionMacro fm = (FunctionMacro) macro;
FunctionReplacementUnit unit = fm.getReplacementUnit(index);
if (unit.formalIndex >= 0) { // a formal parameter, substitution
// ignore startToken
return index == that.index;
}
}
// an expansion token, ignore index
if (startToken == null) {
if (that.startToken != null)
return false;
}
return startToken.equals(that.startToken);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!(obj instanceof CommonMacroExpansion))
return false;
CommonMacroExpansion that = (CommonMacroExpansion) obj;
return similar(that);
/*
* if (startToken == null) { if (that.startToken != null) return false;
* } else if (!startToken.equals(that.startToken)) { return false; } if
* (macro == null) { if (that.macro != null) return false; } else if
* (!macro.equals(that.macro)) { return false; } if (index !=
* that.index) return false; return true;
*/
}
}