Command-line

According to the command line arguments, the cduce command behaves either as an interactive toplevel, an interpreter, a compiler, or a loader.

  • cduce [OPTIONS ...]  [--arg ARGUMENT ...]
    

    The command operates as an interactive toplevel. See the Toplevel section below.

  • cduce [OPTIONS ...] [ script.cd | --stdin ] [--arg ARGUMENT ...]
    
    cduce [OPTIONS ...] --script script.cd [ ARGUMENT ...]
    

    The command runs the script script.cd.

  • cduce [OPTIONS ...] --compile script.cd
    

    The command compiles the script script.cd and produces script.cdo. If the OCaml/CDuce interface is available and enabled, the compilers looks for a corresponding OCaml interface script.cmi. See the Interfacing CDuce with OCaml page for more information.

  • cduce [OPTIONS ...] --run [ script.cdo ... ] [--arg ARGUMENT ...]
    

    The command runs one or several pre-compiled scripts.

The arguments that follow the --arg option are the scripts' command line. They can be accessed within CDuce using the argv operator (of type [] -> [ String* ]).

The options and arguments are:

  • --verbose (for --compile mode only). Display the type of values in the compiled unit.
  • --obj-dir directory (for --compile mode only). Specify where to put the .cdo file (default: same directory as the source file).
  • --I directory Add a directory to the search path for .cdo, .cmi and include files.
  • --stdin. Read CDuce script from standard input.
  • --no feature. Disable one of the built-in optional features. The list of feature and their symbolic name can be obtained with the -v option. Can be used for instance to turn the Expat parser off, in order to use PXP, if both have been included at compile time.
  • -v, --version. Show version information and built-in optional features, and exit.
  • --mlstub. See Interfacing CDuce with OCaml.
  • --help. Show usage information about the command line.

Scripting

CDuce can be used for writing scripts. As usual it suffices to start the script file by #!install_dir/cduce to call in a batch way the CDuce interpreter. The --script option can be used to avoid --arg when calling the script. Here is an example of a script file that prints all the titles of the filters of an Evolution mail client.

#!/bin/env cduce --script

type Filter = <filteroptions>[<ruleset> [(<rule>[<title>String _*])+]];;

let src : Latin1 =
  match argv [] with
    | [ f ] -> f
    | _ -> raise "Invalid command line"
in
let filter : Filter = 
      match load_xml src with
       | x&Filter -> x
       | _ -> raise "Not a filter document"
in 
print_xml(<filters>([filter]/<ruleset>_/<rule>_/<title>_)) ;;


Phrases

CDuce programs are sequences of phrases, which can be juxtaposed or separated by ;;. There are several kinds of phrases:

  • Types declarations type T = t. Adjacent types declarations are mutually recursive, e.g.:
    type T = <a>[ S* ]
    type S = <b>[ T ]
    
  • Function declarations let f .... Adjacent function declarations are mutually recursive, e.g.:
    let f (x : Int) : Int = g x
    let g (x : Int) : Int  = x + 1
    
  • Global bindings let p = e (bind the result of the expression e using the pattern p), let p : t = e (gives a less precise type to the expression), let p :? t = e (dynamically checks that the expression has some type).
  • Evaluation statements: an expression to evaluate.
  • Textual inclusion include "other_cduce_script.cd"; note that cycle of inclusion are detected and automatically broken. Filename are relative to the directory of the current file (or the current directory in the toplevel).
  • Global namespace binding: see XML Namespaces.
  • Schema declaration: see XML Schema.
  • Alias for an external unit using alias = "unit" or using alias = unit: gives an alternative name for a pre-compiled unit. Values, types, namespace prefixes, schema from unit.cdo can be referred to either as alias.ident or as unit.ident.
  • Open an external unit open u: the effect of this statement is to import all the idenfiers exported by the compilation unit u into the current scope. These identifiers are also re-exported by the current unit.

Toplevel

If no CDuce file is given on the command line, the interpreter behaves as an interactive toplevel.

Toplevel phrases are processed after each ;;. Mutually recursive declarations of types or functions must be contained in a single adjacent sequence of phrases (without ;; inbetween).

You can quit the toplevel with the toplevel directive #quit but also with either Ctrl-C or Ctrl-D. Another option is to use the built-in exit.

The toplevel directive #help prints an help message about the available toplevel directives.

The toplevel directive #env prints the current environment: the set of defined global types and values, and also the current sets of prefix-to-namespace bindings used for parsing (as defined by the user) and for pretty-printing (as computed by CDuce itself).

The two toplevel directives #silent and #verbose can be used to turn down and up toplevel outputs (results of typing and evaluation).

The toplevel directive #reinit_ns reinit the table of prefix-to-namespace bindings used for pretty-printing values and types with namespaces (see XML Namespaces).

The toplevel directive #print_type shows a representationo of a CDuce type (including types imported from XML Schema documents).

The toplevel directive #builtins prints the name of embedded OCaml values (see Interfacing CDuce with OCaml).

The toplevel has no line editing facilities. You can use an external wrapper such as ledit.

Lexical entities

The identifiers (for variables, types, recursive patterns, ...) are qualified names, in the sense of XML Namespaces. The chapter XML Namespaces explains how to declare namespace prefixes in CDuce. Identifiers are resolved as XML attributes (which means that the default namespace does not apply). All the identifiers are in the same scope. For instance, there cannot be simultaneously a type and variable (or a schema, a namespace prefix, an alias for an external unit) with the same name.

The dot must be protected by a backslash in identifiers, to avoid ambiguity with the dot notation.

The dot notation serves several purposes:

  • to refer to values and types declared in a separate CDuce compilation unit;
  • to refer to values from OCaml compilation unit (see Interfacing CDuce with OCaml);
  • to refer to schema components (see XML Schema);
  • to select a field from a record expression.

CDuce supports two style of comments: (* ... *) and /* ... */. The first style allows the programmer to put a piece a code apart. Nesting is allowed, and strings within simple or double quotes are not searched for the end-marker *). In particular, simple quotes (and apostrophes) have to be balanced inside a (* ... *) comment. The other style /* ... */ is more adapted to textual comments. They cannot be nested and quotes are not treated specially inside the comment.