Commit 70fed3a6 authored by Pietro Abate's avatar Pietro Abate

[r2005-01-03 15:10:20 by afrisch] Doc

Original author: afrisch
Date: 2005-01-03 15:10:21+00:00
parent 21178a79
......@@ -11,11 +11,12 @@ Since 0.2.1
- better compilation of sequence capture variables
- punning in record/attribute expressions and values ({ x; y } -> {x=x;y=y})
- removed the warning "no caml interface"
- add "system: Latin1->Latin1", "exit: (0--255)->Empty"
- add "system" and "exit" built-in functions
- (e :? t) raises an exception when e doesn't have type t;
the exception is an explanation of why this is not the case.
- apps-cduce-cvs GODI package is updatable
- /* ... */ comments
- fix --stdin
0.2.1
......
......@@ -326,9 +326,12 @@ let compile src out_dir =
let compile_run src =
try
if not (Filename.check_suffix src ".cd")
then raise (InvalidInputFilename src);
let cu = Filename.chop_suffix (Filename.basename src) ".cd" in
let cu =
if src = "" then "<stdin>"
else
if not (Filename.check_suffix src ".cd")
then raise (InvalidInputFilename src)
else Filename.chop_suffix (Filename.basename src) ".cd" in
let id = Types.CompUnit.mk (U.mk_latin1 cu) in
Librarian.compile !verbose cu id src;
Librarian.run id
......
......@@ -151,18 +151,20 @@ let rec compile verbose name id src =
check_loop id;
protect_op "Compile external file";
let ic =
try open_in src
with Sys_error _ -> raise (CannotOpen src) in
if src = "" then stdin
else
try open_in src
with Sys_error _ -> raise (CannotOpen src) in
Location.push_source (`File src);
let input = Stream.of_channel ic in
let p =
try Parser.prog input
with
| Stdpp.Exc_located (_, (Location _ as e)) -> raise e
(* | Stdpp.Exc_located ((i,j), e) -> raise_loc i j e *)
| Stdpp.Exc_located ((i,j), e) -> raise_loc i.Lexing.pos_cnum j.Lexing.pos_cnum e
| Stdpp.Exc_located ((i,j), e) ->
raise_loc i.Lexing.pos_cnum j.Lexing.pos_cnum e
in
close_in ic;
if src <> "" then close_in ic;
let argv = ident (U.mk "argv") in
during_compile := true;
C.enter id;
......
......@@ -361,6 +361,8 @@ EXTEND
(true,p,e)
| "let"; p = pat; "="; e = expr -> (false,p,e)
| "let"; p = pat; ":"; t = pat; "="; e = expr -> (false,p, Forget (e,t))
| "let"; p = pat; ":"; "?"; t = pat; "="; e = expr ->
(false,p, Check (e,t))
]
];
......
......@@ -91,6 +91,11 @@ let rec token = lexer
comment (L.lexeme_start lexbuf) lexbuf;
in_comment := false;
token lexbuf
| "/*" ->
in_comment := true;
tcomment (L.lexeme_start lexbuf) lexbuf;
in_comment := false;
token lexbuf
| eof ->
return lexbuf ("EOI","")
| _ ->
......@@ -113,6 +118,14 @@ and comment start = lexer
| _ ->
comment start lexbuf
and tcomment start = lexer
| "*/" ->
()
| eof ->
error start (start+2) "Unterminated comment"
| _ ->
tcomment start lexbuf
and string start double = lexer
| '"' | "'" ->
let d = L.latin1_lexeme_char lexbuf 0 = '"' in
......
open Operators
open Builtin_defs
open Ident
let len = 1024;;
let variant_type_ascii l =
List.fold_left
(fun accu (l,t) ->
Types.cup accu
(Types.times
(Types.cons (Types.atom (Atoms.atom (Atoms.V.mk_ascii l))))
(Types.cons t)))
Types.empty
l
let run_process s =
let ic = Unix.open_process_in s in
let b = Buffer.create (1024*10) in
let buf = String.create len in
let rec aux () =
let i = input ic buf 0 len in
if i = 0 then () else (Buffer.add_string b (String.sub buf 0 i); aux ())
in
aux ();
let s = Value.string_latin1 (Buffer.contents b) in
s, Unix.close_process_in ic
let record_type_ascii l =
Types.record' (false,
(LabelMap.from_list_disj
(List.map (fun (l,t) -> Value.label_ascii l, Types.cons t) l)))
module Reader = struct
let b = Buffer.create 10240
let buf = String.create 1024
let rec read_loop ic =
let i = input ic buf 0 (String.length buf) in
if i > 0 then (Buffer.add_string b (String.sub buf 0 i); read_loop ic)
let ic ic =
read_loop ic;
let s = Buffer.contents b in
Buffer.clear b;
s
end
let run_process cmd =
let (sout,sin,serr) as h = Unix.open_process_full cmd (Unix.environment()) in
close_out sin;
let sout = Reader.ic sout in
let serr = Reader.ic serr in
sout,serr, Unix.close_process_full h
let process_status = function
| Unix.WEXITED n ->
Value.Pair (Value.atom_ascii "exited", Value.ocaml2cduce_int n)
| Unix.WSTOPPED n ->
Value.Pair (Value.atom_ascii "stopped", Value.ocaml2cduce_int n)
| Unix.WSIGNALED n ->
Value.Pair (Value.atom_ascii "signaled", Value.ocaml2cduce_int n)
let system_out =
record_type_ascii [
"stdout", string_latin1;
"stderr", string_latin1;
"status", variant_type_ascii [
"exited", int;
"stopped", int;
"signaled", int
]
]
let () = register_fun "system" string_latin1 string_latin1
let () = register_fun "system" string_latin1 system_out
(fun v ->
Location.protect_op "system";
match run_process (Value.get_string_latin1 v) with
| s,Unix.WEXITED n ->
if (n = 0) then s
else
Value.raise'
(Value.tagged_tuple "exited" [ Value.ocaml2cduce_int n; s ])
| s,Unix.WSTOPPED n ->
Value.raise'
(Value.tagged_tuple "stopped" [ Value.ocaml2cduce_int n; s ])
| s,Unix.WSIGNALED n ->
Value.raise'
(Value.tagged_tuple "signaled" [ Value.ocaml2cduce_int n; s ])
let cmd = Value.get_string_latin1 v in
let sout,serr,ps = run_process cmd in
Value.record_ascii [
"stdout", Value.string_latin1 sout;
"stderr", Value.string_latin1 serr;
"status", process_status ps
]
)
let () = register_fun "exit" byte_int Types.empty
......
......@@ -575,12 +575,17 @@ let label_ascii s =
let record l =
Record (LabelMap.from_list_disj l)
let record_ascii l =
record (List.map (fun (l,v) -> (label_ascii l, v)) l)
let get_field v l =
match v with
| Record fields -> LabelMap.assoc l fields
| _ -> raise Not_found
let get_field_ascii v l = get_field v (label_ascii l)
let abstract a v =
Abstract (a,Obj.repr v)
......
......@@ -57,7 +57,9 @@ val fold_sequence: ('a -> t -> 'a) -> 'a -> t -> 'a
val atom_ascii : string -> t
val label_ascii : string -> label
val record : (label * t) list -> t
val record_ascii : (string * t) list -> t
val get_field : t -> label -> t
val get_field_ascii : t -> string -> t
val get_variant : t -> string * t option
......
......@@ -29,6 +29,8 @@ The simplest way to compile and install CDuce is probably to
use the
<a href="http://www.ocaml-programming.de/godi/">
GODI distribution</a>, and to select the <tt>apps-cduce</tt> package.
There is also a <tt>apps-cduce-cvs</tt> package which synchronize
itself with the CDuce CVS development tree.
</p>
</box>
......@@ -53,10 +55,9 @@ of the CVS tree.
</p>
<p>
In order to build CDuce from the current CVS tree, you need
to install <a href="#side">ulex</a>, and also attentively
read the instructions in the <a href="INSTALL">INSTALL</a> file included in the
repository.
Another way to follow the development in the CVS is to is the
<tt>apps-cduce-cvs</tt> <a
href="http://www.ocaml-programming.de/godi/"> GODI</a> package.
</p>
<!--
......
......@@ -334,7 +334,9 @@ There are three kinds of operators on records:
<code>%%l%%</code> is the name of a label which must be
present in the result of the evaluation of <code>%%e%%</code>.
This construction is equivalent to: <code>match %%e%% with
{ %%l%% = x } -> x</code>.
{ %%l%% = x } -> x</code>. It is necessary to put
whitespace between the expression and the dot
when the expression is an identifier.
</li>
<li>
Record concatenation:
......@@ -363,6 +365,13 @@ Binary arithmetic operators on integers:
for projection and <em>not</em> for division.
</p>
<p>
The operator <code>+,-</code> and <code>*</code> are typed
using simple interval arithmetic. The operators <code>div</code>
and <code>mod</code> produce a warning at compile type if
the type of there second argument include the integer <code>0</code>.
</p>
</box>
<box title="Generic comparisons, if-then-else" link="comp">
......@@ -434,7 +443,19 @@ let %%p%% = (%%e%% : %%t%%) in %%...%%
Note that the upward coercion allows earlier detection of type errors,
better localization in the program, and more informative messages.
</p>
<p>
CDuce also have a dynamic type-check construction:
</p>
<sample><![CDATA[
(%%e%% :? %%t%%)
let %%p%% :? %%t%% = %%e%% in %%...%%
]]></sample>
<p>
If the value resulting from the evaluation of <code>%%e%%</code>
does not have type <code>%%t%%</code>, an exception
whose argument (of type <code>Latin1</code>) explains the reason
of the mismatch is raised.
</p>
</box>
<box title="XML-specific constructions" link="xml">
......@@ -644,6 +665,32 @@ argument is the filename and the second one is the string to dump.
</box>
<box title="System" link="sys">
<section title="Running external commands">
<p>
The predefined function <code>system</code> executes
an external command (passed to <code>/bin/sh</code>)
and returns its standard output and standard error
channels and its exit code. The type for <code>system</code>
is:
</p>
<sample><![CDATA[
Latin1 -> {| stdout = Latin1; stderr = Latin1;
status = (`exited,Int) | (`stopped,Int) | (`signaled,Int) |}
]]></sample>
</section>
<section title="Running external commands">
<p>
The predefined function <code>exit</code> terminates
the current process. Its type is <code>0--255 -> Empty</code>.
The argument is the exit code.
</p>
</section>
</box>
<box title="Namespaces" link="ns">
<p>
......
......@@ -27,6 +27,9 @@ toplevel. See the <a href="#toplevel">Toplevel</a> section below.
<sample>
cduce [OPTIONS ...] [ {{script}}.cd | --stdin ] [--arg ARGUMENT ...]
</sample>
<sample>
cduce [OPTIONS ...] --script {{script}}.cd [ ARGUMENT ...]
</sample>
<p>
The command runs the script <code>{{script}}.cd</code>.
</p>
......@@ -109,22 +112,29 @@ and built-in optional features, and exit.
<p>
CDuce can be used for writing scripts. As usual it suffices to start
the script file by <code> #!%%install_dir%%/cduce</code> to call in a batch way
the CDuce interpreter. Here is an example of a script file that prints all the
titles of the filters of an Evolution mail client.
the script file by <code> #!%%install_dir%%/cduce</code> to call in a
batch way the CDuce interpreter. The <code>--script</code> option can
be used to avoid <code>--arg</code> 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.
</p>
<sample><![CDATA[
#!/usr/local/bin/cduce
#!/usr/local/bin/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 "/home/beppe/evolution/filters.xml" with
match load_xml src with
| x&Filter -> x
| _ -> raise "Not a filter document"
in print_xml(<filters>([filter]/<ruleset>_/<rule>_/<title>_)) ;;
in
print_xml(<filters>([filter]/<ruleset>_/<rule>_/<title>_)) ;;
]]></sample>
......@@ -186,7 +196,7 @@ and global namespace default <code>namespace "%%...%%"</code>
<li>Schema declaration <code>schema %%name%% = "%%...%%"</code>
(see <local href="manual_schema">XML Schema</local>).</li>
<li>Give an alias for an external unit <code>using %%alias%% = "%%unit%%"</code>
<li>Alias for an external unit <code>using %%alias%% = "%%unit%%"</code>
or <code>using %%alias%% = %%unit%%</code>:
gives an alternative name for a pre-compiled unit. Values
and types from <code>%%unit%%.cdo</code> can be referred to either as
......@@ -198,6 +208,22 @@ or as <code>%%unit%%:%%ident%%</code>.
</box>
<box title="Comments" link="comment">
<p>
CDuce supports two style of comments: <code>(* ... *)</code>
and <code>/* ... */</code>. 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
<code>*)</code>. In particular, simple quotes (and apostrophes)
have to be balanced inside a <code>(* ... *)</code> comment.
The other style <code>/* ... */</code> is more adapted to textual
comments. They cannot be nested and quotes are not treated
specially inside the comment.
</p>
</box>
<box title="Toplevel" link="toplevel">
<p>
......@@ -224,7 +250,7 @@ You can quit the toplevel with the toplevel directive
</p>
<p>
The toplevel directive <code>#dump_value</code> dump an XML-like
representation of the internal cduce representation of the resulting
representation of the internal CDuce representation of the resulting
value of an expression. It should not be considered a normative
representation for CDuce values.
</p>
......
......@@ -322,12 +322,21 @@ the integer itself.</li>
<li>
Grouping <code>(%%R%%)</code>. E.g.: <code>[ x::(Int Int) y ]</code>.
</li>
<li>
Tail predicate <code>/p</code>. The type/pattern <code>p</code>
applies to the current tail of the sequence (the subsequence
starting at the current position). E.g.:
<code>[ (Int /(x:=1) | /(x:=2)) _* ]</code> will bind
<code>x</code> to <code>1</code> if the sequence starts
with an integer and <code>2</code> otherwise.
</li>
</ul>
<p>
Sequence types and patterns also accepts the <code>[ %%...%%; %%...%% ]</code>
notation. This is a convenient way to discard the tail of a sequence
in a pattern, e.g.: <code>[ x::Int* ; _ ]</code>.
in a pattern, e.g.: <code>[ x::Int* ; _ ]</code>, which
is equivalent to <code>[ x::Int* _* ]</code>.
</p>
</section>
......@@ -382,9 +391,15 @@ The syntax of a record expression is
<code>{ %%l1%% = %%e1%%; %%...%%; %%ln%% = %%en%% }</code>
where the <code>%%li%%</code> are label names (same lexical
conventions as for identifiers), and the <code>%%vi%%</code>
are expressions.
are expressions. When an expression <code>%%ei%%</code>
is simply a variable whose name match the field label
<code>%%li%%</code>, it is possible to omit it.
E.g.: <code>{ x; y = 10; z }</code>
is equivalent to <code>{ x = x; y = 10; z = z }</code>.
</p>
<p>
They are two kinds of record types. Open record types
are written <code>{ %%l1%% = %%t1%%; %%...%%; %%ln%% = %%tn%%
......@@ -418,7 +433,18 @@ value is not syntactically equal to this value.
<p>
The syntax is the same for patterns. Note that capture variables
cannot appear in an optional field.
cannot appear in an optional field. A common idiom is to bind
default values to replace missing optinal fields:<code>
({ x = a } | (a := 1)) &amp; { y = b }</code>. A special syntax
makes this idiom more convenient:
<code>{ x = a else (a:=1); y = b }</code>.
</p>
<p>
As for record expressions, when the pattern
is simply a capture variable whose name match the field label,
it is possible to omit it. E.g.: <code>{ x; y = b; z }</code>
is equivalent to <code>{ x = x; y = b; z = z }</code>.
</p>
</box>
......@@ -530,4 +556,12 @@ is only syntactic sugar for the type
</box>
<box title="OCaml abstract types" link="abstr">
<p>
The notation <code>!t</code> is used by the
<local href="manual_interfacewithocaml">CDuce/OCaml interface</local>
to denote the OCaml abstract type <code>t</code>.
</p>
</box>
</page>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment