develop #15
@ -63,7 +63,7 @@ BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: AfterColon
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 80
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
|
@ -22,8 +22,7 @@ namespace obelisk
|
||||
void setArgs(std::vector<std::unique_ptr<ExpressionAST>> args);
|
||||
|
||||
public:
|
||||
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),
|
||||
args_(std::move(args))
|
||||
{
|
||||
|
@ -17,8 +17,7 @@ llvm::Function *obelisk::FunctionAST::codegen()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
llvm::BasicBlock *bB
|
||||
= llvm::BasicBlock::Create(*TheContext, "entry", theFunction);
|
||||
llvm::BasicBlock *bB = llvm::BasicBlock::Create(*TheContext, "entry", theFunction);
|
||||
Builder->SetInsertPoint(bB);
|
||||
|
||||
NamedValues.clear();
|
||||
|
@ -18,8 +18,7 @@ namespace obelisk
|
||||
void setPrototype(std::unique_ptr<PrototypeAST> prototype);
|
||||
|
||||
public:
|
||||
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)),
|
||||
body_(std::move(body))
|
||||
{
|
||||
|
@ -3,17 +3,10 @@
|
||||
|
||||
llvm::Function *obelisk::PrototypeAST::codegen()
|
||||
{
|
||||
std::vector<llvm::Type *> doubles(args_.size(),
|
||||
llvm::Type::getDoubleTy(*TheContext));
|
||||
llvm::FunctionType *FT
|
||||
= llvm::FunctionType::get(llvm::Type::getDoubleTy(*TheContext),
|
||||
doubles,
|
||||
false);
|
||||
std::vector<llvm::Type *> doubles(args_.size(), llvm::Type::getDoubleTy(*TheContext));
|
||||
llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::getDoubleTy(*TheContext), doubles, false);
|
||||
|
||||
llvm::Function *F = llvm::Function::Create(FT,
|
||||
llvm::Function::ExternalLinkage,
|
||||
name_,
|
||||
obelisk::TheModule.get());
|
||||
llvm::Function *F = llvm::Function::Create(FT, llvm::Function::ExternalLinkage, name_, obelisk::TheModule.get());
|
||||
|
||||
unsigned idx = 0;
|
||||
for (auto &arg : F->args())
|
||||
|
@ -19,8 +19,7 @@ namespace obelisk
|
||||
void setArgs(std::vector<std::string> args);
|
||||
|
||||
public:
|
||||
PrototypeAST(const std::string& name,
|
||||
std::vector<std::string> args) :
|
||||
PrototypeAST(const std::string& name, std::vector<std::string> args) :
|
||||
name_(name),
|
||||
args_(std::move(args))
|
||||
{
|
||||
|
@ -50,11 +50,7 @@ obelisk::KnowledgeBase::~KnowledgeBase()
|
||||
void obelisk::KnowledgeBase::enableForeignKeys()
|
||||
{
|
||||
char* errmsg;
|
||||
int result = sqlite3_exec(dbConnection_,
|
||||
"PRAGMA foreign_keys = ON;",
|
||||
NULL,
|
||||
NULL,
|
||||
&errmsg);
|
||||
int result = sqlite3_exec(dbConnection_, "PRAGMA foreign_keys = ON;", NULL, NULL, &errmsg);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
if (errmsg)
|
||||
@ -96,9 +92,7 @@ void obelisk::KnowledgeBase::addEntities(std::vector<obelisk::Entity>& entities)
|
||||
catch (obelisk::DatabaseConstraintException& exception)
|
||||
{
|
||||
// ignore unique constraint error
|
||||
if (std::strcmp(exception.what(),
|
||||
"UNIQUE constraint failed: entity.name")
|
||||
!= 0)
|
||||
if (std::strcmp(exception.what(), "UNIQUE constraint failed: entity.name") != 0)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
@ -117,9 +111,7 @@ void obelisk::KnowledgeBase::addVerbs(std::vector<obelisk::Verb>& verbs)
|
||||
catch (obelisk::DatabaseConstraintException& exception)
|
||||
{
|
||||
// ignore unique constraint error
|
||||
if (std::strcmp(exception.what(),
|
||||
"UNIQUE constraint failed: verb.name")
|
||||
!= 0)
|
||||
if (std::strcmp(exception.what(), "UNIQUE constraint failed: verb.name") != 0)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
@ -163,9 +155,7 @@ void obelisk::KnowledgeBase::getFact(obelisk::Fact& fact)
|
||||
fact.selectFact(dbConnection_);
|
||||
}
|
||||
|
||||
void obelisk::KnowledgeBase::getFloat(float& result1,
|
||||
float& result2,
|
||||
double var)
|
||||
void obelisk::KnowledgeBase::getFloat(float& result1, float& result2, double var)
|
||||
{
|
||||
result1 = (float) var;
|
||||
result2 = (float) (var - (double) result1);
|
||||
|
@ -72,8 +72,7 @@ namespace obelisk
|
||||
* base as.
|
||||
*/
|
||||
KnowledgeBase(const char* filename) :
|
||||
KnowledgeBase(filename,
|
||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
|
||||
KnowledgeBase(filename, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -21,11 +21,7 @@ void obelisk::Entity::selectEntity(sqlite3* dbConnection)
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection,
|
||||
"SELECT id, name FROM entity WHERE name=?",
|
||||
-1,
|
||||
&ppStmt,
|
||||
nullptr);
|
||||
auto result = sqlite3_prepare_v2(dbConnection, "SELECT id, name FROM entity WHERE name=?", -1, &ppStmt, nullptr);
|
||||
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
@ -89,18 +85,13 @@ void obelisk::Entity::insertEntity(sqlite3* dbConnection)
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection,
|
||||
"INSERT INTO entity (name) VALUES (?)",
|
||||
-1,
|
||||
&ppStmt,
|
||||
nullptr);
|
||||
auto result = sqlite3_prepare_v2(dbConnection, "INSERT INTO entity (name) VALUES (?)", -1, &ppStmt, nullptr);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
|
||||
result
|
||||
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
||||
result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
@ -127,8 +118,7 @@ void obelisk::Entity::insertEntity(sqlite3* dbConnection)
|
||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
||||
break;
|
||||
case SQLITE_CONSTRAINT :
|
||||
throw obelisk::DatabaseConstraintException(
|
||||
sqlite3_errmsg(dbConnection));
|
||||
throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
|
||||
case SQLITE_BUSY :
|
||||
throw obelisk::DatabaseBusyException();
|
||||
break;
|
||||
|
@ -18,8 +18,7 @@ namespace obelisk
|
||||
}
|
||||
|
||||
DatabaseException(const int errorCode) :
|
||||
errorMessage_(
|
||||
"database error " + std::to_string(errorCode) + " ocurred")
|
||||
errorMessage_("database error " + std::to_string(errorCode) + " ocurred")
|
||||
{
|
||||
}
|
||||
|
||||
@ -71,8 +70,7 @@ namespace obelisk
|
||||
public:
|
||||
DatabaseBusyException()
|
||||
{
|
||||
setErrorMessage(
|
||||
"database was busy and operation was not performed");
|
||||
setErrorMessage("database was busy and operation was not performed");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -208,8 +208,7 @@ void obelisk::Fact::insertFact(sqlite3* dbConnection)
|
||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
||||
break;
|
||||
case SQLITE_CONSTRAINT :
|
||||
throw obelisk::DatabaseConstraintException(
|
||||
sqlite3_errmsg(dbConnection));
|
||||
throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
|
||||
case SQLITE_BUSY :
|
||||
throw obelisk::DatabaseBusyException();
|
||||
break;
|
||||
|
@ -34,9 +34,7 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
Fact(obelisk::Entity leftEntity,
|
||||
obelisk::Entity rightEntity,
|
||||
obelisk::Verb verb) :
|
||||
Fact(obelisk::Entity leftEntity, obelisk::Entity rightEntity, obelisk::Verb verb) :
|
||||
id_(0),
|
||||
leftEntity_(leftEntity),
|
||||
rightEntity_(rightEntity),
|
||||
@ -44,10 +42,7 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
Fact(int id,
|
||||
obelisk::Entity leftEntity,
|
||||
obelisk::Entity rightEntity,
|
||||
obelisk::Verb verb) :
|
||||
Fact(int id, obelisk::Entity leftEntity, obelisk::Entity rightEntity, obelisk::Verb verb) :
|
||||
id_(id),
|
||||
leftEntity_(leftEntity),
|
||||
rightEntity_(rightEntity),
|
||||
|
@ -33,9 +33,7 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
SuggestAction(obelisk::Fact fact,
|
||||
obelisk::Action trueAction,
|
||||
obelisk::Action falseAction) :
|
||||
SuggestAction(obelisk::Fact fact, obelisk::Action trueAction, obelisk::Action falseAction) :
|
||||
id_(0),
|
||||
fact_(fact),
|
||||
trueAction_(trueAction),
|
||||
@ -43,10 +41,7 @@ namespace obelisk
|
||||
{
|
||||
}
|
||||
|
||||
SuggestAction(int id,
|
||||
obelisk::Fact fact,
|
||||
obelisk::Action trueAction,
|
||||
obelisk::Action falseAction) :
|
||||
SuggestAction(int id, obelisk::Fact fact, obelisk::Action trueAction, obelisk::Action falseAction) :
|
||||
id_(id),
|
||||
fact_(fact),
|
||||
trueAction_(trueAction),
|
||||
|
@ -23,11 +23,7 @@ void obelisk::Verb::selectVerb(sqlite3* dbConnection)
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection,
|
||||
"SELECT id, name FROM verb WHERE name=?",
|
||||
-1,
|
||||
&ppStmt,
|
||||
nullptr);
|
||||
auto result = sqlite3_prepare_v2(dbConnection, "SELECT id, name FROM verb WHERE name=?", -1, &ppStmt, nullptr);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
@ -89,18 +85,13 @@ void obelisk::Verb::insertVerb(sqlite3* dbConnection)
|
||||
|
||||
sqlite3_stmt* ppStmt = nullptr;
|
||||
|
||||
auto result = sqlite3_prepare_v2(dbConnection,
|
||||
"INSERT INTO verb (name) VALUES (?)",
|
||||
-1,
|
||||
&ppStmt,
|
||||
nullptr);
|
||||
auto result = sqlite3_prepare_v2(dbConnection, "INSERT INTO verb (name) VALUES (?)", -1, &ppStmt, nullptr);
|
||||
if (result != SQLITE_OK)
|
||||
{
|
||||
throw obelisk::DatabaseException(sqlite3_errmsg(dbConnection));
|
||||
}
|
||||
|
||||
result
|
||||
= sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
||||
result = sqlite3_bind_text(ppStmt, 1, getName().c_str(), -1, SQLITE_TRANSIENT);
|
||||
switch (result)
|
||||
{
|
||||
case SQLITE_OK :
|
||||
@ -127,8 +118,7 @@ void obelisk::Verb::insertVerb(sqlite3* dbConnection)
|
||||
sqlite3_set_last_insert_rowid(dbConnection, 0);
|
||||
break;
|
||||
case SQLITE_CONSTRAINT :
|
||||
throw obelisk::DatabaseConstraintException(
|
||||
sqlite3_errmsg(dbConnection));
|
||||
throw obelisk::DatabaseConstraintException(sqlite3_errmsg(dbConnection));
|
||||
case SQLITE_BUSY :
|
||||
throw obelisk::DatabaseBusyException();
|
||||
break;
|
||||
|
@ -15,8 +15,7 @@ static int obelisk::mainLoop()
|
||||
|
||||
try
|
||||
{
|
||||
kb = std::unique_ptr<obelisk::KnowledgeBase> {
|
||||
new obelisk::KnowledgeBase("cromer.kb")};
|
||||
kb = std::unique_ptr<obelisk::KnowledgeBase> {new obelisk::KnowledgeBase("cromer.kb")};
|
||||
}
|
||||
catch (obelisk::KnowledgeBaseException& exception)
|
||||
{
|
||||
@ -44,10 +43,8 @@ static int obelisk::mainLoop()
|
||||
case obelisk::Lexer::kTokenEof :
|
||||
return EXIT_SUCCESS;
|
||||
case ';' : // ignore top-level semicolons.
|
||||
std::cout << "Identifier: "
|
||||
<< parser->getLexer()->getIdentifier() << std::endl;
|
||||
std::cout << "Num: " << parser->getLexer()->getNumberValue()
|
||||
<< std::endl;
|
||||
std::cout << "Identifier: " << parser->getLexer()->getIdentifier() << std::endl;
|
||||
std::cout << "Num: " << parser->getLexer()->getNumberValue() << std::endl;
|
||||
try
|
||||
{
|
||||
parser->getNextToken();
|
||||
|
@ -44,15 +44,13 @@ void obelisk::Parser::setCurrentToken(int currentToken)
|
||||
currentToken_ = currentToken;
|
||||
}
|
||||
|
||||
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::logError(
|
||||
const char* str)
|
||||
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::logError(const char* str)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", str);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::logErrorPrototype(
|
||||
const char* str)
|
||||
std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::logErrorPrototype(const char* str)
|
||||
{
|
||||
logError(str);
|
||||
return nullptr;
|
||||
@ -86,14 +84,12 @@ std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parsePrimary()
|
||||
|
||||
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseNumberExpression()
|
||||
{
|
||||
auto result = std::make_unique<obelisk::NumberExpressionAST>(
|
||||
getLexer()->getNumberValue());
|
||||
auto result = std::make_unique<obelisk::NumberExpressionAST>(getLexer()->getNumberValue());
|
||||
getNextToken();
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<obelisk::ExpressionAST>
|
||||
obelisk::Parser::parseParenthesisExpression()
|
||||
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseParenthesisExpression()
|
||||
{
|
||||
getNextToken();
|
||||
auto v = parseExpression();
|
||||
@ -110,8 +106,7 @@ std::unique_ptr<obelisk::ExpressionAST>
|
||||
return v;
|
||||
}
|
||||
|
||||
std::unique_ptr<obelisk::ExpressionAST>
|
||||
obelisk::Parser::parseIdentifierExpression()
|
||||
std::unique_ptr<obelisk::ExpressionAST> obelisk::Parser::parseIdentifierExpression()
|
||||
{
|
||||
std::string idName = getLexer()->getIdentifier();
|
||||
getNextToken();
|
||||
@ -181,8 +176,7 @@ std::unique_ptr<obelisk::PrototypeAST> obelisk::Parser::parsePrototype()
|
||||
|
||||
getNextToken();
|
||||
|
||||
return std::make_unique<obelisk::PrototypeAST>(functionName,
|
||||
std::move(argNames));
|
||||
return std::make_unique<obelisk::PrototypeAST>(functionName, std::move(argNames));
|
||||
}
|
||||
|
||||
std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseDefinition()
|
||||
@ -196,8 +190,7 @@ std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseDefinition()
|
||||
|
||||
if (auto expression = parseExpression())
|
||||
{
|
||||
return std::make_unique<FunctionAST>(std::move(prototype),
|
||||
std::move(expression));
|
||||
return std::make_unique<FunctionAST>(std::move(prototype), std::move(expression));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@ -208,10 +201,8 @@ std::unique_ptr<obelisk::FunctionAST> obelisk::Parser::parseTopLevelExpression()
|
||||
if (auto expression = parseExpression())
|
||||
{
|
||||
// Make an anonymous prototype
|
||||
auto prototype = std::make_unique<obelisk::PrototypeAST>("__anon_expr",
|
||||
std::vector<std::string>());
|
||||
return std::make_unique<obelisk::FunctionAST>(std::move(prototype),
|
||||
std::move(expression));
|
||||
auto prototype = std::make_unique<obelisk::PrototypeAST>("__anon_expr", std::vector<std::string>());
|
||||
return std::make_unique<obelisk::FunctionAST>(std::move(prototype), std::move(expression));
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
@ -241,8 +232,7 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
|
||||
getNextToken();
|
||||
if (getCurrentToken() != '(')
|
||||
{
|
||||
throw obelisk::ParserException(
|
||||
"expected '(' but got '" + std::to_string(getCurrentToken()) + "'");
|
||||
throw obelisk::ParserException("expected '(' but got '" + std::to_string(getCurrentToken()) + "'");
|
||||
}
|
||||
|
||||
syntax.push('(');
|
||||
@ -308,14 +298,12 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
|
||||
|
||||
if (leftEntities.size() == 0)
|
||||
{
|
||||
throw obelisk::ParserException(
|
||||
"missing left side entities");
|
||||
throw obelisk::ParserException("missing left side entities");
|
||||
}
|
||||
|
||||
if (rightEntities.size() == 0)
|
||||
{
|
||||
throw obelisk::ParserException(
|
||||
"missing right side entities");
|
||||
throw obelisk::ParserException("missing right side entities");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -346,9 +334,8 @@ void obelisk::Parser::parseFact(std::vector<obelisk::Fact>& facts)
|
||||
{
|
||||
for (auto& rightEntity : rightEntities)
|
||||
{
|
||||
facts.push_back(obelisk::Fact(obelisk::Entity(leftEntity),
|
||||
obelisk::Entity(rightEntity),
|
||||
obelisk::Verb(verb)));
|
||||
facts.push_back(
|
||||
obelisk::Fact(obelisk::Entity(leftEntity), obelisk::Entity(rightEntity), obelisk::Verb(verb)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -380,8 +367,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
kb->getEntity(entity);
|
||||
if (entity.getId() == 0)
|
||||
{
|
||||
throw obelisk::ParserException(
|
||||
"left entity could not be inserted into the database");
|
||||
throw obelisk::ParserException("left entity could not be inserted into the database");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -399,8 +385,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
kb->getEntity(entity);
|
||||
if (entity.getId() == 0)
|
||||
{
|
||||
throw obelisk::ParserException(
|
||||
"right entity could not be inserted into the database");
|
||||
throw obelisk::ParserException("right entity could not be inserted into the database");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -423,8 +408,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
kb->getVerb(verb);
|
||||
if (verb.getId() == 0)
|
||||
{
|
||||
throw obelisk::ParserException(
|
||||
"verb could not be inserted into the database");
|
||||
throw obelisk::ParserException("verb could not be inserted into the database");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -447,8 +431,7 @@ void obelisk::Parser::handleFact(std::unique_ptr<obelisk::KnowledgeBase>& kb)
|
||||
kb->getFact(fact);
|
||||
if (fact.getId() == 0)
|
||||
{
|
||||
throw obelisk::ParserException(
|
||||
"fact could not be inserted into the database");
|
||||
throw obelisk::ParserException("fact could not be inserted into the database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,13 +21,11 @@ namespace obelisk
|
||||
void setCurrentToken(int currentToken);
|
||||
|
||||
std::unique_ptr<obelisk::ExpressionAST> logError(const char* str);
|
||||
std::unique_ptr<obelisk::PrototypeAST> logErrorPrototype(
|
||||
const char* str);
|
||||
std::unique_ptr<obelisk::PrototypeAST> logErrorPrototype(const char* str);
|
||||
|
||||
std::unique_ptr<obelisk::ExpressionAST> parseExpression();
|
||||
std::unique_ptr<obelisk::ExpressionAST> parseNumberExpression();
|
||||
std::unique_ptr<obelisk::ExpressionAST>
|
||||
parseParenthesisExpression();
|
||||
std::unique_ptr<obelisk::ExpressionAST> parseParenthesisExpression();
|
||||
std::unique_ptr<obelisk::ExpressionAST> parseIdentifierExpression();
|
||||
std::unique_ptr<obelisk::ExpressionAST> parsePrimary();
|
||||
std::unique_ptr<obelisk::PrototypeAST> parsePrototype();
|
||||
|
Loading…
Reference in New Issue
Block a user