diff options
| -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));  	}  };  }  | 
