diff options
| author | Nick Barnes | 2001-10-31 14:40:56 +0000 |
|---|---|---|
| committer | Nick Barnes | 2001-10-31 14:40:56 +0000 |
| commit | 7acfca905d76140f4cc0b09c9a12de237de364cd (patch) | |
| tree | 3ed8babfa3a73d30f29e08ca5d5adcda4ca4e826 /mps/code/protocol.h | |
| parent | b7ce4893f9902d57cd67ac9a92fa6c3d5a8fc833 (diff) | |
| download | emacs-7acfca905d76140f4cc0b09c9a12de237de364cd.tar.gz emacs-7acfca905d76140f4cc0b09c9a12de237de364cd.zip | |
Branch imports for masters.
Copied from Perforce
Change: 23678
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/protocol.h')
| -rw-r--r-- | mps/code/protocol.h | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/mps/code/protocol.h b/mps/code/protocol.h new file mode 100644 index 00000000000..f2c7e4134fb --- /dev/null +++ b/mps/code/protocol.h | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | /* impl.h.protocol: PROTOCOL INHERITANCE DEFINITIONS | ||
| 2 | * | ||
| 3 | * $HopeName: MMsrc!protocol.h(trunk.4) $ | ||
| 4 | * Copyright (C) 1999 Harlequin Limited. All rights reserved. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef protocol_h | ||
| 8 | #define protocol_h | ||
| 9 | |||
| 10 | #include "config.h" | ||
| 11 | #include "mpmtypes.h" | ||
| 12 | |||
| 13 | |||
| 14 | /* Name derivation macros. These are not intended to be used */ | ||
| 15 | /* outside of this file */ | ||
| 16 | |||
| 17 | #define DERIVE_LOCAL(name) protocol ## name | ||
| 18 | #define DERIVE_STRUCT(name) name ## Struct | ||
| 19 | #define DERIVE_ENSURE(name) name ## Get | ||
| 20 | #define DERIVE_ENSURE_OLD(name) Ensure ## name | ||
| 21 | #define DERIVE_ENSURE_INTERNAL(name) protocolGet ## name | ||
| 22 | #define DERIVE_GUARDIAN(name) protocol ## name ## Guardian | ||
| 23 | #define DERIVE_STATIC_STORAGE(name) protocol ## name ## Struct | ||
| 24 | |||
| 25 | |||
| 26 | /* Macro to set the superclass field. This is not intended */ | ||
| 27 | /* to be used outside this file. This is a polymorphic macro */ | ||
| 28 | /* named as a function. See design.mps.protocol.introspect.c-lang */ | ||
| 29 | |||
| 30 | #define ProtocolClassSetSuperclassPoly(class, super) \ | ||
| 31 | (((ProtocolClass)(class))->superclass) = (ProtocolClass)(super) | ||
| 32 | |||
| 33 | |||
| 34 | /* DEFINE_CLASS -- the standard macro for defining a ProtocolClass */ | ||
| 35 | |||
| 36 | #define DEFINE_CLASS(className, var) \ | ||
| 37 | static Bool DERIVE_GUARDIAN(className) = FALSE; \ | ||
| 38 | static DERIVE_STRUCT(className) DERIVE_STATIC_STORAGE(className); \ | ||
| 39 | static void DERIVE_ENSURE_INTERNAL(className)(className); \ | ||
| 40 | extern className DERIVE_ENSURE(className)(void); \ | ||
| 41 | className DERIVE_ENSURE(className)(void) \ | ||
| 42 | { \ | ||
| 43 | if (DERIVE_GUARDIAN(className) == FALSE) { \ | ||
| 44 | LockClaimGlobalRecursive(); \ | ||
| 45 | if (DERIVE_GUARDIAN(className) == FALSE) { \ | ||
| 46 | DERIVE_ENSURE_INTERNAL(className) \ | ||
| 47 | (&DERIVE_STATIC_STORAGE(className)); \ | ||
| 48 | DERIVE_GUARDIAN(className) = TRUE; \ | ||
| 49 | } \ | ||
| 50 | LockReleaseGlobalRecursive(); \ | ||
| 51 | } \ | ||
| 52 | return &DERIVE_STATIC_STORAGE(className); \ | ||
| 53 | } \ | ||
| 54 | /* old name for backward compatibility */ \ | ||
| 55 | extern className DERIVE_ENSURE_OLD(className)(void); \ | ||
| 56 | className DERIVE_ENSURE_OLD(className)(void) \ | ||
| 57 | { \ | ||
| 58 | return DERIVE_ENSURE(className)(); \ | ||
| 59 | } \ | ||
| 60 | static void DERIVE_ENSURE_INTERNAL(className) (className var) | ||
| 61 | |||
| 62 | |||
| 63 | /* INHERIT_CLASS -- the standard macro for inheriting from a superclass */ | ||
| 64 | |||
| 65 | #define INHERIT_CLASS(this, parentName) \ | ||
| 66 | BEGIN \ | ||
| 67 | parentName DERIVE_LOCAL(parentName) = DERIVE_ENSURE(parentName)(); \ | ||
| 68 | *this = *(DERIVE_LOCAL(parentName)); \ | ||
| 69 | ProtocolClassSetSuperclassPoly(this, DERIVE_LOCAL(parentName)); \ | ||
| 70 | END | ||
| 71 | |||
| 72 | |||
| 73 | /* DEFINE_ALIAS_CLASS -- define a new class for the same type | ||
| 74 | * | ||
| 75 | * A convenience macro. Aliases the structure and pointer types | ||
| 76 | * for className to be the same as typeName, and then defines | ||
| 77 | * the class className. | ||
| 78 | */ | ||
| 79 | #define DEFINE_ALIAS_CLASS(className, typeName, var) \ | ||
| 80 | typedef typeName className; \ | ||
| 81 | typedef DERIVE_STRUCT(typeName) DERIVE_STRUCT(className); \ | ||
| 82 | DEFINE_CLASS(className, var) | ||
| 83 | |||
| 84 | |||
| 85 | |||
| 86 | #define ProtocolClassSig ((Sig)0x519B60C7) /* SIGnature PROtocol CLass */ | ||
| 87 | #define ProtocolInstSig ((Sig)0x519B6014) /* SIGnature PROtocol INst */ | ||
| 88 | |||
| 89 | |||
| 90 | /* ProtocolClass -- the class containing the support for the protocol */ | ||
| 91 | |||
| 92 | typedef struct ProtocolClassStruct *ProtocolClass; | ||
| 93 | |||
| 94 | |||
| 95 | /* ProtocolInst -- the instance structure for support of the protocol */ | ||
| 96 | |||
| 97 | typedef struct ProtocolInstStruct *ProtocolInst; | ||
| 98 | |||
| 99 | |||
| 100 | /* ProtocolCoerceInstMethod -- coerce "pro" to an instance of "interface" | ||
| 101 | * | ||
| 102 | * If "pro" is an instance of "interface", then returns TRUE | ||
| 103 | * and sets coerceResult to point directly to the part of "pro" | ||
| 104 | * which contains the slots for "interface" | ||
| 105 | */ | ||
| 106 | typedef Bool (*ProtocolCoerceInstMethod)(ProtocolInst *coerceResult, | ||
| 107 | ProtocolInst pro, | ||
| 108 | ProtocolClass interface); | ||
| 109 | |||
| 110 | /* ProtocolCoerceClassMethod -- coerce "proClass" to an "interface" class | ||
| 111 | * | ||
| 112 | * If "proClass" is a subclass of "interface", then returns TRUE | ||
| 113 | * and sets coerceResult to point directly to the part of | ||
| 114 | * "proClass" which contains the slots for "interface". | ||
| 115 | */ | ||
| 116 | typedef Bool (*ProtocolCoerceClassMethod)(ProtocolClass *coerceResult, | ||
| 117 | ProtocolClass proClass, | ||
| 118 | ProtocolClass interface); | ||
| 119 | |||
| 120 | |||
| 121 | |||
| 122 | typedef struct ProtocolClassStruct { | ||
| 123 | Sig sig; /* design.mps.sig */ | ||
| 124 | ProtocolClass superclass; /* the superclass */ | ||
| 125 | ProtocolCoerceInstMethod coerceInst; /* coerce instance to super */ | ||
| 126 | ProtocolCoerceClassMethod coerceClass; /* coerce class to superclass */ | ||
| 127 | } ProtocolClassStruct; | ||
| 128 | |||
| 129 | |||
| 130 | typedef struct ProtocolInstStruct { | ||
| 131 | Sig sig; /* design.mps.sig */ | ||
| 132 | ProtocolClass class; /* the class */ | ||
| 133 | } ProtocolInstStruct; | ||
| 134 | |||
| 135 | |||
| 136 | /* ProtocolClassGet -- Returns the root of the protocol class hierarchy | ||
| 137 | * | ||
| 138 | * Function name conforms to standard conventions for | ||
| 139 | * protocols. | ||
| 140 | */ | ||
| 141 | extern ProtocolClass ProtocolClassGet(void); | ||
| 142 | |||
| 143 | |||
| 144 | /* Checking functions */ | ||
| 145 | |||
| 146 | extern Bool ProtocolClassCheck(ProtocolClass class); | ||
| 147 | extern Bool ProtocolInstCheck(ProtocolInst pro); | ||
| 148 | |||
| 149 | |||
| 150 | /* ProtocolIsSubclass - use macro IsSubclass to access this. | ||
| 151 | * | ||
| 152 | * A predicate for testing subclass relationships. | ||
| 153 | * A protocol class is always a subclass of itself. | ||
| 154 | */ | ||
| 155 | extern Bool ProtocolIsSubclass(ProtocolClass sub, ProtocolClass super); | ||
| 156 | |||
| 157 | |||
| 158 | /* Protocol introspection interface */ | ||
| 159 | |||
| 160 | /* The following are macros because of the need to cast */ | ||
| 161 | /* subtypes of ProtocolClass. Nevertheless they are named */ | ||
| 162 | /* as functions. See design.mps.protocol.introspect.c-lang */ | ||
| 163 | |||
| 164 | |||
| 165 | #define ProtocolClassSuperclassPoly(class) \ | ||
| 166 | (((ProtocolClass)(class))->superclass) | ||
| 167 | |||
| 168 | #define ClassOfPoly(inst) ((ProtocolInst)(inst)->class) | ||
| 169 | |||
| 170 | #define IsSubclassPoly(sub, super) \ | ||
| 171 | ProtocolIsSubclass((ProtocolClass)(sub), (ProtocolClass)(super)) | ||
| 172 | |||
| 173 | |||
| 174 | /* SUPERCLASS - get the superclass object, given a class name | ||
| 175 | * | ||
| 176 | * Returns the superclass, with type ProtocolClass. Clients will | ||
| 177 | * probably wish to cast this. See | ||
| 178 | * design.mps.protocol.int.static-superclass | ||
| 179 | */ | ||
| 180 | #define SUPERCLASS(className) \ | ||
| 181 | ProtocolClassSuperclassPoly(DERIVE_ENSURE(className)()) | ||
| 182 | |||
| 183 | |||
| 184 | #endif /* protocol_h */ | ||