//so declare them private for safety sake.
instanceModifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;
} else {
instanceModifiers = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
}
final JavaFieldDeclaration instanceDeclaration =
new JavaFieldDeclaration(instanceModifiers,
className,
fieldName,
initializer);
if (functions.getNFunctions() <= 1) {
instanceDeclaration.setJavaDoc(new JavaDocComment("Singleton instance of this class."));
} else {
instanceDeclaration.setJavaDoc(new JavaDocComment("Instance of this class representing CAL function " + mf.getName() + "."));
}
javaClassRep.addFieldDeclaration(instanceDeclaration);
}
if (sharedValues.getNStaticErrorInfo() > 0) {
javaClassRep.addComment(new JavaStatement.MultiLineComment("ErrorInfo instances."));
}
for (final String name : sharedValues.getStaticErrorInfoNames()) {
final JavaExpression initializer = sharedValues.getStaticError(name);
final int instanceModifiers = Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL;
final JavaFieldDeclaration errorDeclaration = new JavaFieldDeclaration(instanceModifiers, JavaTypeName.ERRORINFO, name, initializer);
javaClassRep.addFieldDeclaration(errorDeclaration);
}
// If this function references other supercombinators we need to set
// up a field for each referenced SC, a flag to indicate the
// initialization state of the referenced SC fields, and potentially an
// object to be used as a synchronization mutex for the initialization method.
final int referencedDCModifiers = Modifier.STATIC | Modifier.PRIVATE | Modifier.FINAL;
// Create an instance field for each referenced data constructor. This will give us
// a local reference that can be used in the body function.
// e.g. RTFunction i_Foo;
if (sharedValues.getNReferencedDCs() > 0) {
javaClassRep.addComment(new JavaStatement.MultiLineComment("Data constructor class instances for all referenced data constructors."));
}
for (final ReferencedDCInfo rfi : sharedValues.getReferencedDCs()) {
DataConstructor dc = rfi.getDC();
JavaField jf = rfi.getJField();
JavaExpression fieldInitializer;
if (dc.getArity() > 0) {
// Just invoke the regular make invocation to get the singleton SC/DC instance.
fieldInitializer =
new MethodInvocation.Static(jf.getFieldType(), "make", JavaExpression.EMPTY_JAVA_EXPRESSION_ARRAY, JavaExpression.EMPTY_TYPE_NAME_ARRAY, jf.getFieldType());
} else {
// This is a zero arity data constructor. We get the singleton instance by accessing
// the DataType class factory method if the data type has more than one zero arity DC.
TypeConstructor typeCons = dc.getTypeConstructor();
if (SCJavaDefn.isTagDC(dc, module)) {
JavaTypeName typeClass = CALToJavaNames.createTypeNameFromType(typeCons, module);
JavaTypeName tagDCTypeName = CALToJavaNames.createTypeNameForTagDCFromType(typeCons, module);
Integer ordinal = Integer.valueOf(dc.getOrdinal());
fieldInitializer = new MethodInvocation.Static(typeClass, "getTagDC", LiteralWrapper.make(ordinal), JavaTypeName.INT, tagDCTypeName);
} else {
// Just invoke the regular make invocation to get the singleton SC/DC instance.
fieldInitializer =
new MethodInvocation.Static(jf.getFieldType(), "make", JavaExpression.EMPTY_JAVA_EXPRESSION_ARRAY, JavaExpression.EMPTY_TYPE_NAME_ARRAY, jf.getFieldType());
}
}
JavaFieldDeclaration dcDeclaration =
new JavaFieldDeclaration(
referencedDCModifiers,
jf.getFieldType(),
jf.getFieldName(),
fieldInitializer);
javaClassRep.addFieldDeclaration(dcDeclaration);
}
if (functions.includesCAFs()) {
javaClassRep.addComment(new JavaStatement.MultiLineComment("Mappings of execution context to CAF instances."));
// Add an instance field to hold a Map of
// ExecutionContext -> RTFullApp.General._0
// A map for associating instances of this SC with execution contexts.
// This is only created for CAF functions. There are two reasons why CAFs
// have an instance for each execution context. One is thread safety. The
// other is so that different threads of execution can release cached CAF
// results at will.
for (final MachineFunction mf : functions.getTopLevelCALFunctions()) {
if (mf.isCAF()) {
//we do not synchronize the instance map, but rather the methods in the CAF class that mutate it.
//this is because the make method has check-then-modify semantics, and so needs to be synchronized at the method
//level anyways.
JavaExpression instancesMapInit = new ClassInstanceCreationExpression(JavaTypeName.WEAK_HASH_MAP);
String mapPrefix = functions.getFNamePrefix(mf.getName());
JavaFieldDeclaration instancesMap =
new JavaFieldDeclaration (
Modifier.STATIC | Modifier.PRIVATE | Modifier.FINAL,
JavaTypeName.MAP,
mapPrefix + "$instancesMap",
instancesMapInit);
instancesMap.setJavaDoc(new JavaDocComment("Execution context -> instance map for " + mf.getName()));
javaClassRep.addFieldDeclaration(instancesMap);
}
}
}
// We have two int instance fields to hold the tag, indicating which function
// is represented by the class instance, and the arity of that function.
// These fields are only needed if the class represents more than one function.
if (functions.getNFunctions() > 1) {
JavaFieldDeclaration scTagDeclaration =
new JavaFieldDeclaration(Modifier.PRIVATE | Modifier.FINAL,
JavaTypeName.INT,
SCDefinitionBuilder.functionTagFieldName,
null);
List<String> commentLines = new ArrayList<String> ();
commentLines.add ("Tag field indicating which CAL function this class instance represents.");
for (int i = 0, n = functions.getTopLevelCALFunctions().size(); i < n; ++i) {
String fName = functions.getFunctionNameFromIndex(i);
commentLines.add(" " + i + " -> " + fName);
}
scTagDeclaration.setJavaDoc(new JavaStatement.JavaDocComment(commentLines));
javaClassRep.addFieldDeclaration(scTagDeclaration);
JavaFieldDeclaration arityDeclaration =
new JavaFieldDeclaration(Modifier.PRIVATE | Modifier.FINAL,
JavaTypeName.INT,
"arity",
null);
arityDeclaration.setJavaDoc(new JavaStatement.JavaDocComment("Field holding arity of represented function."));
javaClassRep.addFieldDeclaration(arityDeclaration);
}
if (LECCMachineConfiguration.SANITY_CHECK_LET_VARS) {
// Create a boolean flag for each lifted let variable definition.
for (final MachineFunction mf : functions.getLiftedLetVarDefFunctions()) {
String flagName = CALToJavaNames.cleanSCName(mf.getName()) + "_flag_";
javaClassRep.addFieldDeclaration(
new JavaFieldDeclaration(Modifier.PRIVATE, JavaTypeName.BOOLEAN, flagName, LiteralWrapper.make(Boolean.FALSE)));
}
}
}