feature/kb #14

Merged
cromer merged 27 commits from feature/kb into develop 2023-02-23 01:09:37 -03:00
20 changed files with 492 additions and 117 deletions
Showing only changes of commit 09925b567c - Show all commits

View File

@ -11,9 +11,28 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The LLVM context.
*
*/
static std::unique_ptr<llvm::LLVMContext> TheContext; static std::unique_ptr<llvm::LLVMContext> TheContext;
/**
* @brief The LLVM module.
*
*/
static std::unique_ptr<llvm::Module> TheModule; static std::unique_ptr<llvm::Module> TheModule;
/**
* @brief The LLVM IR builder.
*
*/
static std::unique_ptr<llvm::IRBuilder<>> Builder; static std::unique_ptr<llvm::IRBuilder<>> Builder;
/**
* @brief The LLVM named values.
*
*/
static std::map<std::string, llvm::Value *> NamedValues; static std::map<std::string, llvm::Value *> NamedValues;
} // namespace obelisk } // namespace obelisk

View File

@ -9,25 +9,71 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The call AST expression node used to call functions.
*
*/
class CallExpressionAST : public ExpressionAST class CallExpressionAST : public ExpressionAST
{ {
private: private:
/**
* @brief The function being called.
*
*/
std::string callee_; std::string callee_;
/**
* @brief The arguments passed to the function.
*
*/
std::vector<std::unique_ptr<ExpressionAST>> args_; std::vector<std::unique_ptr<ExpressionAST>> args_;
/**
* @brief Get the callee.
*
* @return std::string Returns the name of the function being called.
*/
std::string getCallee(); std::string getCallee();
/**
* @brief Set the callee.
*
* @param[in] callee The name of the function.
*/
void setCallee(std::string callee); void setCallee(std::string callee);
/**
* @brief Get the arguments being used by the function.
*
* @return std::vector<std::unique_ptr<ExpressionAST>> Returns an AST expression containing the args.
*/
std::vector<std::unique_ptr<ExpressionAST>> getArgs(); std::vector<std::unique_ptr<ExpressionAST>> getArgs();
/**
* @brief Set the arguments to be used by the function.
*
* @param[in] args The args to set.
*/
void setArgs(std::vector<std::unique_ptr<ExpressionAST>> args); void setArgs(std::vector<std::unique_ptr<ExpressionAST>> args);
public: public:
/**
* @brief Construct a new CallExpressionAST object.
*
* @param[in] callee The function to call.
* @param[in] args The args to pass into the function.
*/
CallExpressionAST(const std::string &callee, std::vector<std::unique_ptr<ExpressionAST>> args) : CallExpressionAST(const std::string &callee, std::vector<std::unique_ptr<ExpressionAST>> args) :
callee_(callee), callee_(callee),
args_(std::move(args)) args_(std::move(args))
{ {
} }
/**
* @brief Generate the calle IR code.
*
* @return llvm::Value*
*/
llvm::Value *codegen() override; llvm::Value *codegen() override;
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -7,8 +7,21 @@
namespace obelisk namespace obelisk
{ {
std::unique_ptr<ExpressionAST> LogError(const char *Str); /**
llvm::Value *LogErrorV(const char *Str); * @brief Log an AST expression error.
*
* @param[in] str The error message.
* @return std::unique_ptr<ExpressionAST> Returns the AST expression that caused the error.
*/
std::unique_ptr<ExpressionAST> LogError(const char *str);
/**
* @brief Log an AST value error.
*
* @param[in] str The error message.
* @return llvm::Value* Returns the AST value that caused the error.
*/
llvm::Value *LogErrorV(const char *str);
} // namespace obelisk } // namespace obelisk
#endif #endif

View File

@ -5,10 +5,24 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief A generic AST expression which other expression will inherit from.
*
*/
class ExpressionAST class ExpressionAST
{ {
public: public:
/**
* @brief Destroy the ExpressionAST object.
*
*/
virtual ~ExpressionAST() = default; virtual ~ExpressionAST() = default;
/**
* @brief Generate LLVM IR code based on the AST expression.
*
* @return llvm::Value* Returns the LLVM code value from the expression.
*/
virtual llvm::Value *codegen() = 0; virtual llvm::Value *codegen() = 0;
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -8,22 +8,57 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief A Funcion AST node.
*
*/
class FunctionAST class FunctionAST
{ {
private: private:
/**
* @brief The prototype of the function.
*
*/
std::unique_ptr<PrototypeAST> prototype_; std::unique_ptr<PrototypeAST> prototype_;
/**
* @brief The body of the function.
*
*/
std::unique_ptr<ExpressionAST> body_; std::unique_ptr<ExpressionAST> body_;
/**
* @brief Get the prototype.
*
* @return std::unique_ptr<PrototypeAST> Returns the prototype AST.
*/
std::unique_ptr<PrototypeAST> getPrototype(); std::unique_ptr<PrototypeAST> getPrototype();
/**
* @brief Set the prototype.
*
* @param[in] prototype Set the prototype.
*/
void setPrototype(std::unique_ptr<PrototypeAST> prototype); void setPrototype(std::unique_ptr<PrototypeAST> prototype);
public: public:
/**
* @brief Construct a new FunctionAST object.
*
* @param[in] prototype The prototype of the function.
* @param[in] body The body of the function.
*/
FunctionAST(std::unique_ptr<PrototypeAST> prototype, std::unique_ptr<ExpressionAST> body) : FunctionAST(std::unique_ptr<PrototypeAST> prototype, std::unique_ptr<ExpressionAST> body) :
prototype_(std::move(prototype)), prototype_(std::move(prototype)),
body_(std::move(body)) body_(std::move(body))
{ {
} }
/**
* @brief Generate LLVM IR code.
*
* @return llvm::Function* Returns the LLVM IR function code.
*/
llvm::Function *codegen(); llvm::Function *codegen();
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -5,20 +5,49 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief A number expression AST node.
*
*/
class NumberExpressionAST : public ExpressionAST class NumberExpressionAST : public ExpressionAST
{ {
private: private:
/**
* @brief The number.
*
*/
double number_; double number_;
/**
* @brief Get the number.
*
* @return double Returns the number.
*/
double getNumber(); double getNumber();
/**
* @brief Set the number.
*
* @param[in] number The number.
*/
void setNumber(double number); void setNumber(double number);
public: public:
/**
* @brief Construct a new NumberExpressionAST object.
*
* @param[in] number The number.
*/
NumberExpressionAST(double number) : NumberExpressionAST(double number) :
number_(number) number_(number)
{ {
} }
/**
* @brief Generate LLVM IR code for the number.
*
* @return llvm::Value* Returns the genrated IR code.
*/
llvm::Value *codegen() override; llvm::Value *codegen() override;
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -8,28 +8,73 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The prototype AST node.
*
*/
class PrototypeAST class PrototypeAST
{ {
private: private:
/**
* @brief The name of the prototype.
*
*/
std::string name_; std::string name_;
/**
* @brief The arguments the protype accepts.
*
*/
std::vector<std::string> args_; std::vector<std::string> args_;
/**
* @brief Set the name of the prototype.
*
* @param[in] name The name.
*/
void setName(const std::string& name); void setName(const std::string& name);
/**
* @brief Get the arguments the prototype accepts.
*
* @return std::vector<std::string> Returns the arguments.
*/
std::vector<std::string> getArgs(); std::vector<std::string> getArgs();
/**
* @brief Set the arguments the prototype accepts.
*
* @param[in] args The arguments.
*/
void setArgs(std::vector<std::string> args); void setArgs(std::vector<std::string> args);
public: public:
/**
* @brief Construct a new PrototypeAST object.
*
* @param[in] name The name of the prototype.
* @param[in] args The arguments the prototype accepts.
*/
PrototypeAST(const std::string& name, std::vector<std::string> args) : PrototypeAST(const std::string& name, std::vector<std::string> args) :
name_(name), name_(name),
args_(std::move(args)) args_(std::move(args))
{ {
} }
/**
* @brief Get the name of the prototype.
*
* @return const std::string& Returns the name of the prototype.
*/
const std::string& getName() const const std::string& getName() const
{ {
return name_; return name_;
} }
/**
* @brief Generate LLVM IR code for the prototype.
*
* @return llvm::Function* Returns IR code for the prototype.
*/
llvm::Function* codegen(); llvm::Function* codegen();
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -7,19 +7,49 @@
namespace obelisk namespace obelisk
{ {
/**
* @brief The variable expression AST node.
*
*/
class VariableExpressionAST : public ExpressionAST class VariableExpressionAST : public ExpressionAST
{ {
private: private:
/**
* @brief The name of the variable.
*
*/
std::string name_; std::string name_;
/**
* @brief Get the name of the variable.
*
* @return std::string Returns the name of the variable.
*/
std::string getName(); std::string getName();
/**
* @brief Set the name of the variable.
*
* @param[in] name The name of the variable.
*/
void setName(const std::string name); void setName(const std::string name);
public: public:
/**
* @brief Construct a new VariableExpressionAST object.
*
* @param[in] name The name of the variable.
*/
VariableExpressionAST(const std::string &name) : VariableExpressionAST(const std::string &name) :
name_(name) name_(name)
{ {
} }
/**
* @brief Generate the variable LLVM IR code.
*
* @return llvm::Value* Returns the generated IR code.
*/
llvm::Value *codegen() override; llvm::Value *codegen() override;
}; };
} // namespace obelisk } // namespace obelisk

View File

@ -56,22 +56,19 @@ namespace obelisk
/** /**
* @brief Comment the rest of the line. * @brief Comment the rest of the line.
* *
* @param[in] lastChar The char to check to see if it in the end of * @param[in] lastChar The char to check to see if it in the end of the line.
* the line.
*/ */
void commentLine(int* lastChar); void commentLine(int* lastChar);
public: public:
/** /**
* @brief These token represent recognized language keywords and * @brief These token represent recognized language keywords and language functionality.
* language functionality.
* *
*/ */
enum Token enum Token
{ {
/** /**
* @brief End of file is returned when the source code is * @brief End of file is returned when the source code is finished.
* finished.
* *
*/ */
kTokenEof = -1, kTokenEof = -1,
@ -82,8 +79,7 @@ namespace obelisk
*/ */
kTokenFact = -2, kTokenFact = -2,
/** /**
* @brief A rule which is a relationship between a new fact a * @brief A rule which is a relationship between a new fact a existing fact.
* existing fact.
* *
*/ */
kTokenRule = -3, kTokenRule = -3,
@ -137,16 +133,14 @@ namespace obelisk
* @brief Gets the next token in the source code. * @brief Gets the next token in the source code.
* *
* @throws LexerException when an invalid token is found. * @throws LexerException when an invalid token is found.
* @return int Returns a Token value or char if no known token was * @return int Returns a Token value or char if no known token was found.
* found.
*/ */
int getToken(); int getToken();
/** /**
* @brief Get the last identifier. * @brief Get the last identifier.
* *
* @return const std::string& Returns a string that contains the * @return const std::string& Returns a string that contains the last found identifier.
* last found identifier.
*/ */
const std::string& getIdentifier(); const std::string& getIdentifier();
@ -194,8 +188,7 @@ namespace obelisk
/** /**
* @brief Return the exception's error message. * @brief Return the exception's error message.
* *
* @return const char* Returns a string containing the error * @return const char* Returns a string containing the error message.
* message.
*/ */
const char* what() const noexcept const char* what() const noexcept
{ {

View File

@ -1,15 +1,13 @@
#include <string> #include <string>
/** /**
* @brief The obelisk namespace contains everything needed to compile obelisk. * @brief The obelisk namespace contains everything needed to compile obelisk code.
* code.
* *
*/ */
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The obelisk library provides everything needed to consult the * @brief The obelisk library provides everything needed to consult the KnowledgeBase.
* KnowledgeBase.
* *
*/ */
class Obelisk class Obelisk

View File

@ -18,8 +18,7 @@
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The KnowledgeBase class represents a collection of facts, rules, * @brief The KnowledgeBase class represents a collection of facts, rules, actions, and related language connectors.
* actions, and related language connectors.
* *
*/ */
class KnowledgeBase class KnowledgeBase
@ -46,8 +45,8 @@ namespace obelisk
/** /**
* @brief Enable foreign key functionality in the open database. * @brief Enable foreign key functionality in the open database.
* *
* This must always be done when the connection is opened or it will * This must always be done when the connection is opened or it will not enforce the foreign key
* not enforce the foreign key constraints. * constraints.
*/ */
void enableForeignKeys(); void enableForeignKeys();
@ -62,8 +61,7 @@ namespace obelisk
/** /**
* @brief Construct a new KnowledgeBase object. * @brief Construct a new KnowledgeBase object.
* *
* @param[in] filename The name of the file to save the knowledge * @param[in] filename The name of the file to save the knowledge base as.
* base as.
* @param[in] flags The flags to open the KnowledgeBase with. * @param[in] flags The flags to open the KnowledgeBase with.
*/ */
KnowledgeBase(const char* filename, int flags); KnowledgeBase(const char* filename, int flags);
@ -71,8 +69,7 @@ namespace obelisk
/** /**
* @brief Construct a new KnowledgeBase object. * @brief Construct a new KnowledgeBase object.
* *
* @param[in] filename The name of the file to save the knowledge * @param[in] filename The name of the file to save the knowledge base as.
* base as.
*/ */
KnowledgeBase(const char* filename) : KnowledgeBase(const char* filename) :
KnowledgeBase(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE) KnowledgeBase(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
@ -89,103 +86,96 @@ namespace obelisk
/** /**
* @brief Add entities to the KnowledgeBase. * @brief Add entities to the KnowledgeBase.
* *
* @param[in,out] entities The entities to add. If the insert is * @param[in,out] entities The entities to add. If the insert is successful it will have a row ID, if not
* successful it will have a row ID, if not the ID will be 0. * the ID will be 0.
*/ */
void addEntities(std::vector<obelisk::Entity>& entities); void addEntities(std::vector<obelisk::Entity>& entities);
/** /**
* @brief Add verbs to the KnowledgeBase. * @brief Add verbs to the KnowledgeBase.
* *
* @param[in,out] verbs The verbs to add. If the insert is * @param[in,out] verbs The verbs to add. If the insert is successful it will have a row ID, if not the ID
* successful it will have a row ID, if not the ID will be 0. * will be 0.
*/ */
void addVerbs(std::vector<obelisk::Verb>& verbs); void addVerbs(std::vector<obelisk::Verb>& verbs);
/** /**
* @brief Add actions to the KnowledgeBase. * @brief Add actions to the KnowledgeBase.
* *
* @param[in,out] actions The actions to add. If the insert is * @param[in,out] actions The actions to add. If the insert is successful it will have a row ID, if nto the
* successful it will have a row ID, if nto the ID will be 0. * ID will be 0.
*/ */
void addActions(std::vector<obelisk::Action>& actions); void addActions(std::vector<obelisk::Action>& actions);
/** /**
* @brief Add facts to the KnowledgeBase. * @brief Add facts to the KnowledgeBase.
* *
* @param[in,out] facts The facts to add. If the insert is * @param[in,out] facts The facts to add. If the insert is successful it will have a row ID, if not the ID
* successful it will have a row ID, if not the ID will be 0. * will be 0.
*/ */
void addFacts(std::vector<obelisk::Fact>& facts); void addFacts(std::vector<obelisk::Fact>& facts);
/** /**
* @brief Add suggested actions to the KnowledgeBase. * @brief Add suggested actions to the KnowledgeBase.
* *
* @param[in,out] suggestActions The suggested actions to add. If * @param[in,out] suggestActions The suggested actions to add. If the insert is successful it will have a
* the insert is successful it will have a row ID, if not the ID * row ID, if not the ID will be 0.
* will be 0.
*/ */
void addSuggestActions(std::vector<obelisk::SuggestAction>& suggestActions); void addSuggestActions(std::vector<obelisk::SuggestAction>& suggestActions);
/** /**
* @brief Add rules to the KnowledgeBase. * @brief Add rules to the KnowledgeBase.
* *
* @param[in,out] rules The rules to add. If the insert is successful it * @param[in,out] rules The rules to add. If the insert is successful it will have a row ID, if not the ID
* will have a row ID, if not the ID will be 0. * will be 0.
*/ */
void addRules(std::vector<obelisk::Rule>& rules); void addRules(std::vector<obelisk::Rule>& rules);
/** /**
* @brief Get an Entity object based on the ID it contains. * @brief Get an Entity object based on the ID it contains.
* *
* @param[in,out] entity The Entity object should contain just the * @param[in,out] entity The Entity object should contain just the ID and the rest will be filled in.
* 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. * @brief Get a Verb object based on the ID it contains.
* *
* @param[in,out] verb The Verb object should contain just the ID * @param[in,out] verb The Verb object should contain just the ID and the rest will be filled in.
* and the rest will be filled in.
*/ */
void getVerb(obelisk::Verb& verb); void getVerb(obelisk::Verb& verb);
/** /**
* @brief Get an Action based on the ID it contains. * @brief Get an Action based on the ID it contains.
* *
* @param[in] action The Action object should contain just the ID * @param[in] action The Action object should contain just the ID and the rest will be filled in.
* and the rest will be filled in.
*/ */
void getAction(obelisk::Action& action); void getAction(obelisk::Action& action);
/** /**
* @brief Get a Fact object based on the ID it contains. * @brief Get a Fact object based on the ID it contains.
* *
* @param[in,out] fact The Fact object should contain just the ID * @param[in,out] fact The Fact object should contain just the ID and the rest will be filled in.
* and the rest will be filled in.
*/ */
void getFact(obelisk::Fact& fact); void getFact(obelisk::Fact& fact);
/** /**
* @brief Get a SuggestAction based on the ID it contains. * @brief Get a SuggestAction based on the ID it contains.
* *
* @param[in,out] suggestAction The SuggestAction object should * @param[in,out] suggestAction The SuggestAction object should contain just the ID and the rest will be
* contain just the ID and the rest will be filled in. * filled in.
*/ */
void getSuggestAction(obelisk::SuggestAction& suggestAction); void getSuggestAction(obelisk::SuggestAction& suggestAction);
/** /**
* @brief Get a Rule based on the ID it contains. * @brief Get a Rule based on the ID it contains.
* *
* @param[in,out] rule The Rule object should contain just the ID * @param[in,out] rule The Rule object should contain just the ID and the rest will be filled in.
* and the rest will be filled in.
*/ */
void getRule(obelisk::Rule& rule); void getRule(obelisk::Rule& rule);
/** /**
* @brief Check if a rule looks for this Fact, if so update its * @brief Check if a rule looks for this Fact, if so update its truth.
* truth.
* *
* @param[in,out] fact The Fact to check for existing rules. * @param[in,out] fact The Fact to check for existing rules.
*/ */
@ -201,10 +191,8 @@ namespace obelisk
/** /**
* @brief Take a float and divide it into 2 floats. * @brief Take a float and divide it into 2 floats.
* *
* This is useful to store doubles in SQLite since SQLite doesn't * This is useful to store doubles in SQLite since SQLite doesn't have a double type. Instead just store the
* have a double type. * 2 floats in the database. Then after selecting them combine them.
* 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] result1 The first float generated from the double.
* @param[out] result2 The second float generated from the double. * @param[out] result2 The second float generated from the double.
@ -215,8 +203,7 @@ namespace obelisk
/** /**
* @brief Combines 2 separated floats back into a double. * @brief Combines 2 separated floats back into a double.
* *
* This will recombine the separated floats from the getFloat * This will recombine the separated floats from the getFloat method.
* method.
* *
* @param[out] result The double generated from the combined floats. * @param[out] result The double generated from the combined floats.
* @param[in] var1 The first float to combine. * @param[in] var1 The first float to combine.

View File

@ -8,8 +8,7 @@
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The Action model represents an action to take when a fact is true * @brief The Action model represents an action to take when a fact is true or false.
* or false.
* *
*/ */
class Action class Action
@ -108,16 +107,14 @@ namespace obelisk
void setName(std::string name); void setName(std::string name);
/** /**
* @brief Select an Action from the datbase based on the object * @brief Select an Action from the datbase based on the object name.
* name.
* *
* @param[in] dbConnection The database connection to use. * @param[in] dbConnection The database connection to use.
*/ */
void selectByName(sqlite3* dbConnection); void selectByName(sqlite3* dbConnection);
/** /**
* @brief Insert an Action into the KnowledgeBase based on the * @brief Insert an Action into the KnowledgeBase based on the object's fields.
* object's fields.
* *
* @param[in] dbConnection The database connection to use. * @param[in] dbConnection The database connection to use.
*/ */

View File

@ -8,8 +8,7 @@
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The Entity model represents either a left or right side entity, * @brief The Entity model represents either a left or right side entity, typically used in facts and rules.
* typically used in facts and rules.
* *
*/ */
class Entity class Entity
@ -108,16 +107,14 @@ namespace obelisk
void setName(std::string name); void setName(std::string name);
/** /**
* @brief Select an Entity from the KnowledgeBase based on the object's * @brief Select an Entity from the KnowledgeBase based on the object's name.
* name.
* *
* @param[in] dbConnection The database connection to use. * @param[in] dbConnection The database connection to use.
*/ */
void selectByName(sqlite3* dbConnection); void selectByName(sqlite3* dbConnection);
/** /**
* @brief Insert an Entity into the KnowledgeBase based on the object's * @brief Insert an Entity into the KnowledgeBase based on the object's fields.
* fields.
* *
* @param[in] dbConnection The database connection to use. * @param[in] dbConnection The database connection to use.
*/ */

View File

@ -42,8 +42,7 @@ namespace obelisk
/** /**
* @brief Construct a new DatabaseException object. * @brief Construct a new DatabaseException object.
* *
* @param[in] errorMessage The error message to describe the * @param[in] errorMessage The error message to describe the exception.
* exception.
*/ */
DatabaseException(const std::string& errorMessage) : DatabaseException(const std::string& errorMessage) :
errorMessage_(errorMessage) errorMessage_(errorMessage)
@ -72,8 +71,7 @@ namespace obelisk
}; };
/** /**
* @brief Exception thrown if the string or blob size exceeds sqlite's * @brief Exception thrown if the string or blob size exceeds sqlite's limits.
* limits.
* *
*/ */
class DatabaseSizeException : public obelisk::DatabaseException class DatabaseSizeException : public obelisk::DatabaseException
@ -107,8 +105,7 @@ namespace obelisk
}; };
/** /**
* @brief Exception thrown if there is not enough memory to perform the * @brief Exception thrown if there is not enough memory to perform the operation.
* operation.
* *
*/ */
class DatabaseMemoryException : public obelisk::DatabaseException class DatabaseMemoryException : public obelisk::DatabaseException
@ -178,8 +175,7 @@ namespace obelisk
/** /**
* @brief Construct a new DatabaseConstraintException object. * @brief Construct a new DatabaseConstraintException object.
* *
* @param[in] errorMessage The error message to send when the * @param[in] errorMessage The error message to send when the constraint is violated.
* constraint is violated.
*/ */
DatabaseConstraintException(const std::string& errorMessage) DatabaseConstraintException(const std::string& errorMessage)
{ {

View File

@ -10,8 +10,7 @@
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The Fact model represents truth in the releationship between two * @brief The Fact model represents truth in the releationship between two entities separated by a verb.
* entities separated by a verb.
* *
*/ */
class Fact class Fact
@ -36,8 +35,7 @@ namespace obelisk
obelisk::Entity rightEntity_; obelisk::Entity rightEntity_;
/** /**
* @brief The Verb that represents the relationship in the * @brief The Verb that represents the relationship in the expression.
* expression.
* *
*/ */
obelisk::Verb verb_; obelisk::Verb verb_;
@ -79,10 +77,8 @@ namespace obelisk
/** /**
* @brief Construct a new Fact object. * @brief Construct a new Fact object.
* *
* @param[in] leftEntity The Entity on the left side of the * @param[in] leftEntity The Entity on the left side of the expression.
* expression. * @param[in] rightEntity The Entity on the right side of the expression.
* @param[in] rightEntity The Entity on the right side of the
* expression.
* @param[in] verb The Verb separating the entities. * @param[in] verb The Verb separating the entities.
* @param[in] isTrue Whether or not the fact is true. * @param[in] isTrue Whether or not the fact is true.
*/ */
@ -99,10 +95,8 @@ namespace obelisk
* @brief Construct a new Fact object. * @brief Construct a new Fact object.
* *
* @param[in] id The ID of the Fact in the KnowledgeBase. * @param[in] id The ID of the Fact in the KnowledgeBase.
* @param[in] leftEntity The Entity on the left side of the * @param[in] leftEntity The Entity on the left side of the expression.
* expression. * @param[in] rightEntity The Entity on the right side of the expression.
* @param[in] rightEntity The Entity on the right side of the
* expression.
* @param[in] verb The Verb separating the entities. * @param[in] verb The Verb separating the entities.
* @param[in] isTrue Whether or not the fact is true. * @param[in] isTrue Whether or not the fact is true.
*/ */
@ -198,8 +192,7 @@ namespace obelisk
void setIsTrue(bool isTrue); void setIsTrue(bool isTrue);
/** /**
* @brief Select the Fact from the KnowledgeBase by IDs of the * @brief Select the Fact from the KnowledgeBase by IDs of the sub-objects.
* sub-objects.
* *
* @param[in] dbConnection The database connection to use. * @param[in] dbConnection The database connection to use.
*/ */
@ -213,8 +206,7 @@ namespace obelisk
void insert(sqlite3* dbConnection); void insert(sqlite3* dbConnection);
/** /**
* @brief Update whether or not the fact is true in the * @brief Update whether or not the fact is true in the KnowledgeBase.
* KnowledgeBase.
* *
* @param[in] dbConnection The database connection. * @param[in] dbConnection The database connection.
*/ */

View File

@ -134,8 +134,7 @@ namespace obelisk
void setReason(obelisk::Fact reason); void setReason(obelisk::Fact reason);
/** /**
* @brief Select the Rule from the KnowledgeBase by IDs of the * @brief Select the Rule from the KnowledgeBase by IDs of the sub-objects.
* sub-objects.
* *
* @param[in] dbConnection The database connection to use. * @param[in] dbConnection The database connection to use.
*/ */

View File

@ -9,8 +9,7 @@
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The SuggestAction model representas the actions to take depending * @brief The SuggestAction model representas the actions to take depending on if the Fact is true or false.
* on if the Fact is true or false.
* *
*/ */
class SuggestAction class SuggestAction
@ -161,8 +160,7 @@ namespace obelisk
void setFalseAction(obelisk::Action falseAction); void setFalseAction(obelisk::Action falseAction);
/** /**
* @brief Select the SuggestAction from the KnowledgeBase by IDs of the * @brief Select the SuggestAction from the KnowledgeBase by IDs of the sub-objects.
* sub-objects.
* *
* @param[in] dbConnection The database connection to use. * @param[in] dbConnection The database connection to use.
*/ */

View File

@ -8,8 +8,7 @@
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The Verb model represents a verb which is used to connnect * @brief The Verb model represents a verb which is used to connnect entities.
* entities.
* *
*/ */
class Verb class Verb

View File

@ -1,8 +1,7 @@
#include <getopt.h> #include <getopt.h>
/** /**
* @brief The obelisk namespace contains everything needed to compile obelisk. * @brief The obelisk namespace contains everything needed to compile obelisk code.
* code.
* *
*/ */
namespace obelisk namespace obelisk
@ -38,6 +37,7 @@ Options:
/** /**
* @brief This is the main loop for obelisk. * @brief This is the main loop for obelisk.
*
* This loop handles lexing and parsing of obelisk source code. * This loop handles lexing and parsing of obelisk source code.
* *
* @return int Returns EXIT_SUCCESS or EXIT_FAILURE. * @return int Returns EXIT_SUCCESS or EXIT_FAILURE.

View File

@ -18,16 +18,14 @@
namespace obelisk namespace obelisk
{ {
/** /**
* @brief The Parser is responsible for analyzing the language's key words * @brief The Parser is responsible for analyzing the language's key words and taking action based on its analysis.
* and taking action based on its analysis.
* *
*/ */
class Parser class Parser
{ {
private: private:
/** /**
* @brief The Lexer object that the Parser is using to Parse a * @brief The Lexer object that the Parser is using to Parse a specific source file.
* specific source file.
* *
*/ */
std::shared_ptr<obelisk::Lexer> lexer_; std::shared_ptr<obelisk::Lexer> lexer_;
@ -45,69 +43,259 @@ namespace obelisk
*/ */
void setCurrentToken(int currentToken); void setCurrentToken(int currentToken);
/**
* @brief Log errors from the LLVM parsing.
*
* @param[in] str The error message.
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the AST expression that caused the error.
*/
std::unique_ptr<obelisk::ExpressionAST> logError(const char* str); std::unique_ptr<obelisk::ExpressionAST> logError(const char* str);
/**
* @brief Log errors from the LLVM parsing involving the prototypes.
*
* @param[in] str The error message.
* @return std::unique_ptr<obelisk::PrototypeAST> Returns the AST for the prototype.
*/
std::unique_ptr<obelisk::PrototypeAST> logErrorPrototype(const char* str); std::unique_ptr<obelisk::PrototypeAST> logErrorPrototype(const char* str);
/**
* @brief The AST expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parseExpression(); std::unique_ptr<obelisk::ExpressionAST> parseExpression();
/**
* @brief The AST number expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parseNumberExpression(); std::unique_ptr<obelisk::ExpressionAST> parseNumberExpression();
/**
* @brief The AST parenthesis expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parseParenthesisExpression(); std::unique_ptr<obelisk::ExpressionAST> parseParenthesisExpression();
/**
* @brief The AST identifier expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parseIdentifierExpression(); std::unique_ptr<obelisk::ExpressionAST> parseIdentifierExpression();
/**
* @brief The AST primary expression parser.
*
* @return std::unique_ptr<obelisk::ExpressionAST> Returns the parsed AST expression.
*/
std::unique_ptr<obelisk::ExpressionAST> parsePrimary(); std::unique_ptr<obelisk::ExpressionAST> parsePrimary();
/**
* @brief The AST prototype parser.
*
* @return std::unique_ptr<obelisk::PrototypeAST> Returns the parsed AST prototype expression.
*/
std::unique_ptr<obelisk::PrototypeAST> parsePrototype(); std::unique_ptr<obelisk::PrototypeAST> parsePrototype();
/**
* @brief The AST definition parser.
*
* @return std::unique_ptr<obelisk::FunctionAST> Returns the parsed AST definition expression.
*/
std::unique_ptr<obelisk::FunctionAST> parseDefinition(); std::unique_ptr<obelisk::FunctionAST> parseDefinition();
/**
* @brief The AST top level expression parser.
*
* @return std::unique_ptr<obelisk::FunctionAST> Returns the parsed AST top level expression.
*/
std::unique_ptr<obelisk::FunctionAST> parseTopLevelExpression(); std::unique_ptr<obelisk::FunctionAST> parseTopLevelExpression();
/**
* @brief The AST external definition parser.
*
* @return std::unique_ptr<obelisk::PrototypeAST> Returns the parsed AST external definition.
*/
std::unique_ptr<obelisk::PrototypeAST> parseExtern(); std::unique_ptr<obelisk::PrototypeAST> parseExtern();
/**
* @brief Parse a SuggestAction.
*
* @param[out] suggestAction The parsed SuggestAction.
*/
void parseAction(obelisk::SuggestAction& suggestAction); void parseAction(obelisk::SuggestAction& suggestAction);
/**
* @brief Parse a Rule.
*
* @param[out] rule The parsed Rule.
*/
void parseRule(obelisk::Rule& rule); void parseRule(obelisk::Rule& rule);
/**
* @brief Parse Facts.
*
* @param[out] facts The parsed Facts.
*/
void parseFact(std::vector<obelisk::Fact>& facts); void parseFact(std::vector<obelisk::Fact>& facts);
public: public:
/**
* @brief Construct a new Parser object.
*
* @param[in] lexer The lexer the parser uses to retrieve parts of the language.
*/
Parser(std::shared_ptr<obelisk::Lexer> lexer) : Parser(std::shared_ptr<obelisk::Lexer> lexer) :
lexer_(lexer) lexer_(lexer)
{ {
} }
/**
* @brief Get the Lexer.
*
* @return std::shared_ptr<obelisk::Lexer> Returns the current Lexer in use by the Parser.
*/
std::shared_ptr<obelisk::Lexer> getLexer(); std::shared_ptr<obelisk::Lexer> getLexer();
/**
* @brief Set the Lexer to use during the parsing phase.
*
* @param[in] lexer The Lexer.
*/
void setLexer(std::shared_ptr<obelisk::Lexer> lexer); void setLexer(std::shared_ptr<obelisk::Lexer> lexer);
/**
* @brief Gets the current token held inside the Lexer.
*
* @return int Returns the current token.
*/
int getCurrentToken(); int getCurrentToken();
/**
* @brief Instructs the Lexer to retrieve a new token.
*
* @return int Returns the next token.
*/
int getNextToken(); int getNextToken();
void handleDefinition(); /**
void handleExtern(); * @brief Parse the SuggestAction and then insert it into the KnowledgeBase.
void handleTopLevelExpression(); *
* @param[in] kb The KnowledgeBase to insert the SuggestAction into.
*/
void handleAction(std::unique_ptr<obelisk::KnowledgeBase>& kb); void handleAction(std::unique_ptr<obelisk::KnowledgeBase>& kb);
/**
* @brief Parse the Rule and then insert it into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to insert the Rule into.
*/
void handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb); void handleRule(std::unique_ptr<obelisk::KnowledgeBase>& kb);
/**
* @brief Parse the Fact and then insert it into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to insert the Fact into.
*/
void handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb); void handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb);
/**
* @brief Helper used to insert an Entity into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] entity The Entity to insert. It will contain the ID of the Entity after inserting it.
*/
void insertEntity(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Entity& entity); void insertEntity(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Entity& entity);
/**
* @brief Helper used to insert a Verb into the KnowledgeBase.
*
* @param[in] kb The KnowledegeBase to use.
* @param[in,out] verb The Verb to insert. It will contain the ID of the Verb after inserting it.
*/
void insertVerb(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Verb& verb); void insertVerb(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Verb& verb);
/**
* @brief Helper used to insert an Action into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] action The Action to insert. It will contain the ID of the Action after inserting it.
*/
void insertAction(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Action& action); void insertAction(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Action& action);
/**
* @brief Helper used to insert a Fact into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] fact The Fact to insert. It will contain the ID of the Fact after inserting it.
* @param[in] updateIsTrue If true, it will update the value of is_true in the KnowledgeBase if the Fact
* already exists.
*/
void insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb, void insertFact(std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::Fact& fact, obelisk::Fact& fact,
bool updateIsTrue = false); bool updateIsTrue = false);
/**
* @brief Helper used to insert a SuggestAction into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] suggestAction The SuggestAction to insert. It will contain the ID of the SuggestAction
* after inserting it.
*/
void insertSuggestAction(std::unique_ptr<obelisk::KnowledgeBase>& kb, void insertSuggestAction(std::unique_ptr<obelisk::KnowledgeBase>& kb,
obelisk::SuggestAction& suggestAction); obelisk::SuggestAction& suggestAction);
/**
* @brief Helper usedto insert a Rule into the KnowledgeBase.
*
* @param[in] kb The KnowledgeBase to use.
* @param[in,out] rule The Rule to insert. It will contain the ID of the Rule after inserting it.
*/
void insertRule(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Rule& rule); void insertRule(std::unique_ptr<obelisk::KnowledgeBase>& kb, obelisk::Rule& rule);
}; };
/**
* @brief The exceptions thrown by the Parser.
*
*/
class ParserException : public std::exception class ParserException : public std::exception
{ {
private: private:
/**
* @brief The error message.
*
*/
const std::string errorMessage_; const std::string errorMessage_;
public: public:
/**
* @brief Construct a new ParserException object.
*
*/
ParserException() : ParserException() :
errorMessage_("an unknown error ocurred") errorMessage_("an unknown error ocurred")
{ {
} }
/**
* @brief Construct a new ParserException object.
*
* @param[in] errorMessage The error message.
*/
ParserException(const std::string& errorMessage) : ParserException(const std::string& errorMessage) :
errorMessage_(errorMessage) errorMessage_(errorMessage)
{ {
} }
/**
* @brief Return the error message as a C style string.
*
* @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();