From e41852c7ec8cb95f47180005a38e6ff43c4549f9 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Fri, 21 Nov 2014 21:02:48 +0100 Subject: working on Logger and Typesystem --- src/core/Logger.cpp | 69 +++++++++++++++++++++++++ src/core/Logger.hpp | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ src/core/Typesystem.cpp | 112 +++++++++++++++++++++++++++++++++++++++++ src/core/Typesystem.hpp | 89 +++++++++++++++++++++++++++++---- 4 files changed, 391 insertions(+), 9 deletions(-) create mode 100644 src/core/Logger.cpp create mode 100644 src/core/Logger.hpp create mode 100644 src/core/Typesystem.cpp (limited to 'src') 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 . +*/ + +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 . +*/ + +#ifndef _OUSIA_LOGGER_HPP_ +#define _OUSIA_LOGGER_HPP_ + +#include +#include +#include + +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(severity) > static_cast(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 . +*/ + +#include +#include + +#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 ESCAPE_CHARACTERS_TO_CODEPOINT{ + {'n', '\n'}, + {'r', '\r'}, + {'t', '\t'}, + {'b', '\b'}, + {'f', '\f'}, + {'v', '\v'} +}; + +static const std::unordered_map 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 StringType::create() +{ + return new StringInstance(getManager(), this, ""); +} + +Rooted StringType::parse(const std::string &str) +{ + /*std::stringstream ss; + int state = 0;*/ + return nullptr; +} + +/* Class Typesystem */ + +void Typesystem::doResolve(std::vector> &res, + const std::vector &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; + /** + * 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) : Managed(mgr), type(acquire(type)) { } + + virtual std::string toString() = 0; +}; + +class StringInstance : public TypeInstance { +public: + std::string value; + + StringInstance(Manager &mgr, Handle 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 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 parse(const std::string &str) = 0; }; +class StringType : public Type { +public: + using Type::Type; + + Rooted create() override; + + Rooted parse(const std::string &str) override; +}; + class Typesystem : public Node { private: - const std::vector> types; - const std::vector> constants; + NodeVector types; + ManagedMap constants; protected: - void doResolve(std::vector> &res, + void doResolve(std::vector> &res, const std::vector &path, Filter filter, void *filterData, unsigned idx, VisitorSet &visited) override; @@ -66,16 +133,20 @@ protected: public: using Node::Node; - const &std::vector> getTypes() { return types; } + Typesystem(Manager &mgr) : Node(mgr), types(this), constants(this) {} - const &std::vector> getConstants() { return constants; } + const NodeVector &getTypes() { return types; } - void addType(Handle type) { - types.push_back(acquire(type)); + const ManagedMap &getConstants() + { + return constants; } - void addConstant(Handle ) { - + void addType(Handle type) { types.push_back(type); } + + void addConstant(const std::string &name, Handle instance) + { + constants.insert(std::make_pair(name, instance)); } }; } -- cgit v1.2.3