baum

annotate baum.c @ 33:2e564bf8599c

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