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