Fixed issue where an indexer followed by a binary operator would ignore the binary
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Deukhoofd 2019-08-18 15:44:55 +02:00
parent b4897c77ec
commit faa3000d95
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
3 changed files with 57 additions and 2 deletions

View File

@ -331,7 +331,10 @@ namespace Porygon::Parser {
/////////////////
ParsedExpression *Parser::ParseExpression(const Token *current) {
auto expression = this->ParseBinaryExpression(current, OperatorPrecedence::No);
return this->ParseBinaryExpression(current, OperatorPrecedence::No);
}
ParsedExpression* Parser::ParseComplexExpression(ParsedExpression* expression){
auto peekKind = this->Peek()->GetKind();
while (peekKind == TokenKind::OpenParenthesis ||
peekKind == TokenKind::OpenSquareBracket ||
@ -455,8 +458,10 @@ namespace Porygon::Parser {
auto operand = this->ParseBinaryExpression(next, unaryPrecedence);
auto startPos = current->GetStartPosition();
left = new UnaryExpression(operatorKind, operand, startPos, operand->GetEndPosition() - startPos);
left = this -> ParseComplexExpression(left);
} else {
left = this->ParsePrimaryExpression(current);
left = this -> ParseComplexExpression(left);
}
while (true) {
auto next = this->Peek();
@ -469,8 +474,9 @@ namespace Porygon::Parser {
auto right = this->ParseBinaryExpression(this->Next(), binaryPrecedence);
auto startPos = left->GetStartPosition();
left = new BinaryExpression(operatorKind, left, right, startPos, right->GetEndPosition() - startPos);
left = this -> ParseComplexExpression(left);
}
return left;
return this -> ParseComplexExpression(left);
}
ParsedExpression *Parser::ParsePrimaryExpression(const Token *current) {

View File

@ -45,6 +45,7 @@ namespace Porygon::Parser {
// Expressions
ParsedExpression *ParseExpression(const Token *current);
ParsedExpression *ParseComplexExpression(ParsedExpression* previous);
ParsedExpression *ParseBinaryExpression(const Token *current, OperatorPrecedence parentPrecedence);
ParsedExpression *ParsePrimaryExpression(const Token *current);
ParsedExpression *ParseParenthesizedExpression(const Token *current);

View File

@ -20,6 +20,7 @@ using namespace Porygon::Utilities;
class UserDataTestObject{
public:
int foo = 10;
int readonly = 5;
vector<int> fooVector = {5,10,15,25};
int getFoo(){
return foo;
@ -41,6 +42,7 @@ private:
public:
PORYGON_USERDATA(UserDataTestObject,
PORYGON_INTEGER_FIELD(foo)
PORYGON_READONLY_INTEGER_FIELD(readonly)
PORYGON_INTEGER_FUNCTION(getFoo)
PORYGON_INTEGER_FUNCTION(Addition, PORYGON_INTEGER_TYPE, PORYGON_INTEGER_TYPE)
PORYGON_READONLY_VECTOR_FIELD(fooVector, PORYGON_INTEGER_TYPE)
@ -173,6 +175,52 @@ end
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
}
TEST_CASE( "returns readonly value + 2", "[integration]" ) {
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData());
Script* script = Script::Create(R"(
function testFunc(testObject obj)
return obj.readonly + 2
end
)");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc");
auto funcType = func -> GetType();
auto obj = new UserDataTestObject();
auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj);
auto result = script->CallFunction(u"testFunc", {parameter});
REQUIRE(result -> EvaluateInteger() == 7);
delete obj;
delete parameter;
delete script;
delete func;
delete result;
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
}
TEST_CASE( "returns negative readonly value", "[integration]" ) {
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData());
Script* script = Script::Create(R"(
function testFunc(testObject obj)
return -obj.readonly
end
)");
REQUIRE(!script->Diagnostics -> HasErrors());
script->Evaluate();
auto func = (GenericFunctionEvalValue*)script -> GetVariable(u"testFunc");
auto funcType = func -> GetType();
auto obj = new UserDataTestObject();
auto parameter = new UserDataValue(HashedString::ConstHash("testObject"), obj);
auto result = script->CallFunction(u"testFunc", {parameter});
REQUIRE(result -> EvaluateInteger() == -5);
delete obj;
delete parameter;
delete script;
delete func;
delete result;
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
}
TEST_CASE( "Iterate over userdata vector keys", "[integration]" ) {
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData());
Script* script = Script::Create(R"(