mirror of https://github.com/mgba-emu/mgba.git
Debugger: Improve paren parsing, add lexing tests
This commit is contained in:
parent
d7900fdf5f
commit
47605b40e7
|
@ -415,6 +415,8 @@ set(DEBUGGER_SRC
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/symbols.c
|
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/symbols.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/cli-debugger.c)
|
${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/cli-debugger.c)
|
||||||
|
|
||||||
|
file(GLOB DEBUGGER_TEST_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/debugger/test/*.c)
|
||||||
|
|
||||||
set(FEATURE_SRC)
|
set(FEATURE_SRC)
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6")
|
||||||
|
|
||||||
|
@ -686,6 +688,7 @@ endif()
|
||||||
|
|
||||||
if(USE_DEBUGGERS)
|
if(USE_DEBUGGERS)
|
||||||
list(APPEND FEATURE_SRC ${DEBUGGER_SRC})
|
list(APPEND FEATURE_SRC ${DEBUGGER_SRC})
|
||||||
|
list(APPEND TEST_SRC ${DEBUGGER_TEST_SRC})
|
||||||
list(APPEND FEATURES DEBUGGERS)
|
list(APPEND FEATURES DEBUGGERS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,11 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
_lexOperator(lv, token);
|
_lexOperator(lv, token);
|
||||||
state = LEX_ROOT;
|
state = LEX_ROOT;
|
||||||
break;
|
break;
|
||||||
|
case ')':
|
||||||
|
lvNext = LexVectorAppend(lv);
|
||||||
|
lvNext->type = TOKEN_CLOSE_PAREN_TYPE;
|
||||||
|
state = LEX_EXPECT_OPERATOR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
state = LEX_ERROR;
|
state = LEX_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -332,6 +337,7 @@ size_t lexExpression(struct LexVector* lv, const char* string, size_t length) {
|
||||||
lvNext->type = TOKEN_IDENTIFIER_TYPE;
|
lvNext->type = TOKEN_IDENTIFIER_TYPE;
|
||||||
lvNext->identifierValue = strndup(tokenStart, string - tokenStart);
|
lvNext->identifierValue = strndup(tokenStart, string - tokenStart);
|
||||||
break;
|
break;
|
||||||
|
case LEX_ROOT:
|
||||||
case LEX_EXPECT_OPERATOR:
|
case LEX_EXPECT_OPERATOR:
|
||||||
break;
|
break;
|
||||||
case LEX_EXPECT_BINARY_FIRST:
|
case LEX_EXPECT_BINARY_FIRST:
|
||||||
|
@ -369,7 +375,7 @@ static struct ParseTree* _parseTreeCreate() {
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _parseExpression(struct ParseTree* tree, struct LexVector* lv, size_t i, int precedence, int openParens) {
|
static size_t _parseExpression(struct ParseTree* tree, struct LexVector* lv, size_t i, int precedence, int* openParens) {
|
||||||
struct ParseTree* newTree = 0;
|
struct ParseTree* newTree = 0;
|
||||||
while (i < LexVectorSize(lv)) {
|
while (i < LexVectorSize(lv)) {
|
||||||
struct Token* token = LexVectorGetPointer(lv, i);
|
struct Token* token = LexVectorGetPointer(lv, i);
|
||||||
|
@ -400,12 +406,14 @@ static size_t _parseExpression(struct ParseTree* tree, struct LexVector* lv, siz
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TOKEN_OPEN_PAREN_TYPE:
|
case TOKEN_OPEN_PAREN_TYPE:
|
||||||
i = _parseExpression(tree, lv, i + 1, INT_MAX, openParens + 1);
|
++*openParens;
|
||||||
|
i = _parseExpression(tree, lv, i + 1, INT_MAX, openParens);
|
||||||
break;
|
break;
|
||||||
case TOKEN_CLOSE_PAREN_TYPE:
|
case TOKEN_CLOSE_PAREN_TYPE:
|
||||||
if (openParens <= 0) {
|
if (*openParens <= 0) {
|
||||||
tree->token.type = TOKEN_ERROR_TYPE;
|
tree->token.type = TOKEN_ERROR_TYPE;
|
||||||
}
|
}
|
||||||
|
--*openParens;
|
||||||
return i + 1;
|
return i + 1;
|
||||||
case TOKEN_OPERATOR_TYPE:
|
case TOKEN_OPERATOR_TYPE:
|
||||||
newPrecedence = _operatorPrecedence[token->operatorValue];
|
newPrecedence = _operatorPrecedence[token->operatorValue];
|
||||||
|
@ -441,7 +449,14 @@ void parseLexedExpression(struct ParseTree* tree, struct LexVector* lv) {
|
||||||
tree->lhs = 0;
|
tree->lhs = 0;
|
||||||
tree->rhs = 0;
|
tree->rhs = 0;
|
||||||
|
|
||||||
_parseExpression(tree, lv, 0, INT_MAX, 0);
|
int openParens = 0;
|
||||||
|
_parseExpression(tree, lv, 0, INT_MAX, &openParens);
|
||||||
|
if (openParens) {
|
||||||
|
if (tree->token.type == TOKEN_IDENTIFIER_TYPE) {
|
||||||
|
free(tree->token.identifierValue);
|
||||||
|
}
|
||||||
|
tree->token.type = TOKEN_ERROR_TYPE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexFree(struct LexVector* lv) {
|
void lexFree(struct LexVector* lv) {
|
||||||
|
|
|
@ -0,0 +1,459 @@
|
||||||
|
/* Copyright (c) 2013-2017 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "util/test/suite.h"
|
||||||
|
|
||||||
|
#include <mgba/internal/debugger/parser.h>
|
||||||
|
|
||||||
|
#define LEX(STR) \
|
||||||
|
struct LexVector lv; \
|
||||||
|
LexVectorInit(&lv, 0); \
|
||||||
|
size_t adjusted = lexExpression(&lv, STR, strlen(STR)); \
|
||||||
|
assert_false(adjusted > strlen(STR))
|
||||||
|
|
||||||
|
#define UNLEX \
|
||||||
|
lexFree(&lv); \
|
||||||
|
LexVectorDeinit(&lv)
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexEmpty) {
|
||||||
|
LEX("");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 0);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexInt) {
|
||||||
|
LEX("0");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->uintValue, 0);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexDecimal) {
|
||||||
|
LEX("10");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->uintValue, 10);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexBinary) {
|
||||||
|
LEX("0b10");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->uintValue, 2);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexHex) {
|
||||||
|
LEX("0x10");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->uintValue, 0x10);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexInvalidDecimal) {
|
||||||
|
LEX("1a");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_ERROR_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexInvalidBinary) {
|
||||||
|
LEX("0b12");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_ERROR_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexInvalidHex) {
|
||||||
|
LEX("0x1g");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_ERROR_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexTruncatedBinary) {
|
||||||
|
LEX("0b");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_ERROR_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexTruncatedHex) {
|
||||||
|
LEX("0x");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_ERROR_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifier) {
|
||||||
|
LEX("x");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_IDENTIFIER_TYPE);
|
||||||
|
assert_string_equal(LexVectorGetPointer(&lv, 0)->identifierValue, "x");
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexAddOperator) {
|
||||||
|
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_ADD);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierAddOperator) {
|
||||||
|
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_ADD);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexSubOperator) {
|
||||||
|
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_SUBTRACT);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierSubOperator) {
|
||||||
|
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_SUBTRACT);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexMulOperator) {
|
||||||
|
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_MULTIPLY);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierMulOperator) {
|
||||||
|
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_MULTIPLY);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexDivOperator) {
|
||||||
|
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_DIVIDE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierDivOperator) {
|
||||||
|
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_DIVIDE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexAndOperator) {
|
||||||
|
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_AND);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierAndOperator) {
|
||||||
|
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_AND);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexOrOperator) {
|
||||||
|
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_OR);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierOrOperator) {
|
||||||
|
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_OR);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexXorOperator) {
|
||||||
|
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_XOR);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierXorOperator) {
|
||||||
|
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_XOR);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexLessOperator) {
|
||||||
|
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_LESS);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierLessOperator) {
|
||||||
|
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_LESS);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexGreaterOperator) {
|
||||||
|
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_GREATER);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierGreaterOperator) {
|
||||||
|
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_GREATER);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexSimpleExpression) {
|
||||||
|
LEX("1+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_ADD);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->uintValue, 1);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexOpenParen) {
|
||||||
|
LEX("(");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_OPEN_PAREN_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexCloseParen) {
|
||||||
|
LEX("(0)");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 3);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_OPEN_PAREN_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 1)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 1)->uintValue, 0);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->type, TOKEN_CLOSE_PAREN_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexIdentifierCloseParen) {
|
||||||
|
LEX("(x)");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 3);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_OPEN_PAREN_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 1)->type, TOKEN_IDENTIFIER_TYPE);
|
||||||
|
assert_string_equal(LexVectorGetPointer(&lv, 1)->identifierValue, "x");
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->type, TOKEN_CLOSE_PAREN_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexParentheticalExpression) {
|
||||||
|
LEX("(1+1)");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 5);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_OPEN_PAREN_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 1)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 1)->uintValue, 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->type, TOKEN_OPERATOR_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->operatorValue, OP_ADD);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 3)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 3)->uintValue, 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 4)->type, TOKEN_CLOSE_PAREN_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(lexNestedParentheticalExpression) {
|
||||||
|
LEX("(1+(2+3))");
|
||||||
|
|
||||||
|
assert_int_equal(LexVectorSize(&lv), 9);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 0)->type, TOKEN_OPEN_PAREN_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 1)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 1)->uintValue, 1);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->type, TOKEN_OPERATOR_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 2)->operatorValue, OP_ADD);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 3)->type, TOKEN_OPEN_PAREN_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 4)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 4)->uintValue, 2);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 5)->type, TOKEN_OPERATOR_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 5)->operatorValue, OP_ADD);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 6)->type, TOKEN_UINT_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 6)->uintValue, 3);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 7)->type, TOKEN_CLOSE_PAREN_TYPE);
|
||||||
|
assert_int_equal(LexVectorGetPointer(&lv, 8)->type, TOKEN_CLOSE_PAREN_TYPE);
|
||||||
|
|
||||||
|
UNLEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_SUITE_DEFINE(Lexer,
|
||||||
|
cmocka_unit_test(lexEmpty),
|
||||||
|
cmocka_unit_test(lexInt),
|
||||||
|
cmocka_unit_test(lexDecimal),
|
||||||
|
cmocka_unit_test(lexHex),
|
||||||
|
cmocka_unit_test(lexBinary),
|
||||||
|
cmocka_unit_test(lexInvalidDecimal),
|
||||||
|
cmocka_unit_test(lexInvalidHex),
|
||||||
|
cmocka_unit_test(lexInvalidBinary),
|
||||||
|
cmocka_unit_test(lexTruncatedHex),
|
||||||
|
cmocka_unit_test(lexTruncatedBinary),
|
||||||
|
cmocka_unit_test(lexIdentifier),
|
||||||
|
cmocka_unit_test(lexAddOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierAddOperator),
|
||||||
|
cmocka_unit_test(lexSubOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierSubOperator),
|
||||||
|
cmocka_unit_test(lexMulOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierMulOperator),
|
||||||
|
cmocka_unit_test(lexDivOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierDivOperator),
|
||||||
|
cmocka_unit_test(lexAndOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierAndOperator),
|
||||||
|
cmocka_unit_test(lexOrOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierOrOperator),
|
||||||
|
cmocka_unit_test(lexXorOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierXorOperator),
|
||||||
|
cmocka_unit_test(lexLessOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierLessOperator),
|
||||||
|
cmocka_unit_test(lexGreaterOperator),
|
||||||
|
cmocka_unit_test(lexIdentifierGreaterOperator),
|
||||||
|
cmocka_unit_test(lexSimpleExpression),
|
||||||
|
cmocka_unit_test(lexOpenParen),
|
||||||
|
cmocka_unit_test(lexCloseParen),
|
||||||
|
cmocka_unit_test(lexIdentifierCloseParen),
|
||||||
|
cmocka_unit_test(lexParentheticalExpression),
|
||||||
|
cmocka_unit_test(lexNestedParentheticalExpression))
|
Loading…
Reference in New Issue