(* Copyright (C) 1992, Digital Equipment Corporation *) (* All rights reserved. *) (* See the file COPYRIGHT for a full description. *) (* File: Decl.m3 *) (* Last modified on Fri Sep 11 14:59:52 PDT 1992 by kalsow *) (* modified on Sat Mar 16 01:56:20 1991 by muller *) MODULE Decl; IMPORT M3, Token, Error, String, ESet, Module, Exceptionz; IMPORT Constant, Tipe, Variable, Procedure, Revelation; FROM Scanner IMPORT GetToken, Match1, cur; TYPE TK = Token.T; PROCEDURE Parse (READONLY fail: Token.Set; interface, top_level: BOOLEAN; VAR fails: M3.ExSet) = VAR att: Attributes; BEGIN att.isInline := FALSE; att.isExternal := FALSE; att.isUnused := FALSE; att.isObsolete := FALSE; att.alias := NIL; LOOP CASE cur.token OF | TK.tEXTERNAL => IF NOT Module.IsInterface () THEN Error.Msg ("External declarations only allowed in interfaces"); END; ParseExternalPragma (fail, att.alias); att.isExternal := TRUE; | TK.tINLINE => att.isInline := TRUE; GetToken (); (* INLINE *) Match1 (TK.tENDPRAGMA, fail); | TK.tUNUSED => att.isUnused := TRUE; GetToken (); (* UNUSED *) Match1 (TK.tENDPRAGMA, fail); | TK.tOBSOLETE => att.isObsolete := TRUE; GetToken (); (* OBSOLETE *) Match1 (TK.tENDPRAGMA, fail); ELSE EXIT; END; END; CASE cur.token OF | TK.tCONST => att.isExternal := att.isExternal OR Module.IsExternal (); Constant.ParseDecl (fail, att); | TK.tTYPE => Tipe.Parse (fail, att); | TK.tVAR => att.isExternal := att.isExternal OR Module.IsExternal (); Variable.ParseDecl (fail, att); | TK.tPROCEDURE => att.isExternal := att.isExternal OR Module.IsExternal (); Procedure.ParseDecl (fail, att, interface); | TK.tREVEAL => IF (NOT top_level) THEN Error.Msg ("nested revelation") END; Revelation.Parse (fail, att); | TK.tEXCEPTION => IF (NOT top_level) THEN Error.Msg ("nested exception declaration") END; att.isExternal := att.isExternal OR Module.IsExternal (); Exceptionz.ParseDecl (fail, att); | TK.tFATAL => fails := ESet.ParseFails (fail, fails); ELSE IF att.isInline OR att.isExternal OR att.isUnused OR att.isObsolete THEN Error.Msg ("declaration pragma not followed by a declaration"); END; END; END Parse; VAR cString: String.T := NIL; PROCEDURE ParseExternalPragma (READONLY fail: Token.Set; VAR alias: String.T)= BEGIN alias := NIL; <* ASSERT cur.token = TK.tEXTERNAL *> GetToken (); (* EXTERNAL *) IF (cur.token = TK.tIDENT) OR (cur.token = TK.tTEXTCONST) THEN alias := cur.string; GetToken (); (* IDENT, TEXTCONST *) IF (cur.token = TK.tCOLON) THEN GetToken (); (* : *) IF (cur.token = TK.tIDENT) OR (cur.token = TK.tTEXTCONST) THEN IF (cString = NIL) THEN cString := String.Add ("C") END; IF (cur.string # cString) THEN Error.Str (cur.string, "unsupported external language"); END; GetToken (); (* C *) ELSE Error.Msg ("Missing language for <*EXTERNAL*> pragma"); END; END; END; Match1 (TK.tENDPRAGMA, fail); END ParseExternalPragma; BEGIN END Decl.