baum

view baum.c @ 43:c7dca4a1dc37

added test programs; added another example program
author meillo@marmaro.de
date Sat, 01 Mar 2008 21:13:12 +0100
parents 1ad3d7305e5d
children 0b82169d4129
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 void printNode(struct Node* node, int level);
21 void printTree(struct Node* root, int level);
22 struct Node* lastNode(struct Node* node);
23 void delete(struct Node* node);
26 struct Stackitem {
27 struct Node* node;
28 struct Stackitem* next;
29 };
33 struct Node* root = 0;
34 struct Stackitem* stack = NULL;
37 void logit(char* text) {
38 if (option_verbose) {
39 fprintf(stderr, "[%s]\n", text);
40 }
41 }
44 /* new */
45 struct Node* newNode(char* name, unsigned char value) {
46 struct Node* node;
47 node = (struct Node*) malloc(sizeof(struct Node));
48 strcpy(node->name, name);
49 node->value = value;
50 node->right = 0;
51 node->down = 0;
52 return node;
53 }
57 struct Node* lastNode(struct Node* node) {
58 while (node->right != NULL) {
59 node = node->right;
60 }
61 return node;
62 }
64 struct Node* insertLast(struct Node* node, struct Node* insert) {
65 node = lastNode(node);
66 node->right = insert;
67 return insert;
68 }
71 /* delete */
72 void delete(struct Node* node) {
73 if (node == NULL) {
74 return;
75 }
76 delete(node->down);
77 delete(node->right);
78 free(node); node=0;
79 }
82 /* print */
83 void printNode(struct Node* node, int level) {
84 if (node != NULL) {
85 while (level-- > 0) {
86 fprintf(stderr, "\t");
87 }
88 fprintf(stderr, "%s (%d|%c)\n", node->name, node->value, node->value);
89 }
90 }
92 void printTree(struct Node* root, int level) {
93 if (root == NULL) {
94 return;
95 }
96 printNode(root, level);
97 printTree(root->down, level+1);
98 printTree(root->right, level);
99 }
105 /* stack for read_input */
106 void push(struct Node* node) {
107 struct Stackitem* tmp;
108 struct Stackitem* new;
109 new = (struct Stackitem*) malloc(sizeof(struct Stackitem));
110 new->node = node;
111 tmp = stack;
112 stack = new;
113 stack->next = tmp;
114 }
115 struct Node* pull() {
116 if (stack == NULL) {
117 return NULL;
118 }
119 struct Stackitem* tmp;
120 struct Node* node;
121 tmp = stack;
122 stack = stack->next;
123 node = tmp->node;
124 free(tmp); tmp=0;
125 return node;
126 }
130 /* read input */
131 void read_input(char* filename) {
132 int c;
133 int indent;
134 char name[256];
135 int value;
136 int last_indent;
137 struct Node* last_node;
138 struct Node* node;
139 FILE* file;
141 indent = 0;
142 strcpy(name, "");
143 value = 0;
144 last_indent = -1;
145 last_node = NULL;
146 file = fopen(filename, "r");
148 while ((c = getc(file)) != EOF) {
149 if (c == '#') { /* comment */
150 while ((c = getc(file)) != '\n') {
151 }
152 }
154 if (c == ' ' || c == '\t') { /* indent if at start of line */
155 if (strlen(name) == 0) {
156 indent++;
157 }
158 }
160 if (c == '\n') { /* end of line: create node */
161 if (strlen(name) > 0) {
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 if (last_node == NULL) {
171 root = node;
172 last_node = root;
173 } else {
174 last_node->down = node;
175 }
176 push(last_node);
177 } else if (indent == last_indent) { /* right */
178 last_node->right = node;
179 } else if (indent < last_indent) { /* up */
180 /* handle if it goes more than one level up */
181 while (indent < last_indent) {
182 last_node = pull();
183 last_indent--;
184 }
185 last_node->right = node;
186 }
187 last_indent = indent;
188 last_node = node;
189 }
190 indent = 0;
191 strcpy(name, "");
192 value = 0;
193 }
195 if (c >= 'a' && c <= 'z') { /* name */
196 int i = 1;
197 name[0] = (char) c;
198 while ((c = getc(file)) != '(') {
199 name[i] = (char) c;
200 i++;
201 if (i > 255) {
202 fprintf(stderr, "error: node name too long, or no value given\n");
203 exit(6);
204 }
205 }
206 name[i] = '\0';
207 }
209 if (c == '(') { /* value */
210 fscanf(file, "%d)", &value);
211 }
213 }
215 /* clear stack */
216 while (stack != NULL) {
217 pull();
218 }
220 fclose(file);
221 }
225 /* main */
226 int main(int argc, char* argv[]) {
227 unsigned char shell_return = 0;
229 option_verbose = 0;
231 while (--argc > 0 && (*++argv)[0] == '-') {
232 if (strcmp(argv[0], "--version") == 0) {
233 printf("\
234 baum %s\n\
235 an esoteric programming language\n\
236 by markus schnalke and julian forster\n\
237 http://prog.marmaro.de/baum\n\
238 ", VERSION);
239 exit(0);
240 } else if (strcmp(argv[0], "--help") == 0) {
241 printf("\
242 baum --version print version information and exit\n\
243 baum --help print this output\n\
244 baum [-v] <file> (verbosly) run file\n\
245 ");
246 exit(0);
247 } else if (strcmp(argv[0], "-v") == 0) {
248 option_verbose = 1;
249 /*
250 } else if (strcmp(argv[0], "-W") == 0) {
251 / * TODO: catch if no value given * /
252 iDWarn = atoi((++argv)[0]);
253 argc--;
254 */
255 } else {
256 fprintf(stderr, "unknown option: %s\n", argv[0]);
257 exit(126);
258 }
259 }
261 if (argc != 1) {
262 fprintf(stderr, "%d source files given, please specify one.\n", argc);
263 exit(3);
264 }
266 read_input(argv[0]);
268 if (option_verbose) {
269 fprintf(stderr, "\n\ntree read from input\n(should be the same without comments and empty lines)\n\n");
270 printTree(root, 0);
271 }
273 shell_return = action(root);
274 fflush(stdout);
276 if (option_verbose) {
277 fprintf(stderr, "\n\ntree after execution of the program\n\n");
278 printTree(root, 0);
279 }
281 delete(root);
282 exit(shell_return);
283 }