src/debugger/test/parser.c (view raw)
1/* Copyright (c) 2013-2017 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include "util/test/suite.h"
7
8#include <mgba/internal/debugger/parser.h>
9
10struct LPTest {
11 struct LexVector lv;
12 struct ParseTree tree;
13};
14
15#define PARSE(STR) \
16 struct LPTest* lp = *state; \
17 lexFree(&lp->lv); \
18 LexVectorClear(&lp->lv); \
19 size_t adjusted = lexExpression(&lp->lv, STR, strlen(STR), ""); \
20 assert_false(adjusted > strlen(STR)); \
21 struct ParseTree* tree = &lp->tree; \
22 parseLexedExpression(tree, &lp->lv)
23
24static int parseSetup(void** state) {
25 struct LPTest* lp = malloc(sizeof(struct LPTest));
26 LexVectorInit(&lp->lv, 0);
27 *state = lp;
28 return 0;
29}
30
31static int parseTeardown(void** state) {
32 struct LPTest* lp = *state;
33 parseFree(&lp->tree);
34 lexFree(&lp->lv);
35 LexVectorDeinit(&lp->lv);
36 free(lp);
37 return 0;
38}
39
40M_TEST_DEFINE(parseEmpty) {
41 PARSE("");
42
43 assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE);
44}
45
46M_TEST_DEFINE(parseInt) {
47 PARSE("0");
48
49 assert_int_equal(tree->token.type, TOKEN_UINT_TYPE);
50 assert_int_equal(tree->token.uintValue, 0);
51}
52
53M_TEST_DEFINE(parseLexError) {
54 PARSE("@");
55
56 assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE);
57}
58
59M_TEST_DEFINE(parseError) {
60 PARSE("1 2");
61
62 assert_int_equal(tree->token.type, TOKEN_ERROR_TYPE);
63}
64
65M_TEST_DEFINE(parseSimpleExpression) {
66 PARSE("1+2");
67
68 assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE);
69 assert_int_equal(tree->token.operatorValue, OP_ADD);
70 assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE);
71 assert_int_equal(tree->lhs->token.uintValue, 1);
72 assert_int_equal(tree->rhs->token.type, TOKEN_UINT_TYPE);
73 assert_int_equal(tree->rhs->token.uintValue, 2);
74}
75
76M_TEST_DEFINE(parseAddMultplyExpression) {
77 PARSE("1+2*3");
78
79 assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE);
80 assert_int_equal(tree->token.operatorValue, OP_ADD);
81 assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE);
82 assert_int_equal(tree->lhs->token.uintValue, 1);
83 assert_int_equal(tree->rhs->token.type, TOKEN_OPERATOR_TYPE);
84 assert_int_equal(tree->rhs->token.uintValue, OP_MULTIPLY);
85 assert_int_equal(tree->rhs->lhs->token.type, TOKEN_UINT_TYPE);
86 assert_int_equal(tree->rhs->lhs->token.uintValue, 2);
87 assert_int_equal(tree->rhs->rhs->token.type, TOKEN_UINT_TYPE);
88 assert_int_equal(tree->rhs->rhs->token.uintValue, 3);
89}
90
91M_TEST_DEFINE(parseParentheticalExpression) {
92 PARSE("(1+2)");
93
94 assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE);
95 assert_int_equal(tree->token.operatorValue, OP_ADD);
96 assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE);
97 assert_int_equal(tree->lhs->token.uintValue, 1);
98 assert_int_equal(tree->rhs->token.type, TOKEN_UINT_TYPE);
99 assert_int_equal(tree->rhs->token.uintValue, 2);
100}
101
102M_TEST_DEFINE(parseParentheticalAddMultplyExpression) {
103 PARSE("(1+2)*3");
104
105 assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE);
106 assert_int_equal(tree->token.operatorValue, OP_MULTIPLY);
107 assert_int_equal(tree->lhs->token.type, TOKEN_OPERATOR_TYPE);
108 assert_int_equal(tree->lhs->token.uintValue, OP_ADD);
109 assert_int_equal(tree->lhs->lhs->token.type, TOKEN_UINT_TYPE);
110 assert_int_equal(tree->lhs->lhs->token.uintValue, 1);
111 assert_int_equal(tree->lhs->lhs->token.type, TOKEN_UINT_TYPE);
112 assert_int_equal(tree->lhs->rhs->token.uintValue, 2);
113 assert_int_equal(tree->rhs->token.type, TOKEN_UINT_TYPE);
114 assert_int_equal(tree->rhs->token.uintValue, 3);
115}
116
117M_TEST_DEFINE(parseIsolatedOperator) {
118 PARSE("+");
119
120 assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE);
121 assert_int_equal(tree->lhs->token.type, TOKEN_ERROR_TYPE);
122 assert_int_equal(tree->rhs->token.type, TOKEN_ERROR_TYPE);
123}
124
125M_TEST_DEFINE(parseUnaryChainedOperator) {
126 PARSE("1+*2");
127
128 assert_int_equal(tree->token.type, TOKEN_OPERATOR_TYPE);
129 assert_int_equal(tree->token.operatorValue, OP_ADD);
130 assert_int_equal(tree->lhs->token.type, TOKEN_UINT_TYPE);
131 assert_int_equal(tree->lhs->token.uintValue, 1);
132 assert_int_equal(tree->rhs->token.type, TOKEN_OPERATOR_TYPE);
133 assert_int_equal(tree->rhs->token.operatorValue, OP_DEREFERENCE);
134 assert_int_equal(tree->rhs->rhs->token.type, TOKEN_UINT_TYPE);
135 assert_int_equal(tree->rhs->rhs->token.uintValue, 2);
136}
137
138M_TEST_SUITE_DEFINE(Parser,
139 cmocka_unit_test_setup_teardown(parseEmpty, parseSetup, parseTeardown),
140 cmocka_unit_test_setup_teardown(parseInt, parseSetup, parseTeardown),
141 cmocka_unit_test_setup_teardown(parseLexError, parseSetup, parseTeardown),
142 cmocka_unit_test_setup_teardown(parseError, parseSetup, parseTeardown),
143 cmocka_unit_test_setup_teardown(parseSimpleExpression, parseSetup, parseTeardown),
144 cmocka_unit_test_setup_teardown(parseAddMultplyExpression, parseSetup, parseTeardown),
145 cmocka_unit_test_setup_teardown(parseParentheticalExpression, parseSetup, parseTeardown),
146 cmocka_unit_test_setup_teardown(parseParentheticalAddMultplyExpression, parseSetup, parseTeardown),
147 cmocka_unit_test_setup_teardown(parseIsolatedOperator, parseSetup, parseTeardown),
148 cmocka_unit_test_setup_teardown(parseUnaryChainedOperator, parseSetup, parseTeardown))