baum

view baum.c @ 30:cd979b979610

fixed multiple (un)indentions in read_input; some better comments
author meillo@marmaro.de
date Fri, 22 Feb 2008 14:47:47 +0100
parents 88a51653db83
children 4e60d96265f0
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_check = 0;
21 int option_verbose = 0;
23 struct Node* root = 0;
24 struct Stackitem* stack = NULL;
27 void printNode(struct Node* node);
28 void printTree(struct Node* root);
29 struct Node* lastNode(struct Node* node);
30 void delete(struct Node* node);
34 void logit(char* text) {
35 if (option_verbose) {
36 fprintf(stderr, "[%s]\n", text);
37 }
38 }
41 /* new */
42 struct Node* newNode(char* name, unsigned char value) {
43 struct Node* node;
44 node = (struct Node*) malloc(sizeof(struct Node));
45 strcpy(node->name, name);
46 node->value = value;
47 node->right = 0;
48 node->down = 0;
49 return node;
50 }
54 struct Node* lastNode(struct Node* node) {
55 while (node->right != NULL) {
56 node = node->right;
57 }
58 return node;
59 }
61 struct Node* insertLast(struct Node* node, struct Node* insert) {
62 node = lastNode(node);
63 node->right = insert;
64 return insert;
65 }
68 /* delete */
69 void delete(struct Node* node) {
70 if (node == NULL) {
71 return;
72 }
73 if (node->down != NULL) {
74 delete(node->down);
75 }
76 if (node->right != NULL) {
77 delete(node->right);
78 }
79 free(node); node=0;
80 }
83 /* print */
84 void printNode(struct Node* node) {
85 if (node != NULL) {
86 fprintf(stderr, "Node: %10s (%d|%c)\n", node->name, node->value, node->value);
87 }
88 }
90 void printTree(struct Node* root) {
91 if (root == NULL) {
92 return;
93 }
95 printNode(root);
96 fprintf(stderr, " down: ");
97 if (root->down != NULL) {
98 printTree(root->down);
99 } else {
100 fprintf(stderr, "NULL\n");
101 }
102 fprintf(stderr, " right: ");
103 if (root->right != NULL) {
104 printTree(root->right);
105 } else {
106 fprintf(stderr, "NULL\n");
107 }
108 }
114 /* stack for read_input */
115 void push(struct Node* node) {
116 struct Stackitem* tmp;
117 struct Stackitem* new;
118 new = (struct Stackitem*) malloc(sizeof(struct Stackitem));
119 new->node = node;
120 tmp = stack;
121 stack = new;
122 stack->next = tmp;
123 }
124 struct Node* pull() {
125 if (stack == NULL) {
126 return NULL;
127 }
128 struct Stackitem* tmp;
129 struct Node* node;
130 tmp = stack;
131 stack = stack->next;
132 node = tmp->node;
133 free(tmp); tmp=0;
134 return node;
135 }
139 /* read input */
140 void read_input(char* filename) {
141 int c;
142 int indent;
143 char name[256];
144 int value;
145 int last_indent;
146 struct Node* last_node;
147 struct Node* node;
148 FILE* file;
150 indent = 0;
151 strcpy(name, "");
152 value = 0;
153 last_indent = -1;
154 root = newNode("blackhole", 0);
155 last_node = root;
156 file = fopen(filename, "r");
158 while ((c = getc(file)) != EOF) {
159 if (c == '#') { /* comment */
160 while ((c = getc(file)) != '\n') {
161 }
162 }
164 if (c == ' ' || c == '\t') { /* indent if at start of line */
165 if (strlen(name) == 0) {
166 indent++;
167 }
168 }
170 if (c == '\n') { /* end of line: create node */
171 if (strlen(name) > 0) {
172 if (option_verbose) {
173 fprintf(stderr, " %d - %s - %d\n", indent, name, value);
174 }
175 /* create node */
176 node = newNode((char*) name, value);
177 if (indent > last_indent) { /* down */
178 /* if it goes more than one level down -> error */
179 if (indent - last_indent > 1) {
180 fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n");
181 exit(50);
182 }
183 last_node->down = node;
184 push(last_node);
185 } else if (indent == last_indent) { /* right */
186 last_node->right = node;
187 } else if (indent < last_indent) { /* up */
188 /* handle if it goes more than one level up */
189 while (indent < last_indent) {
190 last_node = pull();
191 last_indent--;
192 }
193 last_node->right = node;
194 }
195 last_indent = indent;
196 last_node = node;
197 }
198 indent = 0;
199 strcpy(name, "");
200 value = 0;
201 }
203 if (c >= 'a' && c <= 'z') { /* name */
204 int i = 1;
205 name[0] = (char) c;
206 while ((c = getc(file)) != '(') {
207 name[i] = (char) c;
208 i++;
209 if (i > 255) {
210 break;
211 }
212 }
213 name[i] = '\0';
214 }
216 if (c == '(') { /* value */
217 fscanf(file, "%d)", &value);
218 }
220 }
222 /* clear stack */
223 while (stack != NULL) {
224 pull();
225 }
227 fclose(file);
228 }
232 /* main */
233 int main(int argc, char* argv[]) {
234 unsigned char shell_return = 0;
236 while (--argc > 0 && (*++argv)[0] == '-') {
237 if (strcmp(argv[0], "--version") == 0) {
238 printf("\
239 baum %s\n\
240 an esoteric programming language\n\
241 by markus schnalke and julian forster\n\
242 http://prog.marmaro.de/baum\n\
243 ", VERSION);
244 exit(0);
245 } else if (strcmp(argv[0], "--help") == 0) {
246 printf("\
247 baum --version print version information and exit\n\
248 baum --help print this output\n\
249 baum [-v] -c <file> (verbosly) check file and return 1 if invalid\n\
250 baum [-v] <file> (verbosly) run file\n\
251 ");
252 exit(0);
253 } else if (strcmp(argv[0], "-c") == 0) {
254 option_check = 1;
255 } else if (strcmp(argv[0], "-v") == 0) {
256 option_verbose = 1;
257 /*
258 } else if (strcmp(argv[0], "-W") == 0) {
259 / * TODO: catch if no value given * /
260 iDWarn = atoi((++argv)[0]);
261 argc--;
262 */
263 } else {
264 fprintf(stderr, "unknown option: %s\n", argv[0]);
265 exit(127);
266 }
267 }
269 if (argc != 1) {
270 fprintf(stderr, "%d source files given, please specify one.\n", argc);
271 exit(3);
272 }
274 read_input(argv[0]);
276 if (option_verbose) {
277 printTree(root);
278 }
280 shell_return = action(root);
282 if (option_verbose) {
283 printTree(root);
284 }
286 delete(root);
287 exit(shell_return);
288 }