commit dea162504bae1c6a215381d5055fa5ad23fff8ab
parent 2b705fa259384af58c6450f412fe47efd5fe3431
Author: Juan F. Meleiro <juan@juanmeleiro.mat.br>
Date: Fri, 26 Apr 2024 23:29:11 -0300
Finish implementing use test for model.c
Diffstat:
6 files changed, 83 insertions(+), 37 deletions(-)
diff --git a/coding/gardener.c b/coding/gardener.c
@@ -1,4 +1,3 @@
-#include <assert.h>
#include <stdio.h>
#include "gardener.h"
@@ -7,11 +6,13 @@
#include "tree.h"
#include "schema.h"
+#define ensure(G, COND, ERR) if (!COND) { set_error(G, ERR); return; }
+
struct gardener {
schema *top;
stack *treestack;
stack *schemastack;
- bool error;
+ gardener_status error;
};
/* GETTERS */
@@ -34,7 +35,7 @@ get_cur_schema(gardener *g)
return peek(g->schemastack);
}
-bool
+gardener_status
get_error(gardener *g)
{
return g->error;
@@ -43,9 +44,9 @@ get_error(gardener *g)
/* SETTERS */
void
-set_error(gardener *g)
+set_error(gardener *g, gardener_status e)
{
- g->error = true;
+ g->error = e;
}
/* PUBLIC */
@@ -77,8 +78,10 @@ sub(gardener* g, symbol key, symbol constructor)
schema *cur_schema = get_cur_schema(g);
symbol head = get_head(get_cur_tree(g));
- assert(has_key(cur_schema, head, key));
+
+ ensure(g, has_key(cur_schema, head, key), SUB_INVALID_KEY);
schema *sub_schema = get_subschema(cur_schema, head, key);
+ ensure(g, is_constructor(sub_schema, constructor), SUB_WITH_INVALID_CONSTRUCTOR);
tree *new = new_node(constructor);
set_subtree(get_cur_tree(g), key, new);
@@ -90,24 +93,19 @@ sub(gardener* g, symbol key, symbol constructor)
void
start(gardener* g, symbol c)
{
- assert(is_empty(g->treestack));
+ ensure(g, is_empty(g->treestack), START_ON_NONEMPTY_STACK);
tree *t = new_node(c);
push(g->treestack, t);
}
-bool
+void
done(gardener* g)
{
- bool res = check(get_cur_schema(g), get_cur_tree(g));
-
- if (res) {
- if (!is_empty(g->treestack))
- pop(g->treestack);
- } else {
- set_error(g);
- }
- return res;
+ ensure(g, (!is_empty(g->treestack)), DONE_ON_EMPTY_STACK);
+ ensure(g, check(get_cur_schema(g), get_cur_tree(g)), DONE_ON_INVALID_TREE);
+ pop(g->treestack);
+ pop(g->schemastack);
}
void
@@ -115,7 +113,8 @@ show(FILE *f, gardener *g)
{
schema *s = get_cur_schema(g);
tree *cur = get_cur_tree(g);
- symbol head = get_head(get_cur_tree(g));
+ if (cur == NULL) return;
+ symbol head = get_head(cur);
bool err = get_error(g);
fprintf(f, "schema %s\n", repr(get_name(s)));
@@ -125,10 +124,25 @@ show(FILE *f, gardener *g)
for (size_t i = 0; i < num; i++) {
if (!get_subtree(cur, keys[i]))
if (takes_leaf(s, head, keys[i]))
- fprintf(f, "goal symbol %s\n", repr(keys[i]));
+ fprintf(f, "symbol %s\n", repr(keys[i]));
else
fprintf(f, "goal %s %s\n", repr(get_name(get_subschema(s, head, keys[i]))), repr(keys[i]));
}
- if (err) fprintf(f, "ERROR\n");
+ switch (get_error(g)) {
+ case SUB_INVALID_KEY:
+ fprintf(f, "error SUB_INVALID_KEY");
+ break;
+ case DONE_ON_EMPTY_STACK:
+ fprintf(f, "error DONE_ON_EMPTY_STACK");
+ break;
+ case START_ON_NONEMPTY_STACK:
+ fprintf(f, "error START_ON_NONEMPTY_STACK");
+ break;
+ case SUB_WITH_INVALID_CONSTRUCTOR:
+ fprintf(f, "error SUB_WITH_INVALID_CONSTRUCTOR");
+ break;
+ case OK:
+ break;
+ }
}
diff --git a/coding/gardener.h b/coding/gardener.h
@@ -2,14 +2,23 @@
#include <stdbool.h>
#include "schema.h"
+typedef enum {
+ OK,
+ SUB_INVALID_KEY,
+ DONE_ON_EMPTY_STACK,
+ START_ON_NONEMPTY_STACK,
+ SUB_WITH_INVALID_CONSTRUCTOR,
+ DONE_ON_INVALID_TREE
+} gardener_status;
+
typedef struct gardener gardener;
gardener* new_gardener(schema*);
-bool get_error(gardener*);
+gardener_status get_error(gardener*);
void fill(gardener*, symbol key, symbol value);
void sub(gardener*, symbol key, symbol constructor);
-bool done(gardener*);
+void done(gardener*);
void sup(gardener*, symbol key, symbol constructor);
void start(gardener*, symbol constructor);
diff --git a/coding/gardener.test.c b/coding/gardener.test.c
@@ -18,7 +18,7 @@ test_empty_constructor_success(void)
gardener *g = new_gardener(s);
start(g, c);
- res &= done(g);
+ done(g);
res &= !get_error(g);
return res;
@@ -27,16 +27,13 @@ test_empty_constructor_success(void)
bool
test_empty_constructor_empty_tree_fail(void)
{
- bool res = true;
-
symbol c = intern("c");
schema *s = new_schema(intern("test"));
add_constructor(s, c);
gardener *g = new_gardener(s);
- res &= !done(g);
- res &= get_error(g);
- return res;
+ done(g);
+ return get_error(g) == DONE_ON_EMPTY_STACK;
}
bool
@@ -58,8 +55,8 @@ test_double_deep_schema_fail(void)
gardener *g = new_gardener(s);
start(g, c);
- res &= !done(g);
- res &= get_error(g);
+ done(g);
+ res &= (get_error(g) == DONE_ON_INVALID_TREE);
return res;
}
@@ -85,7 +82,7 @@ test_double_deep_schema_success(void)
start(g, c);
sub(g, k, d);
- res &= done(g);
+ done(g);
res &= !get_error(g);
return res;
@@ -113,7 +110,7 @@ test_triple_deep_schema_fail(void)
start(g, c);
sub(g, k, d);
- res &= !done(g);
+ done(g);
res &= get_error(g);
return res;
@@ -140,13 +137,14 @@ test_triple_deep_schema_success(void)
start(g, c);
sub(g, k, d);
fill(g, k, k);
- res &= done(g);
+ done(g);
res &= !get_error(g);
return res;
}
-int main()
+int
+main()
{
assert(test_empty_constructor_success());
assert(test_empty_constructor_empty_tree_fail());
diff --git a/coding/model.test.c b/coding/model.test.c
@@ -97,13 +97,25 @@ test_use(void)
gardener *g = new_gardener(schema(context));
start(g, I("attitude"));
- assert(!get_error(g));
+ assert(get_error(g) == OK);
fill(g, I("name"), I("wft"));
+ assert(get_error(g) == OK);
sub(g, I("vars"), I("var"));
+ assert(get_error(g) == OK);
fill(g, I("name"), I("a"));
+ assert(get_error(g) == OK);
sub(g, I("rest"), I("nil"));
+ assert(get_error(g) == OK);
done(g);
- // done(g);
+ assert(get_error(g) == OK);
+ done(g);
+ assert(get_error(g) == OK);
+ sub(g, I("pressupositions"), I("nil"));
+ assert(get_error(g) == OK);
+ done(g);
+ assert(get_error(g) == OK);
+ done(g);
+ assert(get_error(g) == OK);
show(stdout, g);
}
diff --git a/coding/schema.c b/coding/schema.c
@@ -138,8 +138,10 @@ check(schema* s, tree* t)
if (!t) return false;
if (s == LEAF && is_leaf(t)) return true;
- bool good = true;
symbol head = get_head(t);
+ if (!is_constructor(s, head)) return false;
+
+ bool good = true;
size_t lim = get_amount_of_keys(get_constructor(s, head)->subschemas);
symbol *keys = get_keys(get_constructor(s, head)->subschemas);
diff --git a/coding/test.do b/coding/test.do
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+redo symbol.test
+redo assoc.test
+redo stack.test
+redo tree.test
+redo schema.test
+redo gardener.test
+redo model.test
+
+echo Done. >&2