baum

view baum.c @ 34:e986c6abed2b

eliminated generic blackhole node at root
author meillo@marmaro.de
date Sat, 01 Mar 2008 17:45:55 +0100
parents 2e564bf8599c
children 29172b6e802a
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.2"
20 int option_verbose = 0;
22 struct Node* root = 0;
23 struct Stackitem* stack = NULL;
26 void printNode(struct Node* node, int level);
27 void printTree(struct Node* root, int level);
28 struct Node* lastNode(struct Node* node);
29 void delete(struct Node* node);
33 void logit(char* text) {
34 if (option_verbose) {
35 fprintf(stderr, "[%s]\n", text);
36 }
37 }
40 /* new */
41 struct Node* newNode(char* name, unsigned char value) {
42 struct Node* node;
43 node = (struct Node*) malloc(sizeof(struct Node));
44 strcpy(node->name, name);
45 node->value = value;
46 node->right = 0;
47 node->down = 0;
48 return node;
49 }
53 struct Node* lastNode(struct Node* node) {
54 while (node->right != NULL) {
55 node = node->right;
56 }
57 return node;
58 }
60 struct Node* insertLast(struct Node* node, struct Node* insert) {
61 node = lastNode(node);
62 node->right = insert;
63 return insert;
64 }
67 /* delete */
68 void delete(struct Node* node) {
69 if (node == NULL) {
70 return;
71 }
72 delete(node->down);
73 delete(node->right);
74 free(node); node=0;
75 }
78 /* print */
79 void printNode(struct Node* node, int level) {
80 if (node != NULL) {
81 while (level-- > 0) {
82 fprintf(stderr, "\t");
83 }
84 fprintf(stderr, "%s (%d|%c)\n", node->name, node->value, node->value);
85 }
86 }
88 void printTree(struct Node* root, int level) {
89 if (root == NULL) {
90 return;
91 }
92 printNode(root, level);
93 printTree(root->down, level+1);
94 printTree(root->right, level);
95 }
101 /* stack for read_input */
102 void push(struct Node* node) {
103 struct Stackitem* tmp;
104 struct Stackitem* new;
105 new = (struct Stackitem*) malloc(sizeof(struct Stackitem));
106 new->node = node;
107 tmp = stack;
108 stack = new;
109 stack->next = tmp;
110 }
111 struct Node* pull() {
112 if (stack == NULL) {
113 return NULL;
114 }
115 struct Stackitem* tmp;
116 struct Node* node;
117 tmp = stack;
118 stack = stack->next;
119 node = tmp->node;
120 free(tmp); tmp=0;
121 return node;
122 }
126 /* read input */
127 void read_input(char* filename) {
128 int c;
129 int indent;
130 char name[256];
131 int value;
132 int last_indent;
133 struct Node* last_node;
134 struct Node* node;
135 FILE* file;
137 indent = 0;
138 strcpy(name, "");
139 value = 0;
140 last_indent = -1;
141 last_node = NULL;
142 file = fopen(filename, "r");
144 while ((c = getc(file)) != EOF) {
145 if (c == '#') { /* comment */
146 while ((c = getc(file)) != '\n') {
147 }
148 }
150 if (c == ' ' || c == '\t') { /* indent if at start of line */
151 if (strlen(name) == 0) {
152 indent++;
153 }
154 }
156 if (c == '\n') { /* end of line: create node */
157 if (strlen(name) > 0) {
158 if (option_verbose) {
159 fprintf(stderr, " %d - %s - %d\n", indent, name, value);
160 }
161 /* create node */
162 node = newNode((char*) name, value);
163 if (indent > last_indent) { /* down */
164 /* if it goes more than one level down -> error */
165 if (indent > last_indent + 1) {
166 fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n");
167 exit(5);
168 }
169 if (last_node == NULL) {
170 root = node;
171 last_node = root;
172 } else {
173 last_node->down = node;
174 }
175 push(last_node);
176 } else if (indent == last_indent) { /* right */
177 last_node->right = node;
178 } else if (indent < last_indent) { /* up */
179 /* handle if it goes more than one level up */
180 while (indent < last_indent) {
181 last_node = pull();
182 last_indent--;
183 }
184 last_node->right = node;
185 }
186 last_indent = indent;
187 last_node = node;
188 }
189 indent = 0;
190 strcpy(name, "");
191 value = 0;
192 }
194 if (c >= 'a' && c <= 'z') { /* name */
195 int i = 1;
196 name[0] = (char) c;
197 while ((c = getc(file)) != '(') {
198 name[i] = (char) c;
199 i++;
200 if (i > 255) {
201 fprintf(stderr, "error: node name too long, or no value given\n");
202 exit(6);
203 }
204 }
205 name[i] = '\0';
206 }
208 if (c == '(') { /* value */
209 fscanf(file, "%d)", &value);
210 }
212 }
214 /* clear stack */
215 while (stack != NULL) {
216 pull();
217 }
219 fclose(file);
220 }
224 /* main */
225 int main(int argc, char* argv[]) {
226 unsigned char shell_return = 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 }