baum
view baum.c @ 32:3903effae5ef
new debian package
author | meillo@marmaro.de |
---|---|
date | Fri, 22 Feb 2008 15:58:25 +0100 |
parents | cd979b979610 |
children | 2e564bf8599c |
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);
27 void printTree(struct Node* root);
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 if (node->down != NULL) {
73 delete(node->down);
74 }
75 if (node->right != NULL) {
76 delete(node->right);
77 }
78 free(node); node=0;
79 }
82 /* print */
83 void printNode(struct Node* node) {
84 if (node != NULL) {
85 fprintf(stderr, "Node: %10s (%d|%c)\n", node->name, node->value, node->value);
86 }
87 }
89 void printTree(struct Node* root) {
90 if (root == NULL) {
91 return;
92 }
94 printNode(root);
95 fprintf(stderr, " down: ");
96 if (root->down != NULL) {
97 printTree(root->down);
98 } else {
99 fprintf(stderr, "NULL\n");
100 }
101 fprintf(stderr, " right: ");
102 if (root->right != NULL) {
103 printTree(root->right);
104 } else {
105 fprintf(stderr, "NULL\n");
106 }
107 }
113 /* stack for read_input */
114 void push(struct Node* node) {
115 struct Stackitem* tmp;
116 struct Stackitem* new;
117 new = (struct Stackitem*) malloc(sizeof(struct Stackitem));
118 new->node = node;
119 tmp = stack;
120 stack = new;
121 stack->next = tmp;
122 }
123 struct Node* pull() {
124 if (stack == NULL) {
125 return NULL;
126 }
127 struct Stackitem* tmp;
128 struct Node* node;
129 tmp = stack;
130 stack = stack->next;
131 node = tmp->node;
132 free(tmp); tmp=0;
133 return node;
134 }
138 /* read input */
139 void read_input(char* filename) {
140 int c;
141 int indent;
142 char name[256];
143 int value;
144 int last_indent;
145 struct Node* last_node;
146 struct Node* node;
147 FILE* file;
149 indent = 0;
150 strcpy(name, "");
151 value = 0;
152 last_indent = -1;
153 root = newNode("blackhole", 0);
154 last_node = root;
155 file = fopen(filename, "r");
157 while ((c = getc(file)) != EOF) {
158 if (c == '#') { /* comment */
159 while ((c = getc(file)) != '\n') {
160 }
161 }
163 if (c == ' ' || c == '\t') { /* indent if at start of line */
164 if (strlen(name) == 0) {
165 indent++;
166 }
167 }
169 if (c == '\n') { /* end of line: create node */
170 if (strlen(name) > 0) {
171 if (option_verbose) {
172 fprintf(stderr, " %d - %s - %d\n", indent, name, value);
173 }
174 /* create node */
175 node = newNode((char*) name, value);
176 if (indent > last_indent) { /* down */
177 /* if it goes more than one level down -> error */
178 if (indent - last_indent > 1) {
179 fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n");
180 exit(5);
181 }
182 last_node->down = node;
183 push(last_node);
184 } else if (indent == last_indent) { /* right */
185 last_node->right = node;
186 } else if (indent < last_indent) { /* up */
187 /* handle if it goes more than one level up */
188 while (indent < last_indent) {
189 last_node = pull();
190 last_indent--;
191 }
192 last_node->right = node;
193 }
194 last_indent = indent;
195 last_node = node;
196 }
197 indent = 0;
198 strcpy(name, "");
199 value = 0;
200 }
202 if (c >= 'a' && c <= 'z') { /* name */
203 int i = 1;
204 name[0] = (char) c;
205 while ((c = getc(file)) != '(') {
206 name[i] = (char) c;
207 i++;
208 if (i > 255) {
209 break;
210 }
211 }
212 name[i] = '\0';
213 }
215 if (c == '(') { /* value */
216 fscanf(file, "%d)", &value);
217 }
219 }
221 /* clear stack */
222 while (stack != NULL) {
223 pull();
224 }
226 fclose(file);
227 }
231 /* main */
232 int main(int argc, char* argv[]) {
233 unsigned char shell_return = 0;
235 while (--argc > 0 && (*++argv)[0] == '-') {
236 if (strcmp(argv[0], "--version") == 0) {
237 printf("\
238 baum %s\n\
239 an esoteric programming language\n\
240 by markus schnalke and julian forster\n\
241 http://prog.marmaro.de/baum\n\
242 ", VERSION);
243 exit(0);
244 } else if (strcmp(argv[0], "--help") == 0) {
245 printf("\
246 baum --version print version information and exit\n\
247 baum --help print this output\n\
248 baum [-v] <file> (verbosly) run file\n\
249 ");
250 exit(0);
251 } else if (strcmp(argv[0], "-v") == 0) {
252 option_verbose = 1;
253 /*
254 } else if (strcmp(argv[0], "-W") == 0) {
255 / * TODO: catch if no value given * /
256 iDWarn = atoi((++argv)[0]);
257 argc--;
258 */
259 } else {
260 fprintf(stderr, "unknown option: %s\n", argv[0]);
261 exit(127);
262 }
263 }
265 if (argc != 1) {
266 fprintf(stderr, "%d source files given, please specify one.\n", argc);
267 exit(3);
268 }
270 read_input(argv[0]);
272 if (option_verbose) {
273 printTree(root);
274 }
276 shell_return = action(root);
278 if (option_verbose) {
279 printTree(root);
280 }
282 delete(root);
283 exit(shell_return);
284 }