| 1 |
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
|
| 2 |
<page name="hacking" new="">
|
| 3 |
|
| 4 |
<title>Hacking CDuce</title>
|
| 5 |
|
| 6 |
|
| 7 |
<box title="Introduction" link="intro">
|
| 8 |
<p>This page contains some information about internals of the CDuce
|
| 9 |
implementation. This can be useful for people wanting to
|
| 10 |
add features to CDuce. This is not for casual users ! </p>
|
| 11 |
</box>
|
| 12 |
|
| 13 |
<box title="Adding operators" link="operators">
|
| 14 |
<p>
|
| 15 |
Below is a copy of a mail to the <local href="mailing">CDuce users
|
| 16 |
mailing list</local>, that
|
| 17 |
describes how to add built-in operators/functions to CDuce.
|
| 18 |
</p>
|
| 19 |
|
| 20 |
<sample>
|
| 21 |
Date: Tue, 19 Aug 2003 10:47:00 +0200 (MET DST)
|
| 22 |
From: Alain Frisch
|
| 23 |
Subject: Re: [cduce-users] System call from Cduce.
|
| 24 |
|
| 25 |
[ WARNING: technical content. Only for CDuce hackers ! ]
|
| 26 |
|
| 27 |
On Mon, 18 Aug 2003, Serge Leblanc wrote:
|
| 28 |
|
| 29 |
> Is it possible with Cduce to call systems functions like getenv ?
|
| 30 |
|
| 31 |
Not yet.
|
| 32 |
|
| 33 |
The current "CDuce standard library" is very small. I'm planning to add a
|
| 34 |
mechanism to make OCaml functions available to CDuce code in a future
|
| 35 |
release (CDuce-to-OCaml FFI).
|
| 36 |
|
| 37 |
For the moment, you can have a look at the file types/builtin.ml in the
|
| 38 |
CDuce distribution. This is where the built-in operators are declared.
|
| 39 |
|
| 40 |
For instance, here is how to implement getenv:
|
| 41 |
|
| 42 |
1. Add to types/builtin.ml the following:
|
| 43 |
|
| 44 |
let exn_not_found =
|
| 45 |
Value.CDuceExn (Value.Atom (Atoms.mk_ascii "Not_found"));;
|
| 46 |
|
| 47 |
unary_op_cst "getenv" string_latin1 string_latin1
|
| 48 |
(fun e ->
|
| 49 |
Location.protect_op "getenv";
|
| 50 |
let var = Value.get_string_latin1 e in
|
| 51 |
try Value.string_latin1 (Sys.getenv var)
|
| 52 |
with Not_found -> raise exn_not_found);;
|
| 53 |
|
| 54 |
Comments:
|
| 55 |
- the first line register the name of the operator, the type
|
| 56 |
of the argument and the type of the result.
|
| 57 |
|
| 58 |
- the last argument is the runtime implementation of the function.
|
| 59 |
It takes the internal representation of a CDuce value (see
|
| 60 |
runtime/value.mli).
|
| 61 |
The first line ensures that we're not running in the web interface
|
| 62 |
(for security, most of the system calls should be disabled).
|
| 63 |
Then we extract the content of the argument as a Caml string
|
| 64 |
(Value.get_string_latin1), we apply the OCaml function
|
| 65 |
(Sys.getenv), and we wrap the result as a CDuce value
|
| 66 |
(Value.string_latin1). In case of failure, we raise
|
| 67 |
a CDuce exception (that can be catched by a CDuce try...with...),
|
| 68 |
which is internally the Caml exception Value.CDuceExn.
|
| 69 |
|
| 70 |
- I'm not completely sure about the type "string_latin1". Conceptually,
|
| 71 |
CDuce strings are sequences of Unicode codepoints. I don't know
|
| 72 |
what is the best way to interpret these sequences when communicating
|
| 73 |
with the OS; this probably depends on the current locale.
|
| 74 |
string_latin1 means that the codepoints must all be in the Latin1
|
| 75 |
character set (initial prefix of the Unicode character set),
|
| 76 |
and we communicate with the OS using the iso-8859-1 encoding.
|
| 77 |
|
| 78 |
- in this case, the typing of the operator is simple (input type /
|
| 79 |
output type). In general, it is possible to specify a more complex
|
| 80 |
typing behavior (actually, an arbitrary transformation from the
|
| 81 |
input type to the output type), but this requires to know some
|
| 82 |
internals of CDuce typing algorithm (which includes a bottom-up
|
| 83 |
propagation of typing constraints to localize errors precisely);
|
| 84 |
for instance, you can have a look at the typing function for the
|
| 85 |
"+" operator (which is overloaded: it denotes addition of integers
|
| 86 |
and merging of records).
|
| 87 |
|
| 88 |
2. Add to parser/parser.ml the following line:
|
| 89 |
| LIDENT "getenv"
|
| 90 |
after the line:
|
| 91 |
| LIDENT "load_file" | LIDENT "load_file_utf8"
|
| 92 |
in the production rule for operators in expressions.
|
| 93 |
|
| 94 |
I'm reluctant to include a lot of operators such as getenv for the moment
|
| 95 |
since I prefer to wait for the cleaner CDuce-to-OCaml FFI. Also,
|
| 96 |
the way to register operators is not documented and may change in the
|
| 97 |
future (especially if CDuce becomes a compiler, of course !).
|
| 98 |
|
| 99 |
But feel free to add whatever you want, and don't hesitate to ask if you
|
| 100 |
need assistance.
|
| 101 |
|
| 102 |
Hope this helps,
|
| 103 |
|
| 104 |
Alain
|
| 105 |
</sample>
|
| 106 |
|
| 107 |
|
| 108 |
</box>
|
| 109 |
</page>
|