rev |
line source |
meillo@0
|
1 /*
|
meillo@0
|
2 * baum - an esoteric programming language
|
meillo@0
|
3 *
|
meillo@0
|
4 * (c) markus schnalke <meillo@marmaro.de>
|
meillo@0
|
5 * and julian forster
|
meillo@0
|
6 *
|
meillo@0
|
7 */
|
meillo@0
|
8
|
meillo@0
|
9
|
meillo@0
|
10 #include <stdio.h>
|
meillo@0
|
11 #include <stdlib.h>
|
meillo@1
|
12 #include <string.h>
|
meillo@0
|
13
|
meillo@1
|
14 #include "baum.h"
|
meillo@2
|
15 #include "actions.h"
|
meillo@0
|
16
|
meillo@37
|
17 #define VERSION "0.3"
|
meillo@13
|
18
|
meillo@30
|
19
|
meillo@5
|
20 struct Node* root = 0;
|
meillo@10
|
21 struct Stackitem* stack = NULL;
|
meillo@0
|
22
|
meillo@0
|
23
|
meillo@33
|
24 void printNode(struct Node* node, int level);
|
meillo@33
|
25 void printTree(struct Node* root, int level);
|
meillo@26
|
26 struct Node* lastNode(struct Node* node);
|
meillo@26
|
27 void delete(struct Node* node);
|
meillo@26
|
28
|
meillo@26
|
29
|
meillo@26
|
30
|
meillo@1
|
31 void logit(char* text) {
|
meillo@13
|
32 if (option_verbose) {
|
meillo@13
|
33 fprintf(stderr, "[%s]\n", text);
|
meillo@13
|
34 }
|
meillo@1
|
35 }
|
meillo@1
|
36
|
meillo@1
|
37
|
meillo@1
|
38 /* new */
|
meillo@3
|
39 struct Node* newNode(char* name, unsigned char value) {
|
meillo@0
|
40 struct Node* node;
|
meillo@0
|
41 node = (struct Node*) malloc(sizeof(struct Node));
|
meillo@9
|
42 strcpy(node->name, name);
|
meillo@3
|
43 node->value = value;
|
meillo@0
|
44 node->right = 0;
|
meillo@0
|
45 node->down = 0;
|
meillo@0
|
46 return node;
|
meillo@0
|
47 }
|
meillo@0
|
48
|
meillo@0
|
49
|
meillo@3
|
50
|
meillo@3
|
51 struct Node* lastNode(struct Node* node) {
|
meillo@3
|
52 while (node->right != NULL) {
|
meillo@3
|
53 node = node->right;
|
meillo@3
|
54 }
|
meillo@3
|
55 return node;
|
meillo@3
|
56 }
|
meillo@3
|
57
|
meillo@15
|
58 struct Node* insertLast(struct Node* node, struct Node* insert) {
|
meillo@3
|
59 node = lastNode(node);
|
meillo@3
|
60 node->right = insert;
|
meillo@15
|
61 return insert;
|
meillo@3
|
62 }
|
meillo@3
|
63
|
meillo@26
|
64
|
meillo@1
|
65 /* delete */
|
meillo@1
|
66 void delete(struct Node* node) {
|
meillo@26
|
67 if (node == NULL) {
|
meillo@26
|
68 return;
|
meillo@0
|
69 }
|
meillo@33
|
70 delete(node->down);
|
meillo@33
|
71 delete(node->right);
|
meillo@26
|
72 free(node); node=0;
|
meillo@0
|
73 }
|
meillo@0
|
74
|
meillo@1
|
75
|
meillo@1
|
76 /* print */
|
meillo@33
|
77 void printNode(struct Node* node, int level) {
|
meillo@5
|
78 if (node != NULL) {
|
meillo@33
|
79 while (level-- > 0) {
|
meillo@33
|
80 fprintf(stderr, "\t");
|
meillo@33
|
81 }
|
meillo@33
|
82 fprintf(stderr, "%s (%d|%c)\n", node->name, node->value, node->value);
|
meillo@5
|
83 }
|
meillo@0
|
84 }
|
meillo@0
|
85
|
meillo@33
|
86 void printTree(struct Node* root, int level) {
|
meillo@26
|
87 if (root == NULL) {
|
meillo@26
|
88 return;
|
meillo@26
|
89 }
|
meillo@33
|
90 printNode(root, level);
|
meillo@33
|
91 printTree(root->down, level+1);
|
meillo@33
|
92 printTree(root->right, level);
|
meillo@0
|
93 }
|
meillo@0
|
94
|
meillo@0
|
95
|
meillo@1
|
96
|
meillo@1
|
97
|
meillo@3
|
98
|
meillo@30
|
99 /* stack for read_input */
|
meillo@9
|
100 void push(struct Node* node) {
|
meillo@10
|
101 struct Stackitem* tmp;
|
meillo@10
|
102 struct Stackitem* new;
|
meillo@10
|
103 new = (struct Stackitem*) malloc(sizeof(struct Stackitem));
|
meillo@9
|
104 new->node = node;
|
meillo@10
|
105 tmp = stack;
|
meillo@10
|
106 stack = new;
|
meillo@10
|
107 stack->next = tmp;
|
meillo@9
|
108 }
|
meillo@9
|
109 struct Node* pull() {
|
meillo@10
|
110 if (stack == NULL) {
|
meillo@9
|
111 return NULL;
|
meillo@9
|
112 }
|
meillo@10
|
113 struct Stackitem* tmp;
|
meillo@9
|
114 struct Node* node;
|
meillo@10
|
115 tmp = stack;
|
meillo@10
|
116 stack = stack->next;
|
meillo@9
|
117 node = tmp->node;
|
meillo@9
|
118 free(tmp); tmp=0;
|
meillo@9
|
119 return node;
|
meillo@9
|
120 }
|
meillo@3
|
121
|
meillo@1
|
122
|
meillo@1
|
123
|
meillo@6
|
124 /* read input */
|
meillo@12
|
125 void read_input(char* filename) {
|
meillo@7
|
126 int c;
|
meillo@8
|
127 int indent;
|
meillo@7
|
128 char name[256];
|
meillo@6
|
129 int value;
|
meillo@9
|
130 int last_indent;
|
meillo@9
|
131 struct Node* last_node;
|
meillo@9
|
132 struct Node* node;
|
meillo@12
|
133 FILE* file;
|
meillo@6
|
134
|
meillo@8
|
135 indent = 0;
|
meillo@8
|
136 strcpy(name, "");
|
meillo@8
|
137 value = 0;
|
meillo@9
|
138 last_indent = -1;
|
meillo@34
|
139 last_node = NULL;
|
meillo@12
|
140 file = fopen(filename, "r");
|
meillo@6
|
141
|
meillo@12
|
142 while ((c = getc(file)) != EOF) {
|
meillo@8
|
143 if (c == '#') { /* comment */
|
meillo@12
|
144 while ((c = getc(file)) != '\n') {
|
meillo@7
|
145 }
|
meillo@7
|
146 }
|
meillo@7
|
147
|
meillo@8
|
148 if (c == ' ' || c == '\t') { /* indent if at start of line */
|
meillo@8
|
149 if (strlen(name) == 0) {
|
meillo@8
|
150 indent++;
|
meillo@8
|
151 }
|
meillo@7
|
152 }
|
meillo@6
|
153
|
meillo@8
|
154 if (c == '\n') { /* end of line: create node */
|
meillo@7
|
155 if (strlen(name) > 0) {
|
meillo@8
|
156 /* create node */
|
meillo@9
|
157 node = newNode((char*) name, value);
|
meillo@9
|
158 if (indent > last_indent) { /* down */
|
meillo@30
|
159 /* if it goes more than one level down -> error */
|
meillo@33
|
160 if (indent > last_indent + 1) {
|
meillo@30
|
161 fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n");
|
meillo@31
|
162 exit(5);
|
meillo@30
|
163 }
|
meillo@34
|
164 if (last_node == NULL) {
|
meillo@34
|
165 root = node;
|
meillo@34
|
166 last_node = root;
|
meillo@34
|
167 } else {
|
meillo@34
|
168 last_node->down = node;
|
meillo@34
|
169 }
|
meillo@9
|
170 push(last_node);
|
meillo@9
|
171 } else if (indent == last_indent) { /* right */
|
meillo@9
|
172 last_node->right = node;
|
meillo@9
|
173 } else if (indent < last_indent) { /* up */
|
meillo@30
|
174 /* handle if it goes more than one level up */
|
meillo@30
|
175 while (indent < last_indent) {
|
meillo@30
|
176 last_node = pull();
|
meillo@30
|
177 last_indent--;
|
meillo@30
|
178 }
|
meillo@9
|
179 last_node->right = node;
|
meillo@9
|
180 }
|
meillo@9
|
181 last_indent = indent;
|
meillo@9
|
182 last_node = node;
|
meillo@6
|
183 }
|
meillo@6
|
184 indent = 0;
|
meillo@6
|
185 strcpy(name, "");
|
meillo@6
|
186 value = 0;
|
meillo@6
|
187 }
|
meillo@7
|
188
|
meillo@8
|
189 if (c >= 'a' && c <= 'z') { /* name */
|
meillo@7
|
190 int i = 1;
|
meillo@7
|
191 name[0] = (char) c;
|
meillo@12
|
192 while ((c = getc(file)) != '(') {
|
meillo@7
|
193 name[i] = (char) c;
|
meillo@7
|
194 i++;
|
meillo@8
|
195 if (i > 255) {
|
meillo@33
|
196 fprintf(stderr, "error: node name too long, or no value given\n");
|
meillo@33
|
197 exit(6);
|
meillo@8
|
198 }
|
meillo@7
|
199 }
|
meillo@7
|
200 name[i] = '\0';
|
meillo@7
|
201 }
|
meillo@7
|
202
|
meillo@8
|
203 if (c == '(') { /* value */
|
meillo@12
|
204 fscanf(file, "%d)", &value);
|
meillo@7
|
205 }
|
meillo@7
|
206
|
meillo@6
|
207 }
|
meillo@7
|
208
|
meillo@30
|
209 /* clear stack */
|
meillo@27
|
210 while (stack != NULL) {
|
meillo@27
|
211 pull();
|
meillo@27
|
212 }
|
meillo@27
|
213
|
meillo@12
|
214 fclose(file);
|
meillo@26
|
215 }
|
meillo@12
|
216
|
meillo@26
|
217
|
meillo@6
|
218
|
meillo@1
|
219 /* main */
|
meillo@0
|
220 int main(int argc, char* argv[]) {
|
meillo@7
|
221 unsigned char shell_return = 0;
|
meillo@38
|
222
|
meillo@38
|
223 option_verbose = 0;
|
meillo@9
|
224
|
meillo@13
|
225 while (--argc > 0 && (*++argv)[0] == '-') {
|
meillo@13
|
226 if (strcmp(argv[0], "--version") == 0) {
|
meillo@26
|
227 printf("\
|
meillo@26
|
228 baum %s\n\
|
meillo@13
|
229 an esoteric programming language\n\
|
meillo@13
|
230 by markus schnalke and julian forster\n\
|
meillo@26
|
231 http://prog.marmaro.de/baum\n\
|
meillo@26
|
232 ", VERSION);
|
meillo@13
|
233 exit(0);
|
meillo@13
|
234 } else if (strcmp(argv[0], "--help") == 0) {
|
meillo@13
|
235 printf("\
|
meillo@13
|
236 baum --version print version information and exit\n\
|
meillo@13
|
237 baum --help print this output\n\
|
meillo@13
|
238 baum [-v] <file> (verbosly) run file\n\
|
meillo@26
|
239 ");
|
meillo@13
|
240 exit(0);
|
meillo@13
|
241 } else if (strcmp(argv[0], "-v") == 0) {
|
meillo@13
|
242 option_verbose = 1;
|
meillo@13
|
243 /*
|
meillo@13
|
244 } else if (strcmp(argv[0], "-W") == 0) {
|
meillo@13
|
245 / * TODO: catch if no value given * /
|
meillo@13
|
246 iDWarn = atoi((++argv)[0]);
|
meillo@13
|
247 argc--;
|
meillo@13
|
248 */
|
meillo@13
|
249 } else {
|
meillo@13
|
250 fprintf(stderr, "unknown option: %s\n", argv[0]);
|
meillo@13
|
251 exit(127);
|
meillo@13
|
252 }
|
meillo@13
|
253 }
|
meillo@13
|
254
|
meillo@13
|
255 if (argc != 1) {
|
meillo@13
|
256 fprintf(stderr, "%d source files given, please specify one.\n", argc);
|
meillo@13
|
257 exit(3);
|
meillo@13
|
258 }
|
meillo@13
|
259
|
meillo@13
|
260 read_input(argv[0]);
|
meillo@13
|
261
|
meillo@13
|
262 if (option_verbose) {
|
meillo@33
|
263 printTree(root, 0);
|
meillo@13
|
264 }
|
meillo@1
|
265
|
meillo@5
|
266 shell_return = action(root);
|
meillo@34
|
267 fflush(stdout);
|
meillo@1
|
268
|
meillo@13
|
269 if (option_verbose) {
|
meillo@33
|
270 printTree(root, 0);
|
meillo@13
|
271 }
|
meillo@13
|
272
|
meillo@9
|
273 delete(root);
|
meillo@5
|
274 exit(shell_return);
|
meillo@0
|
275 }
|