Fixed issue where an indexer followed by a binary operator would ignore the binary
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
b4897c77ec
commit
faa3000d95
|
@ -331,7 +331,10 @@ namespace Porygon::Parser {
|
||||||
/////////////////
|
/////////////////
|
||||||
|
|
||||||
ParsedExpression *Parser::ParseExpression(const Token *current) {
|
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();
|
auto peekKind = this->Peek()->GetKind();
|
||||||
while (peekKind == TokenKind::OpenParenthesis ||
|
while (peekKind == TokenKind::OpenParenthesis ||
|
||||||
peekKind == TokenKind::OpenSquareBracket ||
|
peekKind == TokenKind::OpenSquareBracket ||
|
||||||
|
@ -455,8 +458,10 @@ namespace Porygon::Parser {
|
||||||
auto operand = this->ParseBinaryExpression(next, unaryPrecedence);
|
auto operand = this->ParseBinaryExpression(next, unaryPrecedence);
|
||||||
auto startPos = current->GetStartPosition();
|
auto startPos = current->GetStartPosition();
|
||||||
left = new UnaryExpression(operatorKind, operand, startPos, operand->GetEndPosition() - startPos);
|
left = new UnaryExpression(operatorKind, operand, startPos, operand->GetEndPosition() - startPos);
|
||||||
|
left = this -> ParseComplexExpression(left);
|
||||||
} else {
|
} else {
|
||||||
left = this->ParsePrimaryExpression(current);
|
left = this->ParsePrimaryExpression(current);
|
||||||
|
left = this -> ParseComplexExpression(left);
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
auto next = this->Peek();
|
auto next = this->Peek();
|
||||||
|
@ -469,8 +474,9 @@ namespace Porygon::Parser {
|
||||||
auto right = this->ParseBinaryExpression(this->Next(), binaryPrecedence);
|
auto right = this->ParseBinaryExpression(this->Next(), binaryPrecedence);
|
||||||
auto startPos = left->GetStartPosition();
|
auto startPos = left->GetStartPosition();
|
||||||
left = new BinaryExpression(operatorKind, left, right, startPos, right->GetEndPosition() - startPos);
|
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) {
|
ParsedExpression *Parser::ParsePrimaryExpression(const Token *current) {
|
||||||
|
|
|
@ -45,6 +45,7 @@ namespace Porygon::Parser {
|
||||||
// Expressions
|
// Expressions
|
||||||
|
|
||||||
ParsedExpression *ParseExpression(const Token *current);
|
ParsedExpression *ParseExpression(const Token *current);
|
||||||
|
ParsedExpression *ParseComplexExpression(ParsedExpression* previous);
|
||||||
ParsedExpression *ParseBinaryExpression(const Token *current, OperatorPrecedence parentPrecedence);
|
ParsedExpression *ParseBinaryExpression(const Token *current, OperatorPrecedence parentPrecedence);
|
||||||
ParsedExpression *ParsePrimaryExpression(const Token *current);
|
ParsedExpression *ParsePrimaryExpression(const Token *current);
|
||||||
ParsedExpression *ParseParenthesizedExpression(const Token *current);
|
ParsedExpression *ParseParenthesizedExpression(const Token *current);
|
||||||
|
|
|
@ -20,6 +20,7 @@ using namespace Porygon::Utilities;
|
||||||
class UserDataTestObject{
|
class UserDataTestObject{
|
||||||
public:
|
public:
|
||||||
int foo = 10;
|
int foo = 10;
|
||||||
|
int readonly = 5;
|
||||||
vector<int> fooVector = {5,10,15,25};
|
vector<int> fooVector = {5,10,15,25};
|
||||||
int getFoo(){
|
int getFoo(){
|
||||||
return foo;
|
return foo;
|
||||||
|
@ -41,6 +42,7 @@ private:
|
||||||
public:
|
public:
|
||||||
PORYGON_USERDATA(UserDataTestObject,
|
PORYGON_USERDATA(UserDataTestObject,
|
||||||
PORYGON_INTEGER_FIELD(foo)
|
PORYGON_INTEGER_FIELD(foo)
|
||||||
|
PORYGON_READONLY_INTEGER_FIELD(readonly)
|
||||||
PORYGON_INTEGER_FUNCTION(getFoo)
|
PORYGON_INTEGER_FUNCTION(getFoo)
|
||||||
PORYGON_INTEGER_FUNCTION(Addition, PORYGON_INTEGER_TYPE, PORYGON_INTEGER_TYPE)
|
PORYGON_INTEGER_FUNCTION(Addition, PORYGON_INTEGER_TYPE, PORYGON_INTEGER_TYPE)
|
||||||
PORYGON_READONLY_VECTOR_FIELD(fooVector, PORYGON_INTEGER_TYPE)
|
PORYGON_READONLY_VECTOR_FIELD(fooVector, PORYGON_INTEGER_TYPE)
|
||||||
|
@ -173,6 +175,52 @@ end
|
||||||
UserDataStorage::RemoveType(HashedString::ConstHash("testObject"));
|
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]" ) {
|
TEST_CASE( "Iterate over userdata vector keys", "[integration]" ) {
|
||||||
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData());
|
UserDataStorage::RegisterType(HashedString::ConstHash("testObject"), UserDataTestObject::__createUserData());
|
||||||
Script* script = Script::Create(R"(
|
Script* script = Script::Create(R"(
|
||||||
|
|
Loading…
Reference in New Issue