blob: dcde297ae75f3205fb3e51c1b05fb87efdad889f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004-2008 Gabor Bergmann and Daniel Varro
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Gabor Bergmann - initial API and implementation
*******************************************************************************/
package org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.construction;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.FlatTuple;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.LeftInheritanceTuple;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.Tuple;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.tuple.TupleMask;
import org.eclipse.viatra2.gtasm.patternmatcher.incremental.rete.util.Options;
/**
* Lightweight class that generates Java code of a builder method from the build actions.
* Code is sent to a coordinator to be collected in string buffers there.
* @author Bergmann Gábor
*/
public abstract class CodegenRecorderBuildable<PatternDescription>
implements Buildable<PatternDescription, String, String>
{
public CodegenRecordingCoordinator<PatternDescription> coordinator;
public PatternDescription effort;
public String myName;
public String baseName;
public String indent;
/**
* @param code
* @param indent
* @param myName
*/
public CodegenRecorderBuildable(CodegenRecordingCoordinator<PatternDescription> coordinator,
PatternDescription effort, String indent, String baseName, String instanceSuffix)
{
super();
this.coordinator = coordinator;
this.effort = effort;
this.indent = indent;
this.baseName = baseName;
this.myName = baseName+instanceSuffix;
}
public void reinitialize() {
throw new UnsupportedOperationException();
}
protected String prettyPrintStringArray(String[] elements, String separator) {
if (elements.length == 0) return "";
else {
StringBuilder result = new StringBuilder(elements[0]);
for (int i=1; i<elements.length; ++i) {
result.append(", ");
result.append(elements[i]);
}
return result.toString();
}
}
protected String prettyPrintStringArray(String[] elements) {
return prettyPrintStringArray(elements, ", ");
}
protected String prettyPrintIntArray(int[] elements, String separator) {
if (elements.length == 0) return "";
else {
StringBuilder result = new StringBuilder();
result.append(elements[0]);
for (int i=1; i<elements.length; ++i) {
result.append(", ");
result.append(elements[i]);
}
return result.toString();
}
}
protected String prettyPrintIntArray(int[] elements) {
return prettyPrintIntArray(elements, ", ");
}
protected String prettyPrintObjectArray(Object[] elements, String separator, boolean strict) {
if (elements.length == 0) return "";
else {
StringBuilder result = new StringBuilder(gen(elements[0], strict));
for (int i=1; i<elements.length; ++i) {
result.append(separator);
result.append(gen(elements[i], strict));
}
return result.toString();
}
}
protected String prettyPrintObjectArray(Object[] constantValues, boolean strict) {
return prettyPrintObjectArray(constantValues, ", ", strict);
}
protected void emitLine(String line) {
coordinator.emitPatternBuilderLine(effort, indent, line);
}
protected String call(String methodName, String arguments) {
return(myName+"."+methodName+"("+arguments+")");
}
protected String call(String methodName, String[] arguments) {
return call(methodName, prettyPrintStringArray(arguments));
}
protected String emitFunctionCall(String resultType, String methodName, String arguments) {
return declareNewValue(resultType, call(methodName, arguments));
}
protected String emitFunctionCall(String resultType, String methodName, String[] arguments) {
return declareNewValue(resultType, call(methodName, arguments));
}
protected void emitProcedureCall(String methodName, String arguments) {
emitLine(call(methodName, arguments)+";");
}
protected void emitProcedureCall(String methodName, String[] arguments) {
emitLine(call(methodName, arguments)+";");
}
protected void declareNew(String type, String identifier, String value, boolean isFinal) {
emitLine((isFinal ? "final " : "") + type + " " + identifier + " = " + value + ";");
}
protected String declareNewValue(String type, String value) {
String name = coordinator.newVariableIdentifier();
declareNew(type, name, value, true);
return name;
}
protected String declareNewBuildable(String value) {
String name = coordinator.newBuildableIdentifier();
declareNew(coordinator.buildableType, name, value, true);
return name;
}
protected String gen(Stub<String> stub) {
return stub.getHandle();
}
protected String gen(boolean bool) {
return bool? "true": "false";
}
protected String gen(Integer integer) {
return integer == null ? "null" : integer.toString();
}
protected String gen(int[] ints) {
// return declareNewValue("int[]", "{"+prettyPrintIntArray(ints)+"}");
return "new int[] {" + prettyPrintIntArray(ints) + "}";
}
protected String gen(TupleMask mask) {
return declareNewValue("TupleMask", "new TupleMask("+gen(mask.indices)+", " + gen(mask.sourceWidth)+ ")");
}
protected String gen(Object o, boolean strict) {
if (o instanceof Number) return o.toString();
if (o instanceof String) return "\"" + o.toString() + "\"";
if (!strict) return "\"" + o.toString() + "\"";
throw new UnsupportedOperationException(
"Cannot currently generate code from an " + o.getClass() + " instance: " + o.toString());
}
protected String gen(Object[] o, boolean strict) {
// return declareNewValue("Object[]", "{"+prettyPrintObjectArray(o, strict)+"}");
return "new Object[] {" + prettyPrintObjectArray(o, strict) + "}";
}
protected String gen(Tuple tuple, boolean strict) {
return "new FlatTuple(" + gen(tuple.getElements(), strict) + ")";
}
public String genCalibrationElement(Object calibrationElement) {
return gen(calibrationElement, false);//calibrationElement.toString();
}
// public String genUnaryType(Object type) {
// return type==null? "null" : "context.retrieveUnaryType(\"" + coordinator.targetContext.retrieveUnaryTypeFQN(type) + "\")";
// }
//
// public String genTernaryEdgeType(Object type) {
// return type==null? "null" : "context.retrieveTernaryEdgeType(\"" + coordinator.targetContext.retrieveBinaryEdgeTypeFQN(type) + "\")";
//
// }
// public String genBinaryEdgeType(Object type) {
// return type==null? "null" : "context.retrieveBinaryEdgeType(\"" + coordinator.targetContext.retrieveTernaryEdgeTypeFQN(type) + "\")";
// }
public abstract String genUnaryType(Object type);
public abstract String genTernaryEdgeType(Object type);
public abstract String genBinaryEdgeType(Object type);
public abstract String genPattern(PatternDescription desc);
//public abstract String genPosMap(PatternDescription desc);
public String declareNextContainerVariable() {
return declareNewBuildable(call("getNextContainer", ""));
}
// public String declarePutOnTabVariable(PatternDescription effort) {
// return declareNewBuildable(call("putOnTab", genPattern(effort)));
// }
////////////////////////////////////
// * BL
////////////////////////////////////
public Stub<String> buildBetaNode(Stub<String> primaryStub, Stub<String> sideStub,
TupleMask primaryMask, TupleMask sideMask,
TupleMask complementer, boolean negative)
{
String[] arguments = {
gen(primaryStub), gen(sideStub),
gen(primaryMask), gen(sideMask),
gen(complementer), gen(negative)
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildBetaNode", arguments);
if (negative) {
return new Stub<String>(primaryStub, resultVar);
} else {
Tuple newCalibrationPattern = negative ?
primaryStub.getVariablesTuple() :
complementer.combine(primaryStub.getVariablesTuple(), sideStub.getVariablesTuple(), Options.enableInheritance, true);
return new Stub<String>(primaryStub, sideStub, newCalibrationPattern, resultVar);
}
}
public Stub<String> buildCountCheckBetaNode(Stub<String> primaryStub,
Stub<String> sideStub, TupleMask primaryMask,
TupleMask originalSideMask, int resultPositionInSignature)
{
String[] arguments = {
gen(primaryStub), gen(sideStub),
gen(primaryMask), gen(originalSideMask),
gen(resultPositionInSignature)
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildCountCheckBetaNode", arguments);
return new Stub<String>(primaryStub, primaryStub.getVariablesTuple(), resultVar);
}
public Stub<String> buildCounterBetaNode(Stub<String> primaryStub,
Stub<String> sideStub, TupleMask primaryMask,
TupleMask originalSideMask, TupleMask complementer,
Object aggregateResultCalibrationElement)
{
String[] arguments = {
gen(primaryStub), gen(sideStub),
gen(primaryMask), gen(originalSideMask),
gen(complementer),
genCalibrationElement(aggregateResultCalibrationElement)
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildCounterBetaNode", arguments);
Object[] newCalibrationElement = {aggregateResultCalibrationElement};
Tuple newCalibrationPattern = new LeftInheritanceTuple(primaryStub.getVariablesTuple(), newCalibrationElement);
return new Stub<String>(primaryStub, newCalibrationPattern, resultVar);
}
public void buildConnection(Stub<String> stub, String collector) {
String[] arguments = {
gen(stub), collector
};
emitProcedureCall("buildConnection", arguments);
}
public Stub<String> buildEqualityChecker(Stub<String> stub, int[] indices) {
String[] arguments = {
gen(stub),
gen(indices)
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildEqualityChecker", arguments);
return new Stub<String>(stub, resultVar);
}
public Stub<String> buildInjectivityChecker(Stub<String> stub, int subject, int[] inequalIndices) {
String[] arguments = {
gen(stub), gen(subject),
gen(inequalIndices)
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildInjectivityChecker", arguments);
return new Stub<String>(stub, resultVar);
}
@Override
public Stub<String> buildTransitiveClosure(Stub<String> stub) {
String[] arguments = {
gen(stub)
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildTransitiveClosure", arguments);
return new Stub<String>(stub, resultVar);
}
public Stub<String> buildScopeConstrainer(Stub<String> stub, boolean transitive,
Object unwrappedContainer, int constrainedIndex) {
throw new UnsupportedOperationException("Code generation does not support external scoping as of now");
}
public Stub<String> buildStartStub(Object[] constantValues, Object[] constantNames) {
String[] arguments = {
gen(constantValues, true),
gen(constantNames, false),
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildStartStub", arguments);
return new Stub<String>(new FlatTuple(constantNames), resultVar);
}
public Stub<String> buildTrimmer(Stub<String> stub, TupleMask trimMask) {
String[] arguments = {
gen(stub), gen(trimMask)
};
String resultVar = emitFunctionCall(coordinator.stubType, "buildTrimmer", arguments);
return new Stub<String>(stub, trimMask.transform(stub.getVariablesTuple()), resultVar);
}
public Stub<String> containmentDirectStub(Tuple nodes) {
String[] arguments = {
gen(nodes, false)
};
String resultVar = emitFunctionCall(coordinator.stubType, "containmentDirectStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> containmentTransitiveStub(Tuple nodes) {
String[] arguments = {
gen(nodes, false)
};
String resultVar = emitFunctionCall(coordinator.stubType, "containmentTransitiveStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> unaryTypeStub(Tuple nodes, Object supplierKey) {
String[] arguments = {
gen(nodes, false), declareNewValue("Object", genUnaryType(supplierKey))
};
String resultVar = emitFunctionCall(coordinator.stubType, "unaryTypeStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> generalizationDirectStub(Tuple nodes) {
String[] arguments = {
gen(nodes, false)
};
String resultVar = emitFunctionCall(coordinator.stubType, "generalizationDirectStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> generalizationTransitiveStub(Tuple nodes) {
String[] arguments = {
gen(nodes, false)
};
String resultVar = emitFunctionCall(coordinator.stubType, "generalizationTransitiveStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> instantiationDirectStub(Tuple nodes) {
String[] arguments = {
gen(nodes, false)
};
String resultVar = emitFunctionCall(coordinator.stubType, "instantiationDirectStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> instantiationTransitiveStub(Tuple nodes) {
String[] arguments = {
gen(nodes, false)
};
String resultVar = emitFunctionCall(coordinator.stubType, "instantiationTransitiveStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> patternCallStub(Tuple nodes, PatternDescription supplierKey)
{
//if (!coordinator.collectors.containsKey(supplierKey)) coordinator.unbuilt.add(supplierKey);
String[] arguments = {
gen(nodes, false), genPattern(supplierKey)
};
String resultVar = emitFunctionCall(coordinator.stubType, "patternCallStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> binaryEdgeTypeStub(Tuple nodes, Object supplierKey) {
String[] arguments = {
gen(nodes, false), declareNewValue("Object", genBinaryEdgeType(supplierKey))
};
String resultVar = emitFunctionCall(coordinator.stubType, "binaryEdgeTypeStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public Stub<String> ternaryEdgeTypeStub(Tuple nodes, Object supplierKey) {
String[] arguments = {
gen(nodes, false), declareNewValue("Object", genTernaryEdgeType(supplierKey))
};
String resultVar = emitFunctionCall(coordinator.stubType, "ternaryEdgeTypeStub", arguments);
return new Stub<String>(nodes, resultVar);
}
public String patternCollector(PatternDescription pattern) {
String patternName = genPattern(pattern);
String[] arguments = {patternName};
return emitFunctionCall(coordinator.collectorType, "patternCollector", arguments);
// return coordinator.allocateNewCollector(pattern);
}
// /**
// * @pre coordinator.isComplete()
// */
// public void printInitializer(String collectorsMap, String posMappingMap) {
// for (Entry<PatternDescription, String> entry : coordinator.collectors.entrySet()) {
// String patternName = genPattern(entry.getKey());
// emitLine("// "+patternName);
// emitLine(posMappingMap + ".put(" + patternName + ", " +genPosMap(entry.getKey()) + ");");
// String[] arguments = {patternName};
// String resultVar = emitFunctionCall(coordinator.collectorType, "patternCollector", arguments);
// emitLine(entry.getValue() + " = " + resultVar + ";");
// emitLine(collectorsMap + ".put(" + patternName + ", " +entry.getValue() + ");");
// }
// }
}