-- This is the file EXPr.ADS 7:36AM 10/11/95 -- It contains the specification of package expr, which defines -- Exp, a type to implement SymbolicExpressions -- and all the subtypes needed for expressions. Constructors,Selectors and -- Testers are provided. The package expr.io defines put and get -- on these types. The package eval defines evaluation of expressions. with list; package expr is type Symbol is new String(1..8); package SymList is new List(Symbol); type SymbolList is new SymList.pointer; -- The primitives for SymbolLists and for ExpLists are implicitly declared -- when we declare the types SymbolList and ExpList to be derived from -- pointer, after appropriately instantiating the generic list package for -- each. I would have preferred keeping the types Symbol and Exp private, -- but gnat would not allow it, as the corresponding List instantiations -- could not occur until Symbol and Exp were known, and if they didn't occur -- until the private part, then the primitives operating on SymbolLists and -- ExpLists would not be visible. (An alternative would be to declare the -- primitives in the visible part of the specifcation, but gnat would not -- recognize that they had been defined once the instantiations had occurred. -- I assume it was expecting them to be overridden by new definitions.) type ExpRec is private; type Exp is access ExpRec; package ExprList is new List(Exp); type ExpList is new ExprList.pointer; -- the Exptypes done and endparen are for convenience in input of expressions -- they are not really types of expressions as defined by the specification type ExpType is (const, var, def, set, fcn, seq, app, done, endparen); -- since we want to allow the evaluation of expressions involving -- numeric primitives, we flag them as primitives -- since we don't have their definitions available as we do for defined (or -- compound) functions type FcnType is (compound, primitive); -- constructor functions for expressions function MkConst(I : Integer) return Exp; function MkVar(Name : Symbol) return Exp; function MkDef(Name : Symbol; E : Exp) return Exp; function MkSet(Name : Symbol; E : Exp) return Exp; function MkFcn(FnTyp : FcnType; Name : Symbol; Namelist : SymbolList; FcnBody : Exp) return Exp; function MkSeq(EL : ExpList) return Exp; function MkApp(Op : Exp; ArgList : ExpList) return Exp; function MkDummy(Msg : Symbol) return Exp; function MkEndparen(Msg : Symbol) return Exp; -- selector functions function TypeOfExp(E : Exp) return ExpType; function TypeOfFcn(E : Exp) return FcnType; function ConstVal(C : Exp) return Integer; function VarName(Var : Exp) return Symbol; function DefName(Defn : Exp) return Symbol; function DefBody(Defn : Exp) return Exp; function SetName(SetExp : Exp) return Symbol; function SetBody(SetExp : Exp) return Exp; function FcnName(Fcn : Exp) return Symbol; function FcnParams(Fcn : Exp) return SymbolList; function FcnBody(Fcn : Exp) return Exp; function Seq(SeqExp : Exp) return ExpList; function AppOp(FunApp : Exp) return Exp; function AppArgs(FunApp : Exp) return ExpList; -- tester functions function IsConst(E : Exp) return Boolean; function IsVar(E : Exp) return Boolean; function IsDef(E : Exp) return Boolean; function IsSet(E : Exp) return Boolean; function IsFcn(E : Exp) return Boolean; function IsSeq(E : Exp) return Boolean; function IsApp(E : Exp) return Boolean; function IsDummy(E : Exp) return Boolean; function IsEndparen(E : Exp) return Boolean; private -- the type ExpRec is a variant record. It is provided a default so that Ada -- will allow the reassignment of different variants to the same variable type ExpRec(etype:ExpType:=const) is record case etype is when const => value: Integer; when var => vname: Symbol; when def|set => name: Symbol; expr:Exp; when fcn => funtype : FcnType; fname : Symbol; params : SymbolList; fnbody : Exp; when seq => list : ExpList; when app => op : Exp; arglist : ExpList; when done|endparen => dummy: Symbol; end case; end record; end expr;