diff --git a/src/knowledge_base.cpp b/src/knowledge_base.cpp new file mode 100644 index 0000000..b70d004 --- /dev/null +++ b/src/knowledge_base.cpp @@ -0,0 +1,59 @@ +#include "knowledge_base.h" + +#include + +const std::string obelisk::Sql::create_facts_table + = "CREATE TABLE fact (id INT PRIMARY KEY NOT NULL);"; + +obelisk::KnowledgeBase::KnowledgeBase(const char* filename) +{ + KnowledgeBase(filename, DEFAULT_FLAGS); +} + +obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags) +{ + filename_ = std::move(filename); + flags_ = std::move(flags); + + auto result = sqlite3_open_v2(filename, &dbConnection_, flags, NULL); + if (result != SQLITE_OK) + { + logSqliteError(result); + } + + char* tmp; + result = sqlite3_exec(dbConnection_, + obelisk::Sql::create_facts_table.c_str(), + NULL, + NULL, + &tmp); + if (tmp) + { + std::string errmsg(tmp); + throw obelisk::KnowledgeBaseException(errmsg); + } +} + +obelisk::KnowledgeBase::~KnowledgeBase() +{ + sqlite3_close_v2(dbConnection_); +} + +// TODO: log files? +void obelisk::KnowledgeBase::logSqliteError(int result) +{ + std::cout << sqlite3_errstr(result) << std::endl; +} + +void obelisk::KnowledgeBase::getFloat(float* result1, + float* result2, + double var) +{ + *result1 = (float) var; + *result2 = (float) (var - (double) *result1); +} + +void obelisk::KnowledgeBase::getDouble(double* result, float var1, float var2) +{ + *result = (double) ((double) var2 + (double) var1); +} diff --git a/src/knowledge_base.h b/src/knowledge_base.h new file mode 100644 index 0000000..aa8f09b --- /dev/null +++ b/src/knowledge_base.h @@ -0,0 +1,61 @@ +#ifndef OBELISK_KNOWLEDGE_BASE_H +#define OBELISK_KNOWLEDGE_BASE_H + +#include + +#include +#include + +namespace obelisk +{ + class KnowledgeBase + { + private: + const int DEFAULT_FLAGS + = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + const char* filename_; + sqlite3* dbConnection_; + int flags_; + void logSqliteError(int result); + + public: + KnowledgeBase(const char* filename); + KnowledgeBase(const char* filename, int flags); + ~KnowledgeBase(); + + template + int addFacts(std::string verb, T leftEntities, U rightEntities); + // TODO: add parameter for fact + template + int addRules(std::string verb, T leftEntities, U rightEntities); + template int addActions(); + + void getDouble(double* result, float var1, float var2); + void getFloat(float* result1, float* result2, double var); + }; + + class Sql + { + public: + static const std::string create_facts_table; + }; + + class KnowledgeBaseException : public std::exception + { + private: + std::string errorMessage_; + + public: + KnowledgeBaseException(std::string errorMessage) : + errorMessage_(errorMessage) + { + } + + const char* what() const noexcept + { + return errorMessage_.c_str(); + } + }; +} // namespace obelisk + +#endif diff --git a/src/meson.build b/src/meson.build index 3be46cd..d7c5d50 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,13 +1,17 @@ obelisk_sources = files( 'obelisk.cpp', 'lexer.cpp', - 'parser.cpp' + 'parser.cpp', + 'knowledge_base.cpp' ) +sqlite3 = dependency('sqlite3') + subdir('ast') obelisk_sources += obelisk_ast_sources executable('obelisk', obelisk_sources, + dependencies : [sqlite3], install : true ) diff --git a/src/models/entity.cpp b/src/models/entity.cpp new file mode 100644 index 0000000..c2d29bd --- /dev/null +++ b/src/models/entity.cpp @@ -0,0 +1,30 @@ +#include "models/entity.h" + +obelisk::Entity::Entity() +{ +} + +obelisk::Entity::Entity(std::string name) +{ + name = name; +} + +int obelisk::Entity::getId() +{ + return id_; +} + +void obelisk::Entity::setId(int id) +{ + id_ = id; +} + +std::string obelisk::Entity::getName() +{ + return name_; +} + +void obelisk::Entity::setName(std::string name) +{ + name_ = name_; +} diff --git a/src/models/entity.h b/src/models/entity.h new file mode 100644 index 0000000..4663fbf --- /dev/null +++ b/src/models/entity.h @@ -0,0 +1,26 @@ +#ifndef OBELISK_MODELS_ENTITY_H +#define OBELISK_MODELS_ENTITY_H + +#include + +namespace obelisk +{ + class Entity + { + private: + int id_; + std::string name_; + + public: + Entity(); + Entity(std::string name); + + int getId(); + void setId(int id); + + std::string getName(); + void setName(std::string name); + }; +} // namespace obelisk + +#endif diff --git a/src/models/verb.cpp b/src/models/verb.cpp new file mode 100644 index 0000000..eab0251 --- /dev/null +++ b/src/models/verb.cpp @@ -0,0 +1,36 @@ +#include "models/verb.h" + +obelisk::Verb::Verb() +{ +} + +obelisk::Verb::Verb(std::string verb) +{ + verb_ = verb; +} + +obelisk::Verb::Verb(int id, std::string verb) +{ + id_ = id; + verb_ = verb; +} + +int obelisk::Verb::getId() +{ + return id_; +} + +void obelisk::Verb::setId(int id) +{ + id_ = id; +} + +std::string obelisk::Verb::getVerb() +{ + return verb_; +} + +void obelisk::Verb::setVerb(std::string verb) +{ + verb_ = verb; +} diff --git a/src/models/verb.h b/src/models/verb.h new file mode 100644 index 0000000..1919bef --- /dev/null +++ b/src/models/verb.h @@ -0,0 +1,27 @@ +#ifndef OBELISK_MODELS_VERB_H +#define OBELISK_MODELS_VERB_H + +#include + +namespace obelisk +{ + class Verb + { + private: + int id_; + std::string verb_; + + public: + Verb(); + Verb(std::string verb); + Verb(int id, std::string verb); + + int getId(); + void setId(int id); + + std::string getVerb(); + void setVerb(std::string verb); + }; +} // namespace obelisk + +#endif diff --git a/src/obelisk.cpp b/src/obelisk.cpp index 90bf451..5e46be6 100644 --- a/src/obelisk.cpp +++ b/src/obelisk.cpp @@ -1,8 +1,11 @@ +#include "knowledge_base.h" #include "lexer.h" #include "obelisk.h" #include "parser.h" +#include #include +#include static void mainLoop() { @@ -44,6 +47,43 @@ int main(int argc, char** argv) std::cout << argv[i] << std::endl; } + try + { + obelisk::KnowledgeBase* kb = new obelisk::KnowledgeBase("cromer.kb"); + + /*std::vector leftObjects; + std::vector rightObjects; + leftObjects.push_back("chris"); + leftObjects.push_back("martin"); + + rightObjects.push_back("happy"); + rightObjects.push_back("smart"); + + kb->addFacts("is", leftObjects, rightObjects);*/ + } + catch (obelisk::KnowledgeBaseException& exception) + { + std::cout << exception.what() << std::endl; + return EXIT_FAILURE; + } + + // This can be used to store a double as 2 floats in the database, then restore it back to a double. + // Inspired by Godot's double precision on the GPU to render large worlds. + /*float first; + float second; + double var = 0.123456789012345; + kb->getFloat(&first, &second, var); + std::cout << std::setprecision(std::numeric_limits::digits10) + << "Double: " << var << std::endl + << "First: " << first << std::endl + << "Second: " << second << std::endl; + var = 0.0; + kb->getDouble(&var, first, second); + std::cout << std::setprecision(std::numeric_limits::digits10) + << "Double: " << var << std::endl + << "First: " << first << std::endl + << "Second: " << second << std::endl;*/ + mainLoop(); return EXIT_SUCCESS;