baum

annotate baum.c @ 30:cd979b979610

fixed multiple (un)indentions in read_input; some better comments
author meillo@marmaro.de
date Fri, 22 Feb 2008 14:47:47 +0100
parents 88a51653db83
children 4e60d96265f0
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@29 17 #define VERSION "0.2"
meillo@13 18
meillo@30 19
meillo@13 20 int option_check = 0;
meillo@13 21 int option_verbose = 0;
meillo@0 22
meillo@5 23 struct Node* root = 0;
meillo@10 24 struct Stackitem* stack = NULL;
meillo@0 25
meillo@0 26
meillo@26 27 void printNode(struct Node* node);
meillo@26 28 void printTree(struct Node* root);
meillo@26 29 struct Node* lastNode(struct Node* node);
meillo@26 30 void delete(struct Node* node);
meillo@26 31
meillo@26 32
meillo@26 33
meillo@1 34 void logit(char* text) {
meillo@13 35 if (option_verbose) {
meillo@13 36 fprintf(stderr, "[%s]\n", text);
meillo@13 37 }
meillo@1 38 }
meillo@1 39
meillo@1 40
meillo@1 41 /* new */
meillo@3 42 struct Node* newNode(char* name, unsigned char value) {
meillo@0 43 struct Node* node;
meillo@0 44 node = (struct Node*) malloc(sizeof(struct Node));
meillo@9 45 strcpy(node->name, name);
meillo@3 46 node->value = value;
meillo@0 47 node->right = 0;
meillo@0 48 node->down = 0;
meillo@0 49 return node;
meillo@0 50 }
meillo@0 51
meillo@0 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@26 67
meillo@1 68 /* delete */
meillo@1 69 void delete(struct Node* node) {
meillo@26 70 if (node == NULL) {
meillo@26 71 return;
meillo@0 72 }
meillo@26 73 if (node->down != NULL) {
meillo@26 74 delete(node->down);
meillo@26 75 }
meillo@26 76 if (node->right != NULL) {
meillo@26 77 delete(node->right);
meillo@26 78 }
meillo@26 79 free(node); node=0;
meillo@0 80 }
meillo@0 81
meillo@1 82
meillo@1 83 /* print */
meillo@0 84 void printNode(struct Node* node) {
meillo@5 85 if (node != NULL) {
meillo@9 86 fprintf(stderr, "Node: %10s (%d|%c)\n", node->name, node->value, node->value);
meillo@5 87 }
meillo@0 88 }
meillo@0 89
meillo@0 90 void printTree(struct Node* root) {
meillo@26 91 if (root == NULL) {
meillo@26 92 return;
meillo@26 93 }
meillo@26 94
meillo@26 95 printNode(root);
meillo@26 96 fprintf(stderr, " down: ");
meillo@26 97 if (root->down != NULL) {
meillo@26 98 printTree(root->down);
meillo@26 99 } else {
meillo@26 100 fprintf(stderr, "NULL\n");
meillo@26 101 }
meillo@26 102 fprintf(stderr, " right: ");
meillo@26 103 if (root->right != NULL) {
meillo@26 104 printTree(root->right);
meillo@26 105 } else {
meillo@26 106 fprintf(stderr, "NULL\n");
meillo@0 107 }
meillo@0 108 }
meillo@0 109
meillo@0 110
meillo@1 111
meillo@1 112
meillo@3 113
meillo@30 114 /* stack for read_input */
meillo@9 115 void push(struct Node* node) {
meillo@10 116 struct Stackitem* tmp;
meillo@10 117 struct Stackitem* new;
meillo@10 118 new = (struct Stackitem*) malloc(sizeof(struct Stackitem));
meillo@9 119 new->node = node;
meillo@10 120 tmp = stack;
meillo@10 121 stack = new;
meillo@10 122 stack->next = tmp;
meillo@9 123 }
meillo@9 124 struct Node* pull() {
meillo@10 125 if (stack == NULL) {
meillo@9 126 return NULL;
meillo@9 127 }
meillo@10 128 struct Stackitem* tmp;
meillo@9 129 struct Node* node;
meillo@10 130 tmp = stack;
meillo@10 131 stack = stack->next;
meillo@9 132 node = tmp->node;
meillo@9 133 free(tmp); tmp=0;
meillo@9 134 return node;
meillo@9 135 }
meillo@3 136
meillo@1 137
meillo@1 138
meillo@6 139 /* read input */
meillo@12 140 void read_input(char* filename) {
meillo@7 141 int c;
meillo@8 142 int indent;
meillo@7 143 char name[256];
meillo@6 144 int value;
meillo@9 145 int last_indent;
meillo@9 146 struct Node* last_node;
meillo@9 147 struct Node* node;
meillo@12 148 FILE* file;
meillo@6 149
meillo@8 150 indent = 0;
meillo@8 151 strcpy(name, "");
meillo@8 152 value = 0;
meillo@9 153 last_indent = -1;
meillo@9 154 root = newNode("blackhole", 0);
meillo@9 155 last_node = root;
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@13 172 if (option_verbose) {
meillo@13 173 fprintf(stderr, " %d - %s - %d\n", indent, name, value);
meillo@13 174 }
meillo@8 175 /* create node */
meillo@9 176 node = newNode((char*) name, value);
meillo@9 177 if (indent > last_indent) { /* down */
meillo@30 178 /* if it goes more than one level down -> error */
meillo@30 179 if (indent - last_indent > 1) {
meillo@30 180 fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n");
meillo@30 181 exit(50);
meillo@30 182 }
meillo@9 183 last_node->down = node;
meillo@9 184 push(last_node);
meillo@9 185 } else if (indent == last_indent) { /* right */
meillo@9 186 last_node->right = node;
meillo@9 187 } else if (indent < last_indent) { /* up */
meillo@30 188 /* handle if it goes more than one level up */
meillo@30 189 while (indent < last_indent) {
meillo@30 190 last_node = pull();
meillo@30 191 last_indent--;
meillo@30 192 }
meillo@9 193 last_node->right = node;
meillo@9 194 }
meillo@9 195 last_indent = indent;
meillo@9 196 last_node = node;
meillo@6 197 }
meillo@6 198 indent = 0;
meillo@6 199 strcpy(name, "");
meillo@6 200 value = 0;
meillo@6 201 }
meillo@7 202
meillo@8 203 if (c >= 'a' && c <= 'z') { /* name */
meillo@7 204 int i = 1;
meillo@7 205 name[0] = (char) c;
meillo@12 206 while ((c = getc(file)) != '(') {
meillo@7 207 name[i] = (char) c;
meillo@7 208 i++;
meillo@8 209 if (i > 255) {
meillo@8 210 break;
meillo@8 211 }
meillo@7 212 }
meillo@7 213 name[i] = '\0';
meillo@7 214 }
meillo@7 215
meillo@8 216 if (c == '(') { /* value */
meillo@12 217 fscanf(file, "%d)", &value);
meillo@7 218 }
meillo@7 219
meillo@6 220 }
meillo@7 221
meillo@30 222 /* clear stack */
meillo@27 223 while (stack != NULL) {
meillo@27 224 pull();
meillo@27 225 }
meillo@27 226
meillo@12 227 fclose(file);
meillo@26 228 }
meillo@12 229
meillo@26 230
meillo@6 231
meillo@1 232 /* main */
meillo@0 233 int main(int argc, char* argv[]) {
meillo@7 234 unsigned char shell_return = 0;
meillo@9 235
meillo@13 236 while (--argc > 0 && (*++argv)[0] == '-') {
meillo@13 237 if (strcmp(argv[0], "--version") == 0) {
meillo@26 238 printf("\
meillo@26 239 baum %s\n\
meillo@13 240 an esoteric programming language\n\
meillo@13 241 by markus schnalke and julian forster\n\
meillo@26 242 http://prog.marmaro.de/baum\n\
meillo@26 243 ", VERSION);
meillo@13 244 exit(0);
meillo@13 245 } else if (strcmp(argv[0], "--help") == 0) {
meillo@13 246 printf("\
meillo@13 247 baum --version print version information and exit\n\
meillo@13 248 baum --help print this output\n\
meillo@13 249 baum [-v] -c <file> (verbosly) check file and return 1 if invalid\n\
meillo@13 250 baum [-v] <file> (verbosly) run file\n\
meillo@26 251 ");
meillo@13 252 exit(0);
meillo@13 253 } else if (strcmp(argv[0], "-c") == 0) {
meillo@13 254 option_check = 1;
meillo@13 255 } else if (strcmp(argv[0], "-v") == 0) {
meillo@13 256 option_verbose = 1;
meillo@13 257 /*
meillo@13 258 } else if (strcmp(argv[0], "-W") == 0) {
meillo@13 259 / * TODO: catch if no value given * /
meillo@13 260 iDWarn = atoi((++argv)[0]);
meillo@13 261 argc--;
meillo@13 262 */
meillo@13 263 } else {
meillo@13 264 fprintf(stderr, "unknown option: %s\n", argv[0]);
meillo@13 265 exit(127);
meillo@13 266 }
meillo@13 267 }
meillo@13 268
meillo@13 269 if (argc != 1) {
meillo@13 270 fprintf(stderr, "%d source files given, please specify one.\n", argc);
meillo@13 271 exit(3);
meillo@13 272 }
meillo@13 273
meillo@13 274 read_input(argv[0]);
meillo@13 275
meillo@13 276 if (option_verbose) {
meillo@13 277 printTree(root);
meillo@13 278 }
meillo@1 279
meillo@5 280 shell_return = action(root);
meillo@1 281
meillo@13 282 if (option_verbose) {
meillo@13 283 printTree(root);
meillo@13 284 }
meillo@13 285
meillo@9 286 delete(root);
meillo@5 287 exit(shell_return);
meillo@0 288 }