Debugger: Simple parser tests
Vicki Pfau vi@endrift.com
Fri, 29 Dec 2017 12:23:42 -0500
2 files changed,
484 insertions(+),
423 deletions(-)
A
src/debugger/test/lexer.c
@@ -0,0 +1,401 @@
+/* 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 = *state; \ + lexFree(lv); \ + LexVectorClear(lv); \ + size_t adjusted = lexExpression(lv, STR, strlen(STR)); \ + assert_false(adjusted > strlen(STR)) + +M_TEST_SUITE_SETUP(Lexer) { + struct LexVector* lv = malloc(sizeof(struct LexVector)); + LexVectorInit(lv, 0); + *state = lv; + return 0; +} + +M_TEST_SUITE_TEARDOWN(Lexer) { + struct LexVector* lv = *state; + lexFree(lv); + LexVectorDeinit(lv); + free(lv); + return 0; +} + +M_TEST_DEFINE(lexEmpty) { + LEX(""); + + assert_int_equal(LexVectorSize(lv), 0); +} + +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); +} + +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); +} + +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); +} + +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); +} + +M_TEST_DEFINE(lexInvalidDecimal) { + LEX("1a"); + + assert_int_equal(LexVectorSize(lv), 1); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexInvalidBinary) { + LEX("0b12"); + + assert_int_equal(LexVectorSize(lv), 1); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexInvalidHex) { + LEX("0x1g"); + + assert_int_equal(LexVectorSize(lv), 1); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexTruncatedBinary) { + LEX("0b"); + + assert_int_equal(LexVectorSize(lv), 1); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); +} + +M_TEST_DEFINE(lexTruncatedHex) { + LEX("0x"); + + assert_int_equal(LexVectorSize(lv), 1); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_ERROR_TYPE); +} + +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"); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +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); +} + +M_TEST_DEFINE(lexOpenParen) { + LEX("("); + + assert_int_equal(LexVectorSize(lv), 1); + assert_int_equal(LexVectorGetPointer(lv, 0)->type, TOKEN_OPEN_PAREN_TYPE); +} + +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); +} + +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); +} + +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); +} + +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); +} + +M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(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))
M
src/debugger/test/parser.c
→
src/debugger/test/parser.c
@@ -7,453 +7,113 @@ #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^"); +struct LPTest { + struct LexVector lv; + struct ParseTree tree; +}; - 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); +#define PARSE(STR) \ + struct LPTest* lp = *state; \ + lexFree(&lp->lv); \ + LexVectorClear(&lp->lv); \ + size_t adjusted = lexExpression(&lp->lv, STR, strlen(STR)); \ + assert_false(adjusted > strlen(STR)); \ + struct ParseTree* tree = &lp->tree; \ + parseLexedExpression(tree, &lp->lv) - UNLEX; +M_TEST_SUITE_SETUP(Parser) { + struct LPTest* lp = malloc(sizeof(struct LPTest)); + LexVectorInit(&lp->lv, 0); + *state = lp; + return 0; } -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_SUITE_TEARDOWN(Parser) { + struct LPTest* lp = *state; + parseFree(lp->tree.lhs); \ + parseFree(lp->tree.rhs); \ + lexFree(&lp->lv); + LexVectorDeinit(&lp->lv); + free(lp); + return 0; } -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); +M_TEST_DEFINE(parseEmpty) { + PARSE(""); - UNLEX; + assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE); } -M_TEST_DEFINE(lexIdentifierLessOperator) { - LEX("x<"); +M_TEST_DEFINE(parseInt) { + PARSE("0"); - 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; + assert_int_equal(tree->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->token.uintValue, 0); } -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); +M_TEST_DEFINE(parseLexError) { + PARSE("@"); - UNLEX; + assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE); } -M_TEST_DEFINE(lexIdentifierGreaterOperator) { - LEX("x>"); +M_TEST_DEFINE(parseSimpleExpression) { + PARSE("1+2"); - 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; + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->token.operatorValue, OP_ADD); + assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->lhs->token.uintValue, 1); + assert_int_equal(tree->rhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->rhs->token.uintValue, 2); } -M_TEST_DEFINE(lexSimpleExpression) { - LEX("1+1"); +M_TEST_DEFINE(parseAddMultplyExpression) { + PARSE("1+2*3"); - 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; + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->token.operatorValue, OP_ADD); + assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->lhs->token.uintValue, 1); + assert_int_equal(tree->rhs->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->rhs->token.uintValue, OP_MULTIPLY); + assert_int_equal(tree->rhs->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->rhs->lhs->token.uintValue, 2); + assert_int_equal(tree->rhs->rhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->rhs->rhs->token.uintValue, 3); } -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); +M_TEST_DEFINE(parseParentheticalExpression) { + PARSE("(1+2)"); - UNLEX; + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->token.operatorValue, OP_ADD); + assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->lhs->token.uintValue, 1); + assert_int_equal(tree->rhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->rhs->token.uintValue, 2); } -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); +M_TEST_DEFINE(parseParentheticalAddMultplyExpression) { + PARSE("(1+2)*3"); - UNLEX; + assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->token.operatorValue, OP_MULTIPLY); + assert_int_equal(tree->lhs->token.type, TOKEN_OPERATOR_TYPE); + assert_int_equal(tree->lhs->token.uintValue, OP_ADD); + assert_int_equal(tree->lhs->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->lhs->lhs->token.uintValue, 1); + assert_int_equal(tree->lhs->lhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->lhs->rhs->token.uintValue, 2); + assert_int_equal(tree->rhs->token.type, TOKEN_UINT_TYPE); + assert_int_equal(tree->rhs->token.uintValue, 3); } -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)) +M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(Parser, + cmocka_unit_test(parseEmpty), + cmocka_unit_test(parseInt), + cmocka_unit_test(parseLexError), + cmocka_unit_test(parseSimpleExpression), + cmocka_unit_test(parseAddMultplyExpression), + cmocka_unit_test(parseParentheticalExpression), + cmocka_unit_test(parseParentheticalAddMultplyExpression))