baum

annotate baum.c @ 61:73de2151aebd

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