]> git.localhorst.tv Git - l2e.git/commitdiff
added type description class
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 5 Sep 2012 19:44:57 +0000 (21:44 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 5 Sep 2012 19:44:57 +0000 (21:44 +0200)
src/loader/TypeDescription.cpp [new file with mode: 0644]
src/loader/TypeDescription.h [new file with mode: 0644]

diff --git a/src/loader/TypeDescription.cpp b/src/loader/TypeDescription.cpp
new file mode 100644 (file)
index 0000000..c69efbe
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * 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];
+}
+
+}
diff --git a/src/loader/TypeDescription.h b/src/loader/TypeDescription.h
new file mode 100644 (file)
index 0000000..0107039
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * 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_ */