diff --git a/.gitignore b/.gitignore index 5a4add7..20003c6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ venv/ # Ignore Python Caches -compiler/results +src/compiler/results __pycache__/ # Ignore CMake's build directory diff --git a/src/CMakeLists.txt b/src/c_interpretter/CMakeLists.txt similarity index 96% rename from src/CMakeLists.txt rename to src/c_interpretter/CMakeLists.txt index 422d52f..efdb86d 100644 --- a/src/CMakeLists.txt +++ b/src/c_interpretter/CMakeLists.txt @@ -1,16 +1,16 @@ -# Make src public to tests -include_directories("${CMAKE_SOURCE_DIR}") - -# Add libraries -## Compiler Compatibility Files -add_subdirectory("${CMAKE_SOURCE_DIR}/src/bool") -add_subdirectory("${CMAKE_SOURCE_DIR}/src/common") - -## Standard Library Wrappers -add_subdirectory("${CMAKE_SOURCE_DIR}/src/mem") - -## Custom Library -add_subdirectory("${CMAKE_SOURCE_DIR}/src/arr") -add_subdirectory("${CMAKE_SOURCE_DIR}/src/tbl") -add_subdirectory("${CMAKE_SOURCE_DIR}/src/rstr") - +# Make src public to tests +include_directories("${CMAKE_SOURCE_DIR}") + +# Add libraries +## Compiler Compatibility Files +add_subdirectory("${CMAKE_SOURCE_DIR}/src/bool") +add_subdirectory("${CMAKE_SOURCE_DIR}/src/common") + +## Standard Library Wrappers +add_subdirectory("${CMAKE_SOURCE_DIR}/src/mem") + +## Custom Library +add_subdirectory("${CMAKE_SOURCE_DIR}/src/arr") +add_subdirectory("${CMAKE_SOURCE_DIR}/src/tbl") +add_subdirectory("${CMAKE_SOURCE_DIR}/src/rstr") + diff --git a/src/CODING_STYLE.md b/src/c_interpretter/CODING_STYLE.md similarity index 100% rename from src/CODING_STYLE.md rename to src/c_interpretter/CODING_STYLE.md diff --git a/src/PORTABILITY_IN_C.md b/src/c_interpretter/PORTABILITY_IN_C.md similarity index 100% rename from src/PORTABILITY_IN_C.md rename to src/c_interpretter/PORTABILITY_IN_C.md diff --git a/src/STANDARD_LIBRARY.md b/src/c_interpretter/STANDARD_LIBRARY.md similarity index 100% rename from src/STANDARD_LIBRARY.md rename to src/c_interpretter/STANDARD_LIBRARY.md diff --git a/src/arr/CMakeLists.txt b/src/c_interpretter/arr/CMakeLists.txt similarity index 97% rename from src/arr/CMakeLists.txt rename to src/c_interpretter/arr/CMakeLists.txt index 2dde5f7..0a5f765 100644 --- a/src/arr/CMakeLists.txt +++ b/src/c_interpretter/arr/CMakeLists.txt @@ -1,5 +1,5 @@ -# Create the 'arr' target -add_library("arr" "${CMAKE_SOURCE_DIR}/src/arr/arr.c") - -# Link executable to libraries +# Create the 'arr' target +add_library("arr" "${CMAKE_SOURCE_DIR}/src/arr/arr.c") + +# Link executable to libraries target_link_libraries("arr" PRIVATE "mem" "common") \ No newline at end of file diff --git a/src/arr/arr.c b/src/c_interpretter/arr/arr.c similarity index 100% rename from src/arr/arr.c rename to src/c_interpretter/arr/arr.c diff --git a/src/arr/arr.h b/src/c_interpretter/arr/arr.h similarity index 100% rename from src/arr/arr.h rename to src/c_interpretter/arr/arr.h diff --git a/src/arr/arr_checks.h b/src/c_interpretter/arr/arr_checks.h similarity index 100% rename from src/arr/arr_checks.h rename to src/c_interpretter/arr/arr_checks.h diff --git a/src/arr/arr_helper.h b/src/c_interpretter/arr/arr_helper.h similarity index 100% rename from src/arr/arr_helper.h rename to src/c_interpretter/arr/arr_helper.h diff --git a/src/arr/arr_macros.h b/src/c_interpretter/arr/arr_macros.h similarity index 100% rename from src/arr/arr_macros.h rename to src/c_interpretter/arr/arr_macros.h diff --git a/src/bool/CMakeLists.txt b/src/c_interpretter/bool/CMakeLists.txt similarity index 100% rename from src/bool/CMakeLists.txt rename to src/c_interpretter/bool/CMakeLists.txt diff --git a/src/bool/bool.h b/src/c_interpretter/bool/bool.h similarity index 95% rename from src/bool/bool.h rename to src/c_interpretter/bool/bool.h index d925d52..02ab420 100644 --- a/src/bool/bool.h +++ b/src/c_interpretter/bool/bool.h @@ -1,7 +1,7 @@ -#pragma once - -#ifndef __STDC_VERSION__ /* C89 */ -typedef enum { false = 0, true = 1 } bool; -#else - #include +#pragma once + +#ifndef __STDC_VERSION__ /* C89 */ +typedef enum { false = 0, true = 1 } bool; +#else + #include #endif \ No newline at end of file diff --git a/src/common/CMakeLists.txt b/src/c_interpretter/common/CMakeLists.txt similarity index 100% rename from src/common/CMakeLists.txt rename to src/c_interpretter/common/CMakeLists.txt diff --git a/src/common/common.c b/src/c_interpretter/common/common.c similarity index 100% rename from src/common/common.c rename to src/c_interpretter/common/common.c diff --git a/src/common/common.h b/src/c_interpretter/common/common.h similarity index 100% rename from src/common/common.h rename to src/c_interpretter/common/common.h diff --git a/src/main.c b/src/c_interpretter/main.c similarity index 97% rename from src/main.c rename to src/c_interpretter/main.c index ea3e3cb..a888648 100644 --- a/src/main.c +++ b/src/c_interpretter/main.c @@ -1,342 +1,342 @@ -#include -#include -#include -#include - -#include "src/arr/arr.h" -#include "src/bool/bool.h" -#include "src/common/common.h" -#include "src/mem/mem.h" -#include "src/rstr/rstr.h" -#include "src/tbl/tbl.h" - -#define CHANNEL stdout - -/* Print status and set test variable as pass or fail */ -#define TEST_INT_EQ(output, oracle, err) \ - do { \ - int _output = (output); \ - int _oracle = (oracle); \ - if (_output == _oracle) { \ - fprintf(CHANNEL, /*GREEN*/ "\033[32m" #output " == " #oracle \ - ": OK\033[0m\n" /*END GREEN*/); \ - } else { \ - fprintf(CHANNEL, /*RED*/ \ - "\033[31m" #output "(=%d) != " #oracle "(=%d)" \ - ", expected " #output " == " #oracle \ - ": FAILURE in %s:%d\033[0m\n" /*END RED*/, \ - _output, _oracle, __FILE__, __LINE__); \ - (err) = -1; \ - } \ - } while (0) - -/* Print status and set test variable as pass or fail */ -#define TEST_PTR_EQ(output, oracle, err) \ - do { \ - void *_output = (output); \ - void *_oracle = (oracle); \ - if (_output == _oracle) { \ - fprintf(CHANNEL, /*GREEN*/ "\033[32m" #output " == " #oracle \ - ": OK\033[0m\n" /*END GREEN*/); \ - } else { \ - fprintf(CHANNEL, /*RED*/ \ - "\033[31m" #output "(=%p) != " #oracle "(=%p)" \ - ", expected " #output " == " #oracle \ - ": FAILURE in %s:%d\033[0m\n" /*END RED*/, \ - _output, _oracle, __FILE__, __LINE__); \ - (err) = -1; \ - } \ - } while (0) - -/* Print status and set test variable as pass or fail */ -#define TEST_PTR_NE(output, oracle, err) \ - do { \ - void *_output = (output); \ - void *_oracle = (oracle); \ - if (_output != _oracle) { \ - fprintf(CHANNEL, /*GREEN*/ "\033[32m" #output " != " #oracle \ - ": OK\033[0m\n" /*END GREEN*/); \ - } else { \ - fprintf(CHANNEL, /*RED*/ \ - "\033[31m" #output "(=%p) == " #oracle "(=%p)" \ - ", expected " #output " != " #oracle \ - ": FAILURE in %s:%d\033[0m\n" /*END RED*/, \ - _output, _oracle, __FILE__, __LINE__); \ - (err) = -1; \ - } \ - } while (0) - -int test_bool(void) { - /* Cannot use regular testing, because that relies upon the boolean working - */ - assert((true && !false) && (true == 1 && false == 0)); - return 0; -} - -/******************************************************************************/ - -int test_mem(void) { - int err = 0; - void *p = NULL, *tmp = NULL; - - /* Basic test malloc and free. */ - TEST_INT_EQ(mem_malloc(&p, 1, 1), 0, err); - TEST_PTR_NE(p, NULL, err); - TEST_INT_EQ(mem_free(&p), 0, err); - TEST_PTR_EQ(p, NULL, err); - - /* Test bad arguments for mem_malloc() */ - TEST_INT_EQ(mem_malloc(NULL, 0, 1), -1, err); /* Pass in NULL ptr => error*/ - TEST_INT_EQ(mem_malloc(NULL, 1, 1), -1, err); - TEST_INT_EQ(mem_malloc(NULL, -1, 1), -1, err); - TEST_INT_EQ(mem_malloc(&p, 0, 0), 0, err); - TEST_PTR_EQ(p, NULL, err); /* p returned as NULL */ - TEST_INT_EQ(mem_malloc(&p, -1, 1), ENOMEM, err); - TEST_PTR_EQ(p, NULL, err); /* Not enough memory => error*/ - errno = 0; - - /* Test bad arguments for mem_free() */ - TEST_INT_EQ(mem_free(NULL), -1, err); - - /* Test bad arguments for mem_realloc() */ - TEST_INT_EQ(mem_realloc(NULL, 0, 1), -1, - err); /* Pass in NULL ptr => error*/ - TEST_INT_EQ(mem_realloc(NULL, 1, 1), -1, err); - TEST_INT_EQ(mem_realloc(NULL, -1, 1), -1, err); - TEST_INT_EQ(mem_realloc(&p, 0, 1), 0, err); - TEST_PTR_EQ(p, NULL, err); - TEST_INT_EQ(mem_realloc(&p, -1, 1), ENOMEM, err); - TEST_PTR_EQ(p, NULL, err); - /* errno still set! */ - TEST_INT_EQ(mem_realloc(NULL, 0, 1), ENOMEM, - err); /* Pass in NULL ptr => error*/ - TEST_INT_EQ(mem_realloc(NULL, 1, 1), ENOMEM, err); - TEST_INT_EQ(mem_realloc(NULL, -1, 1), ENOMEM, err); - TEST_INT_EQ(mem_realloc(&p, 0, 1), ENOMEM, err); /* Pass in ptr => error*/ - TEST_INT_EQ(mem_realloc(&p, 1, 1), ENOMEM, err); - TEST_INT_EQ(mem_realloc(&p, -1, 1), ENOMEM, err); - errno = 0; - - TEST_INT_EQ(mem_realloc(&p, 10, 1), 0, err); - TEST_PTR_NE(p, NULL, err); /* Works */ - TEST_INT_EQ(mem_realloc(&p, 0, 1), 0, err); - TEST_PTR_EQ(p, NULL, err); - TEST_INT_EQ(mem_realloc(&p, 10, 1), 0, err); - TEST_PTR_NE(p, NULL, err); - tmp = p; - TEST_INT_EQ(mem_realloc(&p, -1, 1), ENOMEM, err); - TEST_PTR_NE(p, NULL, err); - TEST_PTR_EQ(p, tmp, err); - errno = 0; - tmp = NULL; - TEST_INT_EQ(mem_realloc(&p, 0, 1), 0, err); - TEST_PTR_EQ(p, NULL, err); - - return err; -} - -/******************************************************************************/ - -int int_print(const void *const restrict ip) { - printf("%d", *(int *)ip); - return 0; -} - -int int_dtor(void *const restrict ip) { - if (ip == NULL) { - return -1; - } - return 0; -} - -int test_arr(void) { - int err = 0, x = 0; - int *y = NULL; - arr a = {0}, b = {0}; - - TEST_INT_EQ(arr_ctor(&a, 10, sizeof(int)), 0, err); - TEST_INT_EQ(arr_ctor(&b, 10, sizeof(int)), 0, err); - - arr_print(&a, int_print); - for (x = 0; x < 11; ++x) { - TEST_INT_EQ(arr_insert(&a, 0, &x), 0, err); - y = (int *)arr_search(&a, 0); - assert(y != NULL && "null!"); - TEST_INT_EQ(*y == x, 1, err); - } - arr_print(&a, int_print); - - for (x = 11; x < 22; ++x) { - TEST_INT_EQ(arr_append(&a, &x), 0, err); - } - arr_print(&a, int_print); - - x = 12; - TEST_INT_EQ(arr_change(&a, 0, &x, int_dtor), 0, err); - arr_print(&a, int_print); - - while (a.len > 0) { - TEST_INT_EQ(arr_remove(&a, 0, int_dtor), 0, err); - } - arr_print(&a, int_print); - - TEST_INT_EQ(arr_dtor(&a, int_dtor), 0, err); - TEST_INT_EQ(arr_dtor(&b, int_dtor), 0, err); - - return err; -} - -/******************************************************************************/ - -size_t simple_str_hash(const void *const restrict str) { - return strlen((const char *const restrict)str); -} - -int str_print(const void *const restrict str) { - assert(str != NULL && "null str"); - printf("\"%s\"", (const char *const restrict)str); - return 0; -} - -int tbl_noop_del(void *const restrict ptr) { - assert(ptr != NULL && "pointer is NULL"); - return 0; -} - -int test_tbl(void) { - /* TODO(dchu): this test was failing so I disabled it. Classic. All of these - macros are enormously confusing. Probably a simpler implementation would - suffice. */ - return 0; - // int err = 0; - // size_t i = 0; - // char *keys[10] = {"a", "bb", "ccc", "dddd", - // "eeeee", "ffffff", "ggggggg", "hhhhhhhh", - // "iiiiiiiii", "jjjjjjjjjj"}; - // int values[10] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; - // tbl *me = NULL; - - // /* Setup */ - // REQUIRE_NO_ERROR(mem_malloc((void **)&me, 1, sizeof(tbl)), - // "malloc failed"); - // REQUIRE_NO_ERROR(tbl_ctor(me, 10, simple_str_hash, - // (int (*)(const void *const restrict, - // const void *const restrict))strcmp), - // "tbl_ctor failed"); - - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - // TEST_INT_EQ(tbl_insert(me, keys[0], &values[0], tbl_noop_del), 0, err); - // TEST_INT_EQ(tbl_insert(me, keys[1], &values[1], tbl_noop_del), 0, err); - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - - // TEST_PTR_EQ(tbl_search(me, keys[0]), &values[0], err); - // TEST_PTR_EQ(tbl_search(me, keys[1]), &values[1], err); - // TEST_PTR_EQ(tbl_search(me, keys[2]), NULL, err); - - // TEST_INT_EQ(tbl_remove(me, keys[0], tbl_noop_del, tbl_noop_del), 0, err); - // TEST_INT_EQ(tbl_remove(me, keys[0], tbl_noop_del, tbl_noop_del), 0, err); - // TEST_PTR_EQ(tbl_search(me, keys[0]), NULL, err); - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - - // TEST_INT_EQ(tbl_insert(me, keys[0], &values[0], tbl_noop_del), 0, err); - // TEST_PTR_EQ(tbl_search(me, keys[0]), &values[0], err); - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - - // TEST_INT_EQ(tbl_insert(me, keys[0], &values[1], tbl_noop_del), 0, err); - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - // TEST_PTR_EQ(tbl_search(me, keys[0]), &values[1], err); - // TEST_INT_EQ(tbl_insert(me, keys[0], &values[0], tbl_noop_del), 0, err); - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - - // for (i = 0; i < 10; ++i) { - // TEST_INT_EQ(tbl_insert(me, keys[i], &values[i], tbl_noop_del), 0, - // err); - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - // TEST_PTR_EQ(tbl_search(me, keys[i]), &values[i], err); - // } - // /* Try to shove an extra in (breaks for now) */ - // TEST_INT_EQ(tbl_insert(me, "extra", &values[0], tbl_noop_del), - // ERROR_NOROOM, err); - - // for (i = 0; i < 10; ++i) { - // TEST_INT_EQ(tbl_remove(me, keys[i], tbl_noop_del, tbl_noop_del), 0, - // err); - // } - // TEST_INT_EQ(tbl_remove(me, keys[0], tbl_noop_del, tbl_noop_del), 0, err); - - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - // for (i = 0; i < 10; ++i) { - // TEST_INT_EQ(tbl_insert(me, keys[i], &values[i], tbl_noop_del), 0, - // err); - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - // TEST_PTR_EQ(tbl_search(me, keys[i]), &values[i], err); - // } - // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); - - // /* Teardown */ - // REQUIRE_NO_ERROR(tbl_dtor(me, tbl_noop_del, tbl_noop_del), - // "tbl_dtor failed"); - // REQUIRE_NO_ERROR(mem_free((void **)&me), "free failed"); - - // return err; -} - -/******************************************************************************/ -int rstr_noop_dtor(char *const str) { - assert(str && "found NULL string"); - return 0; -} - -int test_rstr(void) { - int err = 0; - rstr full, a, b; - const char *const str = - "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; - - REQUIRE_NO_ERROR(rstr_ctor(&full, str, strlen(str)), - "failure to construct"); - REQUIRE_NO_ERROR(rstr_debug(&full), "failure to print"); - REQUIRE_NO_ERROR(rstr_print(&full), "failure to print"); - - TEST_INT_EQ(rstr_debug(NULL), ERROR_NULLPTR, err); - a.str = NULL; - TEST_INT_EQ(rstr_debug(&a), ERROR_NULLPTR, err); - - TEST_INT_EQ(rstr_ctor(&a, str, 10U), 0, err); - TEST_INT_EQ(a.len, 10U, err); - TEST_INT_EQ(rstr_debug(&a), 0, err); - - TEST_INT_EQ(rstr_slice(&full, 0, 10, &b), 0, err); - TEST_INT_EQ(rstr_debug(&b), 0, err); - - TEST_INT_EQ(rstr_cmp(&a, &b), 0, err); - - TEST_INT_EQ(rstr_slice(&b, 0, 5, &b), 0, err); - TEST_INT_EQ(rstr_debug(&b), 0, err); - - /* Cleanup */ - TEST_INT_EQ(rstr_dtor(&full, rstr_noop_dtor), 0, err); - TEST_INT_EQ(rstr_dtor(&a, rstr_noop_dtor), 0, err); - TEST_INT_EQ(rstr_dtor(&b, rstr_noop_dtor), 0, err); - - return err; -} - -int main(void) { - int err = 0; - - /* Technically, this is sketchy because we are assuming that bool works. */ - TEST_INT_EQ(test_bool(), 0, err); - TEST_INT_EQ(test_mem(), 0, err); - TEST_INT_EQ(test_arr(), 0, err); - TEST_INT_EQ(test_tbl(), 0, err); - TEST_INT_EQ(test_rstr(), 0, err); - - if (err == 0) { - fprintf(CHANNEL, /*GREEN*/ - "\033[32m>>> ALL TESTS PASSED! <<<\033[0m\n" /*END GREEN*/); - fflush(CHANNEL); - } - - return err; -} +#include +#include +#include +#include + +#include "src/arr/arr.h" +#include "src/bool/bool.h" +#include "src/common/common.h" +#include "src/mem/mem.h" +#include "src/rstr/rstr.h" +#include "src/tbl/tbl.h" + +#define CHANNEL stdout + +/* Print status and set test variable as pass or fail */ +#define TEST_INT_EQ(output, oracle, err) \ + do { \ + int _output = (output); \ + int _oracle = (oracle); \ + if (_output == _oracle) { \ + fprintf(CHANNEL, /*GREEN*/ "\033[32m" #output " == " #oracle \ + ": OK\033[0m\n" /*END GREEN*/); \ + } else { \ + fprintf(CHANNEL, /*RED*/ \ + "\033[31m" #output "(=%d) != " #oracle "(=%d)" \ + ", expected " #output " == " #oracle \ + ": FAILURE in %s:%d\033[0m\n" /*END RED*/, \ + _output, _oracle, __FILE__, __LINE__); \ + (err) = -1; \ + } \ + } while (0) + +/* Print status and set test variable as pass or fail */ +#define TEST_PTR_EQ(output, oracle, err) \ + do { \ + void *_output = (output); \ + void *_oracle = (oracle); \ + if (_output == _oracle) { \ + fprintf(CHANNEL, /*GREEN*/ "\033[32m" #output " == " #oracle \ + ": OK\033[0m\n" /*END GREEN*/); \ + } else { \ + fprintf(CHANNEL, /*RED*/ \ + "\033[31m" #output "(=%p) != " #oracle "(=%p)" \ + ", expected " #output " == " #oracle \ + ": FAILURE in %s:%d\033[0m\n" /*END RED*/, \ + _output, _oracle, __FILE__, __LINE__); \ + (err) = -1; \ + } \ + } while (0) + +/* Print status and set test variable as pass or fail */ +#define TEST_PTR_NE(output, oracle, err) \ + do { \ + void *_output = (output); \ + void *_oracle = (oracle); \ + if (_output != _oracle) { \ + fprintf(CHANNEL, /*GREEN*/ "\033[32m" #output " != " #oracle \ + ": OK\033[0m\n" /*END GREEN*/); \ + } else { \ + fprintf(CHANNEL, /*RED*/ \ + "\033[31m" #output "(=%p) == " #oracle "(=%p)" \ + ", expected " #output " != " #oracle \ + ": FAILURE in %s:%d\033[0m\n" /*END RED*/, \ + _output, _oracle, __FILE__, __LINE__); \ + (err) = -1; \ + } \ + } while (0) + +int test_bool(void) { + /* Cannot use regular testing, because that relies upon the boolean working + */ + assert((true && !false) && (true == 1 && false == 0)); + return 0; +} + +/******************************************************************************/ + +int test_mem(void) { + int err = 0; + void *p = NULL, *tmp = NULL; + + /* Basic test malloc and free. */ + TEST_INT_EQ(mem_malloc(&p, 1, 1), 0, err); + TEST_PTR_NE(p, NULL, err); + TEST_INT_EQ(mem_free(&p), 0, err); + TEST_PTR_EQ(p, NULL, err); + + /* Test bad arguments for mem_malloc() */ + TEST_INT_EQ(mem_malloc(NULL, 0, 1), -1, err); /* Pass in NULL ptr => error*/ + TEST_INT_EQ(mem_malloc(NULL, 1, 1), -1, err); + TEST_INT_EQ(mem_malloc(NULL, -1, 1), -1, err); + TEST_INT_EQ(mem_malloc(&p, 0, 0), 0, err); + TEST_PTR_EQ(p, NULL, err); /* p returned as NULL */ + TEST_INT_EQ(mem_malloc(&p, -1, 1), ENOMEM, err); + TEST_PTR_EQ(p, NULL, err); /* Not enough memory => error*/ + errno = 0; + + /* Test bad arguments for mem_free() */ + TEST_INT_EQ(mem_free(NULL), -1, err); + + /* Test bad arguments for mem_realloc() */ + TEST_INT_EQ(mem_realloc(NULL, 0, 1), -1, + err); /* Pass in NULL ptr => error*/ + TEST_INT_EQ(mem_realloc(NULL, 1, 1), -1, err); + TEST_INT_EQ(mem_realloc(NULL, -1, 1), -1, err); + TEST_INT_EQ(mem_realloc(&p, 0, 1), 0, err); + TEST_PTR_EQ(p, NULL, err); + TEST_INT_EQ(mem_realloc(&p, -1, 1), ENOMEM, err); + TEST_PTR_EQ(p, NULL, err); + /* errno still set! */ + TEST_INT_EQ(mem_realloc(NULL, 0, 1), ENOMEM, + err); /* Pass in NULL ptr => error*/ + TEST_INT_EQ(mem_realloc(NULL, 1, 1), ENOMEM, err); + TEST_INT_EQ(mem_realloc(NULL, -1, 1), ENOMEM, err); + TEST_INT_EQ(mem_realloc(&p, 0, 1), ENOMEM, err); /* Pass in ptr => error*/ + TEST_INT_EQ(mem_realloc(&p, 1, 1), ENOMEM, err); + TEST_INT_EQ(mem_realloc(&p, -1, 1), ENOMEM, err); + errno = 0; + + TEST_INT_EQ(mem_realloc(&p, 10, 1), 0, err); + TEST_PTR_NE(p, NULL, err); /* Works */ + TEST_INT_EQ(mem_realloc(&p, 0, 1), 0, err); + TEST_PTR_EQ(p, NULL, err); + TEST_INT_EQ(mem_realloc(&p, 10, 1), 0, err); + TEST_PTR_NE(p, NULL, err); + tmp = p; + TEST_INT_EQ(mem_realloc(&p, -1, 1), ENOMEM, err); + TEST_PTR_NE(p, NULL, err); + TEST_PTR_EQ(p, tmp, err); + errno = 0; + tmp = NULL; + TEST_INT_EQ(mem_realloc(&p, 0, 1), 0, err); + TEST_PTR_EQ(p, NULL, err); + + return err; +} + +/******************************************************************************/ + +int int_print(const void *const restrict ip) { + printf("%d", *(int *)ip); + return 0; +} + +int int_dtor(void *const restrict ip) { + if (ip == NULL) { + return -1; + } + return 0; +} + +int test_arr(void) { + int err = 0, x = 0; + int *y = NULL; + arr a = {0}, b = {0}; + + TEST_INT_EQ(arr_ctor(&a, 10, sizeof(int)), 0, err); + TEST_INT_EQ(arr_ctor(&b, 10, sizeof(int)), 0, err); + + arr_print(&a, int_print); + for (x = 0; x < 11; ++x) { + TEST_INT_EQ(arr_insert(&a, 0, &x), 0, err); + y = (int *)arr_search(&a, 0); + assert(y != NULL && "null!"); + TEST_INT_EQ(*y == x, 1, err); + } + arr_print(&a, int_print); + + for (x = 11; x < 22; ++x) { + TEST_INT_EQ(arr_append(&a, &x), 0, err); + } + arr_print(&a, int_print); + + x = 12; + TEST_INT_EQ(arr_change(&a, 0, &x, int_dtor), 0, err); + arr_print(&a, int_print); + + while (a.len > 0) { + TEST_INT_EQ(arr_remove(&a, 0, int_dtor), 0, err); + } + arr_print(&a, int_print); + + TEST_INT_EQ(arr_dtor(&a, int_dtor), 0, err); + TEST_INT_EQ(arr_dtor(&b, int_dtor), 0, err); + + return err; +} + +/******************************************************************************/ + +size_t simple_str_hash(const void *const restrict str) { + return strlen((const char *const restrict)str); +} + +int str_print(const void *const restrict str) { + assert(str != NULL && "null str"); + printf("\"%s\"", (const char *const restrict)str); + return 0; +} + +int tbl_noop_del(void *const restrict ptr) { + assert(ptr != NULL && "pointer is NULL"); + return 0; +} + +int test_tbl(void) { + /* TODO(dchu): this test was failing so I disabled it. Classic. All of these + macros are enormously confusing. Probably a simpler implementation would + suffice. */ + return 0; + // int err = 0; + // size_t i = 0; + // char *keys[10] = {"a", "bb", "ccc", "dddd", + // "eeeee", "ffffff", "ggggggg", "hhhhhhhh", + // "iiiiiiiii", "jjjjjjjjjj"}; + // int values[10] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; + // tbl *me = NULL; + + // /* Setup */ + // REQUIRE_NO_ERROR(mem_malloc((void **)&me, 1, sizeof(tbl)), + // "malloc failed"); + // REQUIRE_NO_ERROR(tbl_ctor(me, 10, simple_str_hash, + // (int (*)(const void *const restrict, + // const void *const restrict))strcmp), + // "tbl_ctor failed"); + + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + // TEST_INT_EQ(tbl_insert(me, keys[0], &values[0], tbl_noop_del), 0, err); + // TEST_INT_EQ(tbl_insert(me, keys[1], &values[1], tbl_noop_del), 0, err); + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + + // TEST_PTR_EQ(tbl_search(me, keys[0]), &values[0], err); + // TEST_PTR_EQ(tbl_search(me, keys[1]), &values[1], err); + // TEST_PTR_EQ(tbl_search(me, keys[2]), NULL, err); + + // TEST_INT_EQ(tbl_remove(me, keys[0], tbl_noop_del, tbl_noop_del), 0, err); + // TEST_INT_EQ(tbl_remove(me, keys[0], tbl_noop_del, tbl_noop_del), 0, err); + // TEST_PTR_EQ(tbl_search(me, keys[0]), NULL, err); + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + + // TEST_INT_EQ(tbl_insert(me, keys[0], &values[0], tbl_noop_del), 0, err); + // TEST_PTR_EQ(tbl_search(me, keys[0]), &values[0], err); + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + + // TEST_INT_EQ(tbl_insert(me, keys[0], &values[1], tbl_noop_del), 0, err); + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + // TEST_PTR_EQ(tbl_search(me, keys[0]), &values[1], err); + // TEST_INT_EQ(tbl_insert(me, keys[0], &values[0], tbl_noop_del), 0, err); + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + + // for (i = 0; i < 10; ++i) { + // TEST_INT_EQ(tbl_insert(me, keys[i], &values[i], tbl_noop_del), 0, + // err); + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + // TEST_PTR_EQ(tbl_search(me, keys[i]), &values[i], err); + // } + // /* Try to shove an extra in (breaks for now) */ + // TEST_INT_EQ(tbl_insert(me, "extra", &values[0], tbl_noop_del), + // ERROR_NOROOM, err); + + // for (i = 0; i < 10; ++i) { + // TEST_INT_EQ(tbl_remove(me, keys[i], tbl_noop_del, tbl_noop_del), 0, + // err); + // } + // TEST_INT_EQ(tbl_remove(me, keys[0], tbl_noop_del, tbl_noop_del), 0, err); + + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + // for (i = 0; i < 10; ++i) { + // TEST_INT_EQ(tbl_insert(me, keys[i], &values[i], tbl_noop_del), 0, + // err); + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + // TEST_PTR_EQ(tbl_search(me, keys[i]), &values[i], err); + // } + // TEST_INT_EQ(tbl_print(me, str_print, int_print), 0, err); + + // /* Teardown */ + // REQUIRE_NO_ERROR(tbl_dtor(me, tbl_noop_del, tbl_noop_del), + // "tbl_dtor failed"); + // REQUIRE_NO_ERROR(mem_free((void **)&me), "free failed"); + + // return err; +} + +/******************************************************************************/ +int rstr_noop_dtor(char *const str) { + assert(str && "found NULL string"); + return 0; +} + +int test_rstr(void) { + int err = 0; + rstr full, a, b; + const char *const str = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit"; + + REQUIRE_NO_ERROR(rstr_ctor(&full, str, strlen(str)), + "failure to construct"); + REQUIRE_NO_ERROR(rstr_debug(&full), "failure to print"); + REQUIRE_NO_ERROR(rstr_print(&full), "failure to print"); + + TEST_INT_EQ(rstr_debug(NULL), ERROR_NULLPTR, err); + a.str = NULL; + TEST_INT_EQ(rstr_debug(&a), ERROR_NULLPTR, err); + + TEST_INT_EQ(rstr_ctor(&a, str, 10U), 0, err); + TEST_INT_EQ(a.len, 10U, err); + TEST_INT_EQ(rstr_debug(&a), 0, err); + + TEST_INT_EQ(rstr_slice(&full, 0, 10, &b), 0, err); + TEST_INT_EQ(rstr_debug(&b), 0, err); + + TEST_INT_EQ(rstr_cmp(&a, &b), 0, err); + + TEST_INT_EQ(rstr_slice(&b, 0, 5, &b), 0, err); + TEST_INT_EQ(rstr_debug(&b), 0, err); + + /* Cleanup */ + TEST_INT_EQ(rstr_dtor(&full, rstr_noop_dtor), 0, err); + TEST_INT_EQ(rstr_dtor(&a, rstr_noop_dtor), 0, err); + TEST_INT_EQ(rstr_dtor(&b, rstr_noop_dtor), 0, err); + + return err; +} + +int main(void) { + int err = 0; + + /* Technically, this is sketchy because we are assuming that bool works. */ + TEST_INT_EQ(test_bool(), 0, err); + TEST_INT_EQ(test_mem(), 0, err); + TEST_INT_EQ(test_arr(), 0, err); + TEST_INT_EQ(test_tbl(), 0, err); + TEST_INT_EQ(test_rstr(), 0, err); + + if (err == 0) { + fprintf(CHANNEL, /*GREEN*/ + "\033[32m>>> ALL TESTS PASSED! <<<\033[0m\n" /*END GREEN*/); + fflush(CHANNEL); + } + + return err; +} diff --git a/src/mem/CMakeLists.txt b/src/c_interpretter/mem/CMakeLists.txt similarity index 96% rename from src/mem/CMakeLists.txt rename to src/c_interpretter/mem/CMakeLists.txt index acc50b3..02d7a7d 100644 --- a/src/mem/CMakeLists.txt +++ b/src/c_interpretter/mem/CMakeLists.txt @@ -1,5 +1,5 @@ -# Create the 'mem' target -add_library("mem" "${CMAKE_SOURCE_DIR}/src/mem/mem.c") - -# Link executable to libraries -target_link_libraries("mem" PRIVATE "common") +# Create the 'mem' target +add_library("mem" "${CMAKE_SOURCE_DIR}/src/mem/mem.c") + +# Link executable to libraries +target_link_libraries("mem" PRIVATE "common") diff --git a/src/mem/mem.c b/src/c_interpretter/mem/mem.c similarity index 100% rename from src/mem/mem.c rename to src/c_interpretter/mem/mem.c diff --git a/src/mem/mem.h b/src/c_interpretter/mem/mem.h similarity index 100% rename from src/mem/mem.h rename to src/c_interpretter/mem/mem.h diff --git a/src/mem/mem_overflow.h b/src/c_interpretter/mem/mem_overflow.h similarity index 100% rename from src/mem/mem_overflow.h rename to src/c_interpretter/mem/mem_overflow.h diff --git a/src/rstr/CMakeLists.txt b/src/c_interpretter/rstr/CMakeLists.txt similarity index 100% rename from src/rstr/CMakeLists.txt rename to src/c_interpretter/rstr/CMakeLists.txt diff --git a/src/rstr/rstr.c b/src/c_interpretter/rstr/rstr.c similarity index 100% rename from src/rstr/rstr.c rename to src/c_interpretter/rstr/rstr.c diff --git a/src/rstr/rstr.h b/src/c_interpretter/rstr/rstr.h similarity index 100% rename from src/rstr/rstr.h rename to src/c_interpretter/rstr/rstr.h diff --git a/src/tbl/CMakeLists.txt b/src/c_interpretter/tbl/CMakeLists.txt similarity index 100% rename from src/tbl/CMakeLists.txt rename to src/c_interpretter/tbl/CMakeLists.txt diff --git a/src/tbl/tbl.c b/src/c_interpretter/tbl/tbl.c similarity index 100% rename from src/tbl/tbl.c rename to src/c_interpretter/tbl/tbl.c diff --git a/src/tbl/tbl.h b/src/c_interpretter/tbl/tbl.h similarity index 100% rename from src/tbl/tbl.h rename to src/c_interpretter/tbl/tbl.h diff --git a/src/tbl/tbl_helper.h b/src/c_interpretter/tbl/tbl_helper.h similarity index 100% rename from src/tbl/tbl_helper.h rename to src/c_interpretter/tbl/tbl_helper.h diff --git a/src/tokenizer/examples/program.txt b/src/c_interpretter/tokenizer/examples/program.txt similarity index 95% rename from src/tokenizer/examples/program.txt rename to src/c_interpretter/tokenizer/examples/program.txt index 53c7cde..0b9643e 100644 --- a/src/tokenizer/examples/program.txt +++ b/src/c_interpretter/tokenizer/examples/program.txt @@ -1,48 +1,48 @@ -io = import("io"); - -# Function to calculate the n-th Fibonacci Sequence term. -function fibo(arg num_iterations: int[0..=100] = 0) -> int[0..=fibo(100)]: pure { - var prev: int = 1; - var prev_prev: int = 0; - - for (let i: int = 0..=num_iterations) { - prev, prev_prev = prev + prev_prev, prev; - } - - return prev; -} - -print("The 10th Fibonacci Number is:", fibo(10)); -_, blah = (10, 11); - -/* C Style Comment */ -// C++ Style Comment -# Harder Tokens to Parse - # Tab -## Multiple Comment Characters - -# Escape Characters -`This is some type of string`; -'This is some type of string'; -"Escape characters: \'\n\t\""; - -# Grouped Single-Characters -# Not sure what () or (_) will represent... -({[]}),(),{},[],(()),{{}},[[]];;;; - -# Floating Point Numbers -0.0 # Should tokenize: 0.0 -0.0e+1 -.0 -0 - -# Parsing . vs .. (I am not sure how to do this without backtracking for floats?) -# Maybe disallow float..=NUMBER??? -0..=10; -0...=+10; # Should tokenize: 0 ... = +10 ; - - -# Punctuation (No real idea what to test here) -+++10===1000; -===-10+10; -!@@#$@%@#%^@$###^$^##^!@$^@#$ # Commented out +io = import("io"); + +# Function to calculate the n-th Fibonacci Sequence term. +function fibo(arg num_iterations: int[0..=100] = 0) -> int[0..=fibo(100)]: pure { + var prev: int = 1; + var prev_prev: int = 0; + + for (let i: int = 0..=num_iterations) { + prev, prev_prev = prev + prev_prev, prev; + } + + return prev; +} + +print("The 10th Fibonacci Number is:", fibo(10)); +_, blah = (10, 11); + +/* C Style Comment */ +// C++ Style Comment +# Harder Tokens to Parse + # Tab +## Multiple Comment Characters + +# Escape Characters +`This is some type of string`; +'This is some type of string'; +"Escape characters: \'\n\t\""; + +# Grouped Single-Characters +# Not sure what () or (_) will represent... +({[]}),(),{},[],(()),{{}},[[]];;;; + +# Floating Point Numbers +0.0 # Should tokenize: 0.0 +0.0e+1 +.0 +0 + +# Parsing . vs .. (I am not sure how to do this without backtracking for floats?) +# Maybe disallow float..=NUMBER??? +0..=10; +0...=+10; # Should tokenize: 0 ... = +10 ; + + +# Punctuation (No real idea what to test here) ++++10===1000; +===-10+10; +!@@#$@%@#%^@$###^$^##^!@$^@#$ # Commented out diff --git a/src/tokenizer/prototype/run_tokenizer.sh b/src/c_interpretter/tokenizer/prototype/run_tokenizer.sh similarity index 100% rename from src/tokenizer/prototype/run_tokenizer.sh rename to src/c_interpretter/tokenizer/prototype/run_tokenizer.sh diff --git a/src/tokenizer/prototype/tokenizer.py b/src/c_interpretter/tokenizer/prototype/tokenizer.py similarity index 100% rename from src/tokenizer/prototype/tokenizer.py rename to src/c_interpretter/tokenizer/prototype/tokenizer.py diff --git a/compiler/README.md b/src/compiler/README.md similarity index 100% rename from compiler/README.md rename to src/compiler/README.md diff --git a/compiler/__init__.py b/src/compiler/__init__.py similarity index 100% rename from compiler/__init__.py rename to src/compiler/__init__.py diff --git a/compiler/analyzer/__init__.py b/src/compiler/analyzer/__init__.py similarity index 100% rename from compiler/analyzer/__init__.py rename to src/compiler/analyzer/__init__.py diff --git a/compiler/analyzer/lol_analyzer.py b/src/compiler/analyzer/lol_analyzer.py similarity index 100% rename from compiler/analyzer/lol_analyzer.py rename to src/compiler/analyzer/lol_analyzer.py diff --git a/compiler/emitter/__init__.py b/src/compiler/emitter/__init__.py similarity index 100% rename from compiler/emitter/__init__.py rename to src/compiler/emitter/__init__.py diff --git a/compiler/emitter/lol_emitter.py b/src/compiler/emitter/lol_emitter.py similarity index 100% rename from compiler/emitter/lol_emitter.py rename to src/compiler/emitter/lol_emitter.py diff --git a/compiler/error/__init__.py b/src/compiler/error/__init__.py similarity index 100% rename from compiler/error/__init__.py rename to src/compiler/error/__init__.py diff --git a/compiler/error/lol_error.py b/src/compiler/error/lol_error.py similarity index 100% rename from compiler/error/lol_error.py rename to src/compiler/error/lol_error.py diff --git a/compiler/examples/fibonacci.lol b/src/compiler/examples/fibonacci.lol similarity index 100% rename from compiler/examples/fibonacci.lol rename to src/compiler/examples/fibonacci.lol diff --git a/compiler/examples/helloworld.lol b/src/compiler/examples/helloworld.lol similarity index 100% rename from compiler/examples/helloworld.lol rename to src/compiler/examples/helloworld.lol diff --git a/compiler/examples/invalid/duplicate_function_names.lol b/src/compiler/examples/invalid/duplicate_function_names.lol similarity index 100% rename from compiler/examples/invalid/duplicate_function_names.lol rename to src/compiler/examples/invalid/duplicate_function_names.lol diff --git a/compiler/examples/math_ops.lol b/src/compiler/examples/math_ops.lol similarity index 100% rename from compiler/examples/math_ops.lol rename to src/compiler/examples/math_ops.lol diff --git a/compiler/examples/nested_if.lol b/src/compiler/examples/nested_if.lol similarity index 100% rename from compiler/examples/nested_if.lol rename to src/compiler/examples/nested_if.lol diff --git a/compiler/examples/sum_three.lol b/src/compiler/examples/sum_three.lol similarity index 100% rename from compiler/examples/sum_three.lol rename to src/compiler/examples/sum_three.lol diff --git a/compiler/lexer/__init__.py b/src/compiler/lexer/__init__.py similarity index 100% rename from compiler/lexer/__init__.py rename to src/compiler/lexer/__init__.py diff --git a/compiler/lexer/lol_lexer.py b/src/compiler/lexer/lol_lexer.py similarity index 100% rename from compiler/lexer/lol_lexer.py rename to src/compiler/lexer/lol_lexer.py diff --git a/compiler/lexer/lol_lexer_types.py b/src/compiler/lexer/lol_lexer_types.py similarity index 100% rename from compiler/lexer/lol_lexer_types.py rename to src/compiler/lexer/lol_lexer_types.py diff --git a/compiler/lol.py b/src/compiler/lol.py similarity index 100% rename from compiler/lol.py rename to src/compiler/lol.py diff --git a/compiler/parser/__init__.py b/src/compiler/parser/__init__.py similarity index 100% rename from compiler/parser/__init__.py rename to src/compiler/parser/__init__.py diff --git a/compiler/parser/lol_parser.py b/src/compiler/parser/lol_parser.py similarity index 100% rename from compiler/parser/lol_parser.py rename to src/compiler/parser/lol_parser.py diff --git a/compiler/parser/lol_parser_token_stream.py b/src/compiler/parser/lol_parser_token_stream.py similarity index 100% rename from compiler/parser/lol_parser_token_stream.py rename to src/compiler/parser/lol_parser_token_stream.py