summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-11-21 21:02:48 +0100
committerAndreas Stöckel <andreas@somweyr.de>2014-11-21 21:02:48 +0100
commite41852c7ec8cb95f47180005a38e6ff43c4549f9 (patch)
treeac7e906e0d30d0109170f31b3980bdb8737052ee
parent642ab72a555c6462d14f4abc698ff8ea13884e49 (diff)
working on Logger and Typesystem
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/core/Logger.cpp69
-rw-r--r--src/core/Logger.hpp130
-rw-r--r--src/core/Typesystem.cpp112
-rw-r--r--src/core/Typesystem.hpp89
5 files changed, 392 insertions, 9 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 97ee48c..0d62197 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -107,6 +107,7 @@ ADD_LIBRARY(ousia_core
src/core/CodeTokenizer
src/core/CSSParser
src/core/Tokenizer
+ src/core/Typesystem
src/core/Utils
)
diff --git a/src/core/Logger.cpp b/src/core/Logger.cpp
new file mode 100644
index 0000000..2317e70
--- /dev/null
+++ b/src/core/Logger.cpp
@@ -0,0 +1,69 @@
+/*
+ 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/>.
+*/
+
+namespace ousia {
+
+static const int BLACK = 30;
+static const int RED = 31;
+static const int GREEN = 32;
+static const int YELLOW = 33;
+static const int BLUE = 34;
+static const int MAGENTA = 35;
+static const int CYAN = 36;
+static const int WHITE = 37;
+
+void StreamLogger::logMessage(const LogMessage &msg) {
+ os << '[';
+ switch (msg.severity) {
+ case Severity::DEBUG:
+ os << "debug" << os;
+ break;
+ case Severity::INFO:
+ os << "info" << os;
+ break;
+ case Severity::WARNING:
+ os << "warning" << os;
+ break;
+ case Severity::ERROR:
+ os << "error" << os;
+ break;
+ case Severity::FATAL_ERROR:
+ is << "fatal error" << os;
+ break;
+ }
+ os << ']';
+
+ // Print the file name
+ if (!msg.file.empty()) {
+ os << msg.file;
+
+ // Print the line and column
+ if (msg.line >= 0) {
+ os << ':' << msg.line;
+ if (msg.column >= 0) {
+ os << ':' << msg.column;
+ }
+ }
+ }
+
+ // Print the actual message
+ os << ' ' << msg.msg;
+}
+
+};
+
diff --git a/src/core/Logger.hpp b/src/core/Logger.hpp
new file mode 100644
index 0000000..8f0abfb
--- /dev/null
+++ b/src/core/Logger.hpp
@@ -0,0 +1,130 @@
+/*
+ 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_LOGGER_HPP_
+#define _OUSIA_LOGGER_HPP_
+
+#include <ostream>
+#include <string>
+#include <vector>
+
+namespace ousia {
+
+enum class Severity : int {
+ DEBUG = 0,
+ INFO = 1,
+ WARNING = 2,
+ ERROR = 3,
+ FATAL_ERROR = 4
+};
+
+struct LogMessage {
+ Severity severity;
+ std::string msg;
+ std::string file;
+ int line;
+ int column;
+
+ LogMessage(Severity severity, std::string msg, std::string file, int line,
+ int column)
+ : severity(severity),
+ msg(std::move(msg)),
+ file(std::move(file)),
+ line(line),
+ column(column){};
+};
+
+class Logger {
+private:
+ Severity maxLogSeverity = Severity::DEBUG;
+ std::string curFile;
+
+protected:
+ virtual void logMessage(const LogMessage &msg){};
+
+public:
+ Logger(){};
+
+ Logger(const Logger &) = delete;
+
+ virtual ~Logger();
+
+ void log(Severity severity, const std::string &msg, const std::string &file,
+ int line = -1, int column = -1)
+ {
+ // Copy the current severity level
+ if (static_cast<int>(severity) > static_cast<int>(maxSeverity)) {
+ maxSeverity = severity;
+ }
+
+ // Call the actual log message function
+ logMessage(LogMessage{severity, msg, file, line, column});
+ }
+
+ void log(Severity severity, const std::string &msg, int line = -1,
+ int column = -1)
+ {
+ log(severity, msg, curFile, line, column);
+ }
+
+ void debug(const std::string &msg, int line = -1, int column = -1)
+ {
+ log(Severity::DEBUG, msg, line, column);
+ }
+
+ void info(const std::string &msg, int line = -1, int column = -1)
+ {
+ log(Severity::INFO, msg, line, column);
+ }
+
+ void warning(const std::string &msg, int line = -1, int column = -1)
+ {
+ log(Severity::WARNING, msg, line, column);
+ }
+
+ void error(const std::string &msg, int line = -1, int column = -1)
+ {
+ log(Severity::ERROR, msg, line, column);
+ }
+
+ void fatalError(const std::string &msg, int line = -1, int column = -1)
+ {
+ log(Severity::FATAL_ERROR, msg, line, column);
+ }
+
+ Severity getMaxSeverity() { return maxSeverity; }
+};
+
+class StreamLogger {
+private:
+ std::ostream &os;
+ bool useColor;
+
+protected:
+ void logMessage(const LogMessage &msg) override;
+
+public:
+ StreamLogger(std::ostream &os, bool useColor = false)
+ : os(os), useColor(useColor)
+ {
+ }
+};
+}
+
+#endif /* _OUSIA_LOGGER_HPP_ */
+
diff --git a/src/core/Typesystem.cpp b/src/core/Typesystem.cpp
new file mode 100644
index 0000000..ebb0692
--- /dev/null
+++ b/src/core/Typesystem.cpp
@@ -0,0 +1,112 @@
+/*
+ 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 StringInstance */
+
+
+/**
+ * Contains a map from escape characters and their corresponding code point.
+ */
+static const std::unordered_map<char, char> ESCAPE_CHARACTERS_TO_CODEPOINT{
+ {'n', '\n'},
+ {'r', '\r'},
+ {'t', '\t'},
+ {'b', '\b'},
+ {'f', '\f'},
+ {'v', '\v'}
+};
+
+static const std::unordered_map<char, char> CODEPOINT_TO_ESCAPE_CHARACTER{
+ {'\n', 'n'},
+ {'\r', 'r'},
+ {'\t', 't'},
+ {'\b', 'b'},
+ {'\f', 'f'},
+ {'\v', 'v'}
+};
+
+static const char MIN_CONTROL_CHARACTER = 0x37;
+
+std::string StringInstance::toString()
+{
+ std::stringstream ss;
+ ss << '"';
+ for (char c: value) {
+ if (c == '"') {
+ ss << '\\';
+ } else if (c == '\\') {
+ ss << "\\\\";
+ } else if (c <= MIN_CONTROL_CHARACTER) {
+ const auto it = CODEPOINT_TO_ESCAPE_CHARACTER.find(c);
+ if (it != CODEPOINT_TO_ESCAPE_CHARACTER.cend()) {
+ ss << '\\' << it->second;
+ } else {
+ ss << c;
+ }
+ }
+ ss << c;
+ }
+ ss << '"';
+ return ss.str();
+}
+
+/* Class StringType */
+
+Rooted<TypeInstance> StringType::create()
+{
+ return new StringInstance(getManager(), this, "");
+}
+
+Rooted<TypeInstance> StringType::parse(const std::string &str)
+{
+ /*std::stringstream ss;
+ int state = 0;*/
+ return nullptr;
+}
+
+/* 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
index 47e7517..c1476ee 100644
--- a/src/core/Typesystem.hpp
+++ b/src/core/Typesystem.hpp
@@ -28,37 +28,104 @@
namespace ousia {
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))
{
}
+
+ virtual std::string toString() = 0;
+};
+
+class StringInstance : public TypeInstance {
+public:
+ std::string value;
+
+ StringInstance(Manager &mgr, Handle<StringType> type, std::string value)
+ : TypeInstance(mgr, type), value(std::move(value))
+ {
+ }
+
+ std::string toString() override;
};
+/**
+ * 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:
using Node::Node;
+ /**
+ * Returns true, if the type cannot be extended.
+ *
+ * @return true if the type is final, false otherwise.
+ */
virtual bool isFinal() const { return true; }
+ /**
+ * Returns true, if the type is a primitive type (not a composite).
+ *
+ * @return true for types such as integers, doubles, enums and strings,
+ * false otherwise.
+ */
virtual bool isPrimitive() const { return true; }
+ /**
+ * 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(const std::string &str) = 0;
};
+class StringType : public Type {
+public:
+ using Type::Type;
+
+ Rooted<TypeInstance> create() override;
+
+ Rooted<TypeInstance> parse(const std::string &str) override;
+};
+
class Typesystem : public Node {
private:
- const std::vector<Owned<Type>> types;
- const std::vector<Owned<TypeInstance>> constants;
+ NodeVector<Type> types;
+ ManagedMap<std::string, TypeInstance> constants;
protected:
- void doResolve(std::vector<Rooted<Node>> &res,
+ void doResolve(std::vector<Rooted<Managed>> &res,
const std::vector<std::string> &path, Filter filter,
void *filterData, unsigned idx,
VisitorSet &visited) override;
@@ -66,16 +133,20 @@ protected:
public:
using Node::Node;
- const &std::vector<Owned<Type>> getTypes() { return types; }
+ Typesystem(Manager &mgr) : Node(mgr), types(this), constants(this) {}
- const &std::vector<Owned<TypeInstance>> getConstants() { return constants; }
+ const NodeVector<Type> &getTypes() { return types; }
- void addType(Handle<Type> type) {
- types.push_back(acquire(type));
+ const ManagedMap<std::string, TypeInstance> &getConstants()
+ {
+ return constants;
}
- void addConstant(Handle<TypeInstance> ) {
-
+ 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));
}
};
}