diff --git a/lv6-ref-man/Makefile b/lv6-ref-man/Makefile index a79a3a5e9d7f7abc612b61aa089e9f2e6cdc22f9..8073c58f0af91eb98fdd5c8a569b17b5fa16c14a 100644 --- a/lv6-ref-man/Makefile +++ b/lv6-ref-man/Makefile @@ -20,14 +20,6 @@ SRCS= \ # Les inclusions de figures FIGDIR=figs -FIGS=\ - $(OBJPDF)/edge.tex \ - $(OBJPDF)/df.tex \ - $(OBJPDF)/map1.tex \ - $(OBJPDF)/red1.tex \ - $(OBJPDF)/fill1.tex \ - $(OBJPDF)/fillred1.tex - all: $(OBJPDF) \ $(FIGS) \ @@ -68,3 +60,45 @@ re: make touch touch.tex make +################################################# +# direct inclusion of lustre non-reg files into the manual + +LUSTRE_DIR=$(HOME)//lus2lic/src/test/should_work +LUS2TEX=$(HOME)/TeXinputs/lus2tex + +EXEMPLES= \ + $(LUSTRE_DIR)/Pascal/struct.lus \ + $(LUSTRE_DIR)/Pascal/consensus2.lus \ + $(LUSTRE_DIR)/NONREG/count.lus \ + $(LUSTRE_DIR)/NONREG/EDGE.lus \ + $(LUSTRE_DIR)/NONREG/STABLE.lus \ + $(LUSTRE_DIR)/NONREG/TIME_STABLE.lus \ + $(LUSTRE_DIR)/NONREG/TIME_STABLE1.lus \ + $(LUSTRE_DIR)/NONREG/COUNTER.lus \ + $(LUSTRE_DIR)/NONREG/SWITCH.lus \ + $(LUSTRE_DIR)/NONREG/SWITCH1.lus \ + $(LUSTRE_DIR)/NONREG/FALLING_EDGE.lus \ + $(LUSTRE_DIR)/NONREG/sincos.lus \ + $(LUSTRE_DIR)/NONREG/integrator.lus \ + $(LUSTRE_DIR)/NONREG/type_decl.lus \ + $(LUSTRE_DIR)/NONREG/merge.lus \ + $(LUSTRE_DIR)/NONREG/enum0.lus \ + $(LUSTRE_DIR)/NONREG/param_node.lus \ + $(LUSTRE_DIR)/NONREG/param_node2.lus \ + $(LUSTRE_DIR)/packEnvTest/complex.lus\ + $(LUSTRE_DIR)/packEnvTest/model.lus + +FIGS=\ + $(OBJPDF)/patate.tex \ + $(OBJPDF)/edge.tex \ + $(OBJPDF)/df.tex \ + $(OBJPDF)/map1.tex \ + $(OBJPDF)/red1.tex \ + $(OBJPDF)/fill1.tex \ + $(OBJPDF)/fillred1.tex + +lus2tex: + for f in ${EXEMPLES}; do \ + $(LUS2TEX) $$f > `basename $$f`.tex ;\ + done +################################################# diff --git a/lv6-ref-man/commandes.tex b/lv6-ref-man/commandes.tex index 1c03d491b403bb3006ef524b9f6e8936d4015e72..f10646da060eb6c7cce8af800edbd68d77018ea9 100644 --- a/lv6-ref-man/commandes.tex +++ b/lv6-ref-man/commandes.tex @@ -1,5 +1,7 @@ \newcommand{\kwd}[1]{{\bf \color{blue3} #1}} +\newcommand{\pause}[0]{} + \newcommand{\kwdd}[1]{{\color{DarkSlateGrey} #1}} \newcommand{\kwddd}[1]{{\bf \color{green4} #1}} diff --git a/lv6-ref-man/lv6-ref-man.tex b/lv6-ref-man/lv6-ref-man.tex index 79f7516aa7273f001b7dc60e6f51d00b75b230f8..4425aac61ef1f6858264ea3805fd470b949f5600 100644 --- a/lv6-ref-man/lv6-ref-man.tex +++ b/lv6-ref-man/lv6-ref-man.tex @@ -32,10 +32,9 @@ read directly this chapter. - %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\chapter{Lustre Core} +\chapter{An Overview of the Lustre Language} % {Basic Lustre} % {Simple Lustre} % {Lustre basics} @@ -48,8 +47,6 @@ read directly this chapter. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Overview of the Language} % \begin{summary} % \sumitem{ginf}{Introduction} @@ -71,7 +68,7 @@ read directly this chapter. % \subsumitem{include}{Including files} % \end{summary} -\subsection{Introduction}\label{ginf} +\section{Introduction}\label{ginf} This manual presents the \lustre\ language, a synchronous language based on the dataflow model and designed for the description and @@ -87,7 +84,7 @@ it makes precise the metalanguage used to describe the syntax throughout the document and describes the lexical rules of the language. -\subsubsection{Synchronous Model}\label{syncmod} +\subsection{Synchronous Model}\label{syncmod} The synchronous model was introduced to provide abstract primitives assuming that a program reacts instantaneously to external @@ -107,29 +104,20 @@ time scale. Consequently, outputs are computed and inputs are taken into account ``at the same time'' (with respect to the discrete time scale). -\subsubsection{Dataflow Model}\label{dataflo} +\subsection{Dataflow Model}\label{dataflo} The dataflow model is based on a block diagram description. A block diagram can be described either graphically, or by a system of equations. A system is made up of a network of operators acting in parallel and in time with their input rate. -\begin{center} -\begin{minipage}{6cm} -\input{df.tex} -\end{minipage}\hspace*{1cm} -\begin{minipage}{8cm} -\begin{program} -\kw{node} count (x,y: \kw{int}) \kw{returns} (s: \kw{int});\\ -\kw{let}\\ -\>s = 2*(x+y);\\ -\kw{tel} -\end{program} -\begin{center} -Textual view of the same network -\end{center} -\end{minipage} -\end{center} + +\begin{example}[A Textual and a graphical view of the same network] +\input{count.lus} + +\vspace{-2cm} \hfill \input{df.tex} +\end{example} + \noindent This model provides the following advantages: @@ -141,7 +129,7 @@ are dependencies between data), \item ability to describe a system graphically. \end{itemize} -\subsubsection{Synchronous Dataflow Model}\label{sydataflow} +\subsection{Synchronous Dataflow Model}\label{sydataflow} \index{synchronous dataflow} The synchronous dataflow approach consists in adding a time @@ -170,7 +158,7 @@ at a given instant cannot depend on future inputs (causality) and can depend on only a bounded number of inputs (each cycle can memorize the value of the previous input). -\subsubsection{Building a Description}\label{buides} +\subsection{Building a Description}\label{buides} A \lustre\ program describes the relations between the outputs and inputs of a system. These relations are expressed using @@ -207,7 +195,7 @@ depends on software and hardware performance. \lustre\ is a language describing systems with a deterministic behavior from both a functional and a time point of view. -\subsection{Basic Features}\label{basic} +\section{Basic Features}\label{basic} In this section, we present informally the main basic features of the language, through several simple examples. @@ -222,7 +210,7 @@ $n$th value. A node defines one or several output parameters as functions of one or several input parameters. All these parameters are flows. -\subsubsection{Simple control devices} \label{control} +\subsection{Simple control devices} \label{control} \begin{figure} \begin{center} @@ -302,23 +290,19 @@ equal to \prog{A} at the first instant, and then forever equal to \noindent So, the complete definition of the node \prog{EDGE} is the following: -\begin{program} -\kw{node} EDGE (X: \kw{bool}) \kw{returns} (Y: \kw{bool});\\ -\kw{let}\\ -\>Y = \kw{false} \fby\ X \kw{and} \kw{not} \kw{pre}(X);\\ -\kw{tel} -\end{program} +\begin{example}[The EDGE node] +\input{EDGE.lus} +\end{example} + Once a node has been defined, it can be called from another node, using it as a new operator. For instance, let us write another node, computing the falling edge of its input parameter: -\begin{program} -\kw{node} FALLING\_EDGE (X: \kw{bool}) \kw{returns} (Y: \kw{bool});\\ -\kw{let}\\ -\>Y = EDGE(\kw{not} X);\\ -\kw{tel} -\end{program} +\begin{example}[The FALLING\_EDGE node] +\input{FALLING_EDGE.lus} +\end{example} + The \prog{EDGE} node is of very common usage for ``deriving'' a Boolean flow, i.e., transforming a ``level'' into a ``signal''. The @@ -334,17 +318,11 @@ not change. ``\prog{initial}'' defines the initial value of Boolean flow, whose value is true whenever the signal occurs. Below is a first version of the program: -\label{switch} -\begin{program} -\kw{node} SWITCH1 (set, reset, initial: \kw{bool}) \kw{returns} (level: \kw{bool});\\ -\kw{let}\\ -\>level = initial \fby\ - \>\>\>\>\>\kw{if} set \kw{then} true\\ -\>\>\>\>\>\>\kw{else} \kw{if} reset \kw{then} \kw{false}\\ -\>\>\>\>\>\>\kw{else} \kw{pre}(level);\\ -\kw{tel} -\end{program} +\begin{example}[The SWITCH1 node] +\input{SWITCH1.lus} +\end{example} + \noindent which specifies that the ``\prog{level}'' is initially equal to ``\prog{initial}'', and then forever, @@ -366,9 +344,12 @@ Moreover, if this node is intended to be used only in contexts where inputs \prog{set} and \prog{reset} are never true together, such an {\em assertion} can be specified: + \begin{program} -\kw{assert} \kw{not} (set \kw{and} reset); -\end{program}\index{assertion} + \kwd{assert} not (set \kwdd{and} reset); +\end{program} +\index{assertion} + Otherwise, this program has a flaw: It cannot be used as a ``one-button'' switch, whose level changes whenever its unique button @@ -376,7 +357,7 @@ is pushed. Let ``\prog{change}'' be a Boolean flow representing a signal, then the call \begin{program} -state = SWITCH1(change,change,\kw{true}); +state = SWITCH1(change,change,\kwdd{true}); \end{program} will compute the always true flow: ``\prog{state}'' is initialized @@ -387,17 +368,11 @@ make the program a bit more complex: the ``\prog{set}'' signal must be considered only when the switch is turned off. We get the following program: -\begin{program} -\kw{node} SWITCH (set, reset, initial: \kw{bool}) \kw{returns} (level: \kw{bool});\\ -\kw{let}\\ -\>level = initial \fby\ - \>\>\>\>\>\kw{if} set \kw{and} \kw{not} \kw{pre}(level) \kw{then} \kw{true}\\ -\>\>\>\>\>\>\kw{else} \kw{if} reset \kw{then} \kw{false}\\ -\>\>\>\>\>\>\kw{else} \kw{pre}(level);\\ -\kw{tel} -\end{program} +\begin{example}[The SWITCH node] +\input{SWITCH.lus} +\end{example} -\subsubsection{Numerical examples} \label{numeric} +\subsection{Numerical examples} \label{numeric} Recursive sequences are very easy to define in \lustre. For instance, the equation ``\prog{N = 0 \fby\ \kw{pre} N + 1;}'' defines the sequence of @@ -405,7 +380,7 @@ natural numbers. Let us complexify this definition to build an integer sequence, whose value is, at each instant, the number of occurrences of the ``true'' value of a Boolean flow \prog{X}: \begin{program} -N = 0 \fby\ \kw{if} X \kw{then} \kw{pre} N + 1 \kw{else} \kw{pre} N; +N = 0 \fby\ \kwdd{if} X \kwdd{then} \kwdd{pre} N + 1 \kwdd{else} \kwdd{pre} N; \end{program} \noindent @@ -413,16 +388,16 @@ This definition does not exactly meet the specification, since it ignores the initial value of \prog{X}. A well-initialized counter could be: \begin{program} -PN = 0 \fby\ \kw{pre} N;\\ -N = \kw{if} X \kw{then} PN + 1 \kw{else} PN; +PN = 0 \fby\ \kwdd{pre} N;\\ +N = \kwdd{if} X \kwdd{then} PN + 1 \kwdd{else} PN; \end{program} or, simply \begin{program} -N = \kw{if} X \kw{then} (0 \fby\ \kw{pre} N) + 1 \kw{else} (0 \fby\ \kw{pre} N); +N = \kwdd{if} X \kwdd{then} (0 \fby\ \kwdd{pre} N) + 1 \kwdd{else} (0 \fby\ \kwdd{pre} N); \end{program} or even \begin{program} -N = (0 \fby\ \kw{pre} N) + \kw{if} X \kw{then} 0 \kw{else} 1; +N = (0 \fby\ \kwdd{pre} N) + \kwdd{if} X \kwdd{then} 0 \kwdd{else} 1; \end{program} \noindent @@ -436,27 +411,21 @@ Let us write a more general operator, with additional inputs: \end{itemize} \noindent The complete definition of this operator is the following: -\begin{program} -\kw{node} COUNTER (init, incr: \kw{int}; X, reset: \kw{bool}) \kw{returns} (N: \kw{int});\\ -\kw{var} PN: \kw{int};\\ -\kw{let}\\ -\>PN = init \fby\ \kw{pre} N;\\ -\>N = - \>\>\kw{if} reset \kw{then} init\\ -\>\>\>\kw{else} \kw{if} X \kw{then} PN + incr\\ -\>\>\>\kw{else} PN;\\ -\kw{tel} -\end{program} + +\begin{example}[The COUNTER node] +\input{COUNTER.lus} +\end{example} + \noindent This node can be used to define, e.g., the sequence of odd integers: \begin{program} -odds = COUNTER (0,2,\kw{true},\kw{false}); +odds = COUNTER (0,2,\kwdd{true},\kwdd{false}); \end{program} \noindent or the sequence of integers modulo 10: \begin{program} -mod10 = COUNTER (0,1,\kw{true},reset);\\ -reset = \kw{true} \fby\ \kw{pre}(mod10)=9; +mod10 = COUNTER (0,1,\kwdd{true},reset);\\ +reset = \kwdd{true} \fby\ \kwdd{pre}(mod10)=9; \end{program} Our next example involves real values. Let $f$ be a real function of @@ -469,24 +438,16 @@ It computes a real-valued flow \prog{Y}, such that \[\prog{Y}_{n+1} = \prog{Y}_n + (\prog{F}_n + \prog{F}_{n+1})*\prog{STEP}_{n+1}/2\] The initial value of \prog{Y} is also an input parameter: -\begin{program} -\kw{node} integrator(F,STEP,init: \kw{real}) \kw{returns} (Y: \kw{real});\\ -\kw{let}\\ -\>Y = init \fby\ \kw{pre}(Y) + ((F + \kw{pre}(F))*STEP)/2.0;\\ -\kw{tel} -\end{program} + +\begin{example}[The integrator node] +\input{integrator.lus} +\end{example} One can try to connect two such integrators in loop to compute the functions $\sin(\omega t)$ and $\cos(\omega t)$ in a simple-minded way: -\begin{program} -\kw{node} sincos(omega:\kw{real}) \kw{returns} (sin, cos: \kw{real});\\ -\kw{let}\\ -\>sin = omega * integrator(cos,0.1,0.0);\\ -\>cos = omega * integrator(-sin,0.1,1.0);\\ -\kw{tel} -\end{program} + Called on this program, the compiler would complain that there is a {\em deadlock}. As a matter of fact, the variables \prog{sin} and @@ -495,15 +456,11 @@ computation of the $n$th value of \prog{sin} needs the $n$th value of \prog{cos}, and conversely. We have to cut the dependence loop, introducing a ``\prog{pre}'' operator: -\begin{program} -\kw{node} sincos(omega:\kw{real}) \kw{returns} (sin, cos: \kw{real});\\ -\kw{let}\\ -\>sin = omega * integrator(cos,0.1,0.0);\\ -\>cos = omega * integrator(0.0 \fby\ -\kw{pre}(sin),0.1,1.0);\\ -\kw{tel} -\end{program} - -\subsubsection{Multiple Equation} \label{ituples}\index{multiple equation} +\begin{example}[The sincos node] +\input{sincos.lus} +\end{example} + +\subsection{Multiple Equation} \label{ituples}\index{multiple equation} The node \prog{sincos} above does not work very well, but it is interesting since it returns more than one output. To call such a node, @@ -526,65 +483,49 @@ corresponding list of expressions, of suitable types. It can be \end{itemize} For instance, the equation \begin{program} -(min, max) = \kw{if} a{\tt <}b \kw{then} (a,b) \kw{else} (b,a); +(min, max) = \kwdd{if} a{\tt <}b \kwdd{then} (a,b) \kwdd{else} (b,a); \end{program} directly defines \prog{min} and \prog{max} to be, respectively, the least and greatest value of \prog{a} and \prog{b}. -\subsubsection{Clocks} \label{clocks} +\subsection{Clocks} \label{clocks} Let us consider the following control device: it receives a signal ``\prog{set}'', and returns a Boolean ``\prog{level}'' that must be true during ``\prog{delay}'' cycles after each reception of ``\prog{set}''. The program is quite simple: -\begin{program} -\kw{node} STABLE (set: \kw{bool}; delay: \kw{int}) \kw{returns} (level: \kw{bool});\\ -\kw{var} count: \kw{int};\\ -\kw{let}\\ -\>level = (count{\tt >}0);\\ -\>count = - \>\>~\kw{if} set \kw{then} delay\\ -\>\>\>~\kw{else} \kw{if} \kw{false} \fby\ \kw{pre}(level) \kw{then} \kw{pre}(count)-1\\ -\>\>\>~\kw{else} 0;\\ -\kw{tel} -\end{program} +\begin{example}[The STABLE node] +\input{STABLE.lus} +\end{example} -Now, suppose we want the ``\prog{level}'' to be high during -``\prog{delay}'' seconds, instead of ``\prog{delay}'' cycles. The -``second'' will be provided as a Boolean input ``\prog{second}'', +Now, suppose we want the ``\prog{level}'' to be high during +``\prog{delay}'' seconds, instead of ``\prog{delay}'' cycles. The +``second'' will be provided as a Boolean input ``\prog{second}'', true whenever a second elapses. Of course, we can write a new program -which freezes the counter whenever the ``\prog{second}'' is not +which freezes the counter whenever the ``\prog{second}'' is not there: -\begin{program} -\kw{node} TIME\_STABLE1(set,second:\kw{bool}; delay:\kw{int}) \kw{returns} (level:\kw{bool});\\ -\kw{var} count: \kw{int};\\ -\kw{let}\\ -\>level = (count{\tt >}0);\\ -\>count = - \>\>~\kw{if} set \kw{then} delay\\ -\>\>\>~\kw{else} \kw{if} second \kw{then}\\ -\>\>\>\>\>\kw{if} \kw{false} \fby\ \kw{pre}(level) \kw{then} \kw{pre}(count)-1\\ -\>\>\>\>\>\kw{else} 0\\ -\>\>\>~\kw{else} (0 \fby\ \kw{pre}(count));\\ -\kw{tel} -\end{program} +\begin{example}[The TIME\_STABLE1 node] +\input{TIME_STABLE1.lus} +\end{example} + + -We can also reuse our node ``\prog{STABLE}'', calling it at a -suitable {\em clock}, by {\em filtering} its input parameters. It -consists of changing the execution cycle of the node, activating it -only at some cycles of the calling program. For the delay to be +We can also reuse our node ``\prog{STABLE}'', calling it at a +suitable {\em clock}, by {\em filtering} its input parameters. It +consists of changing the execution cycle of the node, activating it +only at some cycles of the calling program. For the delay to be counted in seconds, the node ``\prog{STABLE}'' must be activated only -when either a ``\prog{set}'' signal or a ``\prog{second}'' signal -occurs. Moreover, it must be activated at the initial instant, for +when either a ``\prog{set}'' signal or a ``\prog{second}'' signal +occurs. Moreover, it must be activated at the initial instant, for initialization purposes. So the activation clock is \begin{program} -ck = \kw{true} \fby\ set \kw{or} second; +ck = \kwdd{true} \fby\ set \kwdd{or} second; \end{program} -Now a call ``\prog{STABLE((set,delay) \kw{when} ck)}'' +Now a call ``\prog{STABLE((set,delay) \kwdd{when} ck)}'' will feed an instance of ``\prog{STABLE}'' with rarefied inputs, as shown by the following table: \begin{center} @@ -614,14 +555,10 @@ delivered at this rarefied rate. In order to use the result, we have first to {\em project} it onto the clock of the calling program. The resulting node is -\begin{program} -\kw{node} TIME\_STABLE(set, second: \kw{bool}; delay: \kw{int}) \kw{returns} (level: \kw{bool});\\ -\kw{var} ck: \kw{bool};\\ -\kw{let}\\ -\>level = \kw{current}(STABLE((set,delay) \kw{when} ck));\\ -\>ck = \kw{true} \fby\ set \kw{or} second;\\ -\kw{tel} -\end{program} +\begin{example}[The TIME\_STABLE node] +\input{TIME_STABLE.lus} +\end{example} + Here is a simulation of this node: \newcommand{\bbb}[1]{\parbox{3.5cm}{ \vspace{-2mm}\begin{flushright} #1 @@ -658,7 +595,7 @@ tt \\ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\cleardoublepage +\chapter{Lustre Core} \section{Notations} \label{notation} @@ -678,6 +615,8 @@ that}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Lexical aspects} +\todo + \sxDef{Ident} \sxDef{string} \sxDef{Value} @@ -693,7 +632,7 @@ that}. or a list of such things: } -\erwan{ca fait du bruit dans la grammaire tout de même, non ???} +%\erwan{ca fait du bruit dans la grammaire tout de même, non ???} \newcommand{\syntaxPragma}{ \begin{grammarrule} @@ -704,7 +643,7 @@ or a list of such things: } } \syntaxPragma -Pragma can be useful for «retour au source» for example. +% Pragma can be useful for «retour au source» for example. \begin{example}[Pragmas] @@ -716,12 +655,10 @@ Pragma can be useful for %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Identifiers} -\conc{ -Entities are generally referred to through identifiers, but they can also -depend on a package instance (like in {\tt BIN8::binary}). -So we distinguish between the class \sx{Ident} -(returned by the scanner), and the class \sx{Identifier}: -} +\conc{ Entities are generally referred to through identifiers, but +they can also depend on a package instance (like in {\tt +BIN8::binary}). So we distinguish between \sx{Ident}, and +\sx{Identifier}: } \newcommand{\syntaxIdent}{ \begin{grammarrule} @@ -754,7 +691,7 @@ So we distinguish between the class \sx{Ident} \sxDef{Type} \is \sx{Ident} \sor \sx{Record\_Type} \sor \sx{Array\_Type} \sor \sx{Enum\_Type} \\ -\sxDef{Record\_Type} \is \lx{$\{$} \sx{Field\_List} \lx{$\}$} +\sxDef{Record\_Type} \is \lx{struct} \lx{$\{$} \sx{Field\_List} \lx{$\}$} \\ \sxDef{Field\_List} \is \sx{Field} \sor \sx{Field} \lx{,} \sx{Field\_List} \\ @@ -770,9 +707,7 @@ So we distinguish between the class \sx{Ident} \syntaxTypebis \begin{example}[Type Declarations] -\begin{alltt} -\end{alltt} - +\input{type_decl.lus} \end{example} @@ -875,10 +810,10 @@ set of equations defining the outputs. \sxDef{SelTrancheEnd} \is \lx{..} \sx{Expression}\\ -\sxDef{Right\_Part} \is \sx{Expression} \sor \sx{Condact}\\ -\sxDef{Condact} \is \sx{OneCase}$^*$ - \lx{default} \sx{Expression} \lx{;}\\ -\sxDef{OneCase} \is \lx{case} \sx{Expression} \lx{do} \sx{Expression} \lx{;}\\ +%% \sxDef{Right\_Part} \is \sx{Expression} \sor \sx{Condact}\\ +%% \sxDef{Condact} \is \sx{OneCase}$^*$ +%% \lx{default} \sx{Expression} \lx{;}\\ +%% \sxDef{OneCase} \is \lx{case} \sx{Expression} \lx{do} \sx{Expression} \lx{;}\\ \sxDef{Assertion} \is \lx{assert} \sx{Expression} \prag\ \lx{;}\\ @@ -887,7 +822,7 @@ set of equations defining the outputs. } \syntaxEquations -\erwan{On n'a pas dir qu'on virait les condact pour l'instant ???} +% \erwan{On n'a pas dir qu'on virait les condact pour l'instant ???} \begin{example}[Equations] @@ -950,8 +885,8 @@ sense that they are operating pointwise on streams. \lx{else} \sx{Expression} \myor \sx{Call} \myor \sx{Expression} \sx{Selector} - \myor \lx{TO} {\tt $<<$} \sx{Type} {\tt $>>$} \lx{(}\sx{Expression\_List} \lx{)} - \myor \lx{FROM} {\tt $<<$} \sx{Type} {\tt $>>$} \lx{(}\sx{Expression} \lx{)} +%% \myor \lx{TO} {\tt $<<$} \sx{Type} {\tt $>>$} \lx{(}\sx{Expression\_List} \lx{)} +%% \myor \lx{FROM} {\tt $<<$} \sx{Type} {\tt $>>$} \lx{(}\sx{Expression} \lx{)} \\ \sxDef{Expression\_List} \is \sx{Expression} \sor @@ -987,7 +922,6 @@ sense that they are operating pointwise on streams. \end{example} -\erwan{Y'a pas les types enum ???} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -996,9 +930,9 @@ sense that they are operating pointwise on streams. An operator is a predefined Lustre node. Most of them are infix. -\xxx dire lesquels sont infixes ! +\xxx say which one -\xxx parler du package Lustre +%\xxx parler du package Lustre \newcommand{\syntaxBinop}{ @@ -1132,7 +1066,7 @@ In Section~\ref{exemples} we provide a complete and commented program example. \label{data-types} -%%% ??? subsection ou paragraph ??? +%%% ??? section ou paragraph ??? % \subsection{Enumerated types} % \subsection{Structures types} @@ -1148,11 +1082,7 @@ for their declaration and used is provided in Section~\ref{syntax}. \begin{example}[Enumerations] -\begin{alltt} - \kwd{type} - color1 = \kwd{enum} ( blue, white, black ); - color2 = \kwd{enum} ( green, orange, yellow ); -\end{alltt} +\input{enum0.lus} \end{example} \paragraph{Records.} @@ -1163,8 +1093,6 @@ functions, and a constructor function. \todo -\erwan{ dans l'implémentation, il faut ecrire ``enum'', et pas ``struct''. C'est -bizzare non ?} \begin{example}[Records] \begin{alltt} @@ -1216,13 +1144,7 @@ bizzare non ?} } \syntaxType - -\todo ca ce sont les definitions pour les declarations de types, mais il -manque la syntaxe pour la definition des elements de ces types. -... ah si, elles sont définies dans la section Expressions -(record\_exp, fiedl\_exp, etc.). A mettre ici plutot ? - - XXX introduire les tranches. +\todo slices %\cleardoublepage @@ -1247,11 +1169,11 @@ manque la syntaxe pour la definition des elements de ces types. %%% \subsection{Iterators} One the main novelty of Lustre-V6 is to provide a (restricted) notion -of higher-order programming by defining \emph{array iterators}. Five -iterators are predefined, and the user can not define new ones. -Iterators extend nodes operating on scalars to nodes operating on -arrays. +of higher-order programming by defining \emph{array iterators} to +operate over arrays. Iterators replace the use of Lustre V4 +homomorphic extension: +\cite{papier_tableau} @@ -1261,7 +1183,7 @@ arrays. % \label{node-exp} \paragraph{Using node expressions.} -In LustreV6, a node denotation is not necessarily a simple identifier, +In Lustre V6, a node denotation is not necessarily a simple identifier, since a node can be ``built'' by instantiating an iterator with static arguments. A node expression is then defined by: @@ -1492,11 +1414,12 @@ $\forall i = 0 \cdots \mbox{\tt n}-1$, \end{defi} \noindent -\erwan{en fait, une fois que fillred est definit, qu'elle -est l'interet de fill et de red ???? -D'ailleurs, dans lus2lis et dans lic2loc, j'appelle la même fonction -dans les 3 cas ...} +%% \erwan{en fait, une fois que fillred est definit, qu'elle +%% est l'interet de fill et de red ???? + +%% D'ailleurs, dans lus2lis et dans lic2loc, j'appelle la même fonction +%% dans les 3 cas ...} \begin{example}[\fillredop] @@ -1594,7 +1517,7 @@ diese and the nor operators : \begin{example}[boolred] \begin{program} -#(a1, ..., an) \evalto boolred(1,1,n)[a1, ..., an] +#(a1, ..., an) \evalto boolred(1,1,n)[a1, ..., an] \\ nor(a1, ..., an) \evalto boolred(0,0,n)[a1, ..., an] \end{program} @@ -1621,7 +1544,10 @@ profile in the functional programming world : ... -> (a$_{n-1}$' array) -> (a$_n$' array)} Note that it even note possible to give a milner-style type to -describe this iterator. +describe this iterator. Indeed, the type of the node depends on the +size of the array; it would therefore require a dependant-type system. + + \clearpage @@ -1629,6 +1555,28 @@ describe this iterator. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Parametric nodes} + + +node can be parametrised by constants, types, and nodes. + +\begin{example}[Parametric Node] +\input{param_node2.lus} +\end{example} + +\begin{example}[Parametric Node] +\input{param_node.lus} +\end{example} + + +nodes can even be defined recursively using the ``with'' construct + +\begin{example}[Recursive Node] +\input{consensus2.lus} +\end{example} + + + \section{Packages and models} \label{pack-model} @@ -1858,20 +1806,20 @@ a package is a set of definitions of entities: types, constants and operators -a model can have as parameters a type, a constant, or an operator. +a model can have as parameters a type, a constant, or a node. -\erwan{ Dans le document ``package, modeles, généricité'' -(cf -{\tt /home/jahier/lustre-v6/doc/DOCYOUSSEF/pascal\_\_packages\_modeles\_et\_genericite.ps)}, -un certain nombre de points restent ouverts. Quand tranche t'on ? +%% \erwan{ Dans le document ``package, modeles, généricité'' +%% (cf +%% {\tt /home/jahier/lustre-v6/doc/DOCYOUSSEF/pascal\_\_packages\_modeles\_et\_genericite.ps)}, +%% un certain nombre de points restent ouverts. Quand tranche t'on ? -Est-ce ce que ce qu'a implémenté Yussef est satisfaisant ? -Qu'a t'il fait de ce qui était proposé la d'ailleurs ? -} +%% Est-ce ce que ce qu'a implémenté Yussef est satisfaisant ? +%% Qu'a t'il fait de ce qui était proposé la d'ailleurs ? +%% } -\todo +%\todo \cleardoublepage @@ -1880,7 +1828,11 @@ Qu'a t'il fait de ce qui %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{The Merge operator} -\label{condact} +\label{merge} + +\begin{example}[The Merge operator] +\input{merge.lus} +\end{example} \cleardoublepage @@ -1889,24 +1841,25 @@ Qu'a t'il fait de ce qui \label{exemples} -\todo a complete Lustre V6 commented exemple.... +\todo add a complete Lustre V6 commented exemple.... + -\erwan{ lequel ???} -il faudrait qu'il utilise +%% il faudrait qu'il utilise -- des packages +%% - des packages -- des modeles +%% - des modeles -- des types enum et record +%% - des types enum et record -- des tableaux + iterateurs +%% - des tableaux + iterateurs -Au besoin, on donne 2 programmes. +%% Au besoin, on donne 2 programmes. + +%% Ou alors on se contente d'un tutorial ? -Ou alors on se contente d'un tutorial ? \cleardoublepage @@ -1945,6 +1898,11 @@ Ou alors on se contente d'un tutorial ? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Lustre History} + +Lustre V1, v2, v3, ..., v6 + + \section{The Lustre V4 features not supported in Lustre V6} @@ -1958,4 +1916,12 @@ Ou alors on se contente d'un tutorial ? [int, int] -> use int^2 instead \end{alltt} +\begin{figure} +\begin{center} +\input{patate} +\caption{Lustre potatoes} +\label{potatoes} +\end{center} +\end{figure} + \end{document} diff --git a/src/TODO b/src/TODO index 5d8fae5183b08086f1cf8b8e361edf0fa169768c..2f80c97b812815c303d994d0caf9d4c3f0d64bcc 100644 --- a/src/TODO +++ b/src/TODO @@ -143,6 +143,7 @@ n'est pas le cas pour l'instant... cf [solve_ident] * Ne pas générer de "current", "->", "pre" (i.e., les traduire en termes de "merge" et "fby"). +* rajouter "mirror"? * l'unesting des iterateurs devrait etre fait dans split, et pas dans LicDump. D'abord par soucis d'élégance. Mais aussi parce que sinon, @@ -153,6 +154,7 @@ split_acc pour y rajouter une liste de definitions de noeud, qui contiendrait des definitions d'alias. ces noueds peuvent etre contruit en mimiquant LicDump.dump_node_alias. + *** facile ---------- diff --git a/src/global.ml b/src/global.ml index 6b067ab1e6a7d5990cddb7c2b40956edd7c18079..bce60cfeb96a7821f4ad7b7bad032a64bedc8f55 100644 --- a/src/global.ml +++ b/src/global.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 26/11/2008 (at 11:00) by Erwan Jahier> *) +(** Time-stamp: <modified the 05/12/2008 (at 10:41) by Erwan Jahier> *) (** Some global variables. @@ -19,6 +19,7 @@ let one_op_per_equation = ref true let inline_iterator = ref false let lv4 = ref false let expand_enums = ref false +let expand_structs = ref false (* the output channel *) let oc = ref Pervasives.stdout diff --git a/src/main.ml b/src/main.ml index f96606ce7e1939821e1c3f6193504156b1f7971c..4000c06b2bf5434e04fbb6c4697efe6250823355 100644 --- a/src/main.ml +++ b/src/main.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 27/11/2008 (at 10:15) by Erwan Jahier> *) +(** Time-stamp: <modified the 05/12/2008 (at 10:41) by Erwan Jahier> *) (** Here follows a description of the different modules used by this lus2lic compiler. @@ -109,13 +109,17 @@ let rec arg_list = [ (fun _ -> Global.expand_enums := true), "\tTranslate enums into integers" ); +(* ( "--expand-structs", Arg.Unit *) +(* (fun _ -> Global.expand_enums := true), *) +(* "\tReplace structures by as many variables as necessary" *) +(* ); *) ( "--lustre-v4", Arg.Unit - (fun _ -> Global.lv4 := true;Global.inline_iterator := true;Global.expand_enums := true), + (fun _ -> set_v4_options ()), "\tGenerate Lustre V4 compatible Lustre (if possible)" ); ( "-lv4", Arg.Unit - (fun _ -> Global.lv4 := true;Global.inline_iterator := true;Global.expand_enums := true), + (fun _ -> set_v4_options ()), "\tGenerate Lustre V4 compatible Lustre (if possible)" ); @@ -124,6 +128,11 @@ let rec arg_list = [ ("--help", Arg.Unit (fun _ -> (Arg.usage arg_list usage_msg; exit 0)), "\tDisplay this list of options" ) ] +and set_v4_options () = + Global.lv4 := true; + Global.inline_iterator := true; + Global.expand_enums := true; + Global.expand_structs := true and parse_args () = ( Arg.parse arg_list (* liste des options *) diff --git a/src/structExpand.ml b/src/structExpand.ml new file mode 100644 index 0000000000000000000000000000000000000000..8f7e14b79085a13e1e8ef859eda7915cd89ea28b --- /dev/null +++ b/src/structExpand.ml @@ -0,0 +1,27 @@ +(** Time-stamp: <modified the 05/12/2008 (at 15:38) by Erwan Jahier> *) + +(* Replace structures by as many variables as necessary *) + + + + + + +let (node : Eff.local_env -> Eff.id_solver -> Eff.node_exp -> Eff.node_exp) = + fun node_env id_solver n -> + | ExternEff + | AbstractEff -> n + | BodyEff b -> + let loc = match n.loclist_eff with None -> [] | Some l -> l in + let (neqs, nv) = + List.fold_left (inline_eq node_env id_solver) ([], loc) b.eqs_eff + in + let nb = { b with eqs_eff = List.rev neqs } in + let res = + { n with + loclist_eff = Some nv; + def_eff = BodyEff nb + } + in + res + diff --git a/src/structExpand.mli b/src/structExpand.mli new file mode 100644 index 0000000000000000000000000000000000000000..b565e1b60e3f73ebdcee31ff6799c61aad8d088a --- /dev/null +++ b/src/structExpand.mli @@ -0,0 +1,4 @@ +(** Time-stamp: <modified the 05/12/2008 (at 15:38) by Erwan Jahier> *) + + +val node : Eff.local_env -> Eff.id_solver -> Eff.node_exp -> Eff.node_exp diff --git a/src/test/should_work/NONREG/COUNTER.lus b/src/test/should_work/NONREG/COUNTER.lus new file mode 100644 index 0000000000000000000000000000000000000000..bb146c70add8a4857b13202705200d0ec309fe84 --- /dev/null +++ b/src/test/should_work/NONREG/COUNTER.lus @@ -0,0 +1,9 @@ +node COUNTER (init, incr: int; X, reset: bool) returns (N: int); +var PN: int; +let + PN = init -> pre N; + N = + if reset then init + else if X then PN + incr + else PN; +tel diff --git a/src/test/should_work/NONREG/EDGE.lus b/src/test/should_work/NONREG/EDGE.lus new file mode 100644 index 0000000000000000000000000000000000000000..43f90615abfad8f54aa29592371ed845cf41cea7 --- /dev/null +++ b/src/test/should_work/NONREG/EDGE.lus @@ -0,0 +1,4 @@ +node EDGE (X: bool) returns (Y: bool); +let + Y = false -> X and not pre(X); +tel diff --git a/src/test/should_work/NONREG/SWITCH.lus b/src/test/should_work/NONREG/SWITCH.lus new file mode 100644 index 0000000000000000000000000000000000000000..d8f0183599f63f92a589dabcbf7f390a9010bdb5 --- /dev/null +++ b/src/test/should_work/NONREG/SWITCH.lus @@ -0,0 +1,7 @@ +node SWITCH (set, reset, initial: bool) returns (level: bool); +let + level = initial -> + if set and not pre(level) then true + else if reset then false + else pre(level); +tel diff --git a/src/test/should_work/NONREG/SWITCH1.lus b/src/test/should_work/NONREG/SWITCH1.lus new file mode 100644 index 0000000000000000000000000000000000000000..ba1b2e4a770ccfa3a446fa8dee4773be269c038a --- /dev/null +++ b/src/test/should_work/NONREG/SWITCH1.lus @@ -0,0 +1,7 @@ +node SWITCH1 (set, reset, initial: bool) returns (level: bool); +let + level = initial -> + if set then true + else if reset then false + else pre(level); +tel diff --git a/src/test/should_work/NONREG/TIME_STABLE.lus b/src/test/should_work/NONREG/TIME_STABLE.lus new file mode 100644 index 0000000000000000000000000000000000000000..86512231510cf6c37bf81c76ec971b13b7325e37 --- /dev/null +++ b/src/test/should_work/NONREG/TIME_STABLE.lus @@ -0,0 +1,7 @@ +node TIME_STABLE(set, second: bool; delay: int) returns (level: bool); +var ck: bool; +let + level = current(STABLE((set,delay) when ck)); + ck = true -> set or second; +tel +node STABLE (set: bool; delay: int) returns (level: bool);var count: int; let level = (count > 0); count = if set then delay else if false -> pre(level) then pre(count)-1 else 0;tel -- del \ No newline at end of file diff --git a/src/test/should_work/NONREG/TIME_STABLE1.lus b/src/test/should_work/NONREG/TIME_STABLE1.lus new file mode 100644 index 0000000000000000000000000000000000000000..5f5a57e49cc6d22373002e7df8a9efc2b517edb0 --- /dev/null +++ b/src/test/should_work/NONREG/TIME_STABLE1.lus @@ -0,0 +1,12 @@ +node TIME1_STABLE1(set,second:bool; delay:int) returns (level:bool); +var count: int; +let + level = (count > 0); + count = + if set then delay + else if second then + if false -> pre(level) then pre(count)-1 + else 0 + else (0 -> pre(count)); +tel + diff --git a/src/test/should_work/NONREG/count.lus b/src/test/should_work/NONREG/count.lus new file mode 100644 index 0000000000000000000000000000000000000000..8c6e85237a0ea5559e8c443246ec556a3a49ec72 --- /dev/null +++ b/src/test/should_work/NONREG/count.lus @@ -0,0 +1,4 @@ +node count (x,y: int) returns (s: int); +let + s = 2*(x+y); +tel diff --git a/src/test/should_work/NONREG/enum0.lus b/src/test/should_work/NONREG/enum0.lus new file mode 100644 index 0000000000000000000000000000000000000000..334dfe7dd6622aaeaa7259de02b004c310d77fcc --- /dev/null +++ b/src/test/should_work/NONREG/enum0.lus @@ -0,0 +1,3 @@ +type color1 = enum { blue, white, black }; +type color2 = enum { green, orange, yellow }; + diff --git a/src/test/should_work/NONREG/sincos.lus b/src/test/should_work/NONREG/sincos.lus new file mode 100644 index 0000000000000000000000000000000000000000..f74531623e85f1cad9a9f6b92ba144497ba3b746 --- /dev/null +++ b/src/test/should_work/NONREG/sincos.lus @@ -0,0 +1,6 @@ +node sincos(omega:real) returns (sin, cos: real); +let + sin = omega * integrator(cos,0.1,0.0); + cos = omega * integrator(-sin,0.1,1.0); +tel +node integrator(F,STEP,init: real) returns (Y: real); let Y = init -> pre(Y) + ((F + pre(F))*STEP)/2.0; tel -- del diff --git a/src/test/should_work/NONREG/type_decl.lus b/src/test/should_work/NONREG/type_decl.lus new file mode 100644 index 0000000000000000000000000000000000000000..1a78f1277d672914ab4f074b875cdac7c23dd8dc --- /dev/null +++ b/src/test/should_work/NONREG/type_decl.lus @@ -0,0 +1,3 @@ +type alias = int; +type pair = struct { a:int; b:int }; +type color = enum { blue, white, black }; diff --git a/src/test/test.res.exp b/src/test/test.res.exp index d137a48323b58a2ebf3aa39d32a95aaccb82a795..01bc2ddd4c2f88b5940105d61327deeb9d4f77c0 100644 --- a/src/test/test.res.exp +++ b/src/test/test.res.exp @@ -62,6 +62,32 @@ type A_A_A_int_1_2_3 = A_A_int_1_2^3; type A_A_int_1_2 = A_int_1^2; type A_int_1 = int^1; +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/COUNTER.lus +Opening file should_work/NONREG/COUNTER.lus + +node COUNTER::COUNTER( + init:int; + incr:int; + X:bool; + reset:bool) +returns ( + N:int); +var + PN:int; + _v1:int; + _v2:int; + _v3:int; +let + PN = init -> _v1; + _v1 = pre N; + N = if reset then init else _v3; + _v2 = PN + incr; + _v3 = if X then _v2 else PN; +tel +-- end of node COUNTER::COUNTER + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/CURRENT.lus Opening file should_work/NONREG/CURRENT.lus @@ -72,6 +98,48 @@ tel -- end of node CURRENT::CURRENT +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/EDGE.lus +Opening file should_work/NONREG/EDGE.lus +node EDGE::EDGE(X:bool) returns (Y:bool); +var + _v1:bool; + _v2:bool; + _v3:bool; +let + Y = false -> _v3; + _v1 = pre X; + _v2 = not _v1; + _v3 = X and _v2; +tel +-- end of node EDGE::EDGE + + +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/FALLING_EDGE.lus +Opening file should_work/NONREG/FALLING_EDGE.lus +node FALLING_EDGE::EDGE(X:bool) returns (Y:bool); +var + _v1:bool; + _v2:bool; + _v3:bool; +let + Y = false -> _v3; + _v1 = pre X; + _v2 = not _v1; + _v3 = X and _v2; +tel +-- end of node FALLING_EDGE::EDGE +node FALLING_EDGE::FALLING_EDGE(X:bool) returns (Y:bool); +var + _v1:bool; +let + Y = FALLING_EDGE::EDGE(_v1); + _v1 = not X; +tel +-- end of node FALLING_EDGE::FALLING_EDGE + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/Int.lus Opening file should_work/NONREG/Int.lus @@ -649,6 +717,161 @@ tel -- end of node SOURIS::SOURIS +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/STABLE.lus +Opening file should_work/NONREG/STABLE.lus +node STABLE::STABLE(set:bool; delay:int) returns (level:bool); +var + count:int; + _v1:bool; + _v2:bool; + _v3:int; + _v4:int; + _v5:int; +let + level = count > 0; + count = if set then delay else _v5; + _v1 = pre level; + _v2 = false -> _v1; + _v3 = pre count; + _v4 = _v3 - 1; + _v5 = if _v2 then _v4 else 0; +tel +-- end of node STABLE::STABLE + + +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/SWITCH.lus +Opening file should_work/NONREG/SWITCH.lus + +node SWITCH::SWITCH( + set:bool; + reset:bool; + initial:bool) +returns ( + level:bool); +var + _v1:bool; + _v2:bool; + _v3:bool; + _v4:bool; + _v5:bool; + _v6:bool; +let + level = initial -> _v6; + _v1 = pre level; + _v2 = not _v1; + _v3 = set and _v2; + _v4 = pre level; + _v5 = if reset then false else _v4; + _v6 = if _v3 then true else _v5; +tel +-- end of node SWITCH::SWITCH + + +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/SWITCH1.lus +Opening file should_work/NONREG/SWITCH1.lus + +node SWITCH1::SWITCH1( + set:bool; + reset:bool; + initial:bool) +returns ( + level:bool); +var + _v1:bool; + _v2:bool; + _v3:bool; +let + level = initial -> _v3; + _v1 = pre level; + _v2 = if reset then false else _v1; + _v3 = if set then true else _v2; +tel +-- end of node SWITCH1::SWITCH1 + + +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/TIME_STABLE.lus +Opening file should_work/NONREG/TIME_STABLE.lus +node TIME_STABLE::STABLE(set:bool; delay:int) returns (level:bool); +var + count:int; + _v1:bool; + _v2:bool; + _v3:int; + _v4:int; + _v5:int; +let + level = count > 0; + count = if set then delay else _v5; + _v1 = pre level; + _v2 = false -> _v1; + _v3 = pre count; + _v4 = _v3 - 1; + _v5 = if _v2 then _v4 else 0; +tel +-- end of node TIME_STABLE::STABLE + +node TIME_STABLE::TIME_STABLE( + set:bool; + second:bool; + delay:int) +returns ( + level:bool); +var + ck:bool; + _v1:bool when ck; + _v2:int when ck; + _v3:bool when ck; + _v4:bool; +let + level = current _v3; + _v1 = set when ck; + _v2 = delay when ck; + _v3 = TIME_STABLE::STABLE(_v1, _v2); + ck = true -> _v4; + _v4 = set or second; +tel +-- end of node TIME_STABLE::TIME_STABLE + + +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/TIME_STABLE1.lus +Opening file should_work/NONREG/TIME_STABLE1.lus + +node TIME_STABLE1::TIME1_STABLE1( + set:bool; + second:bool; + delay:int) +returns ( + level:bool); +var + count:int; + _v1:bool; + _v2:bool; + _v3:int; + _v4:int; + _v5:int; + _v6:int; + _v7:int; + _v8:int; +let + level = count > 0; + count = if set then delay else _v8; + _v1 = pre level; + _v2 = false -> _v1; + _v3 = pre count; + _v4 = _v3 - 1; + _v5 = if _v2 then _v4 else 0; + _v6 = pre count; + _v7 = 0 -> _v6; + _v8 = if second then _v5 else _v7; +tel +-- end of node TIME_STABLE1::TIME1_STABLE1 + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/Watch.lus Opening file should_work/NONREG/Watch.lus @@ -2460,6 +2683,19 @@ tel -- end of node compteur::compteur +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/count.lus +Opening file should_work/NONREG/count.lus +node count::count(x:int; y:int) returns (s:int); +var + _v1:int; +let + s = 2 * _v1; + _v1 = x + y; +tel +-- end of node count::count + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/cpt.lus Opening file should_work/NONREG/cpt.lus @@ -2774,6 +3010,13 @@ tel -- end of node enum::boo +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/enum0.lus +Opening file should_work/NONREG/enum0.lus +type _enum0::color1 = enum {enum0::blue, enum0::white, enum0::black}; +type _enum0::color2 = enum {enum0::green, enum0::orange, enum0::yellow}; + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/eq1.lus Opening file should_work/NONREG/eq1.lus @@ -3051,6 +3294,35 @@ tel -- end of node initial::initial +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/integrator.lus +Opening file should_work/NONREG/integrator.lus + +node integrator::integrator( + F:real; + STEP:real; + init:real) +returns ( + Y:real); +var + _v1:real; + _v2:real; + _v3:real; + _v4:real; + _v5:real; + _v6:real; +let + Y = init -> _v6; + _v1 = pre Y; + _v2 = pre F; + _v3 = F + _v2; + _v4 = _v3 * STEP; + _v5 = _v4 / 2.0; + _v6 = _v1 + _v5; +tel +-- end of node integrator::integrator + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/long_et_stupide_nom_de_noeud.lus Opening file should_work/NONREG/long_et_stupide_nom_de_noeud.lus @@ -7459,6 +7731,42 @@ extern function simple::f1(x:int) returns (y:int); extern function simple::f2(u:int; v:int) returns (s:int; t:bool); +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/sincos.lus +Opening file should_work/NONREG/sincos.lus +node sincos::integrator(F:real; STEP:real; init:real) returns (Y:real); +var + _v1:real; + _v2:real; + _v3:real; + _v4:real; + _v5:real; + _v6:real; +let + Y = init -> _v6; + _v1 = pre Y; + _v2 = pre F; + _v3 = F + _v2; + _v4 = _v3 * STEP; + _v5 = _v4 / 2.0; + _v6 = _v1 + _v5; +tel +-- end of node sincos::integrator +node sincos::sincos(omega:real) returns (sin:real; cos:real); +var + _v1:real; + _v2:real; + _v3:real; +let + sin = omega * _v1; + _v1 = sincos::integrator(cos, 0.1, 0.0); + cos = omega * _v3; + _v2 = -sin; + _v3 = sincos::integrator(_v2, 0.1, 1.0); +tel +-- end of node sincos::sincos + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/stopwatch.lus Opening file should_work/NONREG/stopwatch.lus @@ -7650,6 +7958,14 @@ tel -- end of node tuple::toto +---------------------------------------------------------------------- +====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/type_decl.lus +Opening file should_work/NONREG/type_decl.lus +type _type_decl::alias = int; +type _type_decl::pair = struct {a : int; b : int}; +type _type_decl::color = enum {type_decl::blue, type_decl::white, type_decl::black}; + + ---------------------------------------------------------------------- ====> ../lus2lic -vl 2 --compile-all-items should_work/NONREG/uu.lus Opening file should_work/NONREG/uu.lus