Commit 45f9d2f8 authored by Erwan Jahier's avatar Erwan Jahier
Browse files

Add --luc2c options to lutin.

--2c-4lustre <string>
            generate C code to be called from Lustre V4
--2c-4scade <string>
            generate C code to be called from Scade
--2c-4luciole
            generate a C file containing the necessary stuff to call the lucky file with luciole
--2c-4alice <string>
            generate C and C++ code to be called from Alice
parent b1c8884c
......@@ -80,6 +80,7 @@
\newcommand{\lustre}{{\sc Lustre}\xspace}
\newcommand{\lurette}{{\sc Lurette}\xspace}
\newcommand{\simtochro}{{\sc Sim2chro}\xspace}
\newcommand{\simtochrogtk}{{\sc Sim2chrogtk}\xspace}
\newcommand{\luciole}{{\sc Luciole}\xspace}
\newcommand{\gnuplotrif}{{\sc Gnuplot-rif}\xspace}
......
......@@ -37,7 +37,7 @@ down (resp up), and so on forever.
\includegraphics[width=15cm]{ud.jpg}
\caption{
This image has been obtained with the command {\tt lutin -l 100 ud.lut -main main > ud.rif ;gnuplot-rif -jpg ud.rif}
}
}\label{gnuplot-ud}
\end{figure}
\subsection{The crazy rabbit}
......
......@@ -14,6 +14,7 @@ Here is the output of {\tt lutin --help}:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{The C and the \ocaml API}
\label{api}
It is possible to call the \lutin interpreter from C or from \Ocaml
programs.
......@@ -51,25 +52,13 @@ Some tools developed in the Verimag lab might be useful in you write
briefly how they can be used in conjunction with \lutin.
\subsubsection{sim2chro}
{\tt sim2chro} is a program written par Yann R\'emond that displays
data files that follows the RIF convention.
\subsubsection{\gnuplotrif}
{\gnuplotrif} is another tool that displays RIF files. Sometimes
it performs a better job than {\tt sim2chro}, sometimes not.
Here is the output of {\tt gnuplot-rif --help}:
\begin{alltt}
\input{gnuplotrif}
\end{alltt}
\todo{Faire une copie d'ecran illustrant \gnuplotrif.}
\subsubsection{\lustre}
Using the {\tt lutin --2c-4lustre <string>} option and the C API
described in Section\ref{api}, one can call the
\lutin interpreter from a lustre node.
A complete example can be found in \verb+examples/lutin/lustre/+.
\subsubsection{\luciole}
......@@ -78,13 +67,13 @@ Here is the output of {\tt gnuplot-rif --help}:
ease the execution of \lustre programs.
Using the {\tt lutin --c-glue luciole} option, one can use the \lutin
Using the {\tt lutin --2c-4luciole} option, one can use the \lutin
interpreter in conjunction with Luciole. This can be very handy when
writing \lutin programs.
A complete example can be found in \verb+examples/lutin/luciole/+.
\todo{Faire une copie d'ecran illustrant une simu luciole/lutin.}
A complete example can be found in \verb+examples/lutin/luciole/+.
\subsubsection{\lurette}
......@@ -101,6 +90,29 @@ inputs. From a lutin-centric point of view, a \lutin program could use
A complete example can be found in {\tt examples/lutin/xlurette}.
\subsubsection{\simtochro}
\simtochro is a program written par Yann R\'emond that displays
data files that follows the RIF convention. For example, to display
à RIF file, one can launch the command : {\tt sim2chrogtk -ecran -in
data.rif }
\subsubsection{\gnuplotrif}
{\gnuplotrif} is another tool that displays RIF files. Sometimes
it performs a better job than \simtochro, sometimes not.
Here is the output of {\tt gnuplot-rif --help}:
\begin{alltt}
\input{gnuplotrif}
\end{alltt}
An example is provided in Figure~\ref{gnuplot-ud} of
Section~\ref{up-and-down}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......
......@@ -21,7 +21,7 @@ ifneq ($(HOST_TYPE),mac)
# cd xlurette/Sildex/ && make test ;
cd ocaml/crazy-rabbit/ && make test ;
endif
cd rml/ && make test ;
((which rmlc && cd rml/ && make test) || true) ;
ifeq ($(HOST_TYPE),sparc-sun)
cd xlurette/Scade-sparc && make test ;
else
......@@ -41,6 +41,8 @@ test-lutin:
cd lutin/C && make test;
cd lutin/ocaml && make test;
cd lutin/external_code && make test;
cd lutin/luciole && make test ;
cd lutin/lustre && make test ;
echo "All lutin tests ran correctly."
test: test-lucky test-lutin
......
LUTIN=../../../$(HOSTTYPE)/bin/lutin
-include Makefile.env
export LURETTE_PATH=../../..
go:
$(LUTIN) --2c-4luciole env.lut -m main && \
make -f Makefile.env
test: go
make clean
let between(x, min, max : real) : bool =
((min < x) and (x < max))
let abs(x : real) : real =
if x > 0.0 then x else -x
let up_and_down(x : real ref; min, max, delta : real) =
exist px : real in
assert px = pre x in
if (pre x < min) or (
(pre x < max) and (pre px <= pre x)
) then (
between(x, pre x, pre x + delta)
) else (
between(x, pre x - delta, pre x)
)
node main(Heat_on : bool) returns (
T1 : real;
T2 : real;
T3 : real) =
exist T:real in
assert abs(T-T1) < 0.5 in
assert abs(T-T2) < 0.5 in
assert abs(T-T3) < 0.5 in
loop [1,1] -- R1: j'aimerais bien ecrire Loop 1 en fait...
{
(6.0 < T) and (T < 9.0)
}
fby
loop { (if Heat_on then T > pre T else T < pre T) and (abs(T-pre T)<1.0) }
CC = gcc -g
LD = gcc -g
EXE=
CFLAGS = \
-L../../../$(HOSTTYPE)/lib \
-I../../../$(HOSTTYPE)/include
LIBS = -lluc4c_nc -llucky_nc -lgmp -lm -ldl -lstdc++
LUTIN=../../../$(HOSTTYPE)/bin/lutin
ifeq ($(HOSTTYPE),win32)
EXE=.exe
CFLAGS = \
-L../../../$(HOSTTYPE)/lib -L/cygdrive/c/TEMP/MinGW/lib \
-I../../../$(HOSTTYPE)/include \
-Winline -Wimplicit-function-declaration
LIBS = -lluc4c_nc -llucky_nc -lgmp -lws2_32 -lm -lstdc++
LUTIN=../../../$(HOSTTYPE)/bin/lutin(EXE)
endif
ifeq ($(HOSTTYPE),mac)
LD = g++ -g
LIBS = -lluc4c_nc -llucky_nc -lgmp -lm -ldl
endif
################################################################
# Calling lutin from Lustre
call_foo_loop.c:foo.c
call_foo_ext_func.c:foo.c
foo.c: foo.lut
$(LUTIN) --2c-4lustre "call_foo" -seed 42 foo.lut -m main
call_foo.ec:
lus2ec call_foo.lus call_foo
call_foo.c: call_foo.ec
ec2c -loop call_foo.ec
%.o : %.c
$(CC) -c $(CFLAGS) $*.c
foo: foo.o call_foo.o call_foo_ext_func.o call_foo_loop.o
$(LD) $(CFLAGS) -o $@ $^ $(LIBS)
################################################################
clean:
rm -f run *.o *~ call_foo_ext* call_foo.c call_foo.h call_foo_loop.c call_foo_loop.h foo.h foo.c *.gp *.plot *.rif *.ec foo *.res #*
test : clean foo
ifeq ($(HOSTTYPE),win32)
foo$(EXE)
else
touch test.rif ; rm test.rif
echo "1 1 1 1 1 1 1 1 1 1 1" | ./foo > test.rif
rm -f test.res && diff -u -i test.rif.exp test.rif > test.res
[ ! -s test.res ] && make clean
endif
utest:
cp test.rif test.rif.exp
-- Time-stamp: <modified the 07/12/2006 (at 16:06) by Erwan Jahier>
function foo ( x:int; y:bool; z:real )
returns( a:int; b:bool; c:real );
node call_foo (dummy : int )
returns( a:int; b:bool; c:real );
let
a, b, c = foo(1 -> pre a, true -> pre b, 10.0 -> pre c);
tel;
let abs_int(x: int) =
if x>=0 then x else -x
let abs_real(x: real) =
if x>=0.0 then x else -x
node main(a:int; b:bool; c:real) returns ( x:int [-100000; 100000]; y:bool; z:real [-100000.0;100000.0]) =
loop
{
(b=>y) and abs_int(x - a) < 5 and abs_real(z - c) < 5.0
}
# Interpreting the lutin file foo.lut with node main
-1 true 7.188031
-2 true 10.880835
0 true 9.916883
1 true 8.889484
3 true 8.694923
7 true 9.681718
3 true 12.275496
6 true 8.423593
5 true 4.455379
2 true 8.274838
6 true 10.193351
......@@ -15,7 +15,7 @@
open LucProg
type gen_mode = C | Lustre | Scade | Alice | Luciole
type gen_mode = Lustre | Scade | Alice | Luciole | Nop
type step_mode = Inside | Edges | Vertices
let step_mode_to_str = function
......@@ -37,7 +37,7 @@ type optionT = {
let (option : optionT) = {
pp = None;
output = None;
gen_mode = C;
gen_mode = Nop;
calling_module_name = "XXX_SCADE_MODULE_NAME";
step_mode = Inside;
seed = None;
......@@ -409,9 +409,9 @@ Step procedure
--------*/";
put ("void " ^ fn ^ "_step(" ^ fn ^ "_ctx* ctx, step_mode sm){\n");
List.iter
(fun var ->
(fun var ->
putln (" lucky_set_input_" ^
(Type.to_string (Var.typ var)) ^ "(ctx->lp, \"" ^
(Var.name var) ^ "\", ctx->_" ^
......@@ -545,13 +545,13 @@ let (build_file_name : string list -> string) =
(****************************************************************************)
open LucProg
open Prog
let (main : unit -> unit) =
fun _ ->
let env_list = option.env in
let state = LucProg.make_state option.pp env_list in
let _ = assert (env_list <> []) in
let from_lutin = Util.get_extension (List.hd env_list) = ".lut" in
let fn = build_file_name env_list in
let _ =
......@@ -564,6 +564,7 @@ let (main : unit -> unit) =
gen_lustre_ext_h fn
in
(match option.gen_mode with
| Nop -> ()
| Lustre -> gen_files_for_lustre ()
| Luciole ->
let var_to_vn_ct v =
......@@ -574,7 +575,6 @@ let (main : unit -> unit) =
Luciole.gen_stubs false from_lutin fn
(List.map var_to_vn_ct state.s.in_vars)
(List.map var_to_vn_ct state.s.out_vars)
| C -> ()
| Scade -> ()
| Alice ->
let alice_args = {
......
......@@ -15,7 +15,7 @@
(* To specify the different C backends (not all the tools have the
same convention for interfacing via C). *)
type gen_mode = C | Lustre | Scade | Alice | Luciole
type gen_mode = Lustre | Scade | Alice | Luciole | Nop
type step_mode = Inside | Edges | Vertices
......
......@@ -29,10 +29,10 @@ let gen_makefile str env_ext =
pn ("all: " ^ str ^ ".dro");
pn (" simec ./" ^ str ^ ".dro");
pn "";
pn (str ^ ".c:" ^ str ^ "_luciole.c");
pn "";
pn (str ^ "_luciole.c: " ^ str ^ env_ext);
pn (" $(LURETTE_PATH)/$(HOSTTYPE)/bin/luc2c -pp lucky_cpp --luciole " ^ str ^ env_ext);
(* pn (str ^ ".c:" ^ str ^ "_luciole.c"); *)
(* pn ""; *)
(* pn (str ^ "_luciole.c: " ^ str ^ env_ext); *)
(* pn (" $(LURETTE_PATH)/$(HOSTTYPE)/bin/luc2c -pp lucky_cpp --luciole " ^ str ^ env_ext); *)
pn "";
pn (str ^ ".dro: " ^ str ^ "_luciole.o " ^ str ^ ".o");
pn (" g++ $(CFLAGS) " ^ str ^ "_luciole.o " ^ str ^ ".o $(LIBS) -shared -o " ^ str ^ ".dro");
......
......@@ -291,6 +291,19 @@ let main () = (
try (
MainArg.parse () ;
if (MainArg.simu ()) then to_simu ()
else if (Luc2c.option.Luc2c.gen_mode <> Luc2c.Nop) then
(
Luc2c.option.Luc2c.output <- MainArg.outfile () ;
Luc2c.option.Luc2c.seed <- (Some(MainArg.seed ()));
Luc2c.option.Luc2c.step_mode <- (
match (MainArg.draw_mode ()) with
| Lucky.StepInside -> Luc2c.Inside
| Lucky.StepEdges -> Luc2c.Edges
| Lucky.StepVertices -> Luc2c.Vertices)
;
Luc2c.option.Luc2c.env <- ([MainArg.infile()]);
Luc2c.main ()
)
else (
let inchannel = if (MainArg.infile() = "") then (
stdin
......
......@@ -18,7 +18,7 @@ let usage_msg = "usage: "^tool_name^" [options] <file> | "^tool_name^" -help"
(* options lists:
_opts = classical Arg option tab used by Arg.parse
_user_man = ad hoc tab for pretty prtting usage
_user_man = ad hoc tab for pretty prtting usage
_hidden_man = ad hoc tab for pretty prtting usage
*)
......@@ -75,6 +75,8 @@ let max_steps () = !_max_steps
let _show_locals = ref false
let show_locals () = !_show_locals
(* all unrecognized options are accumulated *)
let _others = ref []
let add_other s = (
......@@ -170,164 +172,198 @@ let mkopt ol ?(hide=false) ?(arg="") se ml = (
(*** USER OPTIONS TAB **)
let mkoptab () = (
mkopt
["-m";"-main"]
~arg:" <string>"
(Arg.String(function s -> _main_node := s))
["set main node"]
;
mkopt
["-version"]
(Arg.Unit(function _ -> print_string version; exit 0))
["print the current version then exit"]
;
(* verbose *)
mkopt
["-v"]
(Arg.Unit(function _ -> Verbose.on () ))
["set verbose mode"]
;
mkopt
["-vl"]
~arg:" <int>"
(Arg.Int(function i -> Verbose.set i))
["set verbose level"]
;
(* ---- COMPILE OPTIONS *)
mkopt
["-luc"]
(Arg.Unit(function _ -> _simu := false ; ()))
["generate a lucky program"]
;
mkopt
["-o"]
~arg:" <string>"
(Arg.String(function s -> _outfile := Some s))
["with -luc: write to specified file (default is infile_main.luc)"]
;
mkopt
["-os"]
(Arg.Unit(function s -> _outpipe := true))
["with -luc: write to stdout"]
;
mkopt
["-L"; "-lib"]
~arg:"<string>"
(Arg.String(function s -> _libs := s::!_libs))
["add a dynamic library where to search for external code"]
;
(* ---- SIMU/SOLVER OPTIONS *)
(* simu *)
mkopt
["-b";"-boot"]
~arg:" <int>"
(Arg.Set _boot)
["perform a first step without requiring inputs";
"(n.b. fails if inputs are actually required at first step)"
]
;
mkopt
["-seed"]
~arg:" <int>"
(Arg.Int(function i -> _seed := Some i ; ()))
["seed for random engine"]
;
mkopt
["-l"; "--max-steps"]
~arg:" <int>"
(Arg.Int(function i -> _max_steps := Some i ; ()))
["max simulation steps"]
;
mkopt
["--step-inside"]
(Arg.Unit(function _ -> _draw_mode := Lucky.StepInside))
["draw inside the convex hull of solutions (default)"]
;
mkopt
["--step-edges"]
(Arg.Unit(function _ -> _draw_mode := Lucky.StepEdges))
(* "draw inside the convex hull of solutions, but a little bit more at edges and vertices" *)
["draw a little bit more at edges and vertices"]
;
mkopt
["--step-vertices"]
(Arg.Unit(function _ -> _draw_mode := Lucky.StepVertices))
["draw among the vertices of the convex hull of solutions"]
;
mkopt
["-fair"; "--compute-poly-volume"]
(Arg.Set _compute_volume)
[ "Compute polyhedron volume before drawing";
"more fair, but more expensive"
];
mkopt
["-precision";"-p"]
(Arg.Set_int Util.precision)
~arg:" <int>"
[ "precision for conversion float to rationnal (default 2)"
];
mkopt
["-locals";"-loc"]
(Arg.Set _show_locals)
[ "show local variables"
];
(* HIDDEN *)
(* test lexical *)
mkopt ~hide:true
["-tlex"]
(Arg.Unit(function _ -> _test_lex := true ; ()))
["TEST lexical analysis"]
;
(* test syntaxique *)
mkopt ~hide:true
["-tparse"]
(Arg.Unit(function _ -> _test_parse := true ; ()))
["TEST syntactic analysis"]
;
(* test type-checking *)
mkopt ~hide:true
["-tcheck"]
(Arg.Unit(function _ -> _test_check := true ; ()))
["TEST type/binding checking"]
;
(* test expansion *)
mkopt ~hide:true
["-texpand"]
(Arg.Unit(function _ -> _test_expand := true ; ()))
["TEST expansion"]
;
(* test autogen *)
mkopt ~hide:true
["-tauto"]
(Arg.Unit(function _ -> _test_auto := true ; ()))
["test automaton generation"]
;
mkopt ~hide:true
["-h";"-help"; "--help"]
(Arg.Unit help)
[]
;
(* paranoid/debug *)
mkopt ~hide:true
["-paranoid"]
(Arg.Unit(function _ -> Utils.set_paranoid ()))
["paranoid mode (slow)"]
;
mkopt ~hide:true
["-prof"]
(Arg.Unit(function _ -> Utils.set_prof ()))
["profile mode"]
;
(* misc degub flag *)
mkopt ~hide:true
["-debug"; "-dbg"]
(Arg.String (function s -> let x = Verbose.get_flag s in Verbose.set_flag x))
[]
mkopt
["-m";"-main"]
~arg:" <string>"
(Arg.String(function s -> _main_node := s))
["set main node"]
;
mkopt
["-version"]
(Arg.Unit(function _ -> print_string version; exit 0))
["print the current version"]
;
(* verbose *)
mkopt
["-v"]
(Arg.Unit(function _ -> Verbose.on () ))
["set a verbose mode (equivalent to -vl 1)"]
;
mkopt
["-vl"]
~arg:" <int>"
(Arg.Int(function i -> Verbose.set i))
["set the verbose level"]
;
(* ---- COMPILE OPTIONS *)
mkopt
["-luc"]
(Arg.Unit(function _ -> _simu := false ; ()))
["generate a lucky program"]
;
mkopt
["-o"]
~arg:" <string>"
(Arg.String(function s -> _outfile := Some s))
["with -luc: write to specified file (default is infile_main.luc)"]
;
mkopt
["-os"]
(Arg.Unit(function s -> _outpipe := true))
["with -luc: write to stdout"]
;
mkopt
["-L"; "-lib"]
~arg:" <string>"
(Arg.String(function s -> _libs := s::!_libs))
["add a dynamic library where to search for external code"]
;