.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "EC2C 1" .TH EC2C 1 "2020-02-06" "lustre v4, release III.a" "Lustre V4 Distribution" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" ec2c, poc \- ansi C code generator .SH "SYNOPSIS" .IX Header "SYNOPSIS" \&\fBec2c\fR \fIfile\fR\fB.ec\fR [\fBoptions\fR] .PP \&\fBpoc\fR \fIfile\fR\fB.oc\fR [\fBoptions\fR] .SH "DESCRIPTION" .IX Header "DESCRIPTION" These tools are Ansi-C code generators. They are presented together, since they share the same conventions for the generated user interface. Otherwise, they are completely separated tools, working in different formats, and performing different tasks: .IP "\(bu" 4 \&\fBpoc\fR takes as input a \fBoc\fR file, which is already a sequential imperative program; the work of \fBpoc\fR is then a simple translation between similar formalisms. .IP "\(bu" 4 \&\fBec2c\fR compiles an \fBec\fR program into Ansi-C code. Since \fBec\fR (which is a subset of Lustre) is a declarative language, a lot of work remains to do for building sequential code. In this sense, \&\fBec2c\fR is closer (but anyway simpler) to a tool like \fBec2oc\fR. Roughly speaking, using \fBec2c\fR is almost equivalent to using \fBec2oc\fR with the \fB\-0\fR option, and then \fBpoc\fR. The main characteristic of this compiler is that both the compilation time and the size of the code are linear with respect to the size of the source code. Moreover the compilation algorithm strictly follows the Lustre formal semantics, just like the simulator \fBecexe\fR does. .SH "TARGET CODE" .IX Header "TARGET CODE" The code generated by those compilers consists essentially in a procedure implementing a step of the reactive program described in the source file. In order to run the reactive program, the user must write a main loop around the \*(L"step\*(R" procedure. .PP In the following, we precise what it is automatically generated, and what the user has to write. Let us call \fIfoo.oc\fR (resp. \fIfoo.ec\fR) the source file, \&\fI\s-1FOO\s0\fR the \fBoc\fR module (resp. the \fBec\fR node) defined in the source file, \&\fIfoo.c\fR and \fIfoo.h\fR the generated files, and \fIloop.c\fR the main program written by the user. .SS "Execution context" .IX Subsection "Execution context" The generated code allows multiple allocations of a reactive module. The memory needed for an instance of the reactive module is defined in \fIfoo.c\fR, and declared in \fIfoo.h\fR: .PP .Vb 1 \& struct FOO_ctx; .Ve .PP The user does not have to know what this structure is made of, he is only allowed to manipulate pointers. The user can get a new context using a procedure declared in \&\fIfoo.h\fR: .PP .Vb 1 \& struct FOO_ctx * FOO_new_ctx(void* client_data); .Ve .PP The user can associate an extra information to a new execution context using the \f(CW\*(C`client_data\*(C'\fR argument. This information is necessary if the user wants to run several instances of a same reactive module concurrently. .SS "Step procedure" .IX Subsection "Step procedure" The procedure implementing a step of the reactive module is declared in \fIfoo.h\fR: .PP .Vb 1 \& void FOO_step(struct FOO_ctx * ctx); .Ve .PP This procedure is called with an execution context previously created by a call to \f(CW\*(C`FOO_new_ctx\*(C'\fR. This step procedure has no input/output parameters, since communication between the main loop and the reactive module is made via input/output procedures. More precisely, the user must call input procedures to set the input values before he calls the step procedure. The step procedure calls output procedures to send its outputs to the environment. .SS "Inputs and outputs" .IX Subsection "Inputs and outputs" Communications between \fIfoo.c\fR and \fIloop.c\fR are made via input and output procedures. The input procedures are defined in \fIfoo.c\fR and used in the main loop, the output procedures are defined by the user (in \fIloop.c\fR for instance), and used in \&\fIfoo.c\fR. .PP For each input \fB\s-1IN\s0\fR, of type \fB\s-1TYP\s0\fR, \fIfoo.c\fR contains the definition of the procedure: .PP .Vb 1 \& void FOO_I_IN(struct FOO_ctx* context, TYP value); .Ve .PP Note that if \fB\s-1IN\s0\fR is a pure signal (\fBpoc\fR only), the \fIvalue\fR parameter is omitted: .PP .Vb 1 \& void FOO_I_IN(struct FOO_ctx* context); .Ve .PP For each output \fB\s-1OUT\s0\fR, of type \fB\s-1TYP\s0\fR, the user must define a procedure: .PP .Vb 1 \& void FOO_O_OUT(void* client_data, TYP value); .Ve .PP Note that if \fB\s-1OUT\s0\fR is a pure signal (\fBpoc\fR only), the \&\fIvalue\fR parameter is omitted: .PP .Vb 1 \& void FOO_O_OUT(void* client_data); .Ve .PP Output procedures are called within \fBFOO_step(FOO_ctx* ctx)\fR, using the client data which has been associated with \fBctx\fR when it was created. .SS "Example" .IX Subsection "Example" Here is a simple example of a main loop using a reactive module (whose name is \f(CW\*(C`sum\*(C'\fR) with two real inputs (\f(CW\*(C`x\*(C'\fR and \f(CW\*(C`y\*(C'\fR) and a single real output \f(CW\*(C`s\*(C'\fR; note that the \fIclient data\fR is not necessary, since the loop uses only one instance of the reactive module: .PP .Vb 2 \& #include \& #include "sum.h" \& \& void sum_O_s(void* cdata, float _V){ \& printf("result: %f\en", _V); \& } \& \& main(){ \& _float x; \& _float y; \& struct sum_ctx* prg = sum_new_ctx(NULL); \& \& while(1){ \& printf("(float) x ?\en"); \& scanf("%f", &x); \& sum_I_x(prg, x); \& printf("(float) y ?\en"); \& scanf("%f", &y); \& sum_I_y(prg, y); \& sum_step(prg); \& } \& } .Ve .SS "External objects" .IX Subsection "External objects" Each external object declared in the source file is supposed to be implemented by the user. Some information is necessary for the compilation of the \fBc\fR generated code, other is necessary only for linking. .IP "\(bu" 4 \&\fBCompiling\fR The \fIfoo.c\fR program generated by \fBpoc\fR cannot be compiled unless the external types are defined. \&\fBpoc\fR supposes that those definitions are in a file called \&\fIfoo_ext.h\fR. .IP "\(bu" 4 \&\fBLinking\fR External constants, functions and procedures are declared in \fIfoo.c\fR as imported objects, so \fIfoo.c\fR can be compiled separately. Indeed the user must define those objects somewhere, and link the corresponding code with the \fBpoc\fR object code if he wants to build an executable program! .SS "Standard main loop" .IX Subsection "Standard main loop" When called with the \fB\-loop\fR option, \&\fBpoc\fR (resp. \fBec2c\fR) produces an extra c\-file \&\fIFOO_loop.c\fR. This code contains a main procedure implementing a loop which reads inputs on \fBstdin\fR and write outputs to \fBstdout\fR. If \fIfoo.c\fR does not need external object, it is a simple way to obtain executable code. For instance: .PP .Vb 2 \& poc sum.oc \-loop \& gcc sum.c sum_loop.c \-o sum .Ve .PP produces an interactive program \fBsum\fR, which allows the user to test his code. .PP If external objects are needed, the user must write all the necessary code plus two procedures for each external type \fB\s-1TYP\s0\fR: .IP "\(bu" 4 \&\f(CW\*(C`TYP _get_TYP(char* name)\*(C'\fR reads a value of type \fB\s-1TYP\s0\fR on \fBstdin\fR, and returns it. The argument "\f(CW\*(C`name\*(C'\fR\*(L" is the name of the input, used to make the procedure more \*(R"interactive". .IP "\(bu" 4 \&\f(CW\*(C`void _put_TYP(TYP val)\*(C'\fR prints the value "\f(CW\*(C`val\*(C'\fR" on \fBstdout\fR. .SS "Pragmas" .IX Subsection "Pragmas" In order to allow automatic manipulation of the code generated, the compiler generates special comments (pragmas) in the header file. Pragmas are single line Ansi C comments, begining with the string \fBpoc:\fR. Ther is a pragma which gives the name of the module, and a pragma for each input and each output, giving its type and its name. Here is an example of pragma section: .PP .Vb 4 \& //poc:MODULE sum \& //poc:IN _float x \& //poc:IN _float y \& //poc:OUT _float s .Ve .SH "OPTIONS" .IX Header "OPTIONS" .IP "\fB\-v\fR" 4 .IX Item "-v" set the verbose mode. .IP "\fB\-o\fR \fIname\fR" 4 .IX Item "-o name" define the prefix for the target files. The default is to use the name of the module (i.e. node), which is not necessarily the name of the source file. .IP "\fB\-loop\fR" 4 .IX Item "-loop" generate an extra main file called \fIname\fR\fB_loop.c\fR. This main is sufficient to build a stand-alone application if the reactive module does not need any external definitions. .SH "SEE ALSO" .IX Header "SEE ALSO" lustre, lus2ec, ecexe, luciole, simec, lus2oc, ec2oc, ocmin, lus2atg, oc2atg, ec2c, poc, lux, lesar, ecverif, xlesar