Showing the changes to src/include (1 of 10 files). Show all
Unified · Split
| @@ -8,6 +8,9 @@ · 7 unmodified lines | ||
| 8 | 8 | #define _DISVM_SRC_INCLUDE_VM_ASM_H_ |
| 9 | 9 | |
| 10 | 10 | #include <iosfwd> |
| 11 | +#include <sstream> | |
| 12 | +#include <cassert> | |
| 13 | +#include <cstdint> | |
| 11 | 14 | #include "opcodes.h" |
| 12 | 15 | #include "runtime.h" |
| 13 | 16 | |
| @@ -21,6 +24,259 @@ namespace disvm · 7 unmodified lines | ||
| 21 | 24 | // Get the opcode from this string. |
| 22 | 25 | // If the supplied string cannot be resolved or if it is null, the 'invalid' opcode is returned. |
| 23 | 26 | disvm::opcode_t token_to_opcode(const char *); |
| 27 | + | |
| 28 | + // Namedspace named after enum type in Limbo compiler | |
| 29 | + // Source: limbo/types.c | |
| 30 | + namespace sigkind | |
| 31 | + { | |
| 32 | + // Signature stream | |
| 33 | + class sig_stream_t | |
| 34 | + { | |
| 35 | + public: // static | |
| 36 | + static uint32_t compute_signature_hash(const char *); | |
| 37 | + | |
| 38 | + public: | |
| 39 | + std::string get_signature() const; | |
| 40 | + | |
| 41 | + uint32_t get_signature_hash() const; | |
| 42 | + | |
| 43 | + sig_stream_t &operator<<(const char); | |
| 44 | + sig_stream_t &operator<<(const char *); | |
| 45 | + sig_stream_t &operator<<(const sig_stream_t &); | |
| 46 | + | |
| 47 | + private: | |
| 48 | + std::stringstream _ss; | |
| 49 | + }; | |
| 50 | + | |
| 51 | + // Type context modifiers | |
| 52 | + enum class modifier_id_t : uint8_t | |
| 53 | + { | |
| 54 | + self = 'S', | |
| 55 | + cycle = 'y', | |
| 56 | + }; | |
| 57 | + | |
| 58 | + sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::modifier_id_t &); | |
| 59 | + | |
| 60 | + // Instrinsic VM types | |
| 61 | + enum class type_id_t : uint8_t | |
| 62 | + { | |
| 63 | + unknown = 0, | |
| 64 | + none = 'n', | |
| 65 | + byte = 'b', | |
| 66 | + integer = 'i', | |
| 67 | + real = 'r', | |
| 68 | + big = 'B', | |
| 69 | + string = 's', | |
| 70 | + poly = 'P', | |
| 71 | + fixed = 'x', | |
| 72 | + array = 'A', | |
| 73 | + ref = 'R', | |
| 74 | + list = 'L', | |
| 75 | + channel = 'C', | |
| 76 | + adt = 'a', | |
| 77 | + //adtpick = 'p', | |
| 78 | + tuple = 't', | |
| 79 | + module = 'm', | |
| 80 | + function = 'f', | |
| 81 | + function_varargs = 0xff, // "f*" | |
| 82 | + }; | |
| 83 | + | |
| 84 | + sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::type_id_t &); | |
| 85 | + | |
| 86 | + template<type_id_t T> | |
| 87 | + struct Tbasic_type | |
| 88 | + { | |
| 89 | + static const type_id_t id = T; | |
| 90 | + | |
| 91 | + constexpr operator type_id_t() const | |
| 92 | + { | |
| 93 | + return Tbasic_type::id; | |
| 94 | + } | |
| 95 | + }; | |
| 96 | + | |
| 97 | + using Tnone = Tbasic_type<type_id_t::none>; | |
| 98 | + using Tbyte = Tbasic_type<type_id_t::byte>; | |
| 99 | + using Tinteger = Tbasic_type<type_id_t::integer>; | |
| 100 | + using Treal = Tbasic_type<type_id_t::real>; | |
| 101 | + using Tbig = Tbasic_type<type_id_t::big>; | |
| 102 | + using Tstring = Tbasic_type<type_id_t::string>; | |
| 103 | + using Tpoly = Tbasic_type<type_id_t::poly>; | |
| 104 | + | |
| 105 | + class Tfixed : public Tbasic_type<type_id_t::fixed> | |
| 106 | + { | |
| 107 | + public: | |
| 108 | + Tfixed(double scale); | |
| 109 | + | |
| 110 | + friend sig_stream_t &operator<<(sig_stream_t &os, const Tfixed &); | |
| 111 | + | |
| 112 | + private: | |
| 113 | + const double _scale; | |
| 114 | + }; | |
| 115 | + | |
| 116 | + sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tfixed &); | |
| 117 | + | |
| 118 | + // Type that contains/modifies another type | |
| 119 | + template <type_id_t ID> | |
| 120 | + class Tbasic_aggregate_type : public Tbasic_type<ID> | |
| 121 | + { | |
| 122 | + public: | |
| 123 | + template<typename U> | |
| 124 | + static Tbasic_aggregate_type create(const U &type) | |
| 125 | + { | |
| 126 | + sig_stream_t ss; | |
| 127 | + ss << Tbasic_type::id << type; | |
| 128 | + | |
| 129 | + return Tbasic_aggregate_type{ ss }; | |
| 130 | + } | |
| 131 | + | |
| 132 | + friend sig_stream_t &operator<<(sig_stream_t &, const Tbasic_aggregate_type &); | |
| 133 | + | |
| 134 | + private: | |
| 135 | + sig_stream_t _s; | |
| 136 | + Tbasic_aggregate_type(sig_stream_t &s) : _s{ std::move(s) } { } | |
| 137 | + }; | |
| 138 | + | |
| 139 | + using Tarray = Tbasic_aggregate_type<type_id_t::array>; | |
| 140 | + using Tref = Tbasic_aggregate_type<type_id_t::ref>; | |
| 141 | + using Tlist = Tbasic_aggregate_type<type_id_t::list>; | |
| 142 | + using Tchannel = Tbasic_aggregate_type<type_id_t::channel>; | |
| 143 | + | |
| 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 | + | |
| 149 | + // Reference to another previously defined type in the current signature | |
| 150 | + struct Ttype_ref | |
| 151 | + { | |
| 152 | + Ttype_ref(uint32_t num); | |
| 153 | + | |
| 154 | + friend sig_stream_t &operator<<(sig_stream_t &os, const Ttype_ref &); | |
| 155 | + | |
| 156 | + private: | |
| 157 | + const uint32_t _num; | |
| 158 | + }; | |
| 159 | + | |
| 160 | + sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Ttype_ref &); | |
| 161 | + | |
| 162 | + // Named member type | |
| 163 | + struct Tm | |
| 164 | + { | |
| 165 | + Tm(const char *name, const type_id_t &type_id); | |
| 166 | + Tm(const char *name, const char *type_id); | |
| 167 | + | |
| 168 | + friend sig_stream_t &operator<<(sig_stream_t &os, const Tm &); | |
| 169 | + | |
| 170 | + private: | |
| 171 | + const char *_type_id_str; | |
| 172 | + const type_id_t _type_id; | |
| 173 | + const char *_name; | |
| 174 | + }; | |
| 175 | + | |
| 176 | + sig_stream_t & operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tm &); | |
| 177 | + | |
| 178 | + inline void nested_type(const sig_stream_t &) | |
| 179 | + { | |
| 180 | + return; | |
| 181 | + } | |
| 182 | + | |
| 183 | + template<typename T, typename ...S> | |
| 184 | + void nested_type(sig_stream_t &ss, const T &t, const S&...s) | |
| 185 | + { | |
| 186 | + ss << t; | |
| 187 | + nested_type(ss, s...); | |
| 188 | + } | |
| 189 | + | |
| 190 | + template<typename T1, typename T2, typename ...S> | |
| 191 | + void nested_type(sig_stream_t &ss, const T1 &t1, const T2 &t2, const S&...s) | |
| 192 | + { | |
| 193 | + ss << t1 << ','; | |
| 194 | + nested_type(ss, t2, s...); | |
| 195 | + } | |
| 196 | + | |
| 197 | + // Type whose definition depends on contained types | |
| 198 | + template <type_id_t ID> | |
| 199 | + class Tnested_aggregate_type : public Tbasic_type<ID> | |
| 200 | + { | |
| 201 | + public: | |
| 202 | + static const char begin; | |
| 203 | + static const char end; | |
| 204 | + | |
| 205 | + template<typename ...NT> | |
| 206 | + static Tnested_aggregate_type create(const NT&... nestedTypes) | |
| 207 | + { | |
| 208 | + sig_stream_t ss; | |
| 209 | + ss << Tbasic_type::id << Tnested_aggregate_type::begin; | |
| 210 | + | |
| 211 | + nested_type(ss, nestedTypes...); | |
| 212 | + | |
| 213 | + ss << Tnested_aggregate_type::end; | |
| 214 | + | |
| 215 | + return Tnested_aggregate_type{ ss }; | |
| 216 | + } | |
| 217 | + | |
| 218 | + friend sig_stream_t &operator<<(sig_stream_t &, const Tnested_aggregate_type &); | |
| 219 | + | |
| 220 | + private: | |
| 221 | + sig_stream_t _s; | |
| 222 | + Tnested_aggregate_type(sig_stream_t &s) : _s{ std::move(s) } { } | |
| 223 | + }; | |
| 224 | + | |
| 225 | + 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>; | |
| 228 | + | |
| 229 | + 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 &); | |
| 232 | + | |
| 233 | + // Function type | |
| 234 | + template<type_id_t T> | |
| 235 | + class Tfunction_base_type : public Tbasic_type<T> | |
| 236 | + { | |
| 237 | + public: | |
| 238 | + static const char begin = '('; | |
| 239 | + static const char end = ')'; | |
| 240 | + | |
| 241 | + template<typename ...AT> | |
| 242 | + static Tfunction_base_type create(AT... argTypes) | |
| 243 | + { | |
| 244 | + Tfunction_base_type a; | |
| 245 | + a._s << Tfunction_base_type::id << Tfunction_base_type::begin; | |
| 246 | + | |
| 247 | + nested_type(a._s, argTypes...); | |
| 248 | + | |
| 249 | + a._s << Tfunction_base_type::end; | |
| 250 | + return a; | |
| 251 | + } | |
| 252 | + | |
| 253 | + template<typename RT> | |
| 254 | + Tfunction_base_type &returns(RT r) | |
| 255 | + { | |
| 256 | + assert(!_fully_defined && "Function type already complete"); | |
| 257 | + _s << r; | |
| 258 | + _fully_defined = true; | |
| 259 | + | |
| 260 | + return *this; | |
| 261 | + } | |
| 262 | + | |
| 263 | + friend sig_stream_t &operator<<(sig_stream_t &, Tfunction_base_type &); | |
| 264 | + friend sig_stream_t &operator<<(sig_stream_t &, const Tfunction_base_type &); | |
| 265 | + | |
| 266 | + private: | |
| 267 | + bool _fully_defined; | |
| 268 | + sig_stream_t _s; | |
| 269 | + Tfunction_base_type() : _fully_defined{ false } { } | |
| 270 | + }; | |
| 271 | + | |
| 272 | + using Tfunction = Tfunction_base_type<type_id_t::function>; | |
| 273 | + using Tfunction_varargs = Tfunction_base_type<type_id_t::function_varargs>; | |
| 274 | + | |
| 275 | + sig_stream_t &operator<<(sig_stream_t &, disvm::assembly::sigkind::Tfunction &); | |
| 276 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tfunction &); | |
| 277 | + sig_stream_t &operator<<(sig_stream_t &, disvm::assembly::sigkind::Tfunction_varargs &); | |
| 278 | + sig_stream_t &operator<<(sig_stream_t &, const disvm::assembly::sigkind::Tfunction_varargs &); | |
| 279 | + } | |
| 24 | 280 | } |
| 25 | 281 | |
| 26 | 282 | namespace runtime |