{ Didier Parigot }
{ "" }
{-- The type-checking of sample language Simproc - - }
class Program {
case program (Block b);
bool simproc-check () {
bool correct;
switch (this) {
case program (b) :
this.correct = b.correct1 & b.correct2 ;
b.htemp-st = empty-table ;
b.symtab = b.stemp-st ;
}
return this.correct;
}
}
class Block {
case block(Decls ds, Stmts st);
simproc-check () {
bool correct1;
bool correct2;
symbol-table stemp-st;
symbol-table htemp-st;
symbol-table symtab;
switch (this) {
case block(ds, st):
this.correct1 = ds.correct1 ;
this.correct2 = ds.correct2 & st.correct2 ;
this.stemp-st = ds.stemp-st ;
ds.htemp-st = this.htemp-st ;
st.symtab = this.symtab ;
}
}
}
class Decls {
case decls (Decl a*); /* operateur de liste */
simproc-check () {
bool correct1;
bool correct2;
symbol-table stemp-st;
symbol-table htemp-st;
switch (this) {
{ declarations }
///// where decls -> DECL* use $correct1 := map left & value true
other $correct1 (DECL) end map ; $correct2 := map left & value true
other $correct2 (DECL) end map ; $h.temp-st (DECL) := { this definition
appears here only to provide an example of a case position construct ;
it could have been generated automatically using the default rules } case
position is first : $h.temp-st ; other : $s.temp-st (DECL.left) ; end case
; end where ;
///// } }
}
class Decl {
case int-decl (string ID);
case array-decl (string ID, int NUMBER);
case proc-decl (string ID1, string ID2 string ID3, Block BLOCK);
simproc-check () {
bool correct1;
bool correct2;
symbol-table stemp-st;
symbol-table htemp-st;
switch (this) {
case int-decl ( ID) :
{ bool correct; correct = (ID = error-token) ? false : lookup-in-block
(ID,this.htemp-st) ; this.correct1 = correct ; this.correct2 = true ; this.stemp-st
= (correct ? insert (ID, varid, this.htemp-st)) : this.htemp-st; }
case array-decl (ID, NUMBER) :
{
bool correct = (ID = error-token) ? false : lookup-in-block (ID,this.htemp-st)
and NUMBER.correct2 and (NUMBER = 0) ? false : true ;
this.correct1 = correct ;
this.correct2 = true ;
this.stemp-st = (correct ? insert (ID, arrayid, this.htemp-st)) : this.htemp-st;
}
case proc-decl (string ID1, string ID2 string ID3, Block BLOCK) :
{
bool correct = (ID1 = error-token) ? false : lookup-in-block (ID,this.htemp-st)
and (ID2 = error-token) ? false : lookup-in-block (ID,this.htemp-st)
and (ID3 = error-token) ? false : lookup-in-block (ID,this.htemp-st) ;
this.correct1 = correct ; this.correct2 = BLOCK.correct1 and BLOCK.correct2
;
this.stemp-st = (correct ? insert (ID, procid, this.htemp-st)) : this.htemp-st;
BLOCK.htemp-st = insert (ID3,refid,insert (ID2,varid,enter-block (this.symtab)))
;
BLOCK.symtab = BLOCK.stemp-st ;
}
}
}
class Stmts {
where stmt-list -> STMT+ use $correct2 := map left & value true other $correct2 (STMT) end map ; end where ; }
class Stmt {
case assign(Var var, Expr expr);
case ifthenelse (Expr expr1, Expr expr2, Stmts stmts1, Stmts stmts2);
case call (string id, Expr expr, Var var);
simproc-check () {
bool correct2 ;
switch (this) {
case assign(Var var, Expr expr):
this.correct2 = var.correct2 and expr.correct2;
case ifthenelse (Expr expr1, Expr expr2, Stmts stmts1, Stmts stmts2):
this.correct2 = expr1.correct2 and expr2.correct2 and stmts1.correct2 and stmts2.correct2 ;
case call (string id, Expr expr, Var var) :
{
mode mode = lookup (id,this.symtab);
this.correct2 = (((id = error-token) & (mode = error-mode) & (mode
!= procid)) ? flase : true) and expr.correct2 and var.correct2 ;
}
}
}
class Expr {
case bin-expr (Op op, Expr expr1, Expr expr2);
case constant (int number);
case used-var (Var var);
simproc-check () {
bool correct2;
switch (this) {
case bin-expr (Op op, Expr expr1, Expr expr2):
this.correct2 = expr1.correct2 and expr2.correct2 and !(op.op = wrong-op);
case constant (int number):
case used-var (Var var) :
}
}
}
class Op {
case plus ();
case minus ();
case div ();
case mul ();
simproc-check () {
op op;
switch (this) {
case plus () : this.op = addition ;
case minus () : this.op = subtraction ;
case div () : this.op = division ;
case mul () : this.op = multiplication ;
}
}
}
class Var {
case simple-var (string id);
case indexed-var (string id, Expr expr);
simproc-check () {
bool correct2;
switch (this) {
case simple-var (string id) :
this.correct2 = { mode mode; mode = lookup (id,this.symtab); return ((mode= varid) or (mode = refid)) ? true : false; } ;
case indexed-var (string id, Expr expr):
this.correct2 = { mode mode; mode = lookup (id,this.symtab); return ((mode= arrayid) ? true : false) and expr.correct2 ; } ;
}
}
}