new release (cduce 0.5.1)

Date Tags cduce

It has been a busy month for cduce. We added the windows package, cleaned up the distribution and the svn repository, updated the website and added a couple of minor features to cduce itself.

Today we released a minor update: version 0.5.1 I also spent the day updating the debian package.

We had some minor problem with the web server. From time to time the dom0 reboots leaving the website dead. I’m still working to solve this problem.


cdata section in cduce

Date Tags cduce

I wrote a small patch to manipulate cdata section in cduce as follow:

abate@zed.fr:~/Projects/cduce-ocaml-3.10$ledit ./cduce
        CDuce version 0.5.0

# cdata_of ;;
- : String -> String = <fun>

#  type a = <tag>Cdata ;;
Characters 6-7:
Capture variable not allowed: Cdata

# type a = <tag>String ;;
# let b : a = <tag>(cdata_of "ggg>>" );;
val b : a = <tag> 'ggg>>'
# print_xml b ;;
- : Latin1 = "<tag><![CDATA[ggg>>]]></tag>"

# let [ c ] = map [ b ] with c -> c ;;
val c : a = <tag> ggg>>
# print_xml c;;
- : Latin1 = "<tag><![CDATA[ggg>>]]></tag>"

the code in in the svn repository: http://cduce.org/cgi-bin/viewcvs.cgi/cduce/trunk/?root=svn


Unit testing for Cduce

Date Tags cduce

I’ve written a small unit testing suite for cduce using the OUnit library (http://www.xs4all.nl/~mmzeeman/ocaml/ounit-doc/OUnit.html)

Everything is in my dacrs repo waiting for integration: http://web-cduce.pps.jussieu.fr/cgi-bin/darcsweb.cgi?r=cduce;a=summary

I wrote only a handful of tests. This is the main cduce program:

let t1 (s : Latin1) ( t : OUnit.test )    : OUnit.test = (`TestLabel, s, t)
let t2 (s : Latin1) ( f : `nil -> `nil )  : OUnit.test = (`TestLabel, s, (`TestCase, f))
let t3 (s : Latin1) ( l : [OUnit.test*] ) : OUnit.test = (`TestLabel, s, (`TestList, l))

let compare (a : Any) (b : Any) : Bool = a = b

type t = ( `A, Int )

let ae_t      = OUnit.assert_equal with { t } [compare] [] []

let ae_string = OUnit.assert_equal  with { Latin1   } [compare] [] []
let ae_int    = OUnit.assert_equal  with { Caml_int } [compare] [] []
let ae_bool   = OUnit.assert_equal  with { Bool }     [compare] [] []
let ae_Int    = OUnit.assert_equal  with { Int }      [compare] [] []
let ae_float  = OUnit.assert_equal  with { Float }    [compare] [] []
let ae_char   = OUnit.assert_equal  with { Char }     [compare] [] []

let test_funs     ( _ : `nil ) : `nil = ae_Int 45 funs.a

let test_scalar : OUnit.test =
    let factres =
        93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
    in
    let test1 ( _ : `nil ) : `nil = ae_Int factres (scalars.facto 100)
    in
    let test2 ( _ : `nil ) : `nil = ae_Int 10 (scalars.abs -10) in
    let test3 ( _ : `nil ) : `nil = ae_Int 10 (scalars.wrap 100) in
    let test4 ( _ : `nil ) : `nil = ae_Int 10 (scalars.exp_wrap 100) in
    let test5 ( _ : `nil ) : `nil =
        try let _ = (scalars.exp_wrap 101) in raise "Failure"
        with _ -> `nil
    in
    let test6 ( _ : `nil ) : `nil = ae_Int 35 (scalars.eval (`add, 10,
    (`add, 20, 5))) in
    let test7 ( _ : `nil ) : `nil = ae_bool `true (scalars.interval_unicode 'a')
    in
    let test8 ( _ : `nil ) : `nil = ae_bool `false (scalars.interval_unicode 'z')
    in
    let test9 ( _ : `nil ) : `nil = ae_Int 97 (scalars.ic 'a') in
    let test10 ( _ : `nil ) : `nil = ae_char 'a' (scalars.ci 97) in
    let test11 ( _ : `nil ) : `nil =
        namespace ns1 = "A" in
        ae_bool `true (compare `ns1:B scalars.atom) in
    let test12 ( _ : `nil ) : `nil = ae_bool `true (compare [ "A" 'B' ]
    scalars.split) in
    t3 "Test Scalars" [
        (t2 "facto"  test1)
        (t2 "abs"  test2)
        (t2 "wrap"  test3)
        (t2 "exception wrap positive"  test4)
        (t2 "exception wrap negative"  test5)
        (t2 "expr eval negative"  test6)
        (t2 "interval unicode positive"  test7)
        (t2 "interval unicode negative"  test8)
        (t2 "int of char"  test9)
        (t2 "char of int"  test10)
        (t2 "atom"  test11)
        (t2 "split"  test12)
]

let test_operators : OUnit.test =
    let test1 ( _ : `nil ) : `nil =
        ae_bool `true (compare [ 1 2 3 4 ] (operators.seq [1 2] [3 4]))
    in
    let test2 ( _ : `nil ) : `nil = ae_bool `true (operators.neq 1 2) in
    let test3 ( _ : `nil ) : `nil = ae_bool `true notes.load_notes in

    t3 "Test Built-in Operators" [
        (t2 "Sequence"  test1)
        (t2 "neq"  test2)
        (t2 "load_xml"  test3)
    ]


let suite : OUnit.test = t3 "Cduce test suite" [
    test_scalar
    test_operators
]

let _ = OUnit.run_test_tt_main suite

Automatic Ocaml Types for Cduce

Date Tags cduce

A minor limitation of cduce is that all ocaml types must be declared in cduce. This is cumbersome when trying to use an ocaml library from cduce.

I’ve created a small patch to cduce to allow to use ocaml types directly in a cduce program.

The patch is available in my personal darcs repository and pending to be integrated in the main tree.

The repository is here: http://web-cduce.pps.jussieu.fr/cgi-bin/darcsweb.cgi

and the patch http://web-cduce.pps.jussieu.fr/cgi-bin/darcsweb.cgi?r=cduce;a=commit;h=20070621141511-6a509-90fe027988c1d5f12efe21e9cfd7a826aa5a5527.gz

and the tree can be retrived via darcs with

darcs get http://web-cduce.pps.jussieu.fr/darcs/cduce

Dynlink with Cduce

Date Tags cduce

Nothing deep here …

file toto.ml

let toto = ref ( fun () -> 0 )

file foo.ml

let run ( r : int ) () = r
let register i = Toto.toto := i

file bar.cd. This is the cduce program that is then dynamically loaded.

let f : ( `nil -> Caml_int ) = Foo.run 1 ;;
Foo.register f ;;

file main.ml. Note that we have to dynamically load all the libraries.

let _ =
    Dynlink.init ();
    Dynlink.allow_unsafe_modules true

let () =
    try
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/stdlib.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/nums.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/netstring/netstring.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/ulex/ulexing.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/camlp4/gramlib.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/camlp4/odyl.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/camlp4/camlp4.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/curl/curl.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/pxp-engine/pxp_engine.cma";
        Dynlink.loadfile "/usr/lib/ocaml/3.09.2/expat/expat.cma";
        Dynlink.loadfile "/home/users/abate/software/lib/ocaml/cduce/cduce_lib.cma";
        Dynlink.loadfile "foo.cmo";
        Dynlink.loadfile "bar.cmo";
    with Dynlink.Error(e) -> failwith (Dynlink.error_message e)

;;

print_int ( !Toto.toto () )

And to compile everything :

ocamlfind ocamlc -c toto.ml foo.ml
cduce --compile bar.cd
cduce --mlstub bar.cdo > bar.ml
ocamlfind ocamlc -package cduce -linkpkg -c toto.cmo foo.cmo bar.ml
ocamlfind ocamlc -package cduce,dynlink -linkpkg toto.cmo main.ml