summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-12 15:32:51 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-12 15:32:51 +0100
commit29355270d36994b6a33d05bcc1f9a142818a325e (patch)
tree5b954dab34f288a477cedbb86beff775b980cbb0
parent3a86b9dbe2c98c32f08942b07354a0361e8bafdb (diff)
Added new version of Typesystem in cooperation with Andreas.
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/core/Typesystem.cpp78
-rw-r--r--src/core/Typesystem.hpp232
-rw-r--r--src/core/common/Variant.hpp18
-rw-r--r--src/core/model/Typesystem.cpp45
-rw-r--r--src/core/model/Typesystem.hpp381
6 files changed, 445 insertions, 311 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 64285d1..739acd2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,13 +106,13 @@ ADD_LIBRARY(ousia_core
src/core/Registry
src/core/ResourceLocator
src/core/Tokenizer
-# src/core/Typesystem
src/core/common/CharReader
src/core/common/Exceptions
src/core/common/Logger
src/core/common/Utils
src/core/common/Variant
src/core/common/VariantReader
+ src/core/model/Typesystem
src/core/parser/Parser
src/core/parser/ParserStack
src/core/parser/Scope
diff --git a/src/core/Typesystem.cpp b/src/core/Typesystem.cpp
deleted file mode 100644
index a9ef61f..0000000
--- a/src/core/Typesystem.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- Ousía
- Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <unordered_map>
-#include <sstream>
-
-#include "CodeTokenizer.hpp"
-#include "Typesystem.hpp"
-
-namespace ousia {
-
-/* Class EnumType */
-
-EnumType::EnumType(Manager &mgr, const std::set<std::string> &names) :
- Type(mgr, false, true)
-{
- int value = 0;
- for (const auto &name: names) {
- values.insert(std::make_pair(name, value++))
- }
-}
-
-int EnumType::valueOf(const std::string &name)
-{
- auto it = values.find(name);
- if (it != values.end()) {
- return it->second;
- }
- return -1;
-}
-
-std::string EnumType::toString(int value) {
- for (const auto &p : values) {
- if (p->second == value) {
- return p->first;
- }
- }
- return std::string{};
-}
-
-/* Class Typesystem */
-
-void Typesystem::doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx,
- VisitorSet &visited)
-{
- // Try to resolve the given name as a type
- for (auto n: types) {
- n->resolve(res, path, filter, filterData, idx, visited, nullptr);
- }
-
- // Try to resolve the given name as a constant
- const auto it = constants.find(path[idx]);
- if (it != constants.cend()) {
- if (filter && filter(it->second, filterData)) {
- res.push_back(it->second);
- }
- }
-}
-
-}
-
diff --git a/src/core/Typesystem.hpp b/src/core/Typesystem.hpp
deleted file mode 100644
index 8ef3072..0000000
--- a/src/core/Typesystem.hpp
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- Ousía
- Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _OUSIA_TYPESYSTEM_HPP_
-#define _OUSIA_TYPESYSTEM_HPP_
-
-#include <string>
-#include <vector>
-
-#include "BufferedCharReader.hpp"
-#include "Managed.hpp"
-#include "Node.hpp"
-
-namespace ousia {
-
-class Typesystem;
-class Type;
-class StringType;
-
-/**
- * The TypeInstance class represents an instance of a certain type variable:
- * Wheras Type only describes the type of an TypeInstance in an abstract manner,
- * TypeInstance represents an instance of that type.
- */
-class TypeInstance : public Managed {
-public:
- /**
- * Reference to the underlying Type which describes this type instance.
- */
- const Owned<Type> type;
-
- /**
- * Constructor of the TypeInstance class.
- *
- * @param mgr is a reference to the Manager class which manages this object.
- * @param type is a reference to the type this TypeInstance instance is an
- * instance of.
- */
- TypeInstance(Manager &mgr, Handle<Type> type)
- : Managed(mgr), type(acquire(type))
- {
- }
-};
-
-/**
- * Type is an abstract describtion of a type class in the type system. The type
- * class can be used to instantiate instances of the corresponding type.
- */
-class Type : public Node {
-public:
- /**
- * True, if the type cannot be extended.
- */
- const bool isFinal;
-
- /**
- * True, if the type represents a primitive type, such as an integer,
- * doubles, enums and string.
- */
- const bool isPrimitive;
-
- /**
- * Constructor of the Type class.
- *
- * @param mgr is a reference at the underlying node manager.
- * @param bool isFinal specifies whether this type is final.
- * @param bool isPrimitive specifies whether this type is primitive.
- * @param name specifies the internal name of the type.
- * @param typesystem specifies the parent type system.
- */
- Type(Manager &mgr, bool isFinal, bool isPrimitive, std::string name,
- Handle<Typesystem> typesystem = nullptr)
- : Node(mgr, std::move(name), typesystem),
- isFinal(isFinal),
- isPrimitive(isPrimitive)
- {
- }
-
- /**
- * Virtual destructor.
- */
- virtual ~Type(){};
-
- /**
- * Creates a new instance of this type. All values of this type are
- * initialized to default values.
- *
- * @return a new instance of this type.
- */
- // virtual Rooted<TypeInstance> create() = 0;
-
- /**
- * Parses the given string and produces a new instance of the given type.
- *
- * TODO: Add error handler
- *
- * @param str is the string which should be parsed.
- */
- // virtual Rooted<TypeInstance> parse(BufferedCharReader &reader) = 0;
-};
-
-/**
- * Type which is used to represent a string.
- */
-class StringType : public Type {
-public:
- StringType(Manager &mgr, Handle<Typesystem> typesystem)
- : Type(mgr, true, true, "string", typesystem){};
-};
-
-/**
- * Type which is used to represent an integer.
- */
-class IntegerType : public Type {
-public:
- IntegerType(Manager &mgr, Handle<Typesystem> typesystem)
- : Type(mgr, true, true, "int", typesystem){};
-};
-
-/**
- * Type which is used to represent a double.
- */
-class DoubleType : public Type {
-public:
- DoubleType(Manager &mgr, Handle<Typesystem> typesystem)
- : Type(mgr, true, true, "double", typesystem){};
-};
-
-/**
- * Type which represents a enum.
- */
-class EnumType : public Type {
-private:
- std::map<std::string, int> values;
-
-public:
- EnumType(Manager &mgr, std::string name, Handle<Typesystem> typesystem,
- const std::set<std::string> &names);
-
- /**
- * Returns the integer value associated to the given name.
- *
- * @param name is the name of the value that should be looked up.
- * @return the (non-negative) value associated to the given name or -1 if
- * the value does not exist.
- */
- int valueOf(const std::string &name);
-
- /**
- * Returns the name corresponding to the given enum value or an empty string
- * instead.
- *
- * @param value is the integer representation of an enum value that should
- * be converted to the corresponding string.
- * @return the string corresponding to the enum value or an empty string if
- * no entry with such a value exists.
- */
- std::string toString(int value);
-};
-
-/**
- * Type which represents an array.
- */
-class ArrayType : public Type {
-public:
- const Owned<Type> innerType;
-
- ArrayType(Manager &mgr, std::string name, Handle<Typesystem> typesystem,
- Handle<Type> innerType)
- : Type(mgr, false, true, name, typesystem),
- innerType(acquire(innerType)){};
-};
-
-/**
- * Type which represents a structure of other types.
- */
-class StructType : public Type {
-private:
- std::map<std::string, Type> entries;
-
- StructType(Manager)
-}
-
-class Typesystem : public Node {
-private:
- NodeVector<Type> types;
- ManagedMap<std::string, TypeInstance> constants;
-
-protected:
- void doResolve(std::vector<Rooted<Managed>> &res,
- const std::vector<std::string> &path, Filter filter,
- void *filterData, unsigned idx,
- VisitorSet &visited) override;
-
-public:
- using Node::Node;
-
- Typesystem(Manager &mgr) : Node(mgr), types(this), constants(this) {}
-
- const NodeVector<Type> &getTypes() { return types; }
-
- const ManagedMap<std::string, TypeInstance> &getConstants()
- {
- return constants;
- }
-
- void addType(Handle<Type> type) { types.push_back(type); }
-
- void addConstant(const std::string &name, Handle<TypeInstance> instance)
- {
- constants.insert(std::make_pair(name, instance));
- }
-};
-}
-
-#endif /* _OUSIA_TYPESYSTEM_HPP_ */
-
diff --git a/src/core/common/Variant.hpp b/src/core/common/Variant.hpp
index d411fd3..c57ef57 100644
--- a/src/core/common/Variant.hpp
+++ b/src/core/common/Variant.hpp
@@ -434,6 +434,24 @@ public:
bool isMap() const { return type == Type::MAP; }
/**
+ * Checks whether this Variant instance is a primitive type.
+ *
+ * @return true if the Variant instance is a primitive type.
+ */
+ bool isPrimitive() const {
+ switch(type){
+ case Type::NULLPTR:
+ case Type::BOOL:
+ case Type::INT:
+ case Type::DOUBLE:
+ case Type::STRING:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ /**
* Returns the Variant boolean value. Performs no type conversion. Throws an
* exception if the underlying type is not a boolean.
*
diff --git a/src/core/model/Typesystem.cpp b/src/core/model/Typesystem.cpp
new file mode 100644
index 0000000..f3c49dc
--- /dev/null
+++ b/src/core/model/Typesystem.cpp
@@ -0,0 +1,45 @@
+/*
+ Ousía
+ Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Typesystem.hpp"
+
+#include <core/common/Utils.hpp>
+
+namespace ousia {
+namespace model {
+
+EnumerationType EnumerationType::createValidated(
+ Manager &mgr, std::string name, Handle<Typesystem> system,
+ const std::vector<std::string> &values, Logger &logger)
+{
+ std::map<std::string, size_t> unique_values;
+ for (size_t i = 0; i < values.size(); i++) {
+ if (!Utils::isIdentifier(values[i])) {
+ logger.error(values[i] + " is no valid identifier.");
+ }
+
+ if (!(unique_values.insert(std::make_pair(values[i], i))).second) {
+ logger.error(std::string("The value ") + values[i] +
+ " was duplicated.");
+ }
+ }
+ return std::move(EnumerationType(mgr, name, system, unique_values));
+}
+}
+}
+
diff --git a/src/core/model/Typesystem.hpp b/src/core/model/Typesystem.hpp
new file mode 100644
index 0000000..77a862b
--- /dev/null
+++ b/src/core/model/Typesystem.hpp
@@ -0,0 +1,381 @@
+/*
+ Ousía
+ Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file Typesystem.hpp
+ *
+ * TODO: Docu
+ *
+ * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de)
+ */
+
+#ifndef _OUSIA_MODEL_TYPESYSTEM_HPP_
+#define _OUSIA_MODEL_TYPESYSTEM_HPP_
+
+#include <map>
+#include <vector>
+
+#include <core/ManagedContainers.hpp>
+#include <core/Node.hpp>
+#include <core/common/Exceptions.hpp>
+#include <core/common/Logger.hpp>
+#include <core/common/Variant.hpp>
+
+namespace ousia {
+namespace model {
+
+class Typesystem;
+
+class Type : public Node {
+protected:
+ Type(Manager &mgr, std::string name, Handle<Typesystem> system,
+ bool inheritable, bool primitive)
+ : Node(mgr, std::move(name), system),
+ inheritable(inheritable),
+ primitive(primitive)
+ {
+ }
+
+ virtual bool doPrepare(Variant &var, Logger &log) = 0;
+
+public:
+ /**
+ * TODO: DOC
+ */
+ const bool inheritable;
+ /**
+ * TODO: DOC
+ */
+ const bool primitive;
+
+ /**
+ * TODO: DOC
+ */
+ virtual Variant create() = 0;
+
+ /**
+ * TODO: DOC
+ */
+ bool prepare(Variant &var, Logger &log)
+ {
+ try {
+ return doPrepare(var, log);
+ }
+ catch (LoggableException ex) {
+ log.log(ex);
+ var = create();
+ return false;
+ }
+ }
+};
+
+class StringType : public Type {
+protected:
+ /**
+ * TODO: DOC
+ */
+ bool doPrepare(Variant &var, Logger &log) override
+ {
+ if (!var.isPrimitive()) {
+ throw LoggableException{"Expected a string or primitive input."};
+ }
+
+ if (!var.isString()) {
+ log.note(std::string("Implicit type conversion from ") +
+ var.getTypeName() + " to string.");
+ }
+ var = Variant{var.toString().c_str()};
+ return true;
+ }
+
+public:
+ /**
+ * TODO: DOC
+ */
+ StringType(Manager &mgr, Handle<Typesystem> system)
+ : Type(mgr, "string", system, false, true)
+ {
+ }
+
+ /**
+ * TODO: DOC
+ */
+ Variant create() override { return Variant{""}; }
+};
+
+class IntType : public Type {
+protected:
+ /**
+ * TODO: DOC
+ */
+ bool doPrepare(Variant &var, Logger &log) override
+ {
+ if (!var.isInt()) {
+ throw LoggableException{"Expected an integer value."};
+ }
+ return true;
+ }
+
+public:
+ /**
+ * TODO: DOC
+ */
+ IntType(Manager &mgr, Handle<Typesystem> system)
+ : Type(mgr, "int", system, false, true)
+ {
+ }
+
+ /**
+ * TODO: DOC
+ */
+ Variant create() override { return Variant{0}; }
+};
+
+class DoubleType : public Type {
+protected:
+ /**
+ * TODO: DOC
+ */
+ bool doPrepare(Variant &var, Logger &log) override
+ {
+ if (!var.isInt() && !var.isDouble()) {
+ throw LoggableException{"Expected a double value."};
+ }
+ var = Variant{var.toDouble()};
+ return true;
+ }
+
+public:
+ /**
+ * TODO: DOC
+ */
+ DoubleType(Manager &mgr, Handle<Typesystem> system)
+ : Type(mgr, "double", system, false, true)
+ {
+ }
+
+ /**
+ * TODO: DOC
+ */
+ Variant create() override { return Variant{0.}; }
+};
+
+class UnknownType : public Type {
+protected:
+ /**
+ * TODO: DOC
+ */
+ bool doPrepare(Variant &var, Logger &log) override { return true; }
+
+public:
+ /**
+ * TODO: DOC
+ */
+ UnknownType(Manager &mgr, Handle<Typesystem> system)
+ : Type(mgr, "unknown", system, false, true)
+ {
+ }
+
+ /**
+ * TODO: DOC
+ */
+ Variant create() override { return Variant{nullptr}; }
+};
+
+class BoolType : public Type {
+protected:
+ /**
+ * TODO: DOC
+ */
+ bool doPrepare(Variant &var, Logger &log) override
+ {
+ if (!var.isBool()) {
+ throw LoggableException("Expected boolean value!");
+ }
+ return true;
+ }
+
+public:
+ /**
+ * TODO: DOC
+ */
+ BoolType(Manager &mgr, Handle<Typesystem> system)
+ : Type(mgr, "bool", system, false, true)
+ {
+ }
+
+ /**
+ * TODO: DOC
+ */
+ Variant create() override { return Variant{false}; }
+};
+
+class EnumerationType : public Type {
+private:
+ std::map<std::string, size_t> values;
+
+protected:
+ /**
+ * TODO: DOC
+ */
+ bool doPrepare(Variant &var, Logger &log) override
+ {
+ if (var.isInt()) {
+ int i = var.asInt();
+ if (i < 0 || i >= (int)values.size()) {
+ throw LoggableException("Value is out of range.");
+ }
+ } else if (var.isString()) {
+ }
+
+ return true;
+ }
+
+ EnumerationType(Manager &mgr, std::string name, Handle<Typesystem> system,
+ std::map<std::string, size_t> values)
+ : Type(mgr, std::move(name), system, false, false),
+ values(std::move(values))
+ {
+ }
+
+public:
+ /**
+ * TODO: DOC
+ */
+ EnumerationType(Manager &mgr, std::string name, Handle<Typesystem> system,
+ const std::vector<std::string> &values)
+ : Type(mgr, std::move(name), system, false, false)
+ {
+ for (size_t i = 0; i < values.size(); i++) {
+ this->values.insert(std::make_pair(values[i], i));
+ }
+ }
+
+ /**
+ * TODO: DOC
+ */
+ static EnumerationType createValidated(
+ Manager &mgr, std::string name, Handle<Typesystem> system,
+ const std::vector<std::string> &values, Logger &logger);
+
+ /**
+ * TODO: DOC
+ */
+ Variant create() override { return Variant{0}; }
+};
+
+class StructType : public Type {
+public:
+ struct AttributeDescriptor {
+ const std::string name;
+ const Variant defaultValue;
+ const bool optional;
+ const Owned<Type> type;
+
+ AttributeDescriptor(std::string name, Variant defaultValue,
+ bool optional, Owned<Type> type)
+ : name(name),
+ defaultValue(defaultValue),
+ optional(optional),
+ type(type)
+ {
+ }
+ };
+
+private:
+ std::vector<AttributeDescriptor> attrs;
+
+ StructType(Manager &mgr, std::string name, Handle<Typesystem> system,
+ std::vector<AttributeDescriptor> attrs)
+ : Type(mgr, std::move(name), system, true, false),
+ attrs(std::move(attrs))
+ {
+ }
+
+public:
+ // TODO
+ // static StructType createValidated(
+ // Manager &mgr, std::string name, Handle<Typesystem> system,
+ // Handle<StructType> parent,
+ // const std::vector<AttributeDescriptor> &attrs, Logger &logger);
+
+ Variant create() override { return Variant{Variant::arrayType{}}; }
+};
+
+class ArrayType : public Type {
+private:
+ Owned<Type> innerType;
+
+protected:
+ /**
+ * TODO: DOC
+ */
+ bool doPrepare(Variant &var, Logger &log) override
+ {
+ if (!var.isArray()) {
+ throw LoggableException("Expected array!");
+ }
+ bool res = true;
+ for (auto &v : var.asArray()) {
+ if (!innerType->prepare(v, log)) {
+ res = false;
+ }
+ }
+
+ return res;
+ }
+
+public:
+ /**
+ * TODO: DOC
+ */
+ ArrayType(Manager &mgr, std::string name, Handle<Typesystem> system,
+ Handle<Type> innerType)
+ : Type(mgr, std::move(name), system, false, false),
+ innerType(acquire(innerType))
+ {
+ }
+
+ /**
+ * TODO: DOC
+ */
+ Variant create() override { return Variant{Variant::arrayType{}}; }
+
+ Rooted<Type> getType() { return innerType; }
+};
+
+class Typesystem : public Node {
+private:
+ ManagedVector<Type> types;
+
+public:
+ Typesystem(Manager &mgr, std::string name, Handle<Node> parent = nullptr)
+ : Node(mgr, name, parent), types(this)
+ {
+ }
+
+ /**
+ * TODO: DOC
+ */
+ void addType(Handle<Type> type) { types.push_back(type); }
+};
+}
+}
+
+#endif /* _OUSIA_MODEL_TYPESYSTEM_HPP_ */
+