implementation module LinkerMessages; import StdEnv; from StdBool import not; from StdList import isEmpty, ++; import RWSDebugChoice; import StdList; import link_switches; from StdMisc import abort; // Linker Messages; messages should added in reverse order :: LinkerMessagesState = { ok :: !Bool , messages :: LinkerMessages }; :: LinkerMessages :== [LinkerMessage]; :: LinkerMessage = LinkerError !String | LinkerWarning !String | Verbose !String ; instance toString LinkerMessage where { toString (LinkerError error) = "Linker error: " +++ error; toString (LinkerWarning warning) = "Linker warning: " +++ warning; toString (Verbose msg) = "Linker message: " +++ msg; }; // Operations on Linker Messages DefaultLinkerMessages :: LinkerMessagesState; DefaultLinkerMessages = { LinkerMessagesState | ok = True , messages = [] }; class LinkError .a where { isLinkerErrorOccured :: !.a -> (!Bool,!.a); addLinkMessage :: !LinkerMessage !.a -> .a }; instance LinkError LinkerMessagesState where { isLinkerErrorOccured state=:{ok} = (ok,state); addLinkMessage message linker_message_state = addLinkerMessage message linker_message_state }; isLinkerError (LinkerError _) = True; isLinkerError _ = False; strip_linker_message (LinkerError s) = s; strip_linker_message (LinkerWarning s) = s; strip_linker_message (Verbose s) = s; setLinkerMessages :: !LinkerMessages !.LinkerMessagesState -> .LinkerMessagesState; setLinkerMessages linker_messages linker_messages_state=:{messages} = DEBUG_INFO (set_linker_messages linker_messages linker_messages_state) {linker_messages_state &messages = messages} where { set_linker_messages linker_messages linker_messages_state=:{messages} | True <<- (map strip_linker_message linker_messages) #! linker_errors = [ m \\ m <- linker_messages | isLinkerError m]; = { linker_messages_state & ok = isEmpty linker_errors , messages = messages ++ linker_messages }; }; setLinkerMessages _ _ = abort "setLinkerMessage: mismatch"; setLinkerError error :== setLinkerMessages [LinkerError error] DefaultLinkerMessages; getLinkerMessages :: !LinkerMessagesState -> [String]; getLinkerMessages {messages} = [ toString m \\ m <- messages ]; get_LinkerMessages :: !LinkerMessagesState -> LinkerMessages; get_LinkerMessages {messages} = messages; addLinkerMessage message linker_messages_state :== DEBUG_INFO (setLinkerMessages [message] linker_messages_state) linker_messages_state; class AddMessage .a where { AddMessage :: !LinkerMessage !*a -> *a; IsErrorOccured :: !*a -> (!Bool,!*a); GetLinkerMessages :: !*a -> (!LinkerMessages,!*a); SetLinkerMessages :: !LinkerMessages !*a -> *a };