(**
 	Module: Value	
	Description: basic data type in the vectorial faust interpreter.
	@author WANG Haisheng	
	Created: 31/05/2013	Modified: 17/07/2013
*)

open Types;;
open Basic;;
open Nest;;

let convert : (basic -> 'a) -> basic -> 'a = 
  fun oper -> fun b -> oper b;;

class value : basic -> value_type = 
  fun (b_init : basic) ->
    object (self)
      val mutable b = b_init
      method get = b
      method normalize = b <- basic_normalize self#get

      method to_float = convert basic_to_float self#get
      method to_int = convert basic_to_int self#get      
      method to_float_array = convert basic_to_float_array self#get
      method to_string = convert basic_to_string self#get
      method to_neststring = convert basic_to_neststring self#get
      method of_float_array : float array -> value_type =
	fun data -> new value (basic_of_float_array data)

      method private prim1 : (basic -> basic) -> value = 
	fun oper -> 
	  new value (oper self#get)

      method neg = self#prim1 basic_neg
      method recip = self#prim1 basic_recip
      method zero = self#prim1 basic_zero
      method floor = self#prim1 basic_floor
      method ceil = self#prim1 basic_ceil
      method rint = self#prim1 basic_rint
      method int = self#prim1 basic_int
      method float = self#prim1 basic_float
      method sin = self#prim1 basic_sin
      method asin = self#prim1 basic_asin
      method cos = self#prim1 basic_cos
      method acos = self#prim1 basic_acos
      method tan = self#prim1 basic_tan
      method atan = self#prim1 basic_atan
      method exp = self#prim1 basic_exp
      method sqrt = self#prim1 basic_sqrt
      method ln = self#prim1 basic_ln
      method lg = self#prim1 basic_lg
      method abs = self#prim1 basic_abs

      method private prim2 : (basic -> basic -> basic) -> value -> value = 
	fun oper ->
	  fun v ->
	    new value (oper self#get v#get)

      method add = self#prim2 basic_add
      method sub = self#prim2 basic_sub
      method mul = self#prim2 basic_mul
      method div = self#prim2 basic_div
      method power = self#prim2 basic_power
      method _and = self#prim2 basic_and
      method _or = self#prim2 basic_or
      method _xor = self#prim2 basic_xor
      method _mod = self#prim2 basic_mod
      method fmod = self#prim2 basic_fmod
      method remainder = self#prim2 basic_remainder
      method gt = self#prim2 basic_gt
      method lt = self#prim2 basic_lt
      method geq = self#prim2 basic_geq
      method leq = self#prim2 basic_leq
      method eq = self#prim2 basic_eq
      method neq = self#prim2 basic_neq
      method atan2 = self#prim2 basic_atan2
      method max = self#prim2 basic_max
      method min = self#prim2 basic_min
      method shl = self#prim2 basic_shl
      method shr = self#prim2 basic_shr

    end;;