[NEXT] [PREV]    HANDBOOK / CASE STUDY / The Compiler /

Auxiliary Predicates

Gentle
Applications
Concepts
Examples
Handbook
Support
Download

We now define some auxiliary predicates that were used in the above specifications.

(The checks could also be written ``inline'' using conditional statements. We refrained from doing so in order to keep the number of concepts small in the example compiler).

   

362  'action' CheckInt(Type: TYPE, Pos: POS) 
363     'rule' CheckInt(integer, Pos) 
364     'rule' CheckInt(T, Pos) : Error("Integer expected", Pos) 
  
365  'action' CheckBool(Type: TYPE, Pos: POS) 
366     'rule' CheckBool(boolean, Pos) : 
367     'rule' CheckBool(T, Pos) : Error("Boolean expected", Pos) 
  
368  'action' CheckSimple(Type: TYPE, Pos: POS) 
369     'rule' CheckSimple(integer, _) 
370     'rule' CheckSimple(real, _) 
371     'rule' CheckSimple(boolean, _) 
372     'rule' CheckSimple(T, Pos) : Error("simple type expected", Pos) 
  
373  'action' CheckArrayType(Type: TYPE, Pos: POS 
374           -> Lwb: INT, Upb: INT, ElemType: TYPE) 
375     'rule' CheckArrayType(array(Lwb, Upb, ElemType), Pos 
376            -> Lwb, Upb, ElemType) 
377     'rule' CheckArrayType(T, Pos -> 0, 0, none) : 
378        Error("Subscripted var is not an array", Pos) 
  
379  'action' CheckDesignator(E: EXPR, Pos: POS -> D: DESIG) 
380     'rule' CheckDesignator(desig(D), _ -> D) 
381     'rule' CheckDesignator(E, Pos -> none) : 
382        Error("VAR parameter expected", Pos) 
  
383  'action' CheckEquiv(T1: TYPE, T2: TYPE, Pos: POS) 
384     'rule' CheckEquiv(T1, T2, Pos) : eq(T1, T2) 
385     'rule' CheckEquiv(T1, T2, Pos) : 
386        Error("Types are not equivalent", Pos) 
  
387  'action' CheckType(Type: TYPE, Pos: POS) 
388     'rule' CheckType(array(Lwb, Upb, ElemType), Pos) : 
389        CheckBounds(Lwb, Upb, Pos) CheckType(ElemType, Pos) 
390     'rule' CheckType(_, _) : 
  
391  'action' CheckBounds(Lwb: INT, Upb: INT, Pos: POS) 
392     'rule' CheckBounds(Lwb, Upb, _): le(Lwb, Upb) 
393     'rule' CheckBounds(_, _, Pos): 
394        Error("lower bound exceeds upper bound", Pos) 
  
395  'action' CheckNotYetDeclared(Obj: OBJ, Lev: INT, Pos: POS) 
396     'rule' CheckNotYetDeclared(none, Level, Pos) : 
397     'rule' CheckNotYetDeclared(object(_, ObjLev, _), Level, Pos) : 
398        lt(ObjLev, Level) 
399     'rule' CheckNotYetDeclared(_, _, Pos) : 
400        Error("id already declared", Pos) 
  
401  'action' CheckProcedure(OBJ, POS -> DECLLIST, INT, LABEL) 
402     'rule' CheckProcedure(object(procobj(Start,Formals),Level,_),_ 
403        -> Formals, Level, Start) 
404     'rule' CheckProcedure(_, Pos -> nil, 0, Null): 
405        Error("procedure expected", Pos) 
406        NewLabel(-> Null) 
  
407  'action' Error(Msg: STRING, Pos: POS) 


The above predicates check their first argument for semantic constraints. If it is erroneous, then an error message is issued using the library predicate Error(Msg, Pos)).

Some predicates return certain characteristics of their argument.

For example, CheckArrayType(Type, Pos -> Lwb, Upb, ElemType) checks whether the argument is an array type, and returns the lower and upper bound and the element type if this is true.

   

408  'var' CurNestingLevel: INT 
  
409  'action' SetCurrentNesting(N: INT)  
410     'rule' SetCurrentNesting(N): CurNestingLevel <- N 
  
411  'action' GetCurrentNesting(-> INT) 
412     'rule' GetCurrentNesting(-> N): CurNestingLevel -> N 
  
413  'action' TypeCode(Type: TYPE -> Code: INT) 
414     'rule' TypeCode(integer -> 1) 
415     'rule' TypeCode(real -> 2) 
416     'rule' TypeCode(boolean -> 3) 
  
417  'action' TypeSize(Type: TYPE -> Size: INT) 
418     'rule' TypeSize(integer -> 1) 
419     'rule' TypeSize(real -> 1) 
420     'rule' TypeSize(boolean -> 1) 
421     'rule' TypeSize(array(Lwb, Upb, ElemType) 
422            ->((Upb-Lwb)+1)*ElemSize) : 
423        TypeSize(ElemType -> ElemSize) 


The current nesting level of procedures is implemented as a global variable, the predicates SetCurrentNesting and GetCurrentNesting are used to set and get its value.

The predicates TypeCode and TypeSize compute the encoding and the size of a type.





[NEXT] [PREV]