baum

annotate baum.c @ 47:c31b5bb6d493

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