Showing the changes to src/include (1 of 3 files). Show all
Unified · Split
| @@ -30,11 +30,14 @@ namespace disvm · 29 unmodified lines | ||
| 30 | 30 | namespace sigkind |
| 31 | 31 | { |
| 32 | 32 | // Signature stream |
| 33 | − class sig_stream_t | |
| 33 | + class sig_stream_t final | |
| 34 | 34 | { |
| 35 | 35 | public: // static |
| 36 | 36 | static uint32_t compute_signature_hash(const char *); |
| 37 | 37 | |
| 38 | + // Type delimiter | |
| 39 | + static const char delim = ','; | |
| 40 | + | |
| 38 | 41 | public: |
| 39 | 42 | std::string get_signature() const; |
| 40 | 43 | |
| @@ -42,10 +45,11 @@ namespace disvm · 1 unmodified line | ||
| 42 | 45 | |
| 43 | 46 | sig_stream_t &operator<<(const char); |
| 44 | 47 | sig_stream_t &operator<<(const char *); |
| 48 | + sig_stream_t &operator<<(const uint32_t); | |
| 45 | 49 | sig_stream_t &operator<<(const sig_stream_t &); |
| 46 | 50 | |
| 47 | 51 | private: |
| 48 | − std::stringstream _ss; | |
| 52 | + mutable std::stringstream _ss; | |
| 49 | 53 | }; |
| 50 | 54 | |
| 51 | 55 | // Type context modifiers |
| @@ -55,12 +59,12 @@ namespace disvm · 3 unmodified lines | ||
| 55 | 59 | cycle = 'y', |
| 56 | 60 | }; |
| 57 | 61 | |
| 58 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::modifier_id_t &); | |
| 62 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::modifier_id_t &); | |
| 59 | 63 | |
| 60 | 64 | // Instrinsic VM types |
| 61 | 65 | enum class type_id_t : uint8_t |
| 62 | 66 | { |
| 63 | − unknown = 0, | |
| 67 | + unknown = 0, // This will be interpreted as a 'null' value which will help debug where the type building failed. | |
| 64 | 68 | none = 'n', |
| 65 | 69 | byte = 'b', |
| 66 | 70 | integer = 'i', |
| @@ -74,14 +78,14 @@ namespace disvm · 7 unmodified lines | ||
| 74 | 78 | list = 'L', |
| 75 | 79 | channel = 'C', |
| 76 | 80 | adt = 'a', |
| 77 | − //adtpick = 'p', | |
| 81 | + adt_pick_tag = 'p', | |
| 78 | 82 | tuple = 't', |
| 79 | 83 | module = 'm', |
| 80 | 84 | function = 'f', |
| 81 | 85 | function_varargs = 0xff, // "f*" |
| 82 | 86 | }; |
| 83 | 87 | |
| 84 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::type_id_t &); | |
| 88 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::type_id_t &); | |
| 85 | 89 | |
| 86 | 90 | template<type_id_t T> |
| 87 | 91 | struct Tbasic_type |
| @@ -102,7 +106,7 @@ namespace disvm · 14 unmodified lines | ||
| 102 | 106 | using Tstring = Tbasic_type<type_id_t::string>; |
| 103 | 107 | using Tpoly = Tbasic_type<type_id_t::poly>; |
| 104 | 108 | |
| 105 | − class Tfixed : public Tbasic_type<type_id_t::fixed> | |
| 109 | + class Tfixed final : public Tbasic_type<type_id_t::fixed> | |
| 106 | 110 | { |
| 107 | 111 | public: |
| 108 | 112 | Tfixed(double scale); |
| @@ -113,7 +117,7 @@ namespace disvm · 4 unmodified lines | ||
| 113 | 117 | const double _scale; |
| 114 | 118 | }; |
| 115 | 119 | |
| 116 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tfixed &); | |
| 120 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tfixed &); | |
| 117 | 121 | |
| 118 | 122 | // Type that contains/modifies another type |
| 119 | 123 | template <type_id_t ID> |
| @@ -141,14 +145,18 @@ namespace disvm · 21 unmodified lines | ||
| 141 | 145 | using Tlist = Tbasic_aggregate_type<type_id_t::list>; |
| 142 | 146 | using Tchannel = Tbasic_aggregate_type<type_id_t::channel>; |
| 143 | 147 | |
| 144 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tarray &); | |
| 145 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tref &); | |
| 146 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tlist &); | |
| 147 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tchannel &); | |
| 148 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tarray &); | |
| 149 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tref &); | |
| 150 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tlist &); | |
| 151 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tchannel &); | |
| 148 | 152 | |
| 149 | 153 | // Reference to another previously defined type in the current signature |
| 150 | − struct Ttype_ref | |
| 154 | + class Ttype_ref final | |
| 151 | 155 | { |
| 156 | + public: // static | |
| 157 | + static const char id = '@'; | |
| 158 | + | |
| 159 | + public: | |
| 152 | 160 | Ttype_ref(uint32_t num); |
| 153 | 161 | |
| 154 | 162 | friend sig_stream_t &operator<<(sig_stream_t &os, const Ttype_ref &); |
| @@ -157,23 +165,25 @@ namespace disvm · 2 unmodified lines | ||
| 157 | 165 | const uint32_t _num; |
| 158 | 166 | }; |
| 159 | 167 | |
| 160 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Ttype_ref &); | |
| 168 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Ttype_ref &); | |
| 161 | 169 | |
| 162 | 170 | // Named member type |
| 163 | − struct Tm | |
| 171 | + class Tm final | |
| 164 | 172 | { |
| 165 | − Tm(const char *name, const type_id_t &type_id); | |
| 166 | − Tm(const char *name, const char *type_id); | |
| 173 | + public: | |
| 174 | + template <typename T> | |
| 175 | + Tm(const char *name, const T &type) | |
| 176 | + { | |
| 177 | + _s << name << ':' << type; | |
| 178 | + } | |
| 167 | 179 | |
| 168 | 180 | friend sig_stream_t &operator<<(sig_stream_t &os, const Tm &); |
| 169 | 181 | |
| 170 | 182 | private: |
| 171 | − const char *_type_id_str; | |
| 172 | − const type_id_t _type_id; | |
| 173 | − const char *_name; | |
| 183 | + sig_stream_t _s; | |
| 174 | 184 | }; |
| 175 | 185 | |
| 176 | − sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tm &); | |
| 186 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tm &); | |
| 177 | 187 | |
| 178 | 188 | inline void nested_type(const sig_stream_t &) |
| 179 | 189 | { |
| @@ -190,7 +200,7 @@ namespace disvm · 10 unmodified lines | ||
| 190 | 200 | template<typename T1, typename T2, typename ...S> |
| 191 | 201 | void nested_type(sig_stream_t &ss, const T1 &t1, const T2 &t2, const S&...s) |
| 192 | 202 | { |
| 193 | − ss << t1 << ','; | |
| 203 | + ss << t1 << sig_stream_t::type_delim; | |
| 194 | 204 | nested_type(ss, t2, s...); |
| 195 | 205 | } |
| 196 | 206 | |
| @@ -198,7 +208,7 @@ namespace disvm · 1 unmodified line | ||
| 198 | 208 | template <type_id_t ID> |
| 199 | 209 | class Tnested_aggregate_type : public Tbasic_type<ID> |
| 200 | 210 | { |
| 201 | − public: | |
| 211 | + public: // static | |
| 202 | 212 | static const char begin; |
| 203 | 213 | static const char end; |
| 204 | 214 | |
| @@ -215,26 +225,96 @@ namespace disvm · 10 unmodified lines | ||
| 215 | 225 | return Tnested_aggregate_type{ ss }; |
| 216 | 226 | } |
| 217 | 227 | |
| 228 | + public: | |
| 229 | + Tnested_aggregate_type(sig_stream_t &s) | |
| 230 | + : _s{ std::move(s) } | |
| 231 | + { } | |
| 232 | + | |
| 218 | 233 | friend sig_stream_t &operator<<(sig_stream_t &, const Tnested_aggregate_type &); |
| 219 | 234 | |
| 220 | 235 | private: |
| 221 | 236 | sig_stream_t _s; |
| 222 | − Tnested_aggregate_type(sig_stream_t &s) : _s{ std::move(s) } { } | |
| 223 | 237 | }; |
| 224 | 238 | |
| 225 | 239 | using Ttuple = Tnested_aggregate_type<type_id_t::tuple>; |
| 226 | − using Tadt = Tnested_aggregate_type<type_id_t::adt>; | |
| 227 | 240 | using Tmodule = Tnested_aggregate_type<type_id_t::module>; |
| 228 | 241 | |
| 229 | 242 | sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Ttuple &); |
| 230 | − sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tadt &); | |
| 231 | 243 | sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tmodule &); |
| 232 | 244 | |
| 245 | + // Abstract data type (ADT) pick tag | |
| 246 | + // Note: This type should only be a part of an ADT instance. | |
| 247 | + class Tadt_pick_tag final : public Tbasic_type<type_id_t::adt_pick_tag> | |
| 248 | + { | |
| 249 | + public: // static | |
| 250 | + static const char *tag_delim; | |
| 251 | + static const char begin = '('; | |
| 252 | + static const char end = ')'; | |
| 253 | + | |
| 254 | + static Tadt_pick_tag create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms); | |
| 255 | + | |
| 256 | + friend sig_stream_t &operator<<(sig_stream_t &, const Tadt_pick_tag &); | |
| 257 | + | |
| 258 | + private: | |
| 259 | + sig_stream_t _s; | |
| 260 | + Tadt_pick_tag(sig_stream_t &s) : _s{ std::move(s) } { } | |
| 261 | + }; | |
| 262 | + | |
| 263 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tadt_pick_tag &); | |
| 264 | + | |
| 265 | + // Abstract data type (ADT) | |
| 266 | + class Tadt final : public Tnested_aggregate_type<type_id_t::adt> | |
| 267 | + { | |
| 268 | + public: // static | |
| 269 | + // Unhide base class version of function | |
| 270 | + using Tnested_aggregate_type::create; | |
| 271 | + | |
| 272 | + // Create an ADT with a single pick tag | |
| 273 | + static Tadt create(const Tadt_pick_tag &p) | |
| 274 | + { | |
| 275 | + sig_stream_t ss; | |
| 276 | + ss << Tbasic_type::id | |
| 277 | + << Tadt::begin | |
| 278 | + << sig_stream_t::delim | |
| 279 | + << p | |
| 280 | + << Tadt::end; | |
| 281 | + | |
| 282 | + return Tadt{ ss }; | |
| 283 | + } | |
| 284 | + | |
| 285 | + template<typename T, typename ...NT> | |
| 286 | + static Tadt create(const Tadt_pick_tag &p, const T &t, const NT&... nestedTypes) | |
| 287 | + { | |
| 288 | + // [SPEC] When generating type signatures, the Limbo compiler | |
| 289 | + // doesn't identify the case where a pick tag is the first type | |
| 290 | + // so it always prefixes the nested signature with a leading ','. | |
| 291 | + // We special case this scenario to maintain compatibility. The | |
| 292 | + // single pick tag for an ADT must also be handled (above). | |
| 293 | + sig_stream_t ss; | |
| 294 | + ss << Tbasic_type::id | |
| 295 | + << Tadt::begin | |
| 296 | + << sig_stream_t::delim | |
| 297 | + << p | |
| 298 | + << sig_stream_t::delim; | |
| 299 | + | |
| 300 | + nested_type(ss, t, nestedTypes...); | |
| 301 | + | |
| 302 | + ss << Tadt::end; | |
| 303 | + | |
| 304 | + return Tadt{ ss }; | |
| 305 | + } | |
| 306 | + | |
| 307 | + private: | |
| 308 | + Tadt(sig_stream_t &s) : Tnested_aggregate_type{ std::move(s) } { } | |
| 309 | + }; | |
| 310 | + | |
| 311 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tnested_aggregate_type<type_id_t::adt> &); | |
| 312 | + | |
| 233 | 313 | // Function type |
| 234 | 314 | template<type_id_t T> |
| 235 | − class Tfunction_base_type : public Tbasic_type<T> | |
| 315 | + class Tfunction_base_type final : public Tbasic_type<T> | |
| 236 | 316 | { |
| 237 | − public: | |
| 317 | + public: // static | |
| 238 | 318 | static const char begin = '('; |
| 239 | 319 | static const char end = ')'; |
| 240 | 320 | |
| @@ -250,6 +330,7 @@ namespace disvm · 9 unmodified lines | ||
| 250 | 330 | return a; |
| 251 | 331 | } |
| 252 | 332 | |
| 333 | + public: | |
| 253 | 334 | template<typename RT> |
| 254 | 335 | Tfunction_base_type &returns(RT r) |
| 255 | 336 | { |