Merge pull request 'develop' (#5) from develop into master

Reviewed-on: #5
This commit is contained in:
Chris Cromer 2022-11-10 21:31:43 -03:00
commit 24b04a242d
23 changed files with 875 additions and 121 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.code-workspace *.code-workspace
.vscode .vscode
builddir builddir
*.kb

View File

@ -1,20 +1,62 @@
[ [
{ {
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir", "directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "clang++ -Isrc/obelisk.p -Isrc -I../src -fcolor-diagnostics -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -O0 -g -MD -MQ src/obelisk.p/obelisk.cpp.o -MF src/obelisk.p/obelisk.cpp.o.d -o src/obelisk.p/obelisk.cpp.o -c ../src/obelisk.cpp", "command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/obelisk.cpp.o -MF src/obelisk.p/obelisk.cpp.o.d -o src/obelisk.p/obelisk.cpp.o -c ../src/obelisk.cpp",
"file": "../src/obelisk.cpp", "file": "../src/obelisk.cpp",
"output": "src/obelisk.p/obelisk.cpp.o" "output": "src/obelisk.p/obelisk.cpp.o"
}, },
{ {
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir", "directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "clang++ -Isrc/obelisk.p -Isrc -I../src -fcolor-diagnostics -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -O0 -g -MD -MQ src/obelisk.p/lexer.cpp.o -MF src/obelisk.p/lexer.cpp.o.d -o src/obelisk.p/lexer.cpp.o -c ../src/lexer.cpp", "command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/lexer.cpp.o -MF src/obelisk.p/lexer.cpp.o.d -o src/obelisk.p/lexer.cpp.o -c ../src/lexer.cpp",
"file": "../src/lexer.cpp", "file": "../src/lexer.cpp",
"output": "src/obelisk.p/lexer.cpp.o" "output": "src/obelisk.p/lexer.cpp.o"
}, },
{ {
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir", "directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "clang++ -Isrc/obelisk.p -Isrc -I../src -fcolor-diagnostics -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -O0 -g -MD -MQ src/obelisk.p/parser.cpp.o -MF src/obelisk.p/parser.cpp.o.d -o src/obelisk.p/parser.cpp.o -c ../src/parser.cpp", "command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/parser.cpp.o -MF src/obelisk.p/parser.cpp.o.d -o src/obelisk.p/parser.cpp.o -c ../src/parser.cpp",
"file": "../src/parser.cpp", "file": "../src/parser.cpp",
"output": "src/obelisk.p/parser.cpp.o" "output": "src/obelisk.p/parser.cpp.o"
},
{
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/knowledge_base.cpp.o -MF src/obelisk.p/knowledge_base.cpp.o.d -o src/obelisk.p/knowledge_base.cpp.o -c ../src/knowledge_base.cpp",
"file": "../src/knowledge_base.cpp",
"output": "src/obelisk.p/knowledge_base.cpp.o"
},
{
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/models_action.cpp.o -MF src/obelisk.p/models_action.cpp.o.d -o src/obelisk.p/models_action.cpp.o -c ../src/models/action.cpp",
"file": "../src/models/action.cpp",
"output": "src/obelisk.p/models_action.cpp.o"
},
{
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/models_entity.cpp.o -MF src/obelisk.p/models_entity.cpp.o.d -o src/obelisk.p/models_entity.cpp.o -c ../src/models/entity.cpp",
"file": "../src/models/entity.cpp",
"output": "src/obelisk.p/models_entity.cpp.o"
},
{
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/models_fact.cpp.o -MF src/obelisk.p/models_fact.cpp.o.d -o src/obelisk.p/models_fact.cpp.o -c ../src/models/fact.cpp",
"file": "../src/models/fact.cpp",
"output": "src/obelisk.p/models_fact.cpp.o"
},
{
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/models_rule.cpp.o -MF src/obelisk.p/models_rule.cpp.o.d -o src/obelisk.p/models_rule.cpp.o -c ../src/models/rule.cpp",
"file": "../src/models/rule.cpp",
"output": "src/obelisk.p/models_rule.cpp.o"
},
{
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/models_suggest_action.cpp.o -MF src/obelisk.p/models_suggest_action.cpp.o.d -o src/obelisk.p/models_suggest_action.cpp.o -c ../src/models/suggest_action.cpp",
"file": "../src/models/suggest_action.cpp",
"output": "src/obelisk.p/models_suggest_action.cpp.o"
},
{
"directory": "/mnt/data/ubb/courses/proyecto-titulo/obelisk/builddir",
"command": "c++ -Isrc/obelisk.p -Isrc -I../src -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wnon-virtual-dtor -Wextra -Wpedantic -std=c++17 -g -MD -MQ src/obelisk.p/models_verb.cpp.o -MF src/obelisk.p/models_verb.cpp.o.d -o src/obelisk.p/models_verb.cpp.o -c ../src/models/verb.cpp",
"file": "../src/models/verb.cpp",
"output": "src/obelisk.p/models_verb.cpp.o"
} }
] ]

View File

@ -1,10 +1,14 @@
#include "knowledge_base.h" #include "knowledge_base.h"
#include "models/action.h"
#include "models/entity.h"
#include "models/fact.h"
#include "models/rule.h"
#include "models/suggest_action.h"
#include "models/verb.h"
#include <filesystem>
#include <iostream> #include <iostream>
const std::string obelisk::Sql::create_facts_table
= "CREATE TABLE fact (id INT PRIMARY KEY NOT NULL);";
obelisk::KnowledgeBase::KnowledgeBase(const char* filename) obelisk::KnowledgeBase::KnowledgeBase(const char* filename)
{ {
KnowledgeBase(filename, DEFAULT_FLAGS); KnowledgeBase(filename, DEFAULT_FLAGS);
@ -15,28 +19,51 @@ obelisk::KnowledgeBase::KnowledgeBase(const char* filename, int flags)
filename_ = std::move(filename); filename_ = std::move(filename);
flags_ = std::move(flags); flags_ = std::move(flags);
std::filesystem::path path {filename};
auto dbExists = std::filesystem::exists(path);
auto result = sqlite3_open_v2(filename, &dbConnection_, flags, NULL); auto result = sqlite3_open_v2(filename, &dbConnection_, flags, NULL);
if (result != SQLITE_OK) if (result != SQLITE_OK)
{ {
logSqliteError(result); logSqliteError(result);
} }
char* tmp; if (!dbExists)
result = sqlite3_exec(dbConnection_,
obelisk::Sql::create_facts_table.c_str(),
NULL,
NULL,
&tmp);
if (tmp)
{ {
std::string errmsg(tmp); createTable(obelisk::Action::createTable);
throw obelisk::KnowledgeBaseException(errmsg); createTable(obelisk::Entity::createTable);
createTable(obelisk::Verb::createTable);
createTable(obelisk::Fact::createTable);
createTable(obelisk::Rule::createTable);
createTable(obelisk::SuggestAction::createTable);
} }
} }
obelisk::KnowledgeBase::~KnowledgeBase() obelisk::KnowledgeBase::~KnowledgeBase()
{ {
sqlite3_close_v2(dbConnection_); if (dbConnection_)
{
sqlite3_close_v2(dbConnection_);
}
}
void obelisk::KnowledgeBase::createTable(std::function<const char*()> function)
{
char* tmp;
auto result = sqlite3_exec(dbConnection_, function(), NULL, NULL, &tmp);
if (result != SQLITE_OK)
{
logSqliteError(result);
if (tmp)
{
std::string errmsg(tmp);
throw obelisk::KnowledgeBaseException(errmsg);
}
else
{
throw obelisk::KnowledgeBaseException();
}
}
} }
// TODO: log files? // TODO: log files?
@ -45,15 +72,15 @@ void obelisk::KnowledgeBase::logSqliteError(int result)
std::cout << sqlite3_errstr(result) << std::endl; std::cout << sqlite3_errstr(result) << std::endl;
} }
void obelisk::KnowledgeBase::getFloat(float* result1, void obelisk::KnowledgeBase::getFloat(float& result1,
float* result2, float& result2,
double var) double var)
{ {
*result1 = (float) var; result1 = (float) var;
*result2 = (float) (var - (double) *result1); result2 = (float) (var - (double) result1);
} }
void obelisk::KnowledgeBase::getDouble(double* result, float var1, float var2) void obelisk::KnowledgeBase::getDouble(double& result, float var1, float var2)
{ {
*result = (double) ((double) var2 + (double) var1); result = (double) ((double) var2 + (double) var1);
} }

View File

@ -3,6 +3,7 @@
#include <sqlite3.h> #include <sqlite3.h>
#include <functional>
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -14,10 +15,12 @@ namespace obelisk
const int DEFAULT_FLAGS const int DEFAULT_FLAGS
= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
const char* filename_; const char* filename_;
sqlite3* dbConnection_; sqlite3* dbConnection_ = nullptr;
int flags_; int flags_;
void logSqliteError(int result); void logSqliteError(int result);
void createTable(std::function<const char*()> function);
public: public:
KnowledgeBase(const char* filename); KnowledgeBase(const char* filename);
KnowledgeBase(const char* filename, int flags); KnowledgeBase(const char* filename, int flags);
@ -30,23 +33,22 @@ namespace obelisk
int addRules(std::string verb, T leftEntities, U rightEntities); int addRules(std::string verb, T leftEntities, U rightEntities);
template<typename T, typename U> int addActions(); template<typename T, typename U> int addActions();
void getDouble(double* result, float var1, float var2); void getDouble(double& result, float var1, float var2);
void getFloat(float* result1, float* result2, double var); void getFloat(float& result1, float& result2, double var);
};
class Sql
{
public:
static const std::string create_facts_table;
}; };
class KnowledgeBaseException : public std::exception class KnowledgeBaseException : public std::exception
{ {
private: private:
std::string errorMessage_; const std::string errorMessage_;
public: public:
KnowledgeBaseException(std::string errorMessage) : KnowledgeBaseException() :
errorMessage_("an unknown error ocurred")
{
}
KnowledgeBaseException(const std::string& errorMessage) :
errorMessage_(errorMessage) errorMessage_(errorMessage)
{ {
} }

View File

@ -8,7 +8,7 @@ int obelisk::Lexer::getToken()
while (isspace(lastChar)) while (isspace(lastChar))
{ {
lastChar = getchar(); lastChar = std::getc(stdin);
} }
if (isalpha(lastChar)) if (isalpha(lastChar))
@ -20,6 +20,21 @@ int obelisk::Lexer::getToken()
appendIdentifier(lastChar); appendIdentifier(lastChar);
} }
if (getIdentifier() == "fact")
{
return Token::kTokenFact;
}
if (getIdentifier() == "rule")
{
return Token::kTokenFact;
}
if (getIdentifier() == "action")
{
return Token::kTokenAction;
}
if (getIdentifier() == "def") if (getIdentifier() == "def")
{ {
return Token::kTokenDef; return Token::kTokenDef;
@ -90,12 +105,12 @@ void obelisk::Lexer::commentLine(int* lastChar)
while (*lastChar != EOF && *lastChar != '\n' && *lastChar != '\r'); while (*lastChar != EOF && *lastChar != '\n' && *lastChar != '\r');
} }
std::string obelisk::Lexer::getIdentifier() const std::string& obelisk::Lexer::getIdentifier()
{ {
return identifier_; return identifier_;
} }
void obelisk::Lexer::setIdentifier(const std::string identifier) void obelisk::Lexer::setIdentifier(const std::string& identifier)
{ {
identifier_ = identifier; identifier_ = identifier;
} }

View File

@ -3,16 +3,16 @@
#include <string> #include <string>
// TODO: add error handling
namespace obelisk namespace obelisk
{ {
class Lexer class Lexer
{ {
private: private:
std::string identifier_; std::string identifier_;
double numberValue_; double numberValue_;
void setIdentifier(const std::string identifier); void setIdentifier(const std::string& identifier);
void eraseIdentifier(); void eraseIdentifier();
void appendIdentifier(int lastChar); void appendIdentifier(int lastChar);
void setNumberValue(double numberValue); void setNumberValue(double numberValue);
@ -21,12 +21,12 @@ namespace obelisk
public: public:
enum Token enum Token
{ {
kTokenInvalid = -1, kTokenEof = -1,
kTokenEof = -2,
// commands // commands
kTokenFact = -3, kTokenFact = -2,
kTokenRule = -4, kTokenRule = -3,
kTokenAction = -4,
kTokenDef = -5, kTokenDef = -5,
kTokenExtern = -6, kTokenExtern = -6,
@ -38,7 +38,7 @@ namespace obelisk
int getToken(); int getToken();
std::string getIdentifier(); const std::string& getIdentifier();
double getNumberValue(); double getNumberValue();
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -10,6 +10,9 @@ sqlite3 = dependency('sqlite3')
subdir('ast') subdir('ast')
obelisk_sources += obelisk_ast_sources obelisk_sources += obelisk_ast_sources
subdir('models')
obelisk_sources += obelisk_model_sources
executable('obelisk', executable('obelisk',
obelisk_sources, obelisk_sources,
dependencies : [sqlite3], dependencies : [sqlite3],

32
src/models/action.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "models/action.h"
const char* obelisk::Action::createTable()
{
return R"(
CREATE TABLE "action" (
"id" INTEGER NOT NULL UNIQUE,
"name" TEXT NOT NULL CHECK(trim(name) != '') UNIQUE,
PRIMARY KEY("id" AUTOINCREMENT)
);
)";
}
int obelisk::Action::getId()
{
return id_;
}
void obelisk::Action::setId(int id)
{
id_ = id;
}
std::string obelisk::Action::getName()
{
return name_;
}
void obelisk::Action::setName(std::string name)
{
name_ = name;
}

49
src/models/action.h Normal file
View File

@ -0,0 +1,49 @@
#ifndef OBELISK_MODELS_ACTION_H
#define OBELISK_MODELS_ACTION_H
#include <string>
namespace obelisk
{
class Action
{
private:
int id_;
std::string name_;
public:
Action() :
id_(0),
name_("")
{
}
Action(int id) :
id_(id),
name_("")
{
}
Action(std::string name) :
id_(0),
name_(name)
{
}
Action(int id, std::string name) :
id_(id),
name_(name)
{
}
static const char* createTable();
int getId();
void setId(int id);
std::string getName();
void setName(std::string name);
};
} // namespace obelisk
#endif

View File

@ -1,12 +1,14 @@
#include "models/entity.h" #include "models/entity.h"
obelisk::Entity::Entity() const char* obelisk::Entity::createTable()
{ {
} return R"(
CREATE TABLE "entity" (
obelisk::Entity::Entity(std::string name) "id" INTEGER NOT NULL UNIQUE,
{ "name" TEXT NOT NULL CHECK(trim(name) != '') UNIQUE,
name = name; PRIMARY KEY("id" AUTOINCREMENT)
);
)";
} }
int obelisk::Entity::getId() int obelisk::Entity::getId()
@ -26,5 +28,5 @@ std::string obelisk::Entity::getName()
void obelisk::Entity::setName(std::string name) void obelisk::Entity::setName(std::string name)
{ {
name_ = name_; name_ = name;
} }

View File

@ -12,8 +12,31 @@ namespace obelisk
std::string name_; std::string name_;
public: public:
Entity(); Entity() :
Entity(std::string name); id_(0),
name_("")
{
}
Entity(int id) :
id_(id),
name_("")
{
}
Entity(std::string name) :
id_(0),
name_(name)
{
}
Entity(int id, std::string name) :
id_(id),
name_(name)
{
}
static const char* createTable();
int getId(); int getId();
void setId(int id); void setId(int id);

57
src/models/fact.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "models/fact.h"
const char* obelisk::Fact::createTable()
{
return R"(
CREATE TABLE "fact" (
"id" INTEGER NOT NULL UNIQUE,
"left_entity" INTEGER NOT NULL,
"right_entity" INTEGER NOT NULL,
"verb" INTEGER NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT),
FOREIGN KEY("verb") REFERENCES "verb"("id") ON DELETE RESTRICT,
FOREIGN KEY("right_entity") REFERENCES "entity"("id") ON DELETE RESTRICT,
FOREIGN KEY("left_entity") REFERENCES "entity"("id") ON DELETE RESTRICT
);
)";
}
int obelisk::Fact::getId()
{
return id_;
}
void obelisk::Fact::setId(int id)
{
id_ = id;
}
obelisk::Entity obelisk::Fact::getLeftEntity()
{
return leftEntity_;
}
void obelisk::Fact::setLeftEntity(obelisk::Entity leftEntity)
{
leftEntity_ = leftEntity;
}
obelisk::Entity obelisk::Fact::getRightEntity()
{
return rightEntity_;
}
void obelisk::Fact::setRightEntity(obelisk::Entity rightEntity)
{
rightEntity_ = rightEntity;
}
obelisk::Verb obelisk::Fact::getVerb()
{
return verb_;
}
void obelisk::Fact::setVerb(obelisk::Verb verb)
{
verb_ = verb;
}

73
src/models/fact.h Normal file
View File

@ -0,0 +1,73 @@
#ifndef OBELISK_MODELS_FACT_H
#define OBELISK_MODELS_FACT_H
#include "models/entity.h"
#include "models/verb.h"
#include <string>
namespace obelisk
{
class Fact
{
private:
int id_;
obelisk::Entity leftEntity_;
obelisk::Entity rightEntity_;
obelisk::Verb verb_;
public:
Fact() :
id_(0),
leftEntity_(),
rightEntity_(),
verb_()
{
}
Fact(int id) :
id_(id),
leftEntity_(),
rightEntity_(),
verb_()
{
}
Fact(obelisk::Entity leftEntity,
obelisk::Entity rightEntity,
obelisk::Verb verb) :
id_(0),
leftEntity_(leftEntity),
rightEntity_(rightEntity),
verb_(verb)
{
}
Fact(int id,
obelisk::Entity leftEntity,
obelisk::Entity rightEntity,
obelisk::Verb verb) :
id_(id),
leftEntity_(leftEntity),
rightEntity_(rightEntity),
verb_(verb)
{
}
static const char* createTable();
int getId();
void setId(int id);
obelisk::Entity getLeftEntity();
void setLeftEntity(obelisk::Entity leftEntity);
obelisk::Entity getRightEntity();
void setRightEntity(obelisk::Entity leftEntity);
obelisk::Verb getVerb();
void setVerb(obelisk::Verb verb);
};
} // namespace obelisk
#endif

8
src/models/meson.build Normal file
View File

@ -0,0 +1,8 @@
obelisk_model_sources = files(
'action.cpp',
'entity.cpp',
'fact.cpp',
'rule.cpp',
'suggest_action.cpp',
'verb.cpp'
)

45
src/models/rule.cpp Normal file
View File

@ -0,0 +1,45 @@
#include "models/rule.h"
const char* obelisk::Rule::createTable()
{
return R"(
CREATE TABLE "rule" (
"id" INTEGER NOT NULL UNIQUE,
"fact" INTEGER NOT NULL,
"reason" INTEGER NOT NULL CHECK("reason" != "fact"),
PRIMARY KEY("id" AUTOINCREMENT),
FOREIGN KEY("fact") REFERENCES "fact"("id") ON DELETE RESTRICT,
FOREIGN KEY("reason") REFERENCES "fact"("id") ON DELETE RESTRICT
);
)";
}
int obelisk::Rule::getId()
{
return id_;
}
void obelisk::Rule::setId(int id)
{
id_ = id;
}
obelisk::Fact obelisk::Rule::getFact()
{
return fact_;
}
void obelisk::Rule::setFact(obelisk::Fact fact)
{
fact_ = fact;
}
obelisk::Fact obelisk::Rule::getReason()
{
return reason_;
}
void obelisk::Rule::setReason(obelisk::Fact reason)
{
reason_ = reason;
}

59
src/models/rule.h Normal file
View File

@ -0,0 +1,59 @@
#ifndef OBELISK_MODELS_RULE_H
#define OBELISK_MODELS_RULE_H
#include "models/fact.h"
#include <string>
namespace obelisk
{
class Rule
{
private:
int id_;
obelisk::Fact fact_;
obelisk::Fact reason_;
public:
Rule() :
id_(0),
fact_(),
reason_()
{
}
Rule(int id) :
id_(id),
fact_(),
reason_()
{
}
Rule(obelisk::Fact fact, obelisk::Fact reason) :
id_(0),
fact_(fact),
reason_(reason)
{
}
Rule(int id, obelisk::Fact fact, obelisk::Fact reason) :
id_(id),
fact_(fact),
reason_(reason)
{
}
static const char* createTable();
int getId();
void setId(int id);
obelisk::Fact getFact();
void setFact(obelisk::Fact fact);
obelisk::Fact getReason();
void setReason(obelisk::Fact reason);
};
} // namespace obelisk
#endif

View File

@ -0,0 +1,57 @@
#include "models/suggest_action.h"
const char* obelisk::SuggestAction::createTable()
{
return R"(
CREATE TABLE "suggest_action" (
"id" INTEGER NOT NULL UNIQUE,
"fact" INTEGER NOT NULL,
"true_action" INTEGER NOT NULL,
"false_action" INTEGER NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT),
FOREIGN KEY("fact") REFERENCES "fact"("id") ON DELETE RESTRICT,
FOREIGN KEY("true_action") REFERENCES "action"("id") ON DELETE RESTRICT,
FOREIGN KEY("false_action") REFERENCES "action"("id") ON DELETE RESTRICT
);
)";
}
int obelisk::SuggestAction::getId()
{
return id_;
}
void obelisk::SuggestAction::setId(int id)
{
id_ = id;
}
obelisk::Fact obelisk::SuggestAction::getFact()
{
return fact_;
}
void obelisk::SuggestAction::setFact(obelisk::Fact fact)
{
fact_ = fact;
}
obelisk::Action obelisk::SuggestAction::getTrueAction()
{
return trueAction_;
}
void obelisk::SuggestAction::setTrueAction(obelisk::Action trueAction)
{
trueAction_ = trueAction;
}
obelisk::Action obelisk::SuggestAction::getFalseAction()
{
return falseAction_;
}
void obelisk::SuggestAction::setFalseAction(obelisk::Action falseAction)
{
falseAction_ = falseAction;
}

View File

@ -0,0 +1,73 @@
#ifndef OBELISK_MODELS_SUGGEST_ACTION_H
#define OBELISK_MODELS_SUGGEST_ACTION_H
#include "models/action.h"
#include "models/fact.h"
#include <string>
namespace obelisk
{
class SuggestAction
{
private:
int id_;
obelisk::Fact fact_;
obelisk::Action trueAction_;
obelisk::Action falseAction_;
public:
SuggestAction() :
id_(0),
fact_(),
trueAction_(),
falseAction_()
{
}
SuggestAction(int id) :
id_(id),
fact_(),
trueAction_(),
falseAction_()
{
}
SuggestAction(obelisk::Fact fact,
obelisk::Action trueAction,
obelisk::Action falseAction) :
id_(0),
fact_(fact),
trueAction_(trueAction),
falseAction_(falseAction)
{
}
SuggestAction(int id,
obelisk::Fact fact,
obelisk::Action trueAction,
obelisk::Action falseAction) :
id_(id),
fact_(fact),
trueAction_(trueAction),
falseAction_(falseAction)
{
}
static const char* createTable();
int getId();
void setId(int id);
obelisk::Fact getFact();
void setFact(obelisk::Fact fact);
obelisk::Action getTrueAction();
void setTrueAction(obelisk::Action trueAction);
obelisk::Action getFalseAction();
void setFalseAction(obelisk::Action falseAction);
};
} // namespace obelisk
#endif

View File

@ -1,18 +1,14 @@
#include "models/verb.h" #include "models/verb.h"
obelisk::Verb::Verb() const char* obelisk::Verb::createTable()
{ {
} return R"(
CREATE TABLE "verb" (
obelisk::Verb::Verb(std::string verb) "id" INTEGER NOT NULL UNIQUE,
{ "name" TEXT NOT NULL CHECK(trim(name) != "") UNIQUE,
verb_ = verb; PRIMARY KEY("id" AUTOINCREMENT)
} );
)";
obelisk::Verb::Verb(int id, std::string verb)
{
id_ = id;
verb_ = verb;
} }
int obelisk::Verb::getId() int obelisk::Verb::getId()
@ -25,12 +21,12 @@ void obelisk::Verb::setId(int id)
id_ = id; id_ = id;
} }
std::string obelisk::Verb::getVerb() std::string obelisk::Verb::getName()
{ {
return verb_; return name_;
} }
void obelisk::Verb::setVerb(std::string verb) void obelisk::Verb::setName(std::string name)
{ {
verb_ = verb; name_ = name;
} }

View File

@ -9,18 +9,40 @@ namespace obelisk
{ {
private: private:
int id_; int id_;
std::string verb_; std::string name_;
public: public:
Verb(); Verb() :
Verb(std::string verb); id_(0),
Verb(int id, std::string verb); name_("")
{
}
Verb(int id) :
id_(id),
name_("")
{
}
Verb(std::string name) :
id_(0),
name_(name)
{
}
Verb(int id, std::string name) :
id_(id),
name_(name)
{
}
static const char* createTable();
int getId(); int getId();
void setId(int id); void setId(int id);
std::string getVerb(); std::string getName();
void setVerb(std::string verb); void setName(std::string name);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -6,10 +6,11 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
#include <limits> #include <limits>
#include <memory>
static void mainLoop() static void mainLoop()
{ {
obelisk::Parser* parser = new obelisk::Parser(); auto parser = std::unique_ptr<obelisk::Parser> {new obelisk::Parser()};
// Prime the first token. // Prime the first token.
fprintf(stderr, "ready> "); fprintf(stderr, "ready> ");
@ -22,10 +23,6 @@ static void mainLoop()
{ {
case obelisk::Lexer::kTokenEof : case obelisk::Lexer::kTokenEof :
return; return;
case obelisk::Lexer::kTokenInvalid :
std::cerr << "Invalid token!\n";
parser->getNextToken();
return;
case ';' : // ignore top-level semicolons. case ';' : // ignore top-level semicolons.
std::cout << "Identifier: " std::cout << "Identifier: "
<< parser->getLexer()->getIdentifier() << std::endl; << parser->getLexer()->getIdentifier() << std::endl;
@ -33,6 +30,15 @@ static void mainLoop()
<< std::endl; << std::endl;
parser->getNextToken(); parser->getNextToken();
break; break;
case obelisk::Lexer::kTokenFact :
// parser->handleFactFunction();
break;
case obelisk::Lexer::kTokenRule :
// parser->handleRuleFunction();
break;
case obelisk::Lexer::kTokenAction :
// parser->handleActionFunction();
break;
default : default :
parser->getNextToken(); parser->getNextToken();
break; break;
@ -47,9 +53,36 @@ int main(int argc, char** argv)
std::cout << argv[i] << std::endl; std::cout << argv[i] << std::endl;
} }
// 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.
/*try
{
float first;
float second;
double var = 0.123456789012345;
obelisk::KnowledgeBase* kb = new obelisk::KnowledgeBase("cromer.kb");
kb->getFloat(first, second, var);
std::cout << std::setprecision(std::numeric_limits<double>::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<double>::digits10)
<< "Double: " << var << std::endl
<< "First: " << first << std::endl
<< "Second: " << second << std::endl;
}
catch (obelisk::KnowledgeBaseException& exception)
{
return EXIT_FAILURE;
}*/
try try
{ {
obelisk::KnowledgeBase* kb = new obelisk::KnowledgeBase("cromer.kb"); auto kb = std::unique_ptr<obelisk::KnowledgeBase> {
new obelisk::KnowledgeBase("cromer.kb")};
/*std::vector<std::string> leftObjects; /*std::vector<std::string> leftObjects;
std::vector<std::string> rightObjects; std::vector<std::string> rightObjects;
@ -67,23 +100,6 @@ int main(int argc, char** argv)
return EXIT_FAILURE; 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<double>::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<double>::digits10)
<< "Double: " << var << std::endl
<< "First: " << first << std::endl
<< "Second: " << second << std::endl;*/
mainLoop(); mainLoop();
return EXIT_SUCCESS; return EXIT_SUCCESS;

View File

@ -3,29 +3,16 @@
#include "ast/variable_expression_ast.h" #include "ast/variable_expression_ast.h"
#include "parser.h" #include "parser.h"
#include <memory>
#include <stack>
#include <vector>
obelisk::Parser::Parser() obelisk::Parser::Parser()
{ {
lexer_ = new obelisk::Lexer(); lexer_ = std::unique_ptr<obelisk::Lexer> {new obelisk::Lexer()};
} }
obelisk::Parser::Parser(obelisk::Lexer* lexer) std::unique_ptr<obelisk::Lexer>& obelisk::Parser::getLexer()
{
if (lexer != nullptr)
{
lexer_ = lexer;
}
else
{
Parser();
}
}
obelisk::Parser::~Parser()
{
delete lexer_;
}
obelisk::Lexer* obelisk::Parser::getLexer()
{ {
return lexer_; return lexer_;
} }
@ -91,7 +78,7 @@ std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseNumberExpression()
auto result = std::make_unique<obelisk::NumberExpressionAST>( auto result = std::make_unique<obelisk::NumberExpressionAST>(
getLexer()->getNumberValue()); getLexer()->getNumberValue());
getNextToken(); getNextToken();
return std::move(result); return result;
} }
std::unique_ptr<obelisk::ExpressionAST> std::unique_ptr<obelisk::ExpressionAST>
@ -223,3 +210,164 @@ std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::parseExtern()
getNextToken(); getNextToken();
return parsePrototype(); return parsePrototype();
} }
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseAction()
{
//action(is "dangerous" then "avoid" or "ignore");
getNextToken();
if (getCurrentToken() != '(')
{
// TODO: throw an error
}
}
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseRule()
{
//rule("player" can "die" if "enemy1" is "dangerous");
getNextToken();
if (getCurrentToken() != '(')
{
// TODO: throw an error
}
while (true) //left side of Rule
{
getNextToken();
if (getCurrentToken() != '"')
{
//TODO: throw an error
}
/*if (getCurrentToken() == ')') // TODO: break if not string and not "and"
{
// TODO: save the verb
break;
}*/
}
while (true) //right side of Ruke
{
getNextToken();
if (getCurrentToken() != '"')
{
//TODO: throw an error
}
if (getCurrentToken() == ')')
{
// TODO: save the verb
break;
}
}
}
// fact("chris cromer" and "martin" and "Isabella" can "program" and "speak english");
// fact("" and "martin")
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseFact()
{
std::stack<char> syntax;
getNextToken();
if (getCurrentToken() != '(')
{
// TODO: throw an error
}
syntax.push('(');
// ("
bool getEntity {true};
std::vector<std::string> leftEntities;
std::vector<std::string> rightEntities;
std::string entityName {""};
std::string verb {""};
getNextToken();
while (true) //left side of fact
{
if (getEntity)
{
if (getCurrentToken() == '"')
{
if (syntax.top() != '"')
{
// open a double quote
syntax.push('"');
getNextToken();
}
else if (syntax.top() == '"')
{
// close a double quote
syntax.pop();
if (verb == "")
{
leftEntities.push_back(entityName);
}
else
{
rightEntities.push_back(entityName);
}
entityName = "";
getEntity = false;
getNextToken();
continue;
}
}
if (syntax.top() == '"')
{
if (entityName != "")
{
entityName += " ";
}
entityName += getLexer()->getIdentifier();
}
getNextToken();
}
else
{
if (getCurrentToken() == ')')
{
// TODO: throw an error if verb is empty
// TODO: throw an error if rightEntities has 0 elements
break;
}
if (getCurrentToken() == '"')
{
// TODO: throw and error because there is an unexpected double quote.
break;
}
if (getLexer()->getIdentifier() == "and")
{
getNextToken();
getEntity = true;
continue;
}
else
{
verb = getLexer()->getIdentifier();
getEntity = true;
continue;
}
}
}
return nullptr;
}
void obelisk::Parser::handleAction()
{
}
void obelisk::Parser::handleRule()
{
}
void obelisk::Parser::handleFact()
{
parseFact();
}
void obelisk::Parser::insertFact()
{
}

View File

@ -13,7 +13,7 @@ namespace obelisk
class Parser class Parser
{ {
private: private:
obelisk::Lexer* lexer_; std::unique_ptr<obelisk::Lexer> lexer_;
int currentToken_; int currentToken_;
void setCurrentToken(int currentToken); void setCurrentToken(int currentToken);
@ -32,13 +32,14 @@ namespace obelisk
std::unique_ptr<obelisk::FunctionAST> parseDefinition(); std::unique_ptr<obelisk::FunctionAST> parseDefinition();
std::unique_ptr<obelisk::FunctionAST> parseTopLevelExpression(); std::unique_ptr<obelisk::FunctionAST> parseTopLevelExpression();
std::unique_ptr<obelisk::PrototypeAST> parseExtern(); std::unique_ptr<obelisk::PrototypeAST> parseExtern();
std::unique_ptr<obelisk::ExpressionAST> parseAction();
std::unique_ptr<obelisk::ExpressionAST> parseRule();
std::unique_ptr<obelisk::ExpressionAST> parseFact();
public: public:
Parser(); Parser();
Parser(obelisk::Lexer* lexer);
~Parser();
obelisk::Lexer* getLexer(); std::unique_ptr<obelisk::Lexer>& getLexer();
int getCurrentToken(); int getCurrentToken();
@ -47,6 +48,9 @@ namespace obelisk
void handleDefinition(); void handleDefinition();
void handleExtern(); void handleExtern();
void handleTopLevelExpression(); void handleTopLevelExpression();
void handleAction();
void handleRule();
void handleFact();
}; };
} // namespace obelisk } // namespace obelisk