LocalVariable letNameVariable = new LocalVariable(javaName, JavaTypeNames.RTINDIRECTION);
// RTValue javaName = new RTIndirection();
JavaExpression newIndirection = new ClassInstanceCreationExpression(JavaTypeNames.RTINDIRECTION);
LocalVariableDeclaration letDecl = new LocalVariableDeclaration(letNameVariable, newIndirection);
declarationBlock.addStatement(letDecl);
// Emit let variable definition.
// letName.setResult(letDef);
MethodInvocation letInvocation = createInvocation(letNameVariable, SETRESULT, boxedVarDef);
definitionBlock.addStatement(new ExpressionStatement(letInvocation));
} else
if (info instanceof VarInfo.LetNonRec) {
// This variable is referenced multiple times.
// We need to declare/initialize a local java variable.
// If the variable is already evaluated we behave differently.
if (info.isEvaluated()) {
if (info.getUnboxedType() != null) {
// The definition function will return an unboxed value.
// Declare an unboxed local variable.
LocalVariable unboxedLocal = new LocalVariable(info.getJavaName()+"$U", info.getUnboxedType());
LocalVariableDeclaration unboxedVarDecl = new LocalVariableDeclaration(unboxedLocal, ((VarInfo.LetNonRec)info).getUnboxedVarDef());
declarationBlock.addStatement(unboxedVarDecl);
} else {
// All references will be boxed.
// Declare a boxed local variable an update the strict/lazy refs.
// We use the strict variable def since we know this variable is already evaluated.
LocalVariable boxedLocal = new LocalVariable(info.getJavaName(), JavaTypeNames.RTVALUE);
LocalVariableDeclaration boxedVarDecl = new LocalVariableDeclaration(boxedLocal, ((VarInfo.LetNonRec)info).getStrictVarDef());
declarationBlock.addStatement(boxedVarDecl);
}
} else {
// The variable is not pre-evaluated.
// The variable is referenced more than once.
// We want to use the lazy initializer.
LocalVariable boxedLocal = new LocalVariable(info.getJavaName(), JavaTypeNames.RTVALUE);
LocalVariableDeclaration boxedVarDecl = new LocalVariableDeclaration(boxedLocal, ((VarInfo.LetNonRec)info).getLazyVarDef());
declarationBlock.addStatement(boxedVarDecl);
}
} else
if (info instanceof VarInfo.DCMember){
// The DCMember instance of VarInfo will only have one
// varDef defined. i.e. unboxed or strict or lazy.
JavaExpression unboxedVarDef = ((VarInfo.DCMember)info).getUnboxedVarDef();
JavaExpression lazyVarDef = ((VarInfo.DCMember)info).getLazyVarDef();
JavaExpression strictVarDef = ((VarInfo.DCMember)info).getStrictVarDef();
if (unboxedVarDef != null) {
// Base declarations on unboxed definition.
// Declare a local unboxed variable and update the unboxed reference.
LocalVariable unboxedLocal = new LocalVariable(javaName+"$U", info.getUnboxedType());
LocalVariableDeclaration letDecl = new LocalVariableDeclaration(unboxedLocal, unboxedVarDef);
declarationBlock.addStatement(letDecl);
} else
if (strictVarDef != null) {
// If there is a strict variable definition we should never have unboxed use.
// Since a strict variable of an unboxable type would have an unboxed variable definition.
// Declare a boxed local and update the strict and lazy references.
LocalVariable boxedLocal = new LocalVariable (javaName, JavaTypeNames.RTVALUE);
LocalVariableDeclaration boxedDecl = new LocalVariableDeclaration (boxedLocal, strictVarDef);
declarationBlock.addStatement(boxedDecl);
info.updateStrictReference(boxedLocal);
info.updateLazyReference(boxedLocal);
} else {
// Lazy variable.
// Declare a lazy local variable.
LocalVariable lazyLocal = new LocalVariable(info.getJavaName(), JavaTypeNames.RTVALUE);
LocalVariableDeclaration lazyDecl = new LocalVariableDeclaration(lazyLocal, lazyVarDef);
declarationBlock.addStatement(lazyDecl);
}
}
}