baum

annotate baum.c @ 24:69a7cf2f0c06

make dist includes now a stripped executable (should we include the exe at all?)
author meillo@marmaro.de
date Wed, 13 Feb 2008 22:04:12 +0100
parents bf660b45bba9
children f0856c177403
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 }