History

Finish type signature generation API - All types the Limbo compiler can create can now be created with the API.

arr committed 10 years ago

Commit 265a2bf1 parent f77a2283 files · +154 −59Browse files

Showing the changes to src/include (1 of 3 files). Show all

Unified · Split

src/include/vm_asm.h+109−28
@@ -30,11 +30,14 @@ namespace disvm · 29 unmodified lines
3030 namespace sigkind
3131 {
3232 // Signature stream
33− class sig_stream_t
33+ class sig_stream_t final
3434 {
3535 public: // static
3636 static uint32_t compute_signature_hash(const char *);
3737
38+ // Type delimiter
39+ static const char delim = ',';
40+
3841 public:
3942 std::string get_signature() const;
4043
@@ -42,10 +45,11 @@ namespace disvm · 1 unmodified line
4245
4346 sig_stream_t &operator<<(const char);
4447 sig_stream_t &operator<<(const char *);
48+ sig_stream_t &operator<<(const uint32_t);
4549 sig_stream_t &operator<<(const sig_stream_t &);
4650
4751 private:
48− std::stringstream _ss;
52+ mutable std::stringstream _ss;
4953 };
5054
5155 // Type context modifiers
@@ -55,12 +59,12 @@ namespace disvm · 3 unmodified lines
5559 cycle = 'y',
5660 };
5761
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 &);
5963
6064 // Instrinsic VM types
6165 enum class type_id_t : uint8_t
6266 {
63− unknown = 0,
67+ unknown = 0, // This will be interpreted as a 'null' value which will help debug where the type building failed.
6468 none = 'n',
6569 byte = 'b',
6670 integer = 'i',
@@ -74,14 +78,14 @@ namespace disvm · 7 unmodified lines
7478 list = 'L',
7579 channel = 'C',
7680 adt = 'a',
77− //adtpick = 'p',
81+ adt_pick_tag = 'p',
7882 tuple = 't',
7983 module = 'm',
8084 function = 'f',
8185 function_varargs = 0xff, // "f*"
8286 };
8387
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 &);
8589
8690 template<type_id_t T>
8791 struct Tbasic_type
@@ -102,7 +106,7 @@ namespace disvm · 14 unmodified lines
102106 using Tstring = Tbasic_type<type_id_t::string>;
103107 using Tpoly = Tbasic_type<type_id_t::poly>;
104108
105− class Tfixed : public Tbasic_type<type_id_t::fixed>
109+ class Tfixed final : public Tbasic_type<type_id_t::fixed>
106110 {
107111 public:
108112 Tfixed(double scale);
@@ -113,7 +117,7 @@ namespace disvm · 4 unmodified lines
113117 const double _scale;
114118 };
115119
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 &);
117121
118122 // Type that contains/modifies another type
119123 template <type_id_t ID>
@@ -141,14 +145,18 @@ namespace disvm · 21 unmodified lines
141145 using Tlist = Tbasic_aggregate_type<type_id_t::list>;
142146 using Tchannel = Tbasic_aggregate_type<type_id_t::channel>;
143147
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 &);
148152
149153 // Reference to another previously defined type in the current signature
150− struct Ttype_ref
154+ class Ttype_ref final
151155 {
156+ public: // static
157+ static const char id = '@';
158+
159+ public:
152160 Ttype_ref(uint32_t num);
153161
154162 friend sig_stream_t &operator<<(sig_stream_t &os, const Ttype_ref &);
@@ -157,23 +165,25 @@ namespace disvm · 2 unmodified lines
157165 const uint32_t _num;
158166 };
159167
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 &);
161169
162170 // Named member type
163− struct Tm
171+ class Tm final
164172 {
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+ }
167179
168180 friend sig_stream_t &operator<<(sig_stream_t &os, const Tm &);
169181
170182 private:
171− const char *_type_id_str;
172− const type_id_t _type_id;
173− const char *_name;
183+ sig_stream_t _s;
174184 };
175185
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 &);
177187
178188 inline void nested_type(const sig_stream_t &)
179189 {
@@ -190,7 +200,7 @@ namespace disvm · 10 unmodified lines
190200 template<typename T1, typename T2, typename ...S>
191201 void nested_type(sig_stream_t &ss, const T1 &t1, const T2 &t2, const S&...s)
192202 {
193− ss << t1 << ',';
203+ ss << t1 << sig_stream_t::type_delim;
194204 nested_type(ss, t2, s...);
195205 }
196206
@@ -198,7 +208,7 @@ namespace disvm · 1 unmodified line
198208 template <type_id_t ID>
199209 class Tnested_aggregate_type : public Tbasic_type<ID>
200210 {
201− public:
211+ public: // static
202212 static const char begin;
203213 static const char end;
204214
@@ -215,26 +225,96 @@ namespace disvm · 10 unmodified lines
215225 return Tnested_aggregate_type{ ss };
216226 }
217227
228+ public:
229+ Tnested_aggregate_type(sig_stream_t &s)
230+ : _s{ std::move(s) }
231+ { }
232+
218233 friend sig_stream_t &operator<<(sig_stream_t &, const Tnested_aggregate_type &);
219234
220235 private:
221236 sig_stream_t _s;
222− Tnested_aggregate_type(sig_stream_t &s) : _s{ std::move(s) } { }
223237 };
224238
225239 using Ttuple = Tnested_aggregate_type<type_id_t::tuple>;
226− using Tadt = Tnested_aggregate_type<type_id_t::adt>;
227240 using Tmodule = Tnested_aggregate_type<type_id_t::module>;
228241
229242 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 &);
231243 sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tmodule &);
232244
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+
233313 // Function type
234314 template<type_id_t T>
235− class Tfunction_base_type : public Tbasic_type<T>
315+ class Tfunction_base_type final : public Tbasic_type<T>
236316 {
237− public:
317+ public: // static
238318 static const char begin = '(';
239319 static const char end = ')';
240320
@@ -250,6 +330,7 @@ namespace disvm · 9 unmodified lines
250330 return a;
251331 }
252332
333+ public:
253334 template<typename RT>
254335 Tfunction_base_type &returns(RT r)
255336 {