diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2014-11-21 21:02:48 +0100 |
---|---|---|
committer | Andreas Stöckel <andreas@somweyr.de> | 2014-11-21 21:02:48 +0100 |
commit | e41852c7ec8cb95f47180005a38e6ff43c4549f9 (patch) | |
tree | ac7e906e0d30d0109170f31b3980bdb8737052ee | |
parent | 642ab72a555c6462d14f4abc698ff8ea13884e49 (diff) |
working on Logger and Typesystem
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/core/Logger.cpp | 69 | ||||
-rw-r--r-- | src/core/Logger.hpp | 130 | ||||
-rw-r--r-- | src/core/Typesystem.cpp | 112 | ||||
-rw-r--r-- | src/core/Typesystem.hpp | 89 |
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)); } }; } |