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
63 return *this;63 return *this;
64}64}
65 65
66sig_stream_t &sig_stream_t::operator<<(const uint32_t i)
67{
68 _ss << i;
69 return *this;
70}
71
66sig_stream_t &sig_stream_t::operator<<(const sig_stream_t &ss)72sig_stream_t &sig_stream_t::operator<<(const sig_stream_t &ss)
67{73{
68 _ss << ss._ss.rdbuf();74 _ss << ss._ss.rdbuf();
75
76 // Reset the input stream so it can be inserted in another stream.
77 ss._ss.seekg(0);
69 return *this;78 return *this;
70}79}
71 80
@@ -121,41 +130,17 @@ Ttype_ref::Ttype_ref(uint32_t num) · 49 unmodified lines
121 130
122sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Ttype_ref &r)131sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Ttype_ref &r)
123{132{
124 return os << '@' << r._num;133 return os << Tref::id << r._num;
125}134}
126 135
127Tm::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
133Tm::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
139sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tm &m)136sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tm &m)
140{137{
141 if (m._type_id_str == nullptr)138 return os << m._s;
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 }
151}139}
152 140
153const char Ttuple::begin = '(';141const char Ttuple::begin = '(';
154const char Ttuple::end = ')';142const char Ttuple::end = ')';
155 143
156const char Tadt::begin = '(';
157const char Tadt::end = ')';
158
159const char Tmodule::begin = '{';144const char Tmodule::begin = '{';
160const char Tmodule::end = '}';145const char Tmodule::end = '}';
161 146
@@ -164,14 +149,43 @@ sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Ttupl · 2 unmodified lines
164 return os << t._s;149 return os << t._s;
165}150}
166 151
167sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tadt &a)152sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tmodule &m)
168{153{
169 return os << a._s;154 return os << m._s;
170}155}
171 156
172sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tmodule &m)157const char *Tadt_pick_tag::tag_delim = "=>";
158
159Tadt_pick_tag Tadt_pick_tag::create(const char *pick_tag, uint32_t adt_ref, std::initializer_list<const Tm> tms)
173{160{
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
178sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, const Tadt_pick_tag &t)
179{
180 return os << t._s;
181}
182
183const char Tnested_aggregate_type<type_id_t::adt>::begin = '(';
184const char Tnested_aggregate_type<type_id_t::adt>::end = ')';
185
186sig_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;
175}189}
176 190
177sig_stream_t &disvm::assembly::sigkind::operator<<(sig_stream_t &os, Tfunction &f)191sig_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
261 261
262int main(int argc, char* argv[])262int main(int argc, char* argv[])
263{263{
264 exec_options options = {};264 exec_options options{};
265 265
266 try266 try
267 {267 {
src/include/vm_asm.h+109−28
@@ -30,11 +30,14 @@ namespace disvm · 29 unmodified lines
30 namespace sigkind30 namespace sigkind
31 {31 {
32 // Signature stream32 // Signature stream
33 class sig_stream_t33 class sig_stream_t final
34 {34 {
35 public: // static35 public: // static
36 static uint32_t compute_signature_hash(const char *);36 static uint32_t compute_signature_hash(const char *);
37 37
38 // Type delimiter
39 static const char delim = ',';
40
38 public:41 public:
39 std::string get_signature() const;42 std::string get_signature() const;
40 43
@@ -42,10 +45,11 @@ namespace disvm · 1 unmodified line
42 45
43 sig_stream_t &operator<<(const char);46 sig_stream_t &operator<<(const char);
44 sig_stream_t &operator<<(const char *);47 sig_stream_t &operator<<(const char *);
48 sig_stream_t &operator<<(const uint32_t);
45 sig_stream_t &operator<<(const sig_stream_t &);49 sig_stream_t &operator<<(const sig_stream_t &);
46 50
47 private:51 private:
48 std::stringstream _ss;52 mutable std::stringstream _ss;
49 };53 };
50 54
51 // Type context modifiers55 // Type context modifiers
@@ -55,12 +59,12 @@ namespace disvm · 3 unmodified lines
55 cycle = 'y',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 // Instrinsic VM types64 // Instrinsic VM types
61 enum class type_id_t : uint8_t65 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 none = 'n',68 none = 'n',
65 byte = 'b',69 byte = 'b',
66 integer = 'i',70 integer = 'i',
@@ -74,14 +78,14 @@ namespace disvm · 7 unmodified lines
74 list = 'L',78 list = 'L',
75 channel = 'C',79 channel = 'C',
76 adt = 'a',80 adt = 'a',
77 //adtpick = 'p',81 adt_pick_tag = 'p',
78 tuple = 't',82 tuple = 't',
79 module = 'm',83 module = 'm',
80 function = 'f',84 function = 'f',
81 function_varargs = 0xff, // "f*"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 template<type_id_t T>90 template<type_id_t T>
87 struct Tbasic_type91 struct Tbasic_type
@@ -102,7 +106,7 @@ namespace disvm · 14 unmodified lines
102 using Tstring = Tbasic_type<type_id_t::string>;106 using Tstring = Tbasic_type<type_id_t::string>;
103 using Tpoly = Tbasic_type<type_id_t::poly>;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 public:111 public:
108 Tfixed(double scale);112 Tfixed(double scale);
@@ -113,7 +117,7 @@ namespace disvm · 4 unmodified lines
113 const double _scale;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 // Type that contains/modifies another type122 // Type that contains/modifies another type
119 template <type_id_t ID>123 template <type_id_t ID>
@@ -141,14 +145,18 @@ namespace disvm · 21 unmodified lines
141 using Tlist = Tbasic_aggregate_type<type_id_t::list>;145 using Tlist = Tbasic_aggregate_type<type_id_t::list>;
142 using Tchannel = Tbasic_aggregate_type<type_id_t::channel>;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 &);148 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 &);149 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 &);150 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 &);151 sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tchannel &);
148 152
149 // Reference to another previously defined type in the current signature153 // Reference to another previously defined type in the current signature
150 struct Ttype_ref154 class Ttype_ref final
151 {155 {
156 public: // static
157 static const char id = '@';
158
159 public:
152 Ttype_ref(uint32_t num);160 Ttype_ref(uint32_t num);
153 161
154 friend sig_stream_t &operator<<(sig_stream_t &os, const Ttype_ref &);162 friend sig_stream_t &operator<<(sig_stream_t &os, const Ttype_ref &);
@@ -157,23 +165,25 @@ namespace disvm · 2 unmodified lines
157 const uint32_t _num;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 // Named member type170 // Named member type
163 struct Tm171 class Tm final
164 {172 {
165 Tm(const char *name, const type_id_t &type_id);173 public:
166 Tm(const char *name, const char *type_id);174 template <typename T>
175 Tm(const char *name, const T &type)
176 {
177 _s << name << ':' << type;
178 }
167 179
168 friend sig_stream_t &operator<<(sig_stream_t &os, const Tm &);180 friend sig_stream_t &operator<<(sig_stream_t &os, const Tm &);
169 181
170 private:182 private:
171 const char *_type_id_str;183 sig_stream_t _s;
172 const type_id_t _type_id;
173 const char *_name;
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 inline void nested_type(const sig_stream_t &)188 inline void nested_type(const sig_stream_t &)
179 {189 {
@@ -190,7 +200,7 @@ namespace disvm · 10 unmodified lines
190 template<typename T1, typename T2, typename ...S>200 template<typename T1, typename T2, typename ...S>
191 void nested_type(sig_stream_t &ss, const T1 &t1, const T2 &t2, const S&...s)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 nested_type(ss, t2, s...);204 nested_type(ss, t2, s...);
195 }205 }
196 206
@@ -198,7 +208,7 @@ namespace disvm · 1 unmodified line
198 template <type_id_t ID>208 template <type_id_t ID>
199 class Tnested_aggregate_type : public Tbasic_type<ID>209 class Tnested_aggregate_type : public Tbasic_type<ID>
200 {210 {
201 public:211 public: // static
202 static const char begin;212 static const char begin;
203 static const char end;213 static const char end;
204 214
@@ -215,26 +225,96 @@ namespace disvm · 10 unmodified lines
215 return Tnested_aggregate_type{ ss };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 friend sig_stream_t &operator<<(sig_stream_t &, const Tnested_aggregate_type &);233 friend sig_stream_t &operator<<(sig_stream_t &, const Tnested_aggregate_type &);
219 234
220 private:235 private:
221 sig_stream_t _s;236 sig_stream_t _s;
222 Tnested_aggregate_type(sig_stream_t &s) : _s{ std::move(s) } { }
223 };237 };
224 238
225 using Ttuple = Tnested_aggregate_type<type_id_t::tuple>;239 using Ttuple = Tnested_aggregate_type<type_id_t::tuple>;
226 using Tadt = Tnested_aggregate_type<type_id_t::adt>;
227 using Tmodule = Tnested_aggregate_type<type_id_t::module>;240 using Tmodule = Tnested_aggregate_type<type_id_t::module>;
228 241
229 sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Ttuple &);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 sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tmodule &);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 // Function type313 // Function type
234 template<type_id_t T>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 static const char begin = '(';318 static const char begin = '(';
239 static const char end = ')';319 static const char end = ')';
240 320
@@ -250,6 +330,7 @@ namespace disvm · 9 unmodified lines
250 return a;330 return a;
251 }331 }
252 332
333 public:
253 template<typename RT>334 template<typename RT>
254 Tfunction_base_type &returns(RT r)335 Tfunction_base_type &returns(RT r)
255 {336 {