package org.mozartoz.truffle.nodes;

import org.mozartoz.truffle.runtime.OzFailedValue;
import org.mozartoz.truffle.runtime.OzFuture;
import org.mozartoz.truffle.runtime.OzReadOnly;
import org.mozartoz.truffle.runtime.OzVar;

import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.Specialization;

@NodeChild("value")
public abstract class DerefIfBoundNode extends OzNode {

	public static DerefIfBoundNode create() {
		return DerefIfBoundNodeGen.create(null);
	}

	public static DerefIfBoundNode create(OzNode node) {
		assert !(node instanceof DerefIfBoundNode);
		assert !(node instanceof DerefNode);
		return DerefIfBoundNodeGen.create(node);
	}

	public abstract OzNode getValue();

	public abstract Object executeDerefIfBound(Object value);

	@Specialization
	Object derefIfBound(OzVar var) {
		if (var.isBound()) {
			return var.getBoundValue(this);
		} else {
			return var;
		}
	}

	@Specialization
	Object derefIfBound(OzFuture future) {
		if (future.isBound()) {
			return future.getBoundValue(this);
		} else {
			return future;
		}
	}

	@Specialization
	Object derefIfBound(OzReadOnly readOnly) {
		if (readOnly.isBound()) {
			return readOnly.getBoundValue(this);
		} else {
			return readOnly;
		}
	}

	@Specialization
	Object derefIfBound(OzFailedValue failedValue) {
		return failedValue;
	}

	@Specialization(guards = "!isVariable(value)")
	Object derefIfBound(Object value) {
		return value;
	}

}

@@ -70,158 +70,16 @@
 ime.
-OzFailedValue;%0Aimport org.mozartoz.truffle.runtime.OzFuture;%0Aimport org.mozartoz.truffle.runtime.OzReadOnly;%0Aimport org.mozartoz.truffle.runtime.OzVar
+Variable
 ;%0A%0Ai
@@ -643,151 +643,34 @@
 tion
-%0A%09Object derefIfBound(OzVar var) %7B%0A%09%09if (var.isBound()) %7B%0A%09%09%09return var.getBoundValue(this);%0A%09%09%7D else %7B%0A%09%09%09return var;%0A%09%09%7D%0A%09%7D%0A%0A%09@Specialization
+(guards = %22var.isBound()%22)
 %0A%09Ob
@@ -683,62 +683,30 @@
 eref
-If
 Bound(
-OzFuture future) %7B%0A%09%09if (future.isBound()
+Variable var
 ) %7B%0A
-%09
 %09%09re
@@ -710,22 +710,19 @@
 %09return 
-future
+var
 .getBoun
@@ -740,275 +740,92 @@
 );%0A%09
-%09%7D else %7B%0A%09%09%09return future;%0A%09%09%7D%0A%09%7D%0A%0A%09@Specialization%0A%09Object derefIfBound(OzReadOnly readOnly) %7B%0A%09%09if (readOnly.isBound()) %7B%0A%09%09%09return readOnly.getBoundValue(this);%0A%09%09%7D else %7B%0A%09%09%09return readOnly;%0A%09%09%7D%0A%09%7D%0A%0A%09@Specialization%0A%09Object d
+%7D%0A%0A%09@Specialization(guards = %22!var.isBound()%22)%0A%09Variable noD
 eref
-IfB
+Unb
 ound(
-OzFailedValue failedValue
+Variable var
 ) %7B%0A
@@ -837,19 +837,11 @@
 urn 
-failedValue
+var
 ;%0A%09%7D

Simplify and optimize DerefIfBoundNode