tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

tests.c (5957B)


      1 #include "tricu.h"
      2 #include <assert.h>
      3 #include <string.h>
      4 #include <signal.h>
      5 static volatile sig_atomic_t observed_signal;
      6 static void host_signal(int sig) { observed_signal = sig; }
      7 
      8 /* Independent constructor-level oracles for all reduction rules. */
      9 static tricu_handle stem(tricu_context ctx, tricu_handle x) {
     10     tricu_handle out;
     11     assert(tricu_stem(ctx, x, &out) == TRICU_OK);
     12     return out;
     13 }
     14 static tricu_handle make_fork(tricu_context ctx, tricu_handle a, tricu_handle b) {
     15     tricu_handle out;
     16     assert(tricu_fork(ctx, a, b, &out) == TRICU_OK);
     17     return out;
     18 }
     19 static tricu_handle app(tricu_context ctx, tricu_handle a, tricu_handle b) {
     20     tricu_handle out;
     21     assert(tricu_apply(ctx, a, b, &out) == TRICU_OK);
     22     return out;
     23 }
     24 static void same(tricu_context ctx, tricu_handle a, tricu_handle b) {
     25     uint32_t ka, kb;
     26     assert(tricu_kind(ctx, a, &ka) == TRICU_OK);
     27     assert(tricu_kind(ctx, b, &kb) == TRICU_OK);
     28     assert(ka == kb);
     29     for (uint32_t i = 0; i < ka; ++i) {
     30         tricu_handle ca, cb;
     31         assert(tricu_child(ctx, a, i, &ca) == TRICU_OK);
     32         assert(tricu_child(ctx, b, i, &cb) == TRICU_OK);
     33         same(ctx, ca, cb);
     34         assert(tricu_release(ctx, ca) == TRICU_OK);
     35         assert(tricu_release(ctx, cb) == TRICU_OK);
     36     }
     37 }
     38 static void core_rules(tricu_context ctx) {
     39     tricu_handle t;
     40     assert(tricu_leaf(ctx, &t) == TRICU_OK);
     41     tricu_handle tt = stem(ctx, t), k = make_fork(ctx, t, t);
     42     same(ctx, app(ctx, t, tt), stem(ctx, tt));
     43     same(ctx, app(ctx, tt, k), make_fork(ctx, t, k));
     44     same(ctx, app(ctx, make_fork(ctx, t, tt), k), tt);
     45     /* S (K t) t (t t) = t (t (t t)) */
     46     same(ctx, app(ctx, make_fork(ctx, stem(ctx, k), t), tt), stem(ctx, stem(ctx, tt)));
     47     tricu_handle triage = make_fork(ctx, make_fork(ctx, tt, k), k);
     48     same(ctx, app(ctx, triage, t), tt);
     49     same(ctx, app(ctx, triage, stem(ctx, tt)), t);
     50     same(ctx, app(ctx, triage, make_fork(ctx, t, tt)), stem(ctx, tt));
     51     tricu_handle marker = 987;
     52     assert(tricu_child(ctx, t, 0, &marker) == TRICU_TYPE_ERROR && marker == 987);
     53     tricu_context other;
     54     assert(tricu_context_new(&other) == TRICU_OK);
     55     assert(tricu_retain(other, t, &marker) == TRICU_INVALID_HANDLE && marker == 987);
     56     assert(tricu_retain(ctx, other, &marker) == TRICU_INVALID_HANDLE && marker == 987);
     57     assert(tricu_context_free(other) == TRICU_OK);
     58     assert(tricu_leaf(other, &marker) == TRICU_INVALID_CONTEXT && marker == 987);
     59     const uint8_t bad_utf8[] = {0xc0, 0x80};
     60     assert(tricu_from_utf8(ctx, bad_utf8, 2, &marker) == TRICU_INVALID_DATA && marker == 987);
     61     uint8_t input[256], *output;
     62     size_t length;
     63     for (size_t i = 0; i < sizeof input; ++i) input[i] = (uint8_t)i;
     64     assert(tricu_from_bytes(ctx, input, sizeof input, &marker) == TRICU_OK);
     65     assert(tricu_to_bytes(ctx, marker, &output, &length) == TRICU_OK);
     66     assert(length == sizeof input && memcmp(input, output, length) == 0);
     67     tricu_buffer_free(output);
     68     const uint8_t unicode[] = {'x', 0, 0xc3, 0xa9, 0xf0, 0x9f, 0x8c, 0xb3, 0xef, 0xbb, 0xbf};
     69     assert(tricu_from_utf8(ctx, unicode, sizeof unicode, &marker) == TRICU_OK);
     70     assert(tricu_to_utf8(ctx, marker, &output, &length) == TRICU_OK);
     71     assert(length == sizeof unicode && memcmp(unicode, output, length) == 0);
     72     tricu_buffer_free(output);
     73     tricu_handle invalid;
     74     assert(tricu_from_u64(ctx, 256, &invalid) == TRICU_OK);
     75     invalid = make_fork(ctx, invalid, t);
     76     uint8_t sentinel, *unchanged = &sentinel;
     77     size_t unchanged_length = 987;
     78     assert(tricu_to_bytes(ctx, invalid, &unchanged, &unchanged_length) == TRICU_TYPE_ERROR);
     79     assert(unchanged == &sentinel && unchanged_length == 987);
     80     assert(tricu_from_u64(ctx, 0xd800, &invalid) == TRICU_OK);
     81     invalid = make_fork(ctx, invalid, t);
     82     assert(tricu_to_utf8(ctx, invalid, &unchanged, &unchanged_length) == TRICU_TYPE_ERROR);
     83     assert(unchanged == &sentinel && unchanged_length == 987);
     84     assert(tricu_from_bytes(ctx, NULL, 0, &marker) == TRICU_OK);
     85     assert(tricu_to_bytes(ctx, marker, &output, &length) == TRICU_OK && length == 0);
     86     tricu_buffer_free(output);
     87 }
     88 
     89 int main(void) {
     90     signal(SIGINT, host_signal);
     91     signal(SIGPIPE, host_signal);
     92     tricu_init();
     93     tricu_init();
     94     raise(SIGINT);
     95     assert(observed_signal == SIGINT);
     96     raise(SIGPIPE);
     97     assert(observed_signal == SIGPIPE);
     98     assert(tricu_abi_version() == 1);
     99     tricu_context ctx;
    100     tricu_handle value, alias, result;
    101     assert(tricu_context_new(&ctx) == TRICU_OK);
    102     core_rules(ctx);
    103     assert(tricu_from_u64(ctx, UINT64_MAX, &value) == TRICU_OK);
    104     assert(tricu_retain(ctx, value, &alias) == TRICU_OK);
    105     assert(value != alias);
    106     assert(tricu_release(ctx, value) == TRICU_OK);
    107     result = 123;
    108     assert(tricu_reduce(ctx, value, &result) == TRICU_INVALID_HANDLE);
    109     assert(result == 123);
    110     uint32_t boolean = 999;
    111     assert(tricu_to_bool(ctx, alias, &boolean) == TRICU_TYPE_ERROR);
    112     assert(boolean == 999);
    113     assert(tricu_leaf(ctx, &result) == TRICU_OK);
    114     assert(tricu_to_bool(ctx, result, &boolean) == TRICU_OK && boolean == 0);
    115     assert(tricu_stem(ctx, result, &value) == TRICU_OK);
    116     assert(tricu_to_bool(ctx, value, &boolean) == TRICU_OK && boolean == 1);
    117     uint64_t number;
    118     assert(tricu_to_u64(ctx, alias, &number) == TRICU_OK);
    119     assert(number == UINT64_MAX);
    120     uint8_t *error;
    121     size_t length;
    122     assert(tricu_last_error(ctx, &error, &length) == TRICU_OK);
    123     assert(length > 0);
    124     tricu_buffer_free(error);
    125     assert(tricu_from_utf8(ctx, (const uint8_t *)"a\0b", 3, &value) == TRICU_OK);
    126     uint8_t *bytes;
    127     assert(tricu_to_utf8(ctx, value, &bytes, &length) == TRICU_OK);
    128     assert(length == 3 && memcmp(bytes, "a\0b", 3) == 0);
    129     assert(tricu_context_free(ctx) == TRICU_OK);
    130     assert(memcmp(bytes, "a\0b", 3) == 0);
    131     tricu_buffer_free(bytes);
    132     assert(tricu_context_free(ctx) == TRICU_INVALID_CONTEXT);
    133     return 0;
    134 }