feature/documentation #12

Merged
cromer merged 26 commits from feature/documentation into develop 2023-02-03 23:21:29 -03:00
25 changed files with 3252 additions and 379 deletions

View File

@ -63,7 +63,7 @@ BreakBeforeTernaryOperators: true
BreakConstructorInitializers: AfterColon BreakConstructorInitializers: AfterColon
BreakInheritanceList: AfterColon BreakInheritanceList: AfterColon
BreakStringLiterals: false BreakStringLiterals: false
ColumnLimit: 80 ColumnLimit: 120
CommentPragmas: "^ IWYU pragma:" CommentPragmas: "^ IWYU pragma:"
CompactNamespaces: false CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerAllOnOneLineOrOnePerLine: true

View File

@ -1,98 +0,0 @@
[
{
"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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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",
"output": "src/obelisk.p/obelisk.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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",
"output": "src/obelisk.p/lexer.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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",
"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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MD -MQ src/obelisk.p/ast_call_expression_ast.cpp.o -MF src/obelisk.p/ast_call_expression_ast.cpp.o.d -o src/obelisk.p/ast_call_expression_ast.cpp.o -c ../src/ast/call_expression_ast.cpp",
"file": "../src/ast/call_expression_ast.cpp",
"output": "src/obelisk.p/ast_call_expression_ast.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MD -MQ src/obelisk.p/ast_error.cpp.o -MF src/obelisk.p/ast_error.cpp.o.d -o src/obelisk.p/ast_error.cpp.o -c ../src/ast/error.cpp",
"file": "../src/ast/error.cpp",
"output": "src/obelisk.p/ast_error.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MD -MQ src/obelisk.p/ast_function_ast.cpp.o -MF src/obelisk.p/ast_function_ast.cpp.o.d -o src/obelisk.p/ast_function_ast.cpp.o -c ../src/ast/function_ast.cpp",
"file": "../src/ast/function_ast.cpp",
"output": "src/obelisk.p/ast_function_ast.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MD -MQ src/obelisk.p/ast_number_expression_ast.cpp.o -MF src/obelisk.p/ast_number_expression_ast.cpp.o.d -o src/obelisk.p/ast_number_expression_ast.cpp.o -c ../src/ast/number_expression_ast.cpp",
"file": "../src/ast/number_expression_ast.cpp",
"output": "src/obelisk.p/ast_number_expression_ast.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MD -MQ src/obelisk.p/ast_prototype_ast.cpp.o -MF src/obelisk.p/ast_prototype_ast.cpp.o.d -o src/obelisk.p/ast_prototype_ast.cpp.o -c ../src/ast/prototype_ast.cpp",
"file": "../src/ast/prototype_ast.cpp",
"output": "src/obelisk.p/ast_prototype_ast.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -MD -MQ src/obelisk.p/ast_variable_expression_ast.cpp.o -MF src/obelisk.p/ast_variable_expression_ast.cpp.o.d -o src/obelisk.p/ast_variable_expression_ast.cpp.o -c ../src/ast/variable_expression_ast.cpp",
"file": "../src/ast/variable_expression_ast.cpp",
"output": "src/obelisk.p/ast_variable_expression_ast.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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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 -isystem/usr/lib/llvm-14/include -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -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"
}
]

2659
doc/doxygen.conf.in Normal file

File diff suppressed because it is too large Load Diff

18
doc/meson.build Normal file
View File

@ -0,0 +1,18 @@
cdata.set('TOP_SRCDIR', meson.project_source_root())
cdata.set('TOP_BUILDDIR', meson.project_build_root())
doxyfile = configure_file(input: 'doxygen.conf.in',
output: 'doxygen.conf',
configuration: cdata,
install: false
)
datadir = join_paths(get_option('datadir'), 'doc', 'obelisk')
html_target = custom_target('obelisk-docs',
input: doxyfile,
output: 'html',
command: [doxygen, doxyfile],
install: true,
install_dir: datadir
)

View File

@ -1,6 +1,7 @@
project('obelisk', project('obelisk',
'cpp', 'cpp',
version : '1.0.0', version : '1.0.0',
license : 'BSD-3-Clause',
default_options : [ default_options : [
'warning_level=3', 'warning_level=3',
'c_std=c17', 'c_std=c17',
@ -8,4 +9,21 @@ project('obelisk',
] ]
) )
llvm = dependency('llvm', version: '>= 14.0.0', modules : ['core', 'target', 'mcjit', 'nativecodegen'], required : true, method: 'config-tool')
doxygen = find_program('doxygen', required : false)
cdata = configuration_data()
cdata.set('VERSION', meson.project_version())
if find_program('dot', required : false).found()
cdata.set('HAVE_DOT', 'YES')
else
cdata.set('HAVE_DOT', 'NO')
endif
if doxygen.found()
subdir('doc')
endif
subdir('src') subdir('src')

View File

@ -22,8 +22,7 @@ namespace obelisk
void setArgs(std::vector<std::unique_ptr<ExpressionAST>> args); void setArgs(std::vector<std::unique_ptr<ExpressionAST>> args);
public: public:
CallExpressionAST(const std::string &callee, CallExpressionAST(const std::string &callee, std::vector<std::unique_ptr<ExpressionAST>> args) :
std::vector<std::unique_ptr<ExpressionAST>> args) :
callee_(callee), callee_(callee),
args_(std::move(args)) args_(std::move(args))
{ {

View File

@ -17,8 +17,7 @@ llvm::Function *obelisk::FunctionAST::codegen()
return nullptr; return nullptr;
} }
llvm::BasicBlock *bB llvm::BasicBlock *bB = llvm::BasicBlock::Create(*TheContext, "entry", theFunction);
= llvm::BasicBlock::Create(*TheContext, "entry", theFunction);
Builder->SetInsertPoint(bB); Builder->SetInsertPoint(bB);
NamedValues.clear(); NamedValues.clear();

View File

@ -18,8 +18,7 @@ namespace obelisk
void setPrototype(std::unique_ptr<PrototypeAST> prototype); void setPrototype(std::unique_ptr<PrototypeAST> prototype);
public: public:
FunctionAST(std::unique_ptr<PrototypeAST> prototype, FunctionAST(std::unique_ptr<PrototypeAST> prototype, std::unique_ptr<ExpressionAST> body) :
std::unique_ptr<ExpressionAST> body) :
prototype_(std::move(prototype)), prototype_(std::move(prototype)),
body_(std::move(body)) body_(std::move(body))
{ {

View File

@ -3,17 +3,10 @@
llvm::Function *obelisk::PrototypeAST::codegen() llvm::Function *obelisk::PrototypeAST::codegen()
{ {
std::vector<llvm::Type *> doubles(args_.size(), std::vector<llvm::Type *> doubles(args_.size(), llvm::Type::getDoubleTy(*TheContext));
llvm::Type::getDoubleTy(*TheContext)); llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::getDoubleTy(*TheContext), doubles, false);
llvm::FunctionType *FT
= llvm::FunctionType::get(llvm::Type::getDoubleTy(*TheContext),
doubles,
false);
llvm::Function *F = llvm::Function::Create(FT, llvm::Function *F = llvm::Function::Create(FT, llvm::Function::ExternalLinkage, name_, obelisk::TheModule.get());
llvm::Function::ExternalLinkage,
name_,
obelisk::TheModule.get());
unsigned idx = 0; unsigned idx = 0;
for (auto &arg : F->args()) for (auto &arg : F->args())

View File

@ -19,8 +19,7 @@ namespace obelisk
void setArgs(std::vector<std::string> args); void setArgs(std::vector<std::string> args);
public: public:
PrototypeAST(const std::string& name, PrototypeAST(const std::string& name, std::vector<std::string> args) :
std::vector<std::string> args) :
name_(name), name_(name),
args_(std::move(args)) args_(std::move(args))
{ {

View File

@ -47,20 +47,10 @@ obelisk::KnowledgeBase::~KnowledgeBase()
} }
} }
/**
* @brief Enable foreign key functionality in the open database.
*
* This must always be done when the connection is opened or it will not
* enforce the foreign key constraints.
*/
void obelisk::KnowledgeBase::enableForeignKeys() void obelisk::KnowledgeBase::enableForeignKeys()
{ {
char* errmsg; char* errmsg;
int result = sqlite3_exec(dbConnection_, int result = sqlite3_exec(dbConnection_, "PRAGMA foreign_keys = ON;", NULL, NULL, &errmsg);
"PRAGMA foreign_keys = ON;",
NULL,
NULL,
&errmsg);
if (result != SQLITE_OK) if (result != SQLITE_OK)
{ {
if (errmsg) if (errmsg)
@ -99,12 +89,10 @@ void obelisk::KnowledgeBase::addEntities(std::vector<obelisk::Entity>& entities)
{ {
entity.insertEntity(dbConnection_); entity.insertEntity(dbConnection_);
} }
catch (obelisk::DatabaseException::ConstraintException& exception) catch (obelisk::DatabaseConstraintException& exception)
{ {
// ignore unique constraint error // ignore unique constraint error
if (std::strcmp(exception.what(), if (std::strcmp(exception.what(), "UNIQUE constraint failed: entity.name") != 0)
"UNIQUE constraint failed: entity.name")
!= 0)
{ {
throw; throw;
} }
@ -120,12 +108,10 @@ void obelisk::KnowledgeBase::addVerbs(std::vector<obelisk::Verb>& verbs)
{ {
verb.insertVerb(dbConnection_); verb.insertVerb(dbConnection_);
} }
catch (obelisk::DatabaseException::ConstraintException& exception) catch (obelisk::DatabaseConstraintException& exception)
{ {
// ignore unique constraint error // ignore unique constraint error
if (std::strcmp(exception.what(), if (std::strcmp(exception.what(), "UNIQUE constraint failed: verb.name") != 0)
"UNIQUE constraint failed: verb.name")
!= 0)
{ {
throw; throw;
} }
@ -141,7 +127,7 @@ void obelisk::KnowledgeBase::addFacts(std::vector<obelisk::Fact>& facts)
{ {
fact.insertFact(dbConnection_); fact.insertFact(dbConnection_);
} }
catch (obelisk::DatabaseException::ConstraintException& exception) catch (obelisk::DatabaseConstraintException& exception)
{ {
// ignore unique constraint error // ignore unique constraint error
if (std::strcmp(exception.what(), if (std::strcmp(exception.what(),
@ -169,9 +155,7 @@ void obelisk::KnowledgeBase::getFact(obelisk::Fact& fact)
fact.selectFact(dbConnection_); fact.selectFact(dbConnection_);
} }
void obelisk::KnowledgeBase::getFloat(float& result1, void obelisk::KnowledgeBase::getFloat(float& result1, float& result2, double var)
float& result2,
double var)
{ {
result1 = (float) var; result1 = (float) var;
result2 = (float) (var - (double) result1); result2 = (float) (var - (double) result1);

View File

@ -14,57 +14,188 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The KnowledgeBase class represents a collection of facts, rules,
* actions, and related language connectors.
*
*/
class KnowledgeBase class KnowledgeBase
{ {
private: private:
const int DEFAULT_FLAGS /**
= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; * @brief The filename of the opened knowledge base.
*
*/
const char* filename_; const char* filename_;
/**
* @brief The SQLite connection handle.
*
*/
sqlite3* dbConnection_ = nullptr; sqlite3* dbConnection_ = nullptr;
/**
* @brief The user passed flags to use when opening the database.
*
*/
int flags_; int flags_;
/**
* @brief Enable foreign key functionality in the open database.
*
* This must always be done when the connection is opened or it will
* not enforce the foreign key constraints.
*/
void enableForeignKeys(); void enableForeignKeys();
/**
* @brief Create the tables in the database.
*
* @param[in] function This function is called to create the table.
*/
void createTable(std::function<const char*()> function); void createTable(std::function<const char*()> function);
public: public:
/**
* @brief Construct a new KnowledgeBase object.
*
* @param[in] filename The name of the file to save the knowledge
* base as.
* @param[in] flags The flags to open the knowledge base with.
*/
KnowledgeBase(const char* filename, int flags); KnowledgeBase(const char* filename, int flags);
/**
* @brief Construct a new KnowledgeBase object.
*
* @param[in] filename The name of the file to save the knowledge
* base as.
*/
KnowledgeBase(const char* filename) : KnowledgeBase(const char* filename) :
KnowledgeBase(filename, KnowledgeBase(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
{ {
} }
/**
* @brief Destroy the KnowledgeBase object.
*
* This will close the opened knowledge base before destroying it.
*/
~KnowledgeBase(); ~KnowledgeBase();
/**
* @brief Add entities to the knowledge base.
*
* @param[in,out] entities The entities to add. If the insert is
* successful it will have a row ID, if not the ID will be 0.
*/
void addEntities(std::vector<obelisk::Entity>& entities); void addEntities(std::vector<obelisk::Entity>& entities);
/**
* @brief Add verbs to the knowledge base.
*
* @param[in,out] verbs The verbs to add. If the insert is
* successful it will have a row ID, if not the ID will be 0.
*/
void addVerbs(std::vector<obelisk::Verb>& verbs); void addVerbs(std::vector<obelisk::Verb>& verbs);
/**
* @brief Add facts to the database.
*
* @param[in,out] facts The facts to add. If the insert is
* successful it will have a row ID, if not the ID will be 0.
*/
void addFacts(std::vector<obelisk::Fact>& facts); void addFacts(std::vector<obelisk::Fact>& facts);
/**
* @brief Get an entity object based on the ID it contains.
*
* @param[in,out] entity The Entity object should contain just the
* ID and the rest will be filled in.
*/
void getEntity(obelisk::Entity& entity); void getEntity(obelisk::Entity& entity);
/**
* @brief Get a verb object based on the ID it contains.
*
* @param[in,out] verb The Verb object should contain just the ID
* and the rest will be filled in.
*/
void getVerb(obelisk::Verb& verb); void getVerb(obelisk::Verb& verb);
/**
* @brief Get a fact object based on the ID it contains.
*
* @param[in,out] fact The fact object should contain just the ID
* and the rest will be filled in.
*/
void getFact(obelisk::Fact& fact); void getFact(obelisk::Fact& fact);
void getDouble(double& result, float var1, float var2); /**
* @brief Take a float and divide it into 2 floats.
*
* This is useful to store doubles in SQLite since SQLite doesn't
* have a double type.
* Instead just store the 2 floats in the database. Then after
* selecting them combine them.
*
* @param[out] result1 The first float generated from the double.
* @param[out] result2 The second float generated from the double.
* @param[in] var The double to split into the 2 floats.
*/
void getFloat(float& result1, float& result2, double var); void getFloat(float& result1, float& result2, double var);
/**
* @brief Combines 2 separated floats back into a double.
*
* This will recombine the separated floats from the getFloat
* method.
*
* @param[out] result The double generated from the combined floats.
* @param[in] var1 The first float to combine.
* @param[in] var2 The second float to combine.
*/
void getDouble(double& result, float var1, float var2);
}; };
/**
* @brief Exception thrown by the KnowledgeBase.
*
*/
class KnowledgeBaseException : public std::exception class KnowledgeBaseException : public std::exception
{ {
private: private:
/**
* @brief The error message given.
*
*/
const std::string errorMessage_; const std::string errorMessage_;
public: public:
/**
* @brief Construct a new KnowledgeBaseException object.
*
*/
KnowledgeBaseException() : KnowledgeBaseException() :
errorMessage_("an unknown error ocurred") errorMessage_("an unknown error ocurred")
{ {
} }
/**
* @brief Construct a new KnowledgeBaseException object.
*
* @param[in] errorMessage The error message given when thrown.
*/
KnowledgeBaseException(const std::string& errorMessage) : KnowledgeBaseException(const std::string& errorMessage) :
errorMessage_(errorMessage) errorMessage_(errorMessage)
{ {
} }
/**
* @brief Get the error message that occurred.
*
* @return const char* Returns the error message.
*/
const char* what() const noexcept const char* what() const noexcept
{ {
return errorMessage_.c_str(); return errorMessage_.c_str();

View File

@ -5,58 +5,178 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The Lexer reads and identifies tokens in the obelisk source code.
*
*/
class Lexer class Lexer
{ {
private: private:
/**
* @brief The last found identifier.
*
*/
std::string identifier_; std::string identifier_;
/**
* @brief The last found number.
*
*/
double numberValue_; double numberValue_;
/**
* @brief Set the identifier.
*
* @param[in] identifier The new identifier.
*/
void setIdentifier(const std::string& identifier); void setIdentifier(const std::string& identifier);
/**
* @brief Erase the last identifier.
*
*/
void eraseIdentifier(); void eraseIdentifier();
/**
* @brief Add the last found char to the end of the identifier.
*
* @param[in] lastChar The last char that was found.
*/
void appendIdentifier(int lastChar); void appendIdentifier(int lastChar);
/**
* @brief Set the number value.
*
* @param[in] numberValue The new number value.
*/
void setNumberValue(double numberValue); void setNumberValue(double numberValue);
/**
* @brief Comment the rest of the line.
*
* @param[in] lastChar The char to check to see if it in the end of
* the line.
*/
void commentLine(int* lastChar); void commentLine(int* lastChar);
public: public:
/**
* @brief These token represent recognized language keywords and
* language functionality.
*
*/
enum Token enum Token
{ {
/**
* @brief End of file is returned when the source code is
* finished.
*
*/
kTokenEof = -1, kTokenEof = -1,
// commands /**
* @brief A fact which is a relationship between 2 entities.
*
*/
kTokenFact = -2, kTokenFact = -2,
/**
* @brief A rule which is a relationship between a new fact a
* existing fact.
*
*/
kTokenRule = -3, kTokenRule = -3,
/**
* @brief An action to take if a fact is true.
*
*/
kTokenAction = -4, kTokenAction = -4,
/**
* @brief A definition of a new function.
*
*/
kTokenDef = -5, kTokenDef = -5,
/**
* @brief An external function that will be linked to.
*
*/
kTokenExtern = -6, kTokenExtern = -6,
// primary /**
* @brief An identifier which is a alphanumeric value.
*
*/
kTokenIdentifier = -7, kTokenIdentifier = -7,
/**
* @brief A double floating point value.
*
*/
kTokenNumber = -8, kTokenNumber = -8,
/**
* @brief A string.
*
*/
kTokenString = -9 kTokenString = -9
}; };
/**
* @brief Gets the next token in the source code.
*
* @throws LexerException when an invalid token is found.
* @return int Returns a Token value or char if no known token was
* found.
*/
int getToken(); int getToken();
/**
* @brief Get the last identifier.
*
* @return const std::string& Returns a string that contains the
* last found identifier.
*/
const std::string& getIdentifier(); const std::string& getIdentifier();
/**
* @brief Get the last number value.
*
* @return double Return the last number that was found.
*/
double getNumberValue(); double getNumberValue();
}; };
/**
* @brief Lexer exception class.
*
*/
class LexerException : public std::exception class LexerException : public std::exception
{ {
private: private:
/**
* @brief The error message from the exception.
*
*/
const std::string errorMessage_; const std::string errorMessage_;
public: public:
/**
* @brief Construct a new LexerException object.
*
*/
LexerException() : LexerException() :
errorMessage_("an unknown error ocurred") errorMessage_("an unknown error ocurred")
{ {
} }
/**
* @brief Construct a new LexerException object.
*
* @param[in] errorMessage Error message to include.
*/
LexerException(const std::string& errorMessage) : LexerException(const std::string& errorMessage) :
errorMessage_(errorMessage) errorMessage_(errorMessage)
{ {
} }
/**
* @brief Return the exception's error message.
*
* @return const char* Returns a string containing the error
* message.
*/
const char* what() const noexcept const char* what() const noexcept
{ {
return errorMessage_.c_str(); return errorMessage_.c_str();

View File

@ -5,43 +5,104 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The Action model represents an action to take when a fact is true
* or false.
*
*/
class Action class Action
{ {
private: private:
/**
* @brief The ID of the Action in the knowledge base.
*
*/
int id_; int id_;
/**
* @brief The name of the Action.
*
*/
std::string name_; std::string name_;
public: public:
/**
* @brief Construct a new Action object.
*
*/
Action() : Action() :
id_(0), id_(0),
name_("") name_("")
{ {
} }
/**
* @brief Construct a new Action object.
*
* @param[in] id The ID of the Action.
*/
Action(int id) : Action(int id) :
id_(id), id_(id),
name_("") name_("")
{ {
} }
/**
* @brief Construct a new Action object.
*
* @param[in] name The name of the Action.
*/
Action(std::string name) : Action(std::string name) :
id_(0), id_(0),
name_(name) name_(name)
{ {
} }
/**
* @brief Construct a new Action object.
*
* @param[in] id The ID of the Action.
* @param[in] name The name of the Action.
*/
Action(int id, std::string name) : Action(int id, std::string name) :
id_(id), id_(id),
name_(name) name_(name)
{ {
} }
/**
* @brief Create the Action table in the knowledge base.
*
* @return const char* Returns the query used to create the table.
*/
static const char* createTable(); static const char* createTable();
/**
* @brief Get the ID of the Action.
*
* @return int& Returns the ID.
*/
int& getId(); int& getId();
/**
* @brief Set the ID of the Action.
*
* @param[in] id Set the ID of the Action.
*/
void setId(int id); void setId(int id);
/**
* @brief Get the name of the Action.
*
* @return std::string& The Action name.
*/
std::string& getName(); std::string& getName();
/**
* @brief Set the name of the Action.
*
* @param[in] name The name of the Action.
*/
void setName(std::string name); void setName(std::string name);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -21,11 +21,7 @@ void obelisk::Entity::selectEntity(sqlite3* dbConnection)
sqlite3_stmt* ppStmt = nullptr; sqlite3_stmt* ppStmt = nullptr;
auto result = sqlite3_prepare_v2(dbConnection, auto result = sqlite3_prepare_v2(dbConnection, "SELECT id, name FROM entity WHERE name=?", -1, &ppStmt, nullptr);
"SELECT id, name FROM entity WHERE name=?",
-1,
&ppStmt,
nullptr);
if (result != SQLITE_OK) if (result != SQLITE_OK)
{ {
@ -38,13 +34,13 @@ void obelisk::Entity::selectEntity(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -62,10 +58,10 @@ void obelisk::Entity::selectEntity(sqlite3* dbConnection)
setName((char*) sqlite3_column_text(ppStmt, 1)); setName((char*) sqlite3_column_text(ppStmt, 1));
break; break;
case SQLITE_BUSY : case SQLITE_BUSY :
throw obelisk::DatabaseException::BusyException(); throw obelisk::DatabaseBusyException();
break; break;
case SQLITE_MISUSE : case SQLITE_MISUSE :
throw obelisk::DatabaseException::MisuseException(); throw obelisk::DatabaseMisuseException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -89,30 +85,25 @@ void obelisk::Entity::insertEntity(sqlite3* dbConnection)
sqlite3_stmt* ppStmt = nullptr; sqlite3_stmt* ppStmt = nullptr;
auto result = sqlite3_prepare_v2(dbConnection, auto result = sqlite3_prepare_v2(dbConnection, "INSERT INTO entity (name) VALUES (?)", -1, &ppStmt, nullptr);
"INSERT INTO entity (name) VALUES (?)",
-1,
&ppStmt,
nullptr);
if (result != SQLITE_OK) if (result != SQLITE_OK)
{ {
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
} }
result result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
switch (result) switch (result)
{ {
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -127,13 +118,12 @@ void obelisk::Entity::insertEntity(sqlite3* dbConnection)
sqlite3_set_last_insert_rowid(dbConnection, 0); sqlite3_set_last_insert_rowid(dbConnection, 0);
break; break;
case SQLITE_CONSTRAINT : case SQLITE_CONSTRAINT :
throw obelisk::DatabaseException::ConstraintException( throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
sqlite3_errmsg(dbConnection));
case SQLITE_BUSY : case SQLITE_BUSY :
throw obelisk::DatabaseException::BusyException(); throw obelisk::DatabaseBusyException();
break; break;
case SQLITE_MISUSE : case SQLITE_MISUSE :
throw obelisk::DatabaseException::MisuseException(); throw obelisk::DatabaseMisuseException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));

View File

@ -7,46 +7,119 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The Entity model represents either a left or right side entity,
* typically used in facts and rules.
*
*/
class Entity class Entity
{ {
private: private:
/**
* @brief The ID of the Entity.
*
*/
int id_; int id_;
/**
* @brief The name of the Entity.
*
*/
std::string name_; std::string name_;
public: public:
/**
* @brief Construct a new Entity object.
*
*/
Entity() : Entity() :
id_(0), id_(0),
name_("") name_("")
{ {
} }
/**
* @brief Construct a new Entity object.
*
* @param[in] id The ID of the Entity.
*/
Entity(int id) : Entity(int id) :
id_(id), id_(id),
name_("") name_("")
{ {
} }
/**
* @brief Construct a new Entity object.
*
* @param[in] name The name of the Entity.
*/
Entity(std::string name) : Entity(std::string name) :
id_(0), id_(0),
name_(name) name_(name)
{ {
} }
/**
* @brief Construct a new Entity object.
*
* @param[in] id The ID of the Entity.
* @param[in] name The name of the Entity.
*/
Entity(int id, std::string name) : Entity(int id, std::string name) :
id_(id), id_(id),
name_(name) name_(name)
{ {
} }
/**
* @brief Create the table in the knowledge base.
*
* @return const char* Returns the query used to create the table.
*/
static const char* createTable(); static const char* createTable();
/**
* @brief Get the ID of the Entity.
*
* @return int& Returns the ID.
*/
int& getId(); int& getId();
/**
* @brief Set the ID of the Entity.
*
* @param[in] id The ID of the Entity.
*/
void setId(int id); void setId(int id);
/**
* @brief Get the name of the Entity.
*
* @return std::string& The name of the Entity.
*/
std::string& getName(); std::string& getName();
/**
* @brief Set the name of the Entity.
*
* @param[in] name The name of the Entity.
*/
void setName(std::string name); void setName(std::string name);
/**
* @brief Select an Entity from the database based on the object's
* ID.
*
* @param[in] dbConnection The database connection to use.
*/
void selectEntity(sqlite3* dbConnection); void selectEntity(sqlite3* dbConnection);
/**
* @brief Insert an Entity into the database based on the object's
* fields.
*
* @param[in] dbConnection The database connection to use.
*/
void insertEntity(sqlite3* dbConnection); void insertEntity(sqlite3* dbConnection);
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -8,8 +8,8 @@ namespace obelisk
{ {
class DatabaseException : public std::exception class DatabaseException : public std::exception
{ {
private: protected:
const std::string errorMessage_; std::string errorMessage_;
public: public:
DatabaseException() : DatabaseException() :
@ -18,8 +18,7 @@ namespace obelisk
} }
DatabaseException(const int errorCode) : DatabaseException(const int errorCode) :
errorMessage_( errorMessage_("database error " + std::to_string(errorCode) + " ocurred")
"database error " + std::to_string(errorCode) + " ocurred")
{ {
} }
@ -28,118 +27,75 @@ namespace obelisk
{ {
} }
const char* what() const noexcept virtual const char* what() const noexcept
{ {
return errorMessage_.c_str(); return errorMessage_.c_str();
} }
class SizeException : public std::exception virtual void setErrorMessage(const std::string errorMessage)
{ {
private: errorMessage_ = errorMessage;
const std::string errorMessage_;
public:
SizeException() :
errorMessage_("size of string or blob exceeds limits")
{
}
const char* what() const noexcept
{
return errorMessage_.c_str();
} }
}; };
class RangeException : public std::exception class DatabaseSizeException : public obelisk::DatabaseException
{ {
private:
const std::string errorMessage_;
public: public:
RangeException() : DatabaseSizeException()
errorMessage_("parameter index is out of range")
{ {
} setErrorMessage("size of string or blob exceeds limits");
const char* what() const noexcept
{
return errorMessage_.c_str();
} }
}; };
class MemoryException : public std::exception class DatabaseRangeException : public obelisk::DatabaseException
{ {
private:
const std::string errorMessage_;
public: public:
MemoryException() : DatabaseRangeException()
errorMessage_("not enough memory for operation")
{ {
} setErrorMessage("parameter index is out of range");
const char* what() const noexcept
{
return errorMessage_.c_str();
} }
}; };
class BusyException : public std::exception class DatabaseMemoryException : public obelisk::DatabaseException
{ {
private:
const std::string errorMessage_;
public: public:
BusyException() : DatabaseMemoryException()
errorMessage_(
"database was busy and operation not performed")
{ {
} setErrorMessage("not enough memory for operation");
const char* what() const noexcept
{
return errorMessage_.c_str();
} }
}; };
class MisuseException : public std::exception class DatabaseBusyException : public obelisk::DatabaseException
{ {
private:
const std::string errorMessage_;
public: public:
MisuseException() : DatabaseBusyException()
errorMessage_("misuse of the database routine")
{ {
} setErrorMessage("database was busy and operation was not performed");
const char* what() const noexcept
{
return errorMessage_.c_str();
} }
}; };
class ConstraintException : public std::exception class DatabaseMisuseException : public obelisk::DatabaseException
{ {
private:
const std::string errorMessage_;
public: public:
ConstraintException() : DatabaseMisuseException()
errorMessage_("a constraint exception occurred")
{
}
ConstraintException(const std::string& errorMessage) :
errorMessage_(errorMessage)
{ {
} setErrorMessage("misuse of the database routine");
const char* what() const noexcept
{
return errorMessage_.c_str();
} }
}; };
class DatabaseConstraintException : public obelisk::DatabaseException
{
public:
DatabaseConstraintException()
{
setErrorMessage("a constraint exception occurred");
}
DatabaseConstraintException(const std::string& errorMessage)
{
setErrorMessage(errorMessage);
}
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -9,6 +9,7 @@ const char* obelisk::Fact::createTable()
"left_entity" INTEGER NOT NULL, "left_entity" INTEGER NOT NULL,
"right_entity" INTEGER NOT NULL, "right_entity" INTEGER NOT NULL,
"verb" INTEGER NOT NULL, "verb" INTEGER NOT NULL,
"is_true" INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY("id" AUTOINCREMENT), PRIMARY KEY("id" AUTOINCREMENT),
UNIQUE("left_entity", "right_entity", "verb") UNIQUE("left_entity", "right_entity", "verb")
FOREIGN KEY("verb") REFERENCES "verb"("id") ON DELETE RESTRICT, FOREIGN KEY("verb") REFERENCES "verb"("id") ON DELETE RESTRICT,
@ -43,13 +44,13 @@ void obelisk::Fact::selectFact(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -62,13 +63,13 @@ void obelisk::Fact::selectFact(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -81,13 +82,13 @@ void obelisk::Fact::selectFact(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -107,10 +108,10 @@ void obelisk::Fact::selectFact(sqlite3* dbConnection)
getVerb().setId(sqlite3_column_int(ppStmt, 3)); getVerb().setId(sqlite3_column_int(ppStmt, 3));
break; break;
case SQLITE_BUSY : case SQLITE_BUSY :
throw obelisk::DatabaseException::BusyException(); throw obelisk::DatabaseBusyException();
break; break;
case SQLITE_MISUSE : case SQLITE_MISUSE :
throw obelisk::DatabaseException::MisuseException(); throw obelisk::DatabaseMisuseException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -149,13 +150,13 @@ void obelisk::Fact::insertFact(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -168,13 +169,13 @@ void obelisk::Fact::insertFact(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -187,13 +188,13 @@ void obelisk::Fact::insertFact(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -208,13 +209,12 @@ void obelisk::Fact::insertFact(sqlite3* dbConnection)
sqlite3_set_last_insert_rowid(dbConnection, 0); sqlite3_set_last_insert_rowid(dbConnection, 0);
break; break;
case SQLITE_CONSTRAINT : case SQLITE_CONSTRAINT :
throw obelisk::DatabaseException::ConstraintException( throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
sqlite3_errmsg(dbConnection));
case SQLITE_BUSY : case SQLITE_BUSY :
throw obelisk::DatabaseException::BusyException(); throw obelisk::DatabaseBusyException();
break; break;
case SQLITE_MISUSE : case SQLITE_MISUSE :
throw obelisk::DatabaseException::MisuseException(); throw obelisk::DatabaseMisuseException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));

View File

@ -34,9 +34,7 @@ namespace obelisk
{ {
} }
Fact(obelisk::Entity leftEntity, Fact(obelisk::Entity leftEntity, obelisk::Entity rightEntity, obelisk::Verb verb) :
obelisk::Entity rightEntity,
obelisk::Verb verb) :
id_(0), id_(0),
leftEntity_(leftEntity), leftEntity_(leftEntity),
rightEntity_(rightEntity), rightEntity_(rightEntity),
@ -44,10 +42,7 @@ namespace obelisk
{ {
} }
Fact(int id, Fact(int id, obelisk::Entity leftEntity, obelisk::Entity rightEntity, obelisk::Verb verb) :
obelisk::Entity leftEntity,
obelisk::Entity rightEntity,
obelisk::Verb verb) :
id_(id), id_(id),
leftEntity_(leftEntity), leftEntity_(leftEntity),
rightEntity_(rightEntity), rightEntity_(rightEntity),

View File

@ -33,9 +33,7 @@ namespace obelisk
{ {
} }
SuggestAction(obelisk::Fact fact, SuggestAction(obelisk::Fact fact, obelisk::Action trueAction, obelisk::Action falseAction) :
obelisk::Action trueAction,
obelisk::Action falseAction) :
id_(0), id_(0),
fact_(fact), fact_(fact),
trueAction_(trueAction), trueAction_(trueAction),
@ -43,10 +41,7 @@ namespace obelisk
{ {
} }
SuggestAction(int id, SuggestAction(int id, obelisk::Fact fact, obelisk::Action trueAction, obelisk::Action falseAction) :
obelisk::Fact fact,
obelisk::Action trueAction,
obelisk::Action falseAction) :
id_(id), id_(id),
fact_(fact), fact_(fact),
trueAction_(trueAction), trueAction_(trueAction),

View File

@ -23,11 +23,7 @@ void obelisk::Verb::selectVerb(sqlite3* dbConnection)
sqlite3_stmt* ppStmt = nullptr; sqlite3_stmt* ppStmt = nullptr;
auto result = sqlite3_prepare_v2(dbConnection, auto result = sqlite3_prepare_v2(dbConnection, "SELECT id, name FROM verb WHERE name=?", -1, &ppStmt, nullptr);
"SELECT id, name FROM verb WHERE name=?",
-1,
&ppStmt,
nullptr);
if (result != SQLITE_OK) if (result != SQLITE_OK)
{ {
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -39,13 +35,13 @@ void obelisk::Verb::selectVerb(sqlite3* dbConnection)
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -63,10 +59,10 @@ void obelisk::Verb::selectVerb(sqlite3* dbConnection)
setName((char*) sqlite3_column_text(ppStmt, 1)); setName((char*) sqlite3_column_text(ppStmt, 1));
break; break;
case SQLITE_BUSY : case SQLITE_BUSY :
throw obelisk::DatabaseException::BusyException(); throw obelisk::DatabaseBusyException();
break; break;
case SQLITE_MISUSE : case SQLITE_MISUSE :
throw obelisk::DatabaseException::MisuseException(); throw obelisk::DatabaseMisuseException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -89,30 +85,25 @@ void obelisk::Verb::insertVerb(sqlite3* dbConnection)
sqlite3_stmt* ppStmt = nullptr; sqlite3_stmt* ppStmt = nullptr;
auto result = sqlite3_prepare_v2(dbConnection, auto result = sqlite3_prepare_v2(dbConnection, "INSERT INTO verb (name) VALUES (?)", -1, &ppStmt, nullptr);
"INSERT INTO verb (name) VALUES (?)",
-1,
&ppStmt,
nullptr);
if (result != SQLITE_OK) if (result != SQLITE_OK)
{ {
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
} }
result result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
switch (result) switch (result)
{ {
case SQLITE_OK : case SQLITE_OK :
break; break;
case SQLITE_TOOBIG : case SQLITE_TOOBIG :
throw obelisk::DatabaseException::SizeException(); throw obelisk::DatabaseSizeException();
break; break;
case SQLITE_RANGE : case SQLITE_RANGE :
throw obelisk::DatabaseException::RangeException(); throw obelisk::DatabaseRangeException();
break; break;
case SQLITE_NOMEM : case SQLITE_NOMEM :
throw obelisk::DatabaseException::MemoryException(); throw obelisk::DatabaseMemoryException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
@ -127,13 +118,12 @@ void obelisk::Verb::insertVerb(sqlite3* dbConnection)
sqlite3_set_last_insert_rowid(dbConnection, 0); sqlite3_set_last_insert_rowid(dbConnection, 0);
break; break;
case SQLITE_CONSTRAINT : case SQLITE_CONSTRAINT :
throw obelisk::DatabaseException::ConstraintException( throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
sqlite3_errmsg(dbConnection));
case SQLITE_BUSY : case SQLITE_BUSY :
throw obelisk::DatabaseException::BusyException(); throw obelisk::DatabaseBusyException();
break; break;
case SQLITE_MISUSE : case SQLITE_MISUSE :
throw obelisk::DatabaseException::MisuseException(); throw obelisk::DatabaseMisuseException();
break; break;
default : default :
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection)); throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));

View File

@ -8,15 +8,14 @@
#include <limits> #include <limits>
#include <memory> #include <memory>
static int mainLoop() static int obelisk::mainLoop()
{ {
auto parser = std::unique_ptr<obelisk::Parser> {new obelisk::Parser()}; auto parser = std::unique_ptr<obelisk::Parser> {new obelisk::Parser()};
std::unique_ptr<obelisk::KnowledgeBase> kb; std::unique_ptr<obelisk::KnowledgeBase> kb;
try try
{ {
kb = std::unique_ptr<obelisk::KnowledgeBase> { kb = std::unique_ptr<obelisk::KnowledgeBase> {new obelisk::KnowledgeBase("cromer.kb")};
new obelisk::KnowledgeBase("cromer.kb")};
} }
catch (obelisk::KnowledgeBaseException& exception) catch (obelisk::KnowledgeBaseException& exception)
{ {
@ -44,10 +43,8 @@ static int mainLoop()
case obelisk::Lexer::kTokenEof : case obelisk::Lexer::kTokenEof :
return EXIT_SUCCESS; return EXIT_SUCCESS;
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; std::cout << "Num: " << parser->getLexer()->getNumberValue() << std::endl;
std::cout << "Num: " << parser->getLexer()->getNumberValue()
<< std::endl;
try try
{ {
parser->getNextToken(); parser->getNextToken();
@ -109,5 +106,5 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
}*/ }*/
return mainLoop(); return obelisk::mainLoop();
} }

View File

@ -1 +1,15 @@
static int mainLoop(); /**
* @brief The obelisk namespace contains everything needed to compile obelisk
* code.
*
*/
namespace obelisk
{
/**
* @brief This is the main loop for obelisk.
* This loop handles lexing and parsing of obelisk source code.
*
* @return int Returns EXIT_SUCCESS or EXIT_FAILURE.
*/
static int mainLoop();
} // namespace obelisk

View File

@ -44,15 +44,13 @@ void obelisk::Parser::setCurrentToken(int currentToken)
currentToken_ = currentToken; currentToken_ = currentToken;
} }
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::logError( std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::logError(const char* str)
const char* str)
{ {
fprintf(stderr, "Error: %s\n", str); fprintf(stderr, "Error: %s\n", str);
return nullptr; return nullptr;
} }
std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::logErrorPrototype( std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::logErrorPrototype(const char* str)
const char* str)
{ {
logError(str); logError(str);
return nullptr; return nullptr;
@ -86,14 +84,12 @@ std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parsePrimary()
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseNumberExpression() 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 result; return result;
} }
std::unique_ptr<obelisk::ExpressionAST> std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseParenthesisExpression()
obelisk::Parser::parseParenthesisExpression()
{ {
getNextToken(); getNextToken();
auto v = parseExpression(); auto v = parseExpression();
@ -110,8 +106,7 @@ std::unique_ptr<obelisk::ExpressionAST>
return v; return v;
} }
std::unique_ptr<obelisk::ExpressionAST> std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseIdentifierExpression()
obelisk::Parser::parseIdentifierExpression()
{ {
std::string idName = getLexer()->getIdentifier(); std::string idName = getLexer()->getIdentifier();
getNextToken(); getNextToken();
@ -181,8 +176,7 @@ std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::parsePrototype()
getNextToken(); getNextToken();
return std::make_unique<obelisk::PrototypeAST>(functionName, return std::make_unique<obelisk::PrototypeAST>(functionName, std::move(argNames));
std::move(argNames));
} }
std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseDefinition() std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseDefinition()
@ -196,8 +190,7 @@ std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseDefinition()
if (auto expression = parseExpression()) if (auto expression = parseExpression())
{ {
return std::make_unique<FunctionAST>(std::move(prototype), return std::make_unique<FunctionAST>(std::move(prototype), std::move(expression));
std::move(expression));
} }
return nullptr; return nullptr;
@ -208,10 +201,8 @@ std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseTopLevelExpression()
if (auto expression = parseExpression()) if (auto expression = parseExpression())
{ {
// Make an anonymous prototype // Make an anonymous prototype
auto prototype = std::make_unique<obelisk::PrototypeAST>("__anon_expr", auto prototype = std::make_unique<obelisk::PrototypeAST>("__anon_expr", std::vector<std::string>());
std::vector<std::string>()); return std::make_unique<obelisk::FunctionAST>(std::move(prototype), std::move(expression));
return std::make_unique<obelisk::FunctionAST>(std::move(prototype),
std::move(expression));
} }
return nullptr; return nullptr;
} }
@ -241,8 +232,7 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
getNextToken(); getNextToken();
if (getCurrentToken() != '(') if (getCurrentToken() != '(')
{ {
throw obelisk::ParserException( throw obelisk::ParserException("expected '(' but got '" + std::to_string(getCurrentToken()) + "'");
"expected '(' but got '" + std::to_string(getCurrentToken()) + "'");
} }
syntax.push('('); syntax.push('(');
@ -308,14 +298,12 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
if (leftEntities.size() == 0) if (leftEntities.size() == 0)
{ {
throw obelisk::ParserException( throw obelisk::ParserException("missing left side entities");
"missing left side entities");
} }
if (rightEntities.size() == 0) if (rightEntities.size() == 0)
{ {
throw obelisk::ParserException( throw obelisk::ParserException("missing right side entities");
"missing right side entities");
} }
break; break;
} }
@ -346,9 +334,8 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
{ {
for (auto& rightEntity : rightEntities) for (auto& rightEntity : rightEntities)
{ {
facts.push_back(obelisk::Fact(obelisk::Entity(leftEntity), facts.push_back(
obelisk::Entity(rightEntity), obelisk::Fact(obelisk::Entity(leftEntity), obelisk::Entity(rightEntity), obelisk::Verb(verb)));
obelisk::Verb(verb)));
} }
} }
} }
@ -380,8 +367,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
kb->getEntity(entity); kb->getEntity(entity);
if (entity.getId() == 0) if (entity.getId() == 0)
{ {
throw obelisk::ParserException( throw obelisk::ParserException("left entity could not be inserted into the database");
"left entity could not be inserted into the database");
} }
else else
{ {
@ -399,8 +385,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
kb->getEntity(entity); kb->getEntity(entity);
if (entity.getId() == 0) if (entity.getId() == 0)
{ {
throw obelisk::ParserException( throw obelisk::ParserException("right entity could not be inserted into the database");
"right entity could not be inserted into the database");
} }
else else
{ {
@ -423,8 +408,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
kb->getVerb(verb); kb->getVerb(verb);
if (verb.getId() == 0) if (verb.getId() == 0)
{ {
throw obelisk::ParserException( throw obelisk::ParserException("verb could not be inserted into the database");
"verb could not be inserted into the database");
} }
else else
{ {
@ -447,8 +431,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
kb->getFact(fact); kb->getFact(fact);
if (fact.getId() == 0) if (fact.getId() == 0)
{ {
throw obelisk::ParserException( throw obelisk::ParserException("fact could not be inserted into the database");
"fact could not be inserted into the database");
} }
} }
} }

View File

@ -21,13 +21,11 @@ namespace obelisk
void setCurrentToken(int currentToken); void setCurrentToken(int currentToken);
std::unique_ptr<obelisk::ExpressionAST> logError(const char* str); std::unique_ptr<obelisk::ExpressionAST> logError(const char* str);
std::unique_ptr<obelisk::PrototypeAST> logErrorPrototype( std::unique_ptr<obelisk::PrototypeAST> logErrorPrototype(const char* str);
const char* str);
std::unique_ptr<obelisk::ExpressionAST> parseExpression(); std::unique_ptr<obelisk::ExpressionAST> parseExpression();
std::unique_ptr<obelisk::ExpressionAST> parseNumberExpression(); std::unique_ptr<obelisk::ExpressionAST> parseNumberExpression();
std::unique_ptr<obelisk::ExpressionAST> std::unique_ptr<obelisk::ExpressionAST> parseParenthesisExpression();
parseParenthesisExpression();
std::unique_ptr<obelisk::ExpressionAST> parseIdentifierExpression(); std::unique_ptr<obelisk::ExpressionAST> parseIdentifierExpression();
std::unique_ptr<obelisk::ExpressionAST> parsePrimary(); std::unique_ptr<obelisk::ExpressionAST> parsePrimary();
std::unique_ptr<obelisk::PrototypeAST> parsePrototype(); std::unique_ptr<obelisk::PrototypeAST> parsePrototype();