From f5ef07bebb7cdc0df60c63cc739c44e95ec0650e Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Fri, 29 Dec 2017 14:46:21 -0500 Subject: [PATCH] Add two-character operators --- include/mgba/internal/debugger/parser.h | 8 + src/debugger/parser.c | 135 +++++++++- src/debugger/test/lexer.c | 320 ++++++++++++++++++++++++ 3 files changed, 454 insertions(+), 9 deletions(-) diff --git a/include/mgba/internal/debugger/parser.h b/include/mgba/internal/debugger/parser.h index 62b8f8d41..99c43dc73 100644 --- a/include/mgba/internal/debugger/parser.h +++ b/include/mgba/internal/debugger/parser.h @@ -25,8 +25,16 @@ enum Operation { OP_LESS, OP_GREATER, OP_EQUAL, + OP_NOT_EQUAL, + OP_LOGICAL_AND, + OP_LOGICAL_OR, OP_LE, OP_GE, + OP_NEGATE, + OP_FLIP, + OP_NOT, + OP_SHIFT_L, + OP_SHIFT_R, }; struct Token { diff --git a/src/debugger/parser.c b/src/debugger/parser.c index bc6ca1b14..7cc778208 100644 --- a/src/debugger/parser.c +++ b/src/debugger/parser.c @@ -20,13 +20,84 @@ enum LexState { LEX_EXPECT_HEX_FIRST, LEX_EXPECT_HEX, LEX_EXPECT_PREFIX, - LEX_EXPECT_OPERATOR + LEX_EXPECT_OPERATOR, + LEX_EXPECT_OPERATOR2, }; -static void _lexOperator(struct LexVector* lv, char operator) { +static void _lexOperator(struct LexVector* lv, char operator, enum LexState* state) { + if (*state == LEX_EXPECT_OPERATOR2) { + struct Token* lvNext = LexVectorGetPointer(lv, LexVectorSize(lv) - 1); + if (lvNext->type != TOKEN_OPERATOR_TYPE) { + lvNext->type = TOKEN_ERROR_TYPE; + *state = LEX_ERROR; + return; + } + switch (lvNext->operatorValue) { + case OP_AND: + if (operator == '&') { + lvNext->operatorValue = OP_LOGICAL_AND; + *state = LEX_ROOT; + return; + } + break; + case OP_OR: + if (operator == '|') { + lvNext->operatorValue = OP_LOGICAL_OR; + *state = LEX_ROOT; + return; + } + break; + case OP_LESS: + if (operator == '=') { + lvNext->operatorValue = OP_LE; + *state = LEX_ROOT; + return; + } + if (operator == '<') { + lvNext->operatorValue = OP_SHIFT_L; + *state = LEX_ROOT; + return; + } + break; + case OP_GREATER: + if (operator == '=') { + lvNext->operatorValue = OP_GE; + *state = LEX_ROOT; + return; + } + if (operator == '>') { + lvNext->operatorValue = OP_SHIFT_R; + *state = LEX_ROOT; + return; + } + break; + case OP_ASSIGN: + if (operator == '=') { + lvNext->operatorValue = OP_EQUAL; + *state = LEX_ROOT; + return; + } + break; + case OP_NOT: + if (operator == '=') { + lvNext->operatorValue = OP_NOT_EQUAL; + *state = LEX_ROOT; + return; + } + break; + default: + break; + } + *state = LEX_ERROR; + return; + } struct Token* lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_OPERATOR_TYPE; + *state = LEX_EXPECT_OPERATOR2; switch (operator) { + case '=': + lvNext->operatorValue = OP_ASSIGN; + break; case '+': lvNext->operatorValue = OP_ADD; break; @@ -57,6 +128,9 @@ static void _lexOperator(struct LexVector* lv, char operator) { case '>': lvNext->operatorValue = OP_GREATER; break; + case '!': + lvNext->operatorValue = OP_NOT; + break; default: lvNext->type = TOKEN_ERROR_TYPE; break; @@ -67,6 +141,7 @@ static void _lexValue(struct LexVector* lv, char token, uint32_t next, enum LexS struct Token* lvNext; switch (token) { + case '=': case '+': case '-': case '*': @@ -77,11 +152,11 @@ static void _lexValue(struct LexVector* lv, char token, uint32_t next, enum LexS case '^': case '<': case '>': + case '!': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_UINT_TYPE; lvNext->uintValue = next; - _lexOperator(lv, token); - *state = LEX_ROOT; + _lexOperator(lv, token, state); break; case ')': lvNext = LexVectorAppend(lv); @@ -115,6 +190,20 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { ++adjusted; --length; switch (state) { + case LEX_EXPECT_OPERATOR2: + switch (token) { + case '&': + case '|': + case '=': + case '<': + case '>': + _lexOperator(lv, token, &state); + break; + } + if (state != LEX_EXPECT_OPERATOR2) { + break; + } + // Fall through case LEX_ROOT: tokenStart = string - 1; switch (token) { @@ -158,6 +247,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { break; case LEX_EXPECT_IDENTIFIER: switch (token) { + case '=': case '+': case '-': case '*': @@ -168,11 +258,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { case '^': case '<': case '>': + case '!': lvNext = LexVectorAppend(lv); lvNext->type = TOKEN_IDENTIFIER_TYPE; lvNext->identifierValue = strndup(tokenStart, string - tokenStart - 1); - _lexOperator(lv, token); - state = LEX_ROOT; + _lexOperator(lv, token, &state); break; case ')': lvNext = LexVectorAppend(lv); @@ -305,6 +395,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { break; case LEX_EXPECT_OPERATOR: switch (token) { + case '=': case '+': case '-': case '*': @@ -315,8 +406,8 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { case '^': case '<': case '>': - _lexOperator(lv, token); - state = LEX_ROOT; + case '!': + _lexOperator(lv, token, &state); break; case ')': lvNext = LexVectorAppend(lv); @@ -349,6 +440,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) { break; case LEX_ROOT: case LEX_EXPECT_OPERATOR: + case LEX_EXPECT_OPERATOR2: break; case LEX_EXPECT_BINARY_FIRST: case LEX_EXPECT_HEX_FIRST: @@ -374,8 +466,16 @@ static const int _operatorPrecedence[] = { [OP_LESS] = 6, [OP_GREATER] = 6, [OP_EQUAL] = 7, + [OP_NOT_EQUAL] = 7, [OP_LE] = 6, - [OP_GE] = 6 + [OP_GE] = 6, + [OP_LOGICAL_AND] = 11, + [OP_LOGICAL_OR] = 12, + [OP_NEGATE] = 2, + [OP_FLIP] = 2, + [OP_NOT] = 2, + [OP_SHIFT_L] = 5, + [OP_SHIFT_R] = 5, }; static struct ParseTree* _parseTreeCreate() { @@ -540,12 +640,29 @@ static bool _performOperation(enum Operation operation, int32_t current, int32_t case OP_EQUAL: current = current == next; break; + case OP_NOT_EQUAL: + current = current != next; + break; + case OP_LOGICAL_AND: + current = current && next; + break; + case OP_LOGICAL_OR: + current = current || next; + break; case OP_LE: current = current <= next; break; case OP_GE: current = current >= next; break; + case OP_SHIFT_L: + current <<= next; + break; + case OP_SHIFT_R: + current >>= next; + break; + default: + return false; } *value = current; return true; diff --git a/src/debugger/test/lexer.c b/src/debugger/test/lexer.c index 034887a18..e9e5ac2d2 100644 --- a/src/debugger/test/lexer.c +++ b/src/debugger/test/lexer.c @@ -350,6 +350,298 @@ M_TEST_DEFINE(lexIdentifierGreaterOperator) { assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); } +M_TEST_DEFINE(lexEqualsOperator) { + LEX("1=="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_EQUAL); +} + +M_TEST_DEFINE(lexIdentifierEqualsOperator) { + LEX("x=="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_EQUAL); +} + +M_TEST_DEFINE(lexNotEqualsOperator) { + LEX("1!="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT_EQUAL); +} + +M_TEST_DEFINE(lexIdentifierNotEqualsOperator) { + LEX("x!="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT_EQUAL); +} + +M_TEST_DEFINE(lexLEOperator) { + LEX("1<="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LE); +} + +M_TEST_DEFINE(lexIdentifierLEOperator) { + LEX("x<="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LE); +} + +M_TEST_DEFINE(lexGEOperator) { + LEX("1>="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GE); +} + +M_TEST_DEFINE(lexIdentifierGEOperator) { + LEX("x>="); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GE); +} + +M_TEST_DEFINE(lexLAndOperator) { + LEX("1&&"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LOGICAL_AND); +} + +M_TEST_DEFINE(lexIdentifierLAndOperator) { + LEX("x&&"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LOGICAL_AND); +} + +M_TEST_DEFINE(lexLOrOperator) { + LEX("1||"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LOGICAL_OR); +} + +M_TEST_DEFINE(lexIdentifierLOrOperator) { + LEX("x||"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LOGICAL_OR); +} + +M_TEST_DEFINE(lexShiftLOperator) { + LEX("1<<"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_SHIFT_L); +} + +M_TEST_DEFINE(lexIdentifierShiftLOperator) { + LEX("x<<"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_SHIFT_L); +} + +M_TEST_DEFINE(lexShiftROperator) { + LEX("1>>"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_SHIFT_R); +} + +M_TEST_DEFINE(lexIdentifierShiftROperator) { + LEX("x>>"); + + assert_int_equal(LexVectorSize(lv), 2); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_SHIFT_R); +} + +M_TEST_DEFINE(lexEqualsInvalidOperator) { + LEX("1=|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_ASSIGN); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexIdentifierEqualsInvalidOperator) { + LEX("x=|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_ASSIGN); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexNotInvalidOperator) { + LEX("1!|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexIdentifierNotInvalidOperator) { + LEX("x!|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_NOT); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexLessInvalidOperator) { + LEX("1<|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LESS); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexIdentifierLessInvalidOperator) { + LEX("x<|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_LESS); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexGreaterInvalidOperator) { + LEX("1>|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexIdentifierGreaterInvalidOperator) { + LEX("x>|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_GREATER); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexAndInvalidOperator) { + LEX("1&|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_AND); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexIdentifierAndInvalidOperator) { + LEX("x&|"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_AND); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexOrInvalidOperator) { + LEX("1|>"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_UINT_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 0)->uintValue, 1); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_OR); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexIdentifierOrInvalidOperator) { + LEX("x|>"); + + assert_int_equal(LexVectorSize(lv), 3); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_IDENTIFIER_TYPE); + assert_string_equal(LexVectorGetPointer(lv, 0)->identifierValue, "x"); + assert_int_equal(LexVectorGetPointer(lv, 1)->type, TOKEN_OPERATOR_TYPE); + assert_int_equal(LexVectorGetPointer(lv, 1)->operatorValue, OP_OR); + assert_int_equal(LexVectorGetPointer(lv, 2)->type, TOKEN_ERROR_TYPE); +} + M_TEST_DEFINE(lexSimpleExpression) { LEX("1+1"); @@ -460,6 +752,34 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Lexer, cmocka_unit_test(lexIdentifierLessOperator), cmocka_unit_test(lexGreaterOperator), cmocka_unit_test(lexIdentifierGreaterOperator), + cmocka_unit_test(lexEqualsOperator), + cmocka_unit_test(lexIdentifierEqualsOperator), + cmocka_unit_test(lexNotEqualsOperator), + cmocka_unit_test(lexIdentifierNotEqualsOperator), + cmocka_unit_test(lexLEOperator), + cmocka_unit_test(lexIdentifierLEOperator), + cmocka_unit_test(lexGEOperator), + cmocka_unit_test(lexIdentifierGEOperator), + cmocka_unit_test(lexLAndOperator), + cmocka_unit_test(lexIdentifierLAndOperator), + cmocka_unit_test(lexLOrOperator), + cmocka_unit_test(lexIdentifierLOrOperator), + cmocka_unit_test(lexShiftLOperator), + cmocka_unit_test(lexIdentifierShiftLOperator), + cmocka_unit_test(lexShiftROperator), + cmocka_unit_test(lexIdentifierShiftROperator), + cmocka_unit_test(lexEqualsInvalidOperator), + cmocka_unit_test(lexIdentifierEqualsInvalidOperator), + cmocka_unit_test(lexNotInvalidOperator), + cmocka_unit_test(lexIdentifierNotInvalidOperator), + cmocka_unit_test(lexLessInvalidOperator), + cmocka_unit_test(lexIdentifierLessInvalidOperator), + cmocka_unit_test(lexGreaterInvalidOperator), + cmocka_unit_test(lexIdentifierGreaterInvalidOperator), + cmocka_unit_test(lexAndInvalidOperator), + cmocka_unit_test(lexIdentifierAndInvalidOperator), + cmocka_unit_test(lexOrInvalidOperator), + cmocka_unit_test(lexIdentifierOrInvalidOperator), cmocka_unit_test(lexSimpleExpression), cmocka_unit_test(lexOpenParen), cmocka_unit_test(lexCloseParen),