--- /dev/null
+/*
+ * TypeDescription.cpp
+ *
+ * Created on: Sep 4, 2012
+ * Author: holy
+ */
+
+#include "TypeDescription.h"
+
+#include <cassert>
+#include <stdexcept>
+
+using std::map;
+using std::string;
+using std::vector;
+
+namespace loader {
+
+void TypeDescription::AddField(const std::string &n, const FieldDescription &f) {
+ if (HasField(n)) {
+ throw std::invalid_argument("duplicate definition of field " + n + " of type " + name);
+ } else {
+ fields.insert(std::make_pair(n, f));
+ }
+}
+
+bool TypeDescription::HasField(const std::string &name) const {
+ return fields.count(name);
+}
+
+const FieldDescription &TypeDescription::GetField(const std::string &n) const {
+ map<string, FieldDescription>::const_iterator result(fields.find(n));
+ if (result != fields.end()) {
+ return result->second;
+ } else {
+ throw std::invalid_argument("undefined field " + n + " of type " + name);
+ }
+}
+
+
+void TypeDescription::AddSupertype(int id, std::ptrdiff_t offset) {
+ supertypes[id] = offset;
+}
+
+bool TypeDescription::IsSubtypeOf(int id) const {
+ return supertypes.count(id);
+}
+
+std::ptrdiff_t TypeDescription::SupertypeOffset(int id) const {
+ return supertypes.at(id);
+}
+
+
+vector<TypeDescription> Interpreter::typeDescriptions;
+
+TypeDescription &TypeDescription::CreateOrGet(const std::string &name) {
+ for (vector<TypeDescription>::const_iterator i(typeDescriptions.begin()), end(typeDescriptions.end()); i != end; ++i) {
+ if (i->name == name) {
+ return *i;
+ }
+ }
+ typeDescriptions.push_back(TypeDescription(typeDescriptions.size(), name));
+ return typeDescriptions.back();
+}
+
+int TypeDescription::GetTypeId(const std::string &name) {
+ for (vector<TypeDescription>::size_type i(0), end(typeDescriptions.size()); i < end; ++i) {
+ if (typeDescriptions[i].name == name) {
+ return i;
+ }
+ }
+ typeDescriptions.push_back(TypeDescription(typeDescriptions.size(), name));
+ return typeDescriptions.size() - 1;
+}
+
+const TypeDescription &TypeDescription::Get(int id) {
+ assert(id >= 0 && id < typeDescriptions.size());
+ return typeDescriptions[id];
+}
+
+}
--- /dev/null
+/*
+ * TypeDescription.h
+ *
+ * Created on: Sep 4, 2012
+ * Author: holy
+ */
+
+#ifndef LOADER_TYPEDESCRIPTION_H_
+#define LOADER_TYPEDESCRIPTION_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace loader {
+
+class FieldDescription {
+
+public:
+ FieldDescription(std::ptrdiff_t offset, int type, bool reference = true, bool aggregate = false)
+ : offset(offset), type(type), reference(reference), aggregate(aggregate) { }
+
+ std::ptrdiff_t Offset() const { return offset; };
+ int TypeId() const { return type; }
+ bool IsReferenced() const { return reference; }
+ bool IsAggregate() const { return aggregate; }
+
+private:
+ std::ptrdiff_t offset;
+ int type;
+ bool reference;
+ bool aggregate;
+};
+
+class TypeDescription {
+
+public:
+ void AddField(const std::string &name, const FieldDescription &f);
+ bool HasField(const std::string &name) const;
+ const FieldDescription &GetField(const std::string &name) const;
+
+ void AddSupertype(int id, std::ptrdiff_t offset);
+ bool IsSubtypeOf(int id) const;
+ bool IsSubtypeOf(const TypeDescription &other) const { return IsSubtypeOf(other.TypeId()); }
+ std::ptrdiff_t SupertypeOffset(int id) const;
+ std::ptrdiff_t SupertypeOffset(const TypeDescription &other) const { return SupertypeOffset(other.TypeId()); }
+
+ int TypeId() const { return id; }
+ const std::string &TypeName() const { return name; }
+
+ void SetSize(int s) { size = s; }
+ int Size() const { return size; }
+
+ static TypeDescription &CreateOrGet(const std::string &name);
+ static int GetTypeId(const std::string &);
+ static const TypeDescription &Get(int id);
+
+private:
+ TypeDescription(int id, const std::string &name) : name(name), id(id), size(0) { }
+
+private:
+ std::string name;
+ std::map<std::string, FieldDescription> fields;
+ std::map<int, std::ptrdiff_t> supertypes;
+ int id;
+ int size;
+
+ static std::vector<TypeDescription> typeDescriptions;
+
+};
+
+}
+
+#endif /* LOADER_TYPEDESCRIPTION_H_ */