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

Unified · Split

3 files
  1. src/asm/type_signature.cpp +44 −30
  2. src/exec/main.cpp +1 −1
  3. src/include/vm_asm.h +109 −28
src/asm/type_signature.cpp+44−30
@@ -63,9 +63,18 @@ sig_stream_t &sig_stream_t::operator<<(const char *s) · 62 unmodified lines
6363 return *this;
6464 }
6565
66+sig_stream_t &sig_stream_t::operator<<(const uint32_t i)
67+{
68+ _ss << i;
69+ return *this;
70+}
71+
6672 sig_stream_t &sig_stream_t::operator<<(const sig_stream_t &ss)
6773 {
6874 _ss << ss._ss.rdbuf();
75+
76+ // Reset the input stream so it can be inserted in another stream.
77+ ss._ss.seekg(0);
6978 return *this;
7079 }
7180
@@ -121,41 +130,17 @@ Ttype_ref::Ttype_ref(uint32_t num) · 49 unmodified lines
121130
122131 sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Ttype_ref &r)
123132 {
124− return os << '@' << r._num;
133+ return os << Tref::id << r._num;
125134 }
126135
127−Tm::Tm(const char *name, const type_id_t &type_id)
128− : _name{ name }
129− , _type_id{ type_id }
130− , _type_id_str{ nullptr }
131−{ }
132−
133−Tm::Tm(const char *name, const char *type_id)
134− : _name{ name }
135− , _type_id{ type_id_t::unknown }
136− , _type_id_str{ type_id }
137−{ }
138−
139136 sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tm &m)
140137 {
141− if (m._type_id_str == nullptr)
142− {
143− assert(m._type_id != type_id_t::unknown);
144− return os << m._name << ':' << m._type_id;
145− }
146− else
147− {
148− assert(m._type_id == type_id_t::unknown);
149− return os << m._name << ':' << m._type_id_str;
150− }
138+ return os << m._s;
151139 }
152140
153141 const char Ttuple::begin = '(';
154142 const char Ttuple::end = ')';
155143
156−const char Tadt::begin = '(';
157−const char Tadt::end = ')';
158−
159144 const char Tmodule::begin = '{';
160145 const char Tmodule::end = '}';
161146
@@ -164,14 +149,43 @@ sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Ttupl · 2 unmodified lines
164149 return os << t._s;
165150 }
166151
167−sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tadt &a)
152+sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tmodule &m)
168153 {
169− return os << a._s;
154+ return os << m._s;
170155 }
171156
172−sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tmodule &m)
157+const char *Tadt_pick_tag::tag_delim = "=>";
158+
159+Tadt_pick_tag Tadt_pick_tag::create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms)
173160 {
174− return os << m._s;
161+ sig_stream_t ss;
162+ ss << pick_tag << Tadt_pick_tag::tag_delim << Tbasic_type::id << Tadt_pick_tag::begin;
163+
164+ auto tm = tms.begin();
165+ for (auto c = 0; tm != tms.end(); tm++, c++)
166+ {
167+ if (c > 0)
168+ ss << sig_stream_t::delim;
169+
170+ ss << *tm;
171+ }
172+
173+ ss << Tadt_pick_tag::end << Tref::id << adt_ref;
174+
175+ return Tadt_pick_tag{ ss };
176+}
177+
178+sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tadt_pick_tag &t)
179+{
180+ return os << t._s;
181+}
182+
183+const char Tnested_aggregate_type<type_id_t::adt>::begin = '(';
184+const char Tnested_aggregate_type<type_id_t::adt>::end = ')';
185+
186+sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tnested_aggregate_type<type_id_t::adt> &a)
187+{
188+ return os << a._s;
175189 }
176190
177191 sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, Tfunction &f)
src/exec/main.cpp+1−1
@@ -261,7 +261,7 @@ void process_arg(char* arg, std::function<char *()> next, exec_options &options) · 260 unmodified lines
261261
262262 int main(int argc, char* argv[])
263263 {
264− exec_options options = {};
264+ exec_options options{};
265265
266266 try
267267 {
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 {