3 Description: Faust expression evaluation
5 Created: 03/06/2013 Modified: 04/08/2013
15 exception NotYetDone;;
16 exception Dimension_error of string;;
17 exception Process_error of string;;
19 class dimension : int * int -> dimension_type =
20 fun (init : int * int) ->
23 val _output = snd init
26 method output = _output
28 method par : dimension_type -> dimension_type =
31 ((self#input + dim#input), (self#output + dim#output))
33 method seq : dimension_type -> dimension_type =
35 if self#output = dim#input then
36 new dimension (self#input, dim#output)
37 else raise (Dimension_error "seq dimension not matched.")
39 method split : dimension_type -> dimension_type =
41 if dim#input mod self#output = 0 then
42 new dimension (self#input, dim#output)
43 else raise (Dimension_error "split dimension not matched.")
45 method merge : dimension_type -> dimension_type =
47 if self#output mod dim#input = 0 then
48 new dimension (self#input, dim#output)
49 else raise (Dimension_error "merge dimension not matched.")
51 method _rec : dimension_type -> dimension_type =
53 if self#output >= dim#input && self#input >= dim#output then
54 new dimension (self#input - dim#output, self#output)
55 else raise (Dimension_error "rec dimension not matched.")
59 class process : faust_exp -> process_type =
60 fun (exp_init : faust_exp) ->
69 | Split (e1, e2) -> e1
70 | Merge (e1, e2) -> e1
79 | Split (e1, e2) -> e2
80 | Merge (e1, e2) -> e2
85 val dim = new dimension
89 method get_delay = delay
90 method to_string = "NotYetDone"
91 method virtual evaluate : beam_type -> beam_type
95 class proc_const : faust_exp -> process_type =
96 fun (exp_init : faust_exp) ->
99 val _dim = new dimension (0,1)
104 | _ -> raise (Process_error "const process constructor.")
108 method delay = _delay
109 method private const = _const
111 method eval : beam_type -> beam_type =
112 fun (input : beam_type) ->
113 if input#get = [||] then
114 new beam [| new signal 0 (fun t -> new value self#const)|]
116 raise (Process_error "proc_const accepts no input.")
120 class proc_ident : faust_exp -> process_type =
121 fun (exp_init : faust_exp) ->
127 | _ -> raise (Process_error "ident process constructor.")
129 val _dim = new dimension (dimension_of_symbol self#symb)
130 val _delay = delay_of_symbol _symbol
134 method delay = _delay
135 method symb = _symbol
137 method private beam_of_ident : int -> signal_type -> beam_type =
139 fun (s, signal_type) ->
140 if n = (self#dim)#input then
142 else raise (Process_error ("Ident " ^ string_of_symbol self#symb))
144 method eval : beam_type -> beam_type =
145 fun (input : beam_type) ->
146 let n = Array.length input#get in
148 | Pass -> self#beam_of_ident n input#get.(0)
149 | Stop -> if n = 1 then new beam [||]
150 else raise (Process_error "Ident !")
151 | Add -> self#beam_of_ident n ((input#get.(0))#add input#get.(1))
152 | Sub -> self#beam_of_ident n ((input#get.(0))#sub input#get.(1))
153 | Mul -> self#beam_of_ident n ((input#get.(0))#mul input#get.(1))
154 | Div -> self#beam_of_ident n ((input#get.(0))#div input#get.(1))
155 | Mem -> self#beam_of_ident n ((input#get.(0))#mem)
156 | Delay -> self#beam_of_ident n ((input#get.(0))#delay input#get.(1))
157 | Floor -> self#beam_of_ident n ((input#get.(0))#floor)
158 | Int -> self#beam_of_ident n ((input#get.(0))#int)
159 | Sin -> self#beam_of_ident n ((input#get.(0))#sin)
160 | Cos -> self#beam_of_ident n ((input#get.(0))#cos)
161 | Atan -> self#beam_of_ident n ((input#get.(0))#atan)
162 | Atan2 -> self#beam_of_ident n ((input#get.(0))#atan2 input#get.(1))
163 | Sqrt -> self#beam_of_ident n ((input#get.(0))#sqrt)
164 | Rdtable -> self#beam_of_ident n
165 ((input#get.(1))#rdtable input#get.(0) input#get.(2))
166 | Mod -> self#beam_of_ident n
167 ((input#get.(0))#_mod input#get.(1))
168 | Vectorize -> self#beam_of_ident n
169 ((input#get.(0))#vectorzie input#get.(1))
170 | Vconcat -> self#beam_of_ident n
171 ((input#get.(0))#vconcat input#get.(1))
172 | Vpick -> self#beam_of_ident n
173 ((input#get.(0))#vpick input#get.(1))
174 | Serialize -> self#beam_of_ident n
175 (input#get.(0))#serialize
176 | Larger -> self#beam_of_ident n
177 ((input#get.(0))#larger input#get.(1))
178 | Smaller -> self#beam_of_ident n
179 ((input#get.(0))#smaller input#get.(1))
180 | Prefix -> self#beam_of_ident n
181 ((input#get.(1))#prefix input#get.(0))
182 | Selec2 -> self#beam_of_ident n
183 ((input#get.(0))#select2 input#get.(1) input#get.(2))
184 | Select3 -> self#beam_of_ident n
185 ((input#get.(0))#select3 input#get.(1)
186 input#get.(2) input#get.(3))
190 class proc_par : faust_exp -> process_type =
191 fun (exp_init : faust_exp) ->
197 | _ -> raise (Process_error "par process constructor.")
201 | _ -> raise (Process_error "par process constructor.")
203 val proc_left = (new proc_factory)#make _exp_left
204 val proc_right = (new proc_factory)#make _exp_right
206 val _dim = (proc_left#dim)#par proc_right#dim
207 val _delay = max proc_left#delay proc_right#delay
211 method delay = _delay
213 method eval : beam_type -> beam_type =
214 fun (input : beam_type) ->
215 let (sub_input1, sub_input2) = input#cut proc_left#dim#input in
216 let sub_output1 = proc_left#eval sub_input1 in
217 let sub_output2 = proc_right#eval sub_input2 in
218 sub_output1#append sub_output2
221 and proc_split : faust_exp -> process_type =
222 fun (exp_init : faust_exp) ->
227 | Split (e1, e2) -> e1
228 | _ -> raise (Process_error "par process constructor.")
231 | Split (e1, e2) -> e2
232 | _ -> raise (Process_error "par process constructor.")
234 val proc_left = (new proc_factory)#make _exp_left
235 val proc_right = (new proc_factory)#make _exp_right
237 val _dim = (proc_left#dim)#split proc_right#dim
238 val _delay = proc_left#delay + proc_right#delay
242 method delay = _delay
244 method eval : beam_type -> beam_type =
245 fun (input : beam_type) ->
246 let mid_output = proc_left#eval input in
247 let mid_input = mid_output#matching proc_right#dim#input in
248 proc_right#eval mid_input
252 and proc_merge : faust_exp -> process_type =
253 fun (exp_init : faust_exp) ->
258 | Merge (e1, e2) -> e1
259 | _ -> raise (Process_error "merge process constructor.")
262 | Merge (e1, e2) -> e2
263 | _ -> raise (Process_error "merge process constructor.")
265 val proc_left = (new proc_factory)#make _exp_left
266 val proc_right = (new proc_factory)#make _exp_right
268 val _dim = (proc_left#dim)#merge proc_right#dim
269 val _delay = proc_left#delay + proc_right#delay
273 method delay = _delay
275 method eval : beam_type -> beam_type =
276 fun (input : beam_type) ->
277 let mid_output = proc_left#eval input in
278 let mid_input = mid_output#matching proc_right#dim#input in
279 proc_right#eval mid_input
283 and proc_seq : faust_exp -> process_type =
284 fun (exp_init : faust_exp) ->
290 | _ -> raise (Process_error "seq process constructor.")
294 | _ -> raise (Process_error "seq process constructor.")
296 val proc_left = (new proc_factory)#make _exp_left
297 val proc_right = (new proc_factory)#make _exp_right
299 val _dim = (proc_left#dim)#seq proc_right#dim
300 val _delay = proc_left#delay + proc_right#delay
304 method delay = _delay
306 method eval : beam_type -> beam_type =
307 fun (input : beam_type) ->
308 let mid_output = proc_left#eval input in
309 proc_right#eval mid_output
312 and proc_rec : faust_exp -> process_type =
313 fun (exp_init : faust_exp) ->
319 | _ -> raise (Process_error "rec process constructor.")
323 | _ -> raise (Process_error "rec process constructor.")
325 val proc_left = (new proc_factory)#make _exp_left
326 val proc_right = (new proc_factory)#make _exp_right
328 val _dim = (proc_left#dim)#_rec proc_right#dim
329 val _delay = proc_left#delay
333 method delay = _delay
335 method eval : beam_type -> beam_type =
336 fun (input : beam_type) ->
337 let mid_output = proc_left#eval input in
338 proc_right#eval mid_output
345 method make : faust_exp -> process_type =
346 fun (exp : faust_exp) ->
348 | Const b -> new proc_const exp
349 | Ident s -> new proc_ident exp
350 | Par (e1, e2) -> new proc_par exp
351 | Seq (e1, e2) -> new proc_seq exp
352 | Split (e1, e2) -> new proc_split exp
353 | Merge (e1, e2) -> new proc_merge exp
354 | Rec (e1, e2) -> new proc_rec exp
361 (* PROCESS DELAY ESTIMATION *)
363 (** val delay : faust_exp -> int, returns the number of delays estimated staticly.
364 Attention: delays of "@" is estimated as 10 constant,
365 delays of "vectorize" and "serialize" haven't been implemented,
366 delays of "rdtable" hasn't been implemented.*)
367 let rec delay exp_faust = match exp_faust with
395 |Par (e1, e2) -> max (delay e1) (delay e2)
396 |Seq (e1, e2) -> (delay e1) + (delay e2)
397 |Split (e1, e2) -> (delay e1) + (delay e2)
398 |Merge (e1, e2) -> (delay e1) + (delay e2)
399 |Rec (e1, e2) -> delay e1;;
404 (** val exp_of_string : string -> faust_exp, faust expression parser. *)
405 let exp_of_string s = (Parser.main Lexer.token (Lexing.from_string s));;
409 (* PROCESS DIMENSION ESTIMATION *)
410 (* process dimension := (size of input beam, size of output beam).*)
413 (** val get_root : dimension -> int * int, returns the root of dimension tree. *)
414 let get_root = fun d_tree -> match d_tree with
416 | Tree (d, branches) -> d;;
419 (** val subtree : dimention -> int -> dimension, returns a subtree of dimension tree.*)
420 let subtree = fun d_tree -> fun i ->
422 | End d -> raise (Beam_Matching_Error "Subtree left absent.")
423 | Tree (d, branches) -> (
425 (left, right) -> if i = 0 then left else right);;
427 (** val subtree_left : dimension -> dimension, returns the left subtree of dimension tree.*)
428 let subtree_left = fun d_tree -> subtree d_tree 0;;
431 (** val subtree_right : dimension -> dimension, returns the right subtree of dimension tree.*)
432 let subtree_right = fun d_tree -> subtree d_tree 1;;
434 (** val dim : faust_exp -> int * int, returns dimension for faust expression,
435 along with beam matching.*)
436 let rec dim exp_faust =
438 (** val dimension_constructor : ((int * int) -> (int * int) -> (int * int)) -> faust_exp
439 -> faust_exp -> dimension,
440 returns the dimension tree of constructor(e1, e2).*)
441 let dimension_constructor = fun constructor -> fun e1 -> fun e2 ->
442 let subtree1 = dim e1 in
443 let subtree2 = dim e2 in
444 let root = constructor (get_root subtree1) (get_root subtree2) in
445 Tree (root, (subtree1, subtree2)) in
448 |Const v -> End (0, 1)
463 |Rdtable -> End (3, 1)
465 |Vectorize -> End (2, 1)
466 |Concat -> End (2, 1)
468 |Serialize -> End (1, 1)
469 |Larger -> End (2, 1)
470 |Smaller -> End (2, 1)
471 |Prefix -> End (2, 1)
472 |Selecttwo -> End (3, 1)
473 |Selectthree -> End (4, 1)
476 |Par (e1, e2) -> dimension_constructor d_par e1 e2
477 |Seq (e1, e2) -> dimension_constructor d_seq e1 e2
478 |Split (e1, e2) -> dimension_constructor d_split e1 e2
479 |Merge (e1, e2) -> dimension_constructor d_merge e1 e2
480 |Rec (e1, e2) -> dimension_constructor d_rec e1 e2;;
484 (* AUXILIARY 'CONVERT_TO_STRING' FUNCTIONS *)
486 (** val print_exp : faust_exp -> unit, print to console the input faust expression.*)
488 let rec string_of_exp exp = match exp with
489 |Const v -> "Const" ^ " (" ^ (string_of_value v) ^ ")"
490 |Ident s -> "Ident" ^ " \"" ^ "s" ^ "\""
491 |Par (e1, e2) -> "Par" ^ " (" ^ (string_of_exp e1) ^ ", " ^ (string_of_exp e2) ^ ")"
492 |Seq (e1, e2) -> "Seq" ^ " (" ^ (string_of_exp e1) ^ ", " ^ (string_of_exp e2) ^ ")"
493 |Split (e1, e2) -> "Split" ^ " (" ^ (string_of_exp e1) ^ ", " ^ (string_of_exp e2) ^ ")"
494 |Merge (e1, e2) -> "Merge" ^ " (" ^ (string_of_exp e1) ^ ", " ^ (string_of_exp e2) ^ ")"
495 |Rec (e1, e2) -> "Rec" ^ " (" ^ (string_of_exp e1) ^ ", " ^ (string_of_exp e2) ^ ")"
497 print_string("Parer : Types.faust_exp = "^ (string_of_exp exp));;