baum

view baum.c @ 33:2e564bf8599c

new error code 6; more readable printTree; cleanups
author meillo@marmaro.de
date Sat, 01 Mar 2008 17:36:59 +0100
parents 4e60d96265f0
children e986c6abed2b
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 root = newNode("blackhole", 0);
142 last_node = root;
143 file = fopen(filename, "r");
145 while ((c = getc(file)) != EOF) {
146 if (c == '#') { /* comment */
147 while ((c = getc(file)) != '\n') {
148 }
149 }
151 if (c == ' ' || c == '\t') { /* indent if at start of line */
152 if (strlen(name) == 0) {
153 indent++;
154 }
155 }
157 if (c == '\n') { /* end of line: create node */
158 if (strlen(name) > 0) {
159 if (option_verbose) {
160 fprintf(stderr, " %d - %s - %d\n", indent, name, value);
161 }
162 /* create node */
163 node = newNode((char*) name, value);
164 if (indent > last_indent) { /* down */
165 /* if it goes more than one level down -> error */
166 if (indent > last_indent + 1) {
167 fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n");
168 exit(5);
169 }
170 last_node->down = node;
171 push(last_node);
172 } else if (indent == last_indent) { /* right */
173 last_node->right = node;
174 } else if (indent < last_indent) { /* up */
175 /* handle if it goes more than one level up */
176 while (indent < last_indent) {
177 last_node = pull();
178 last_indent--;
179 }
180 last_node->right = node;
181 }
182 last_indent = indent;
183 last_node = node;
184 }
185 indent = 0;
186 strcpy(name, "");
187 value = 0;
188 }
190 if (c >= 'a' && c <= 'z') { /* name */
191 int i = 1;
192 name[0] = (char) c;
193 while ((c = getc(file)) != '(') {
194 name[i] = (char) c;
195 i++;
196 if (i > 255) {
197 fprintf(stderr, "error: node name too long, or no value given\n");
198 exit(6);
199 }
200 }
201 name[i] = '\0';
202 }
204 if (c == '(') { /* value */
205 fscanf(file, "%d)", &value);
206 }
208 }
210 /* clear stack */
211 while (stack != NULL) {
212 pull();
213 }
215 fclose(file);
216 }
220 /* main */
221 int main(int argc, char* argv[]) {
222 unsigned char shell_return = 0;
224 while (--argc > 0 && (*++argv)[0] == '-') {
225 if (strcmp(argv[0], "--version") == 0) {
226 printf("\
227 baum %s\n\
228 an esoteric programming language\n\
229 by markus schnalke and julian forster\n\
230 http://prog.marmaro.de/baum\n\
231 ", VERSION);
232 exit(0);
233 } else if (strcmp(argv[0], "--help") == 0) {
234 printf("\
235 baum --version print version information and exit\n\
236 baum --help print this output\n\
237 baum [-v] <file> (verbosly) run file\n\
238 ");
239 exit(0);
240 } else if (strcmp(argv[0], "-v") == 0) {
241 option_verbose = 1;
242 /*
243 } else if (strcmp(argv[0], "-W") == 0) {
244 / * TODO: catch if no value given * /
245 iDWarn = atoi((++argv)[0]);
246 argc--;
247 */
248 } else {
249 fprintf(stderr, "unknown option: %s\n", argv[0]);
250 exit(127);
251 }
252 }
254 if (argc != 1) {
255 fprintf(stderr, "%d source files given, please specify one.\n", argc);
256 exit(3);
257 }
259 read_input(argv[0]);
261 if (option_verbose) {
262 printTree(root, 0);
263 }
265 shell_return = action(root);
267 if (option_verbose) {
268 printTree(root, 0);
269 }
271 delete(root);
272 exit(shell_return);
273 }