First version for string_to_number, just one test, is working fine, i'm considering swithching to handling only integers for in the future to manage in special struct that manages doubles as fractions, obviously this will mean changing nodes for general numbers to integers/fractions and shit
This commit is contained in:
@@ -34,6 +34,7 @@ typedef enum {
|
||||
LEXER_EMPTY_INPUT,
|
||||
LEXER_NULL_ARG,
|
||||
LEXER_WRONG_SYNTAX,
|
||||
LEXER_BUF_OVERFLOW,
|
||||
} LexerErr;
|
||||
|
||||
// Can be thought as tokens, they will be used by the parser.
|
||||
@@ -68,6 +69,7 @@ size_t ASTNodeArray_len(ASTNodeArray *arr);
|
||||
// Lexer funtions as well as few functionality
|
||||
LexerErr tokenize(const char* input, ASTNodeArray *out);
|
||||
LexerErr tokenize_number(const char* input, size_t *offset, ASTNode *out);
|
||||
LexerErr string_to_number(const char* str, double *number);
|
||||
LexerErr string_to_number(const char* input, size_t *offset, double *number);
|
||||
void reverser_string(char* input);
|
||||
|
||||
#endif // !LEXER_H
|
||||
|
||||
51
src/lexer.c
51
src/lexer.c
@@ -1,6 +1,10 @@
|
||||
#include "lexer.h"
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define NODE_ARRAY_DEFAULT_SIZE 64
|
||||
// Helps state machine for the lexer :)
|
||||
@@ -79,6 +83,16 @@ ASTNodeArrayErr ASTNodeArray_pop(ASTNodeArray *arr, size_t index, ASTNode *out)
|
||||
return ARRAY_OUT_OF_BOUNDS;
|
||||
}
|
||||
|
||||
if (arr->cap / 4 > arr->len) {
|
||||
size_t new_cap = arr->cap / 2;
|
||||
ASTNode *tmp = realloc(arr->data, new_cap * sizeof(ASTNode));
|
||||
if (tmp == NULL) {
|
||||
return ARRAY_ALLOC;
|
||||
}
|
||||
arr->data = tmp;
|
||||
arr->cap = new_cap;
|
||||
}
|
||||
|
||||
if (out != NULL) {
|
||||
ASTNode node_to_delete = arr->data[index];
|
||||
*out = node_to_delete;
|
||||
@@ -97,3 +111,40 @@ size_t ASTNodeArray_len(ASTNodeArray *arr) {
|
||||
}
|
||||
return arr->len;
|
||||
}
|
||||
|
||||
// CURRENTLY, it only supports ints, not clear how floating
|
||||
// point is implemented but i'll figure it out
|
||||
LexerErr string_to_number(const char *input, size_t *offset, double *number) {
|
||||
char buf[128] = { '\0' };
|
||||
size_t buf_pos = 0;
|
||||
|
||||
size_t current = *offset;
|
||||
while (isdigit(input[current])) {
|
||||
buf[buf_pos] = input[current];
|
||||
|
||||
if (buf_pos >= sizeof(buf)) {
|
||||
return LEXER_BUF_OVERFLOW;
|
||||
}
|
||||
current++;
|
||||
buf_pos++;
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
long count = 0;
|
||||
while (buf[c] != '\0') {
|
||||
|
||||
int digit = buf[c] - '0';
|
||||
|
||||
if (count > (INT_MAX - digit) / 10) {
|
||||
return LEXER_FAILED_NUMBER_CONVERSION;
|
||||
}
|
||||
count = count * 10;
|
||||
count += digit;
|
||||
|
||||
c++;
|
||||
}
|
||||
|
||||
*number = (double) count;
|
||||
*offset = current;
|
||||
return LEXER_OK;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
find_package(cmocka REQUIRED)
|
||||
|
||||
add_executable(test_nodeArray test_ASTNodeArray.c)
|
||||
add_executable(test_lexer test_lexer.c)
|
||||
|
||||
target_link_libraries(test_nodeArray
|
||||
calculator_lib
|
||||
cmocka::cmocka
|
||||
)
|
||||
|
||||
target_link_libraries(test_lexer
|
||||
calculator_lib
|
||||
cmocka::cmocka
|
||||
)
|
||||
|
||||
add_test(NAME nodeArray_tests COMMAND test_nodeArray)
|
||||
add_test(NAME lexer_tests COMMAND test_lexer)
|
||||
|
||||
@@ -34,12 +34,15 @@ static void test_array_push(void **state) {
|
||||
|
||||
assert_int_equal(ASTNodeArray_push(&arr, node3), ARRAY_OK);
|
||||
assert_int_equal(ASTNodeArray_len(&arr), 3);
|
||||
|
||||
ASTNodeArray_free(&arr);
|
||||
}
|
||||
|
||||
static void test_array_pop(void **state) {
|
||||
(void) state;
|
||||
|
||||
ASTNodeArray arr = ASTNodeArray_init(2);
|
||||
// Set to force desize
|
||||
ASTNodeArray arr = ASTNodeArray_init(16);
|
||||
ASTNode node1 = {
|
||||
.type = NODE_NUMBER,
|
||||
.data = { .number = 90 }
|
||||
@@ -68,8 +71,11 @@ static void test_array_pop(void **state) {
|
||||
assert_int_equal(ASTNodeArray_pop(&arr, 1, &node4), ARRAY_OK);
|
||||
assert_int_equal(node4.type, NODE_NUMBER);
|
||||
assert_int_equal(node4.data.number, 80);
|
||||
|
||||
ASTNodeArray_free(&arr);
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_array_push),
|
||||
|
||||
27
test/test_lexer.c
Normal file
27
test/test_lexer.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "lexer.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <setjmp.h>
|
||||
#include <cmocka.h>
|
||||
|
||||
static void test_string_to_number(void **state) {
|
||||
(void) state;
|
||||
|
||||
char num[16] = "2333t55";
|
||||
size_t offset = 0;
|
||||
double result = 0;
|
||||
assert_int_equal(string_to_number(num, &offset, &result), 0);
|
||||
|
||||
assert_int_equal(offset, 4);
|
||||
assert_double_equal(result, 2333, 1e-6);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
const struct CMUnitTest tests[] = {
|
||||
cmocka_unit_test(test_string_to_number),
|
||||
};
|
||||
|
||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||
}
|
||||
Reference in New Issue
Block a user