if (functions.getNCAFs() + functions.getNZeroArityFunctions() <= 1) {
for (final MachineFunction mf : functions.getTopLevelCALFunctions()) {
JavaField instanceField = new JavaField.Static(className, CALToJavaNames.getInstanceFieldName(mf.getQualifiedName(), module), className);
if (mf.isCAF()) {
Block b = new Block();
// This is a CAF (constant applicative form) we want to use the cached instance associated
// with the execution context, if it exists.
// If it doesn't exist we will create an instance and add it to the cache.
String instanceMapFieldName = functions.getFNamePrefix(mf.getName()) + "$instancesMap";
JavaField instanceMapField =
new JavaField.Static(className, instanceMapFieldName, JavaTypeName.MAP);
// RTFunction newInstance = (RTFunction)$instancesMap.get($ec);
JavaExpression.LocalVariable newInstanceVar =
new JavaExpression.LocalVariable("newInstance", returnType);
JavaExpression initializer = new JavaExpression.CastExpression(
returnType,
new MethodInvocation.Instance(
instanceMapField,
"get",
SCJavaDefn.EXECUTION_CONTEXT_VAR,
JavaTypeName.OBJECT,
JavaTypeName.OBJECT,
MethodInvocation.InvocationType.INTERFACE));
JavaStatement decl = new JavaStatement.LocalVariableDeclaration(newInstanceVar, initializer);
b.addStatement(decl);
// If no instance exists for the execution context create one and cache it.
// newInstance == null
JavaExpression comparison = new JavaExpression.OperatorExpression.Binary(JavaOperator.EQUALS_OBJECT, newInstanceVar, JavaExpression.LiteralWrapper.NULL);
// newInstance = new RTFullApp.General_0($instance);
// $instancesMap.put($ec, newInstance);
JavaStatement.Block then = new JavaStatement.Block();
then.addStatement(new ExpressionStatement(new JavaExpression.Assignment(newInstanceVar, new JavaExpression.ClassInstanceCreationExpression(_0TypeName, instanceField, JavaTypeNames.RTSUPERCOMBINATOR))));
JavaExpression cacheValue = new MethodInvocation.Instance(
instanceMapField,
"put",
new JavaExpression[] {
SCJavaDefn.EXECUTION_CONTEXT_VAR,
newInstanceVar },
new JavaTypeName[] {
JavaTypeName.OBJECT,
JavaTypeName.OBJECT },
JavaTypeName.OBJECT,
MethodInvocation.InvocationType.INTERFACE);
then.addStatement(new ExpressionStatement(cacheValue));
// Put the whole if expression together.
JavaStatement ifthen = new JavaStatement.IfThenElseStatement(comparison, then);
b.addStatement(ifthen);
b.addStatement(new ReturnStatement(newInstanceVar));
javaMethod.addStatement(b);
break;
} else if (mf.getArity() == 0) {
Block b = new Block();
// This is an unsafe method. i.e. a non-CAF function of arity zero. Since the
// function can have side effects we need to create a new instance of the class
// each time so that a previously evaluated value doesn't get re-used in place
// of actually executing the function.
JavaExpression.LocalVariable newInstanceVar = new JavaExpression.LocalVariable("newInstance", returnType);
JavaExpression initializer = new ClassInstanceCreationExpression(_0TypeName, instanceField, JavaTypeNames.RTSUPERCOMBINATOR);
JavaStatement decl = new JavaStatement.LocalVariableDeclaration(newInstanceVar, initializer);
b.addStatement(decl);
b.addStatement(new ReturnStatement(newInstanceVar));
javaMethod.addStatement(b);
break;
}
}
} else {
SwitchStatement switchStatement =
new SwitchStatement(new MethodVariable("scIndex"));
for (final MachineFunction mf : functions.getTopLevelCALFunctions()) {
JavaField instanceField = new JavaField.Static(className, CALToJavaNames.getInstanceFieldName(mf.getQualifiedName(), module), className);
int functionIndex = functions.getFunctionIndex(mf.getName());
if (mf.isCAF()) {
Block b = new Block();
// This is a CAF (constant applicative form) we want to use the cached instance associated
// with the execution context, if it exists.
// If it doesn't exist we will create an instance and add it to the cache.
String instanceMapFieldName = functions.getFNamePrefix(mf.getName()) + "$instancesMap";
JavaField instanceMapField =
new JavaField.Static(className, instanceMapFieldName, JavaTypeName.MAP);
// RTFunction newInstance = (RTFunction)$instancesMap.get($ec);
JavaExpression.LocalVariable newInstanceVar = new JavaExpression.LocalVariable("newInstance", returnType);
JavaExpression initializer =
new JavaExpression.CastExpression(returnType, new MethodInvocation.Instance (instanceMapField,
"get",
SCJavaDefn.EXECUTION_CONTEXT_VAR,
JavaTypeName.OBJECT,
JavaTypeName.OBJECT,
MethodInvocation.InvocationType.INTERFACE));
JavaStatement decl = new JavaStatement.LocalVariableDeclaration(newInstanceVar, initializer);
b.addStatement(decl);
// If no instance exists for the execution context create one and cache it.
// newInstance == null
JavaExpression comparison = new JavaExpression.OperatorExpression.Binary(JavaOperator.EQUALS_OBJECT, newInstanceVar, JavaExpression.LiteralWrapper.NULL);
// newInstance = new RTFullApp.General_0($instance);
// $instancesMap.put($ec, newInstance);
JavaStatement.Block then = new JavaStatement.Block();
then.addStatement(new ExpressionStatement(new JavaExpression.Assignment(newInstanceVar, new JavaExpression.ClassInstanceCreationExpression(_0TypeName, instanceField, JavaTypeNames.RTSUPERCOMBINATOR))));
JavaExpression cacheValue =
new MethodInvocation.Instance(instanceMapField,
"put",
new JavaExpression[]{SCJavaDefn.EXECUTION_CONTEXT_VAR, newInstanceVar},
new JavaTypeName[]{JavaTypeName.OBJECT, JavaTypeName.OBJECT},
JavaTypeName.OBJECT,
MethodInvocation.InvocationType.INTERFACE);
then.addStatement(new ExpressionStatement(cacheValue));
// Put the whole if expression together.
JavaStatement ifthen = new JavaStatement.IfThenElseStatement(comparison, then);
b.addStatement(ifthen);
b.addStatement(new ReturnStatement(newInstanceVar));
switchStatement.addCase(
new SwitchStatement.IntCaseGroup(
functionIndex,
b));