@Override
	public Scalar evaluate(final ScriptEnvironment e) {
	
		if (return_type == ScriptEnvironment.FLOW_CONTROL_THROW) {
			final Scalar temp = (Scalar) e.getCurrentFrame().pop();
			if (!SleepUtils.isEmptyScalar(temp)) {
				e.getScriptInstance().clearStackTrace();
				e.getScriptInstance().recordStackFrame("<origin of exception>", getLineNumber());
				e.flagReturn(temp, ScriptEnvironment.FLOW_CONTROL_THROW);
			}
		} else if (return_type == ScriptEnvironment.FLOW_CONTROL_BREAK || return_type == ScriptEnvironment.FLOW_CONTROL_CONTINUE) {
			e.flagReturn(null, return_type);
		} else if (return_type == ScriptEnvironment.FLOW_CONTROL_CALLCC) {
			final Scalar temp = e.getCurrentFrame().isEmpty() ? SleepUtils.getEmptyScalar() : (Scalar) e.getCurrentFrame().pop();
			
			if (!SleepUtils.isFunctionScalar(temp)) {
				e.getScriptInstance().fireWarning("callcc requires a function: " + SleepUtils.describe(temp), getLineNumber());
				e.flagReturn(temp, ScriptEnvironment.FLOW_CONTROL_YIELD);
			} else {
				e.flagReturn(temp, return_type);
			}
		} else if (e.getCurrentFrame().isEmpty()) {
			e.flagReturn(SleepUtils.getEmptyScalar(), return_type);
		} else {
			e.flagReturn((Scalar) e.getCurrentFrame().pop(), return_type);
		}
		
		e.KillFrame();
		return null;
	}