In order to check, if a program is well-formed, a static environment
which maps identifiers totypes has tobe introduced.
\begin{vdm_al} module STATSEM
importsfrom AST all
exportsall
definitions
types
StatEnv = map AST`Identifier to AST`Type;
\end{vdm_al}
Using the static environment, a top-down definition of well-formed
program constructs can be given. In the following definitions the prefix
{\tt wf-} stands for {\it well-formed}.
\begin{vdm_al} functions
wf_Program : AST`Program -> bool
wf_Program(mk_AST`Program(decls, stmt)) ==
wf_Declarations(decls) and wf_Stmt(stmt, get_Declarations(decls));
\end{vdm_al}
The incomplete informal description of the declarations raises
several questions, which force to make design decisions.
A declaration with an initial value contains two type informations,
one in the type and one in the value. The two types must be the
same. An open question is, what happens with uninitialized variables when they are evaluated inside an expression without
having a value associated. This problem concerns both the staticand dynamic semantics. If the value isnot checked in
the static semantics, the dynamic semantics has to take over this
task. The following solutions are possible:
\begin{enumerate}
\item {\it Required initial values}. \\ All declarations must be declared with initial values. This is
the simplest solution. The static semantics checks the
consistency of both types. In the dynamic semantics neither types nor uninitiated values have tobe considered.
\item {\it Default initialization}. \\ In this solution the static semantics checks the typesof initiated variables. In the dynamic semantics the appropriate default initial values have tobesetforvariables which are not initialized explicitly.
Hence the dynamic semantics has to take type information into account.
\item {\it Consideration of missing values}. \\
This is the most complicated solution. Again the static semantics
checks both typesin the declarations. However, the dynamic semantics
has to consider possible uninitiated variablesin every construct
containing expressions. It would be possible to extend the logic to
a three valued logic containing the value {\tt undefined}, e.g. the expression
{\tt true <AND> undefined} could thenbe evaluated to {\tt true}.
\item {\it Generating runtime errors}. \\
The dynamic semantics generates runtime errors, if uninitiated variables are used in expressions.
\end{enumerate} In this specification the second solution will be chosen, where allvariables without initiations are initiated with default values.
\begin{vdm_al}
wf_Declarations : seqof AST`Declaration -> bool
wf_Declarations(decls) ==
(forall i1, i2 insetinds decls &
i1 <> i2 => decls(i1).id <> decls(i2).id) and
(forall d inseq decls &
d.val <> nil =>
((is_AST`BoolVal(d.val) and d.tp = <BoolType>) or
(is_AST`IntVal(d.val) and d.tp = <IntType>)));
get_Declarations : seqof AST`Declaration -> StatEnv
get_Declarations(decls) ==
{id |-> tp | mk_AST`Declaration(id, tp, -) inseq decls};
\end{vdm_al}
The specification of the static semantics of statements is made by
a simple case distinction.
The typesof the left-hand and right-hand side of an assignment
must be the same. In addition the type of the assignment which is needed in
the context of the for-loop is returned.
\begin{vdm_al}
wf_AssignStmt : AST`AssignStmt * StatEnv -> bool * [AST`Type]
wf_AssignStmt(mk_AST`AssignStmt(lhs, rhs), senv) == let mk_(wf_var, tp_var) = wf_Variable(lhs, senv),
mk_(wf_ex, tp_ex) = wf_Expr(rhs, senv) in mk_(wf_ex and wf_var and tp_var = tp_ex, tp_var);
\end{vdm_al} In the conditional statement and the repeat-loop a boolean expression is required:
\begin{vdm_al}
wf_CondStmt : AST`CondStmt * StatEnv -> bool
wf_CondStmt(mk_AST`CondStmt(guard, thenst, elsest), senv) == let mk_(wf_ex, tp_ex) = wf_Expr(guard, senv) in wf_ex and tp_ex = <BoolType> and
wf_Stmt(thenst, senv) and wf_Stmt(elsest, senv);
wf_RepeatStmt : AST`RepeatStmt * StatEnv -> bool
wf_RepeatStmt(mk_AST`RepeatStmt(repeat, until), senv) == let mk_(wf_ex, tp_ex) = wf_Expr(until, senv) in wf_ex and tp_ex = <BoolType> and wf_Stmt(repeat, senv);
\end{vdm_al}
The for-loop is underspecified and raises the question, which
kind of loop is really intended. It isnot clear if the stop expression
should beof type Integer orBool, which leads to two different loop
concepts. For a detailed discussion on the possibilities to interpret the
semantics of the for-loop see Section \ref{dynamic}. For the static semantics
the most obvious design decision has been made that the stop-expression
should beof type Integer.
\begin{vdm_al}
wf_ForStmt : AST`ForStmt * StatEnv -> bool
wf_ForStmt(mk_AST`ForStmt(start, stop, stmt), senv) == let mk_(wf_ass, tp_ass) = wf_AssignStmt(start, senv),
mk_(wf_ex, tp_ex) = wf_Expr(stop, senv) in wf_ass and wf_ex and tp_ass = <IntType> and tp_ex = <IntType> and
wf_Stmt(stmt, senv);
\end{vdm_al}
Handling expressions andvariables, it is necessary toreturn the
type in addition to the well-formedness predicate.
\begin{vdm_al}
wf_Expr : AST`Expr * StatEnv -> bool * [AST`Type]
wf_Expr(ex, senv) == casestrue :
(is_AST`BoolVal(ex)) -> mk_(true, <BoolType>),
(is_AST`IntVal(ex)) -> mk_(true, <IntType>),
(is_AST`Variable(ex)) -> wf_Variable(ex, senv),
(is_AST`BinaryExpr(ex)) -> wf_BinaryExpr(ex, senv), others -> mk_(false, <IntType>) end;
wf_Variable : AST`Variable * StatEnv -> bool * [AST`Type]
wf_Variable(mk_AST`Variable(id), senv) == if id insetdom senv then mk_(true, senv(id)) else mk_(false, nil);
\end{vdm_al}
It isnot explicitly stated if the equality operator should also be
defined for Boolean values. For simplicity the decision is made to
define equality only for Integers.
\begin{vdm_al}
wf_BinaryExpr : AST`BinaryExpr * StatEnv -> bool * [AST`Type]
wf_BinaryExpr(mk_AST`BinaryExpr(lhs, op, rhs), senv) == let mk_(wf_lhs, tp_lhs) = wf_Expr(lhs, senv),
mk_(wf_rhs, tp_rhs) = wf_Expr(rhs, senv) incases op :
<Add>, <Sub>, <Div>, <Mul> ->
mk_(wf_lhs and wf_rhs and
tp_lhs = <IntType> and tp_rhs = <IntType>,
<IntType>),
<Lt>, <Gt>, <Eq> ->
mk_(wf_lhs and wf_rhs and
tp_lhs = <IntType> and tp_rhs = <IntType>,
<BoolType>),
<And>, <Or> ->
mk_(wf_lhs and wf_rhs and
tp_lhs = <BoolType> and tp_rhs = <BoolType>,
<BoolType>), others -> mk_(false, nil) end;
end STATSEM
\end{vdm_al}
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.