baum
view baum.c @ 38:ff01f0f076e4
option_verbose is now global; stuff about warning when (expected) nodes are not there
author | meillo@marmaro.de |
---|---|
date | Sat, 01 Mar 2008 20:04:08 +0100 |
parents | 29172b6e802a |
children | 5c13e29bc6fd |
line source
1 /*
2 * baum - an esoteric programming language
3 *
4 * (c) markus schnalke <meillo@marmaro.de>
5 * and julian forster
6 *
7 */
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
14 #include "baum.h"
15 #include "actions.h"
17 #define VERSION "0.3"
20 struct Node* root = 0;
21 struct Stackitem* stack = NULL;
24 void printNode(struct Node* node, int level);
25 void printTree(struct Node* root, int level);
26 struct Node* lastNode(struct Node* node);
27 void delete(struct Node* node);
31 void logit(char* text) {
32 if (option_verbose) {
33 fprintf(stderr, "[%s]\n", text);
34 }
35 }
38 /* new */
39 struct Node* newNode(char* name, unsigned char value) {
40 struct Node* node;
41 node = (struct Node*) malloc(sizeof(struct Node));
42 strcpy(node->name, name);
43 node->value = value;
44 node->right = 0;
45 node->down = 0;
46 return node;
47 }
51 struct Node* lastNode(struct Node* node) {
52 while (node->right != NULL) {
53 node = node->right;
54 }
55 return node;
56 }
58 struct Node* insertLast(struct Node* node, struct Node* insert) {
59 node = lastNode(node);
60 node->right = insert;
61 return insert;
62 }
65 /* delete */
66 void delete(struct Node* node) {
67 if (node == NULL) {
68 return;
69 }
70 delete(node->down);
71 delete(node->right);
72 free(node); node=0;
73 }
76 /* print */
77 void printNode(struct Node* node, int level) {
78 if (node != NULL) {
79 while (level-- > 0) {
80 fprintf(stderr, "\t");
81 }
82 fprintf(stderr, "%s (%d|%c)\n", node->name, node->value, node->value);
83 }
84 }
86 void printTree(struct Node* root, int level) {
87 if (root == NULL) {
88 return;
89 }
90 printNode(root, level);
91 printTree(root->down, level+1);
92 printTree(root->right, level);
93 }
99 /* stack for read_input */
100 void push(struct Node* node) {
101 struct Stackitem* tmp;
102 struct Stackitem* new;
103 new = (struct Stackitem*) malloc(sizeof(struct Stackitem));
104 new->node = node;
105 tmp = stack;
106 stack = new;
107 stack->next = tmp;
108 }
109 struct Node* pull() {
110 if (stack == NULL) {
111 return NULL;
112 }
113 struct Stackitem* tmp;
114 struct Node* node;
115 tmp = stack;
116 stack = stack->next;
117 node = tmp->node;
118 free(tmp); tmp=0;
119 return node;
120 }
124 /* read input */
125 void read_input(char* filename) {
126 int c;
127 int indent;
128 char name[256];
129 int value;
130 int last_indent;
131 struct Node* last_node;
132 struct Node* node;
133 FILE* file;
135 indent = 0;
136 strcpy(name, "");
137 value = 0;
138 last_indent = -1;
139 last_node = NULL;
140 file = fopen(filename, "r");
142 while ((c = getc(file)) != EOF) {
143 if (c == '#') { /* comment */
144 while ((c = getc(file)) != '\n') {
145 }
146 }
148 if (c == ' ' || c == '\t') { /* indent if at start of line */
149 if (strlen(name) == 0) {
150 indent++;
151 }
152 }
154 if (c == '\n') { /* end of line: create node */
155 if (strlen(name) > 0) {
156 if (option_verbose) {
157 fprintf(stderr, " %d - %s - %d\n", indent, name, value);
158 }
159 /* create node */
160 node = newNode((char*) name, value);
161 if (indent > last_indent) { /* down */
162 /* if it goes more than one level down -> error */
163 if (indent > last_indent + 1) {
164 fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n");
165 exit(5);
166 }
167 if (last_node == NULL) {
168 root = node;
169 last_node = root;
170 } else {
171 last_node->down = node;
172 }
173 push(last_node);
174 } else if (indent == last_indent) { /* right */
175 last_node->right = node;
176 } else if (indent < last_indent) { /* up */
177 /* handle if it goes more than one level up */
178 while (indent < last_indent) {
179 last_node = pull();
180 last_indent--;
181 }
182 last_node->right = node;
183 }
184 last_indent = indent;
185 last_node = node;
186 }
187 indent = 0;
188 strcpy(name, "");
189 value = 0;
190 }
192 if (c >= 'a' && c <= 'z') { /* name */
193 int i = 1;
194 name[0] = (char) c;
195 while ((c = getc(file)) != '(') {
196 name[i] = (char) c;
197 i++;
198 if (i > 255) {
199 fprintf(stderr, "error: node name too long, or no value given\n");
200 exit(6);
201 }
202 }
203 name[i] = '\0';
204 }
206 if (c == '(') { /* value */
207 fscanf(file, "%d)", &value);
208 }
210 }
212 /* clear stack */
213 while (stack != NULL) {
214 pull();
215 }
217 fclose(file);
218 }
222 /* main */
223 int main(int argc, char* argv[]) {
224 unsigned char shell_return = 0;
226 option_verbose = 0;
228 while (--argc > 0 && (*++argv)[0] == '-') {
229 if (strcmp(argv[0], "--version") == 0) {
230 printf("\
231 baum %s\n\
232 an esoteric programming language\n\
233 by markus schnalke and julian forster\n\
234 http://prog.marmaro.de/baum\n\
235 ", VERSION);
236 exit(0);
237 } else if (strcmp(argv[0], "--help") == 0) {
238 printf("\
239 baum --version print version information and exit\n\
240 baum --help print this output\n\
241 baum [-v] <file> (verbosly) run file\n\
242 ");
243 exit(0);
244 } else if (strcmp(argv[0], "-v") == 0) {
245 option_verbose = 1;
246 /*
247 } else if (strcmp(argv[0], "-W") == 0) {
248 / * TODO: catch if no value given * /
249 iDWarn = atoi((++argv)[0]);
250 argc--;
251 */
252 } else {
253 fprintf(stderr, "unknown option: %s\n", argv[0]);
254 exit(127);
255 }
256 }
258 if (argc != 1) {
259 fprintf(stderr, "%d source files given, please specify one.\n", argc);
260 exit(3);
261 }
263 read_input(argv[0]);
265 if (option_verbose) {
266 printTree(root, 0);
267 }
269 shell_return = action(root);
270 fflush(stdout);
272 if (option_verbose) {
273 printTree(root, 0);
274 }
276 delete(root);
277 exit(shell_return);
278 }