gardener.c (4479B)
1 #include <stdio.h> 2 3 #include "gardener.h" 4 5 #include "stack.h" 6 #include "tree.h" 7 #include "schema.h" 8 9 #define ensure(G, COND, ERR) if (!COND) { set_error(G, ERR); return; } 10 11 typedef struct { 12 tree *tree; 13 schema *schema; 14 symbol key; 15 } frame; 16 17 struct gardener { 18 schema *top; 19 stack *stack; 20 gardener_status error; 21 tree *result; 22 }; 23 24 frame* 25 new_frame(void) 26 { 27 frame *f = malloc(sizeof(frame)); 28 f->tree = NULL; 29 f->schema = NULL; 30 f->key = 0; 31 return f; 32 } 33 34 /* GETTERS */ 35 36 schema* 37 get_top(gardener *g) 38 { 39 return g->top; 40 } 41 42 tree* 43 get_cur_tree(gardener *g) 44 { 45 if (peek(g->stack)) 46 return ((frame*)peek(g->stack))->tree; 47 else 48 return g->result; 49 } 50 51 symbol 52 get_cur_constructor(gardener *g) 53 { 54 return get_head(get_cur_tree(g)); 55 } 56 57 schema* 58 get_cur_schema(gardener *g) 59 { 60 if (peek(g->stack)) 61 return ((frame*)peek(g->stack))->schema; 62 else 63 return g->top; 64 } 65 66 gardener_status 67 get_error(gardener *g) 68 { 69 return g->error; 70 } 71 72 tree* 73 result(gardener *g) 74 { 75 return g->result; 76 } 77 78 /* SETTERS */ 79 80 void 81 set_error(gardener *g, gardener_status e) 82 { 83 g->error = e; 84 } 85 86 /* PUBLIC */ 87 88 gardener* 89 new_gardener(schema* s) 90 { 91 gardener *g = malloc(sizeof(gardener)); 92 g->top = s; 93 g->error = false; 94 g->stack = new_stack(); 95 g->result = NULL; 96 return g; 97 } 98 99 100 void 101 fill(gardener* g, symbol key, symbol value) 102 { 103 ensure(g, (get_cur_tree(g) != NULL), NON_START_OP_ON_EMPTY_STACK); 104 tree *new = new_leaf(value); 105 set_subtree(get_cur_tree(g), key, new); 106 } 107 108 109 void 110 sub(gardener* g, symbol key, symbol constructor) 111 { 112 schema *cur_schema = get_cur_schema(g); 113 tree *cur = get_cur_tree(g); 114 ensure(g, (cur != NULL), NON_START_OP_ON_EMPTY_STACK); 115 symbol head = get_head(get_cur_tree(g)); 116 117 ensure(g, has_key(cur_schema, head, key), SUB_INVALID_KEY); 118 schema *sub_schema = get_subschema(cur_schema, head, key); 119 ensure(g, is_constructor(sub_schema, constructor), SUB_WITH_INVALID_CONSTRUCTOR); 120 tree *new = new_node(constructor); 121 122 set_subtree(get_cur_tree(g), key, new); 123 frame *f = new_frame(); 124 f->schema = sub_schema; 125 f->tree = new; 126 f->key = key; 127 push(g->stack, f); 128 } 129 130 void 131 sup(gardener* g, symbol constructor, symbol key) 132 { 133 // schema *cur_schema = get_cur_schema(g); 134 135 // ensure(g, is_constructor(cur_schema, constructor), SUP_WITH_INVALID_CONSTRUCTOR); 136 // ensure(g, has_key(cur_schema, constructor, key), SUP_INVALID_KEY); 137 ensure(g, (g->result == NULL), OP_AFTER_RESULT); 138 139 frame *old = pop(g->stack); 140 141 frame *new = new_frame(); 142 new->tree = new_node(constructor); 143 new->schema = old->schema; 144 new->key = old->key; 145 146 set_subtree(new->tree, key, old->tree); 147 if (peek(g->stack)) set_subtree(((frame*)peek(g->stack))->tree, old->key, new->tree); 148 // free_frame(old); 149 push(g->stack, new); 150 } 151 152 153 void 154 start(gardener* g, symbol c) 155 { 156 ensure(g, is_empty(g->stack), START_ON_NONEMPTY_STACK); 157 ensure(g, (g->result == NULL), OP_AFTER_RESULT); 158 ensure(g, is_constructor(g->top, c), START_WITH_INVALID_CONSTRUCTOR); 159 160 frame *f = new_frame(); 161 f->tree = new_node(c); 162 f->schema = g->top; 163 164 push(g->stack, f); 165 } 166 167 168 void 169 done(gardener* g) 170 { 171 frame *f; 172 ensure(g, (!is_empty(g->stack)), NON_START_OP_ON_EMPTY_STACK); 173 ensure(g, check(get_cur_schema(g), get_cur_tree(g)), DONE_ON_INVALID_TREE); 174 f = (frame*) pop(g->stack); 175 176 if (is_empty(g->stack)) 177 g->result = f->tree; 178 } 179 180 void 181 show(FILE *f, gardener *g) 182 { 183 schema *s = get_cur_schema(g); 184 tree *cur = get_cur_tree(g); 185 if (cur == NULL) { 186 fprintf(f, "schema %s\n", repr(get_name(get_top(g)))); 187 return; 188 } 189 symbol head = get_head(cur); 190 191 fprintf(f, "schema %s\n", repr(get_name(s))); 192 fprintf(f, "head %s\n", repr(head)); 193 size_t num = get_amount_of_required_keys(s, head); 194 symbol *keys = get_required_keys(s, head); 195 for (size_t i = 0; i < num; i++) { 196 if (!get_subtree(cur, keys[i])) { 197 if (takes_leaf(s, head, keys[i])) { 198 fprintf(f, "symbol %s\n", repr(keys[i])); 199 } else { 200 fprintf(f, "goal %s %s\n", repr(get_name(get_subschema(s, head, keys[i]))), repr(keys[i])); 201 } 202 } 203 } 204 switch (get_error(g)) { 205 case SUB_INVALID_KEY: 206 fprintf(f, "error SUB_INVALID_KEY"); 207 break; 208 case NON_START_OP_ON_EMPTY_STACK: 209 fprintf(f, "error NON_START_OP_ON_EMPTY_STACK"); 210 break; 211 case START_ON_NONEMPTY_STACK: 212 fprintf(f, "error START_ON_NONEMPTY_STACK"); 213 break; 214 case OP_AFTER_RESULT: 215 fprintf(f, "error OP_AFTER_RESULT"); 216 break; 217 case SUB_WITH_INVALID_CONSTRUCTOR: 218 fprintf(f, "error SUB_WITH_INVALID_CONSTRUCTOR"); 219 break; 220 case DONE_ON_INVALID_TREE: 221 fprintf(f, "error DONE_ON_INVALID_TREE"); 222 break; 223 case OK: 224 break; 225 } 226 } 227