(* similar to fold_left, dar pentru siruri *)
let fold f v s =
  let len = String.length s in
  let rec foldi i acc =
    if i = len then acc else foldi (i+1) (f acc s.[i])
  in foldi 0 v

module M = Map.Make(Char)

(* expandeaza fiecare neterminal prezent in dictionarul dat *)
let expand dict s =
  fold (fun s c ->
        s ^ (try M.find c dict with Not_found -> String.make 1 c)) "" s

(* expandeaza de n ori fiecare neterminal *)
let rec exprec dict n s =
  if n = 0 then s else exprec dict (n-1) (expand dict s)

(* regulile de rescriere pentru dragon *)
let ddict = M.add 'X' "X+YF" (M.singleton 'Y' "FX-Y")

(* fa un pas in directia data de arg*pi/2 *)                  
let lstep = function
  | 0 -> print_string "h 4 "
  | 1 -> print_string "v 4 "
  | 2 -> print_string "h -4 "
  | 3 -> print_string "v -4 "
  | _ -> ()
           
(* actualizeaza unghiul si/sau fa un pas *)                      
let drawfun ang = function
  | '+' -> (ang + 1) mod 4
  | '-' -> (ang + 3) mod 4
  | 'F' -> lstep ang; ang
  | _ -> ang (* nicio schimbare *)

let dragon n = ignore (fold drawfun 0 (exprec ddict n "FX"))

let () = (
  print_string "<?xml version=\"1.0\"?>\n\
  <svg version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n\
  <path fill=\"none\" stroke=\"grey\" d=\"M 400 600 ";
  dragon 14;
  print_string "\"/>\n</svg>"
)
           

This document was generated using caml2html