From 22be995eefbf6e27f76606226422aaf3fbaa5b80 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 5 Sep 2012 21:44:57 +0200 Subject: [PATCH] added type description class --- src/loader/TypeDescription.cpp | 81 ++++++++++++++++++++++++++++++++++ src/loader/TypeDescription.h | 75 +++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 src/loader/TypeDescription.cpp create mode 100644 src/loader/TypeDescription.h diff --git a/src/loader/TypeDescription.cpp b/src/loader/TypeDescription.cpp new file mode 100644 index 0000000..c69efbe --- /dev/null +++ b/src/loader/TypeDescription.cpp @@ -0,0 +1,81 @@ +/* + * TypeDescription.cpp + * + * Created on: Sep 4, 2012 + * Author: holy + */ + +#include "TypeDescription.h" + +#include +#include + +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::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 Interpreter::typeDescriptions; + +TypeDescription &TypeDescription::CreateOrGet(const std::string &name) { + for (vector::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::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 index 0000000..0107039 --- /dev/null +++ b/src/loader/TypeDescription.h @@ -0,0 +1,75 @@ +/* + * TypeDescription.h + * + * Created on: Sep 4, 2012 + * Author: holy + */ + +#ifndef LOADER_TYPEDESCRIPTION_H_ +#define LOADER_TYPEDESCRIPTION_H_ + +#include +#include +#include +#include + +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 fields; + std::map supertypes; + int id; + int size; + + static std::vector typeDescriptions; + +}; + +} + +#endif /* LOADER_TYPEDESCRIPTION_H_ */ -- 2.39.2