baum

annotate baum.c @ 41:1ad3d7305e5d

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