]> git.lizzy.rs Git - nothing.git/blobdiff - test/interpreter_suite.h
Add TODO(#1022)
[nothing.git] / test / interpreter_suite.h
index f4712107b27bbf5373bbf68d66c9c5864759116b..fb57e27dde7a2540e580cb1e4bff4decca296e56 100644 (file)
 #define INTERPRETER_SUITE_H_
 
 #include "test.h"
-#include "script/builtins.h"
+#include "ebisp/builtins.h"
+#include "ebisp/expr.h"
+#include "ebisp/interpreter.h"
 
 TEST(equal_test)
 {
-    struct Expr nil1 = NIL;
-    struct Expr nil2 = NIL;
-    ASSERT_TRUE(equal(nil1, nil2), "nils are not equal");
-    destroy_expr(nil1);
-    destroy_expr(nil2);
+    Gc *gc = create_gc();
+
+    struct Expr nil1 = NIL(gc);
+    struct Expr nil2 = NIL(gc);
+    ASSERT_TRUE(equal(nil1, nil2), {
+            fprintf(stderr, "Expected: ");
+            print_expr_as_sexpr(stderr, nil1);
+            fprintf(stderr, "\n");
+
+            fprintf(stderr, "Actual: ");
+            print_expr_as_sexpr(stderr, nil2);
+            fprintf(stderr, "\n");
+    });
 
     struct Expr list1 =
-        CONS(SYMBOL("a"),
-             CONS(SYMBOL("b"),
-                  CONS(SYMBOL("c"),
-                       NIL)));
+        CONS(gc, SYMBOL(gc, "a"),
+             CONS(gc, SYMBOL(gc, "b"),
+                  CONS(gc, SYMBOL(gc, "c"),
+                       NIL(gc))));
     struct Expr list2 =
-        CONS(SYMBOL("a"),
-             CONS(SYMBOL("b"),
-                  CONS(SYMBOL("c"),
-                       NIL)));
-    ASSERT_TRUE(equal(list1, list2), "lists are not equal");
-    destroy_expr(list1);
-    destroy_expr(list2);
+        CONS(gc, SYMBOL(gc, "a"),
+             CONS(gc, SYMBOL(gc, "b"),
+                  CONS(gc, SYMBOL(gc, "c"),
+                       NIL(gc))));
+    ASSERT_TRUE(equal(list1, list2), {
+            fprintf(stderr, "Expected: ");
+            print_expr_as_sexpr(stderr, list1);
+            fprintf(stderr, "\n");
+
+            fprintf(stderr, "Actual: ");
+            print_expr_as_sexpr(stderr, list2);
+            fprintf(stderr, "\n");
+    });
+
+    destroy_gc(gc);
 
     return 0;
 }
 
 TEST(assoc_test)
 {
-    struct Expr nil = NIL;
+    Gc *gc = create_gc();
 
-    struct Expr a = SYMBOL("a");
-    struct Expr b = SYMBOL("b");
-    struct Expr c = SYMBOL("c");
+    struct Expr nil = NIL(gc);
 
-    struct Expr a_pair = CONS(a, NUMBER(10.0f));
-    struct Expr b_pair = CONS(b, NUMBER(20.0f));
-    struct Expr c_pair = CONS(c, NUMBER(30.0f));
+    struct Expr a = SYMBOL(gc, "a");
+    struct Expr b = SYMBOL(gc, "b");
+    struct Expr c = SYMBOL(gc, "c");
+
+    struct Expr a_pair = CONS(gc, a, NUMBER(gc, 10));
+    struct Expr b_pair = CONS(gc, b, NUMBER(gc, 20));
+    struct Expr c_pair = CONS(gc, c, NUMBER(gc, 30));
 
     struct Expr alist =
-        CONS(a_pair,
-             CONS(b_pair,
-                  CONS(c_pair, nil)));
+        CONS(gc, a_pair,
+             CONS(gc, b_pair,
+                  CONS(gc, c_pair, nil)));
+
+    struct Expr assoc_result = assoc(a, alist);
+
+    ASSERT_TRUE(equal(a_pair, assoc_result), {
+            fprintf(stderr, "Expected: ");
+            print_expr_as_sexpr(stderr, a_pair);
+            fprintf(stderr, "\n");
+
+            fprintf(stderr, "Actual: ");
+            print_expr_as_sexpr(stderr, assoc_result);
+            fprintf(stderr, "\n");
+    });
+
+    destroy_gc(gc);
+
+    return 0;
+}
+
+TEST(match_list_test)
+{
+    Gc *gc = create_gc();
+
+    struct Expr input = list(
+        gc, "dsqe",
+        42,
+        "hello",
+        "world",
+        CONS(gc, NUMBER(gc, 1), NUMBER(gc, 2)));
+
+    long int d = 0;
+    const char *s = NULL;
+    const char *q = NULL;
+    struct Expr e = NIL(gc);
+
+    struct EvalResult result = match_list(gc, "dsqe", input, &d, &s, &q, &e);
+    ASSERT_FALSE(result.is_error, {
+            fprintf(stderr, "Unpack failed: ");
+            print_expr_as_sexpr(stderr, result.expr);
+            fprintf(stderr, "\n");
+    });
+
+    ASSERT_TRUE(d == 42, {
+        fprintf(stderr, "Expected: 42, Actual: %ld\n", d);
+    });
+    ASSERT_TRUE(strcmp(s, "hello") == 0, {
+        fprintf(stderr, "Expected: hello, Actual: %s\n", s);
+    });
+    ASSERT_TRUE(strcmp(q, "world") == 0, {
+        fprintf(stderr, "Expected: world, Actual: %s\n", q);
+    });
+    ASSERT_TRUE(equal(e, CONS(gc, NUMBER(gc, 1), NUMBER(gc, 2))), {
+            fprintf(stderr, "Expected: ");
+            print_expr_as_sexpr(stderr, CONS(gc, NUMBER(gc, 1), NUMBER(gc, 2)));
+            fprintf(stderr, ", Actual: ");
+            print_expr_as_sexpr(stderr, e);
+            fprintf(stderr, "\n");
+    });
+
+    destroy_gc(gc);
+
+    return 0;
+}
+
+TEST(match_list_empty_list_test)
+{
+    Gc *gc = create_gc();
+
+    long int d = 0;
+    struct EvalResult result = match_list(gc, "d", NIL(gc), &d);
+
+    ASSERT_TRUE(result.is_error, {
+            fprintf(stderr, "Unpack did not fail\n");
+    });
+
+    destroy_gc(gc);
+
+    return 0;
+}
+
+TEST(match_list_head_tail_test)
+{
+    Gc *gc = create_gc();
+
+    struct Expr input = list(gc, "dddd", 1, 2, 3, 4);
+
+    long int x = 0;
+    struct Expr xs = NIL(gc);
+
+    struct EvalResult result = match_list(gc, "d*", input, &x, &xs);
+    ASSERT_TRUE(!result.is_error, {
+            fprintf(stderr, "Could not unpack input: ");
+            print_expr_as_sexpr(stderr, result.expr);
+            fprintf(stderr, "\n");
+    });
+
+    ASSERT_TRUE(x == 1, {
+            fprintf(stderr, "Expected: 1, Actual: %ld\n", x);
+    });
+
+    ASSERT_TRUE(equal(xs, list(gc, "ddd", 2, 3, 4)), {
+            fprintf(stderr, "Expected: (2 3 4), Actual: ");
+            print_expr_as_sexpr(stderr, xs);
+            fprintf(stderr, "\n");
+    })
+
+    destroy_gc(gc);
+
+    return 0;
+}
+
+TEST(match_list_wildcard_test)
+{
+    Gc *gc = create_gc();
+
+    struct Expr input = list(
+        gc, "dddd", 1, 2, 3, 4);
+
+    long int x = 0, y = 0;
+    struct EvalResult result = match_list(gc, "dddd", input, &x, NULL, &y, NULL);
+    ASSERT_TRUE(!result.is_error, {
+            fprintf(stderr, "Matching failed: ");
+            print_expr_as_sexpr(stderr, result.expr);
+            fprintf(stderr, "\n");
+    });
+
+    ASSERT_LONGINTEQ(1L, x);
+    ASSERT_LONGINTEQ(3L, y);
+
+    destroy_gc(gc);
+
+    return 0;
+}
+
+TEST(match_list_singleton_tail_test)
+{
+    Gc *gc = create_gc();
+
+    struct Expr input = list(gc, "d", 1);
+    long int x;
+    struct Expr xs = NIL(gc);
+    struct EvalResult res = match_list(gc, "d*", input, &x, &xs);
+
+    ASSERT_TRUE(!res.is_error, {
+            fprintf(stderr, "Matching failed: ");
+            print_expr_as_sexpr(stderr, res.expr);
+            fprintf(stderr, "\n");
+    });
+
+    ASSERT_LONGINTEQ(1L, x);
+    ASSERT_TRUE(nil_p(xs), {
+            fprintf(stderr, "Tail doesn't appear to be NIL: ");
+            print_expr_as_sexpr(stderr, xs);
+            fprintf(stderr, "\n");
+    });
 
-    equal(a_pair, assoc(b, alist));
+    destroy_gc(gc);
 
-    destroy_expr(alist);
     return 0;
 }
 
@@ -56,6 +229,11 @@ TEST_SUITE(interpreter_suite)
 {
     TEST_RUN(equal_test);
     TEST_RUN(assoc_test);
+    TEST_RUN(match_list_test);
+    TEST_RUN(match_list_empty_list_test);
+    TEST_RUN(match_list_head_tail_test);
+    TEST_RUN(match_list_wildcard_test);
+    TEST_RUN(match_list_singleton_tail_test);
 
     return 0;
 }