commit 337437a00c033fd7b9e1bd278af9b66a64cb8c55
parent dea162504bae1c6a215381d5055fa5ad23fff8ab
Author: Juan F. Meleiro <juan@juanmeleiro.mat.br>
Date: Sat, 27 Apr 2024 00:12:46 -0300
Add result field in gardeners
Diffstat:
9 files changed, 92 insertions(+), 183 deletions(-)
diff --git a/coding/default.test.do b/coding/default.test.do
@@ -3,5 +3,5 @@
headers=*.h
src=$(ls *.c | grep -v .test.c)
redo-ifchange $src $headers
-cc -g -fmax-errors=1 $src $1.c -o $3 >&2
+cc -g -Wall -Wextra -fmax-errors=1 $src $1.c -o $3 >&2
./$3 >&2 || exit 1
diff --git a/coding/gardener.c b/coding/gardener.c
@@ -13,6 +13,7 @@ struct gardener {
stack *treestack;
stack *schemastack;
gardener_status error;
+ tree *result;
};
/* GETTERS */
@@ -41,6 +42,12 @@ get_error(gardener *g)
return g->error;
}
+tree*
+result(gardener *g)
+{
+ return g->result;
+}
+
/* SETTERS */
void
@@ -59,6 +66,7 @@ new_gardener(schema* s)
g->error = false;
g->treestack = new_stack();
g->schemastack = new_stack();
+ g->result = NULL;
push(g->schemastack, g->top);
return g;
}
@@ -67,6 +75,7 @@ new_gardener(schema* s)
void
fill(gardener* g, symbol key, symbol value)
{
+ ensure(g, (get_cur_tree(g) != NULL), NON_START_OP_ON_EMPTY_STACK);
tree *new = new_leaf(value);
set_subtree(get_cur_tree(g), key, new);
}
@@ -75,8 +84,9 @@ fill(gardener* g, symbol key, symbol value)
void
sub(gardener* g, symbol key, symbol constructor)
{
-
schema *cur_schema = get_cur_schema(g);
+ tree *cur = get_cur_tree(g);
+ ensure(g, (cur != NULL), NON_START_OP_ON_EMPTY_STACK);
symbol head = get_head(get_cur_tree(g));
ensure(g, has_key(cur_schema, head, key), SUB_INVALID_KEY);
@@ -94,6 +104,7 @@ void
start(gardener* g, symbol c)
{
ensure(g, is_empty(g->treestack), START_ON_NONEMPTY_STACK);
+ ensure(g, (g->result == NULL), START_AFTER_RESULT);
tree *t = new_node(c);
push(g->treestack, t);
}
@@ -102,10 +113,14 @@ start(gardener* g, symbol c)
void
done(gardener* g)
{
- ensure(g, (!is_empty(g->treestack)), DONE_ON_EMPTY_STACK);
+ tree *res;
+ ensure(g, (!is_empty(g->treestack)), NON_START_OP_ON_EMPTY_STACK);
ensure(g, check(get_cur_schema(g), get_cur_tree(g)), DONE_ON_INVALID_TREE);
- pop(g->treestack);
+ res = pop(g->treestack);
pop(g->schemastack);
+
+ if (is_empty(g->treestack))
+ g->result = res;
}
void
@@ -115,32 +130,39 @@ show(FILE *f, gardener *g)
tree *cur = 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)));
fprintf(f, "head %s\n", repr(head));
size_t num = get_amount_of_required_keys(s, head);
symbol *keys = get_required_keys(s, head);
for (size_t i = 0; i < num; i++) {
- if (!get_subtree(cur, keys[i]))
- if (takes_leaf(s, head, keys[i]))
+ if (!get_subtree(cur, keys[i])) {
+ if (takes_leaf(s, head, keys[i])) {
fprintf(f, "symbol %s\n", repr(keys[i]));
- else
+ } else {
fprintf(f, "goal %s %s\n", repr(get_name(get_subschema(s, head, keys[i]))), repr(keys[i]));
+ }
+ }
}
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");
+ case NON_START_OP_ON_EMPTY_STACK:
+ fprintf(f, "error NON_START_OP_ON_EMPTY_STACK");
break;
case START_ON_NONEMPTY_STACK:
fprintf(f, "error START_ON_NONEMPTY_STACK");
break;
+ case START_AFTER_RESULT:
+ fprintf(f, "error START_AFTER_RESULT");
+ break;
case SUB_WITH_INVALID_CONSTRUCTOR:
fprintf(f, "error SUB_WITH_INVALID_CONSTRUCTOR");
break;
+ case DONE_ON_INVALID_TREE:
+ fprintf(f, "error DONE_ON_INVALID_TREE");
+ break;
case OK:
break;
}
diff --git a/coding/gardener.h b/coding/gardener.h
@@ -5,21 +5,23 @@
typedef enum {
OK,
SUB_INVALID_KEY,
- DONE_ON_EMPTY_STACK,
START_ON_NONEMPTY_STACK,
SUB_WITH_INVALID_CONSTRUCTOR,
- DONE_ON_INVALID_TREE
+ DONE_ON_INVALID_TREE,
+ START_AFTER_RESULT,
+ NON_START_OP_ON_EMPTY_STACK
} gardener_status;
typedef struct gardener gardener;
gardener* new_gardener(schema*);
gardener_status get_error(gardener*);
+tree* result(gardener*);
void fill(gardener*, symbol key, symbol value);
void sub(gardener*, symbol key, symbol constructor);
void done(gardener*);
-void sup(gardener*, symbol key, symbol constructor);
+// void sup(gardener*, symbol key, symbol constructor);
void start(gardener*, symbol constructor);
void show(FILE *f, gardener*);
diff --git a/coding/gardener.test.c b/coding/gardener.test.c
@@ -6,11 +6,44 @@
#include "schema.h"
#include "gardener.h"
+void
+test_new_gardener(void)
+{
+ schema *s = new_schema(intern("test"));
+ gardener *g = new_gardener(s);
+
+ assert(get_error(g) == OK);
+ assert(result(g) == NULL);
+}
+
+void
+test_non_start_at_start(void)
+{
+ schema *s = new_schema(intern("test"));
+ gardener *g = new_gardener(s);
+ fill(g, intern("c"), intern("v"));
+ assert(get_error(g) == NON_START_OP_ON_EMPTY_STACK);
+ sub(g, intern("c"), intern("v"));
+ assert(get_error(g) == NON_START_OP_ON_EMPTY_STACK);
+}
+
+void
+test_start_after_result_fail(void)
+{
+ schema *s = new_schema(intern("test"));
+ add_constructor(s, intern("nil"));
+ gardener *g = new_gardener(s);
+
+ start(g, intern("nil"));
+ done(g);
+ assert(get_error(g) == OK);
+ start(g, intern("nil"));
+ assert(get_error(g) == START_AFTER_RESULT);
+}
+
bool
test_empty_constructor_success(void)
{
- bool res = true;
-
symbol c = intern("c");
schema *s = new_schema(intern("test"));
add_constructor(s, c);
@@ -19,9 +52,7 @@ test_empty_constructor_success(void)
start(g, c);
done(g);
- res &= !get_error(g);
-
- return res;
+ return get_error(g) == OK;
}
bool
@@ -33,14 +64,12 @@ test_empty_constructor_empty_tree_fail(void)
gardener *g = new_gardener(s);
done(g);
- return get_error(g) == DONE_ON_EMPTY_STACK;
+ return get_error(g) == NON_START_OP_ON_EMPTY_STACK;
}
bool
test_double_deep_schema_fail(void)
{
- bool res = true;
-
schema *s = new_schema(intern("test0"));
symbol c = intern("c");
add_constructor(s, c);
@@ -56,16 +85,13 @@ test_double_deep_schema_fail(void)
start(g, c);
done(g);
- res &= (get_error(g) == DONE_ON_INVALID_TREE);
- return res;
+ return get_error(g) == DONE_ON_INVALID_TREE;
}
bool
test_double_deep_schema_success(void)
{
- bool res = true;
-
symbol c = intern("c");
symbol d = intern("d");
symbol k = intern("k");
@@ -83,16 +109,13 @@ test_double_deep_schema_success(void)
sub(g, k, d);
done(g);
- res &= !get_error(g);
- return res;
+ return get_error(g) == OK;
}
bool
test_triple_deep_schema_fail(void)
{
- bool res = true;
-
symbol c = intern("c");
symbol d = intern("d");
symbol k = intern("k");
@@ -111,16 +134,13 @@ test_triple_deep_schema_fail(void)
sub(g, k, d);
done(g);
- res &= get_error(g);
- return res;
+ return get_error(g) == DONE_ON_INVALID_TREE;
}
bool
test_triple_deep_schema_success(void)
{
- bool res = true;
-
schema *s = new_schema(intern("test0"));
symbol c = intern("c");
add_constructor(s, c);
@@ -138,14 +158,14 @@ test_triple_deep_schema_success(void)
sub(g, k, d);
fill(g, k, k);
done(g);
- res &= !get_error(g);
- return res;
+ return get_error(g) == OK;
}
int
main()
{
+ test_new_gardener();
assert(test_empty_constructor_success());
assert(test_empty_constructor_empty_tree_fail());
assert(test_double_deep_schema_fail());
diff --git a/coding/metaschema.c b/coding/metaschema.c
@@ -1,28 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "metaschema.h"
-#include "schema.h"
-
-assoc*
-metacompile(metaschema *m, size_t len)
-{
- assoc *a = new_assoc();
-
- /* 1st: Create all schemas */
- for (size_t i = 0; i < len; i++) {
- schema *s = new_schema(intern(m[i].name));
- assoc_set(a, intern(m[i].name), s);
- }
-
- /* 2nd: Add all constructors */
- for (size_t i = 0; i < len; i++) {
- schema *s = assoc_get(a, intern(m[i].name));
- for (size_t j = 0; j < SIZE(m[i].constructors); j++) {
- printf("Adding constructor %s\n", m[i].constructors[j].head);
- add_constructor(s, intern(m[i].constructors[j].head));
- }
- }
-
- return a;
-}
diff --git a/coding/metaschema.h b/coding/metaschema.h
@@ -1,28 +0,0 @@
-#include <stdlib.h>
-
-#include "assoc.h"
-#include "schema.h"
-
-#define metalen(M) (sizeof(M)/sizeof(metaschema))
-#define SIZE(X) (sizeof(X)/sizeof(X[0]))
-
-typedef struct metaschema metaschema;
-typedef struct metaconstructor metaconstructor;
-typedef struct metakey metakey;
-
-struct metaschema {
- char *name;
- struct metaconstructor *constructors;
-};
-
-struct metaconstructor {
- char *head;
- struct metakey *keys;
-};
-
-struct metakey {
- char *key;
- char *subschema;
-};
-
-assoc* metacompile(metaschema*, size_t);
diff --git a/coding/metaschema.test.c b/coding/metaschema.test.c
@@ -1,64 +0,0 @@
-#include <stdio.h>
-#include <assert.h>
-
-#include "metaschema.h"
-
-void
-test_empty_metaschema(void)
-{
- metaschema m[] = {};
- assoc *a = metacompile(m, metalen(m));
- assert(a);
- assert(get_amount_of_keys(a) == 0);
-}
-
-void
-test_empty_schemas(void)
-{
- metaschema m[] = {
- { .name = "test",
- .constructors = (metaconstructor[]){}
- },
- { .name = "test2",
- .constructors = (metaconstructor[]){}
- },
- { .name = "test3",
- .constructors = (metaconstructor[]){}
- }
- };
- assoc *a = metacompile(m, metalen(m));
- assert(get_amount_of_keys(a) == metalen(m));
- assert(assoc_get(a, intern("test")));
- assert(assoc_get(a, intern("test2")));
- assert(assoc_get(a, intern("test3")));
-}
-
-void
-test_empty_constructors(void)
-{
- metaschema m[] = {
- { .name = "test",
- .constructors = (metaconstructor[]){
- { .head = "constr0",
- .keys = (metakey[]){}
- },
- { .head = "constr1",
- .keys = (metakey[]){}
- }
- }
- }
- };
- assoc *a = metacompile(m, metalen(m));
- schema *s = assoc_get(a, intern("test"));
- assert(is_constructor(s, intern("constr0")));
- assert(is_constructor(s, intern("constr1")));
-}
-
-int
-main()
-{
- test_empty_metaschema();
- test_empty_schemas();
- test_empty_constructors();
- return 0;
-}
diff --git a/coding/model.test.c b/coding/model.test.c
@@ -24,7 +24,6 @@ void
test_context(void)
{
schema *ctx = schema(context);
- bool res = true;
assert (has_key (ctx, I("attitude"), I("name") ));
assert (has_key (ctx, I("attitude"), I("vars") ));
@@ -96,26 +95,17 @@ test_use(void)
{
gardener *g = new_gardener(schema(context));
- start(g, I("attitude"));
- 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);
- 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);
+ start (g, I("attitude") ); 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 ); 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.test.c b/coding/schema.test.c
@@ -40,7 +40,7 @@ test_set_and_query_leaf(void)
return takes_leaf(s, c, a);
}
-bool
+void
test_leaf_exists(void)
{
assert(LEAF != NULL);
@@ -63,18 +63,13 @@ test_listing_all_keys(void)
return good;
}
-bool
-test_check(void)
-{
-}
-
int
main()
{
assert(test_name());
assert(test_set_and_get_subschema());
assert(test_set_and_query_leaf());
- assert(test_leaf_exists());
+ test_leaf_exists();
assert(test_listing_all_keys());
return 0;
}