meillo@0: /* meillo@0: * baum - an esoteric programming language meillo@0: * meillo@0: * (c) markus schnalke meillo@0: * and julian forster meillo@0: * meillo@0: */ meillo@0: meillo@0: meillo@0: #include meillo@0: #include meillo@1: #include meillo@0: meillo@1: #include "baum.h" meillo@0: meillo@54: #define VERSION "0.4" meillo@13: meillo@30: meillo@33: void printNode(struct Node* node, int level); meillo@33: void printTree(struct Node* root, int level); meillo@26: struct Node* lastNode(struct Node* node); meillo@26: void delete(struct Node* node); meillo@26: meillo@26: meillo@41: struct Stackitem { meillo@41: struct Node* node; meillo@41: struct Stackitem* next; meillo@41: }; meillo@41: meillo@41: meillo@41: meillo@41: struct Node* root = 0; meillo@41: struct Stackitem* stack = NULL; meillo@41: meillo@26: meillo@1: void logit(char* text) { meillo@13: if (option_verbose) { meillo@13: fprintf(stderr, "[%s]\n", text); meillo@13: } meillo@1: } meillo@1: meillo@1: meillo@1: /* new */ meillo@3: struct Node* newNode(char* name, unsigned char value) { meillo@0: struct Node* node; meillo@0: node = (struct Node*) malloc(sizeof(struct Node)); meillo@55: if (node == NULL) { meillo@55: perror("unable to allocate memory"); meillo@55: exit(10); meillo@55: } meillo@9: strcpy(node->name, name); meillo@3: node->value = value; meillo@0: node->right = 0; meillo@0: node->down = 0; meillo@0: return node; meillo@0: } meillo@0: meillo@0: meillo@3: meillo@3: struct Node* lastNode(struct Node* node) { meillo@3: while (node->right != NULL) { meillo@3: node = node->right; meillo@3: } meillo@3: return node; meillo@3: } meillo@3: meillo@15: struct Node* insertLast(struct Node* node, struct Node* insert) { meillo@3: node = lastNode(node); meillo@3: node->right = insert; meillo@15: return insert; meillo@3: } meillo@3: meillo@46: struct Node* copyTree(struct Node* node) { meillo@46: if (node == NULL) { meillo@46: return NULL; meillo@46: } meillo@46: struct Node* tmp; meillo@46: tmp = newNode(node->name, node->value); meillo@46: tmp->down = copyTree(node->down); meillo@46: tmp->right = copyTree(node->right); meillo@46: return tmp; meillo@46: } meillo@46: meillo@26: meillo@1: /* delete */ meillo@1: void delete(struct Node* node) { meillo@26: if (node == NULL) { meillo@26: return; meillo@0: } meillo@33: delete(node->down); meillo@33: delete(node->right); meillo@26: free(node); node=0; meillo@0: } meillo@0: meillo@1: meillo@1: /* print */ meillo@33: void printNode(struct Node* node, int level) { meillo@55: if (node == NULL) { meillo@55: return; meillo@5: } meillo@55: while (level-- > 0) { meillo@55: fprintf(stderr, "\t"); meillo@55: } meillo@55: fprintf(stderr, "%s (%d|%c)\n", node->name, node->value, node->value); meillo@0: } meillo@0: meillo@33: void printTree(struct Node* root, int level) { meillo@26: if (root == NULL) { meillo@26: return; meillo@26: } meillo@33: printNode(root, level); meillo@33: printTree(root->down, level+1); meillo@33: printTree(root->right, level); meillo@0: } meillo@0: meillo@0: meillo@1: meillo@1: meillo@3: meillo@30: /* stack for read_input */ meillo@9: void push(struct Node* node) { meillo@10: struct Stackitem* tmp; meillo@10: struct Stackitem* new; meillo@10: new = (struct Stackitem*) malloc(sizeof(struct Stackitem)); meillo@55: if (new == NULL) { meillo@55: perror("unable to allocate memory"); meillo@55: exit(10); meillo@55: } meillo@9: new->node = node; meillo@10: tmp = stack; meillo@10: stack = new; meillo@10: stack->next = tmp; meillo@9: } meillo@9: struct Node* pull() { meillo@10: if (stack == NULL) { meillo@9: return NULL; meillo@9: } meillo@10: struct Stackitem* tmp; meillo@9: struct Node* node; meillo@10: tmp = stack; meillo@10: stack = stack->next; meillo@9: node = tmp->node; meillo@9: free(tmp); tmp=0; meillo@9: return node; meillo@9: } meillo@3: meillo@1: meillo@1: meillo@6: /* read input */ meillo@12: void read_input(char* filename) { meillo@7: int c; meillo@8: int indent; meillo@7: char name[256]; meillo@6: int value; meillo@9: int last_indent; meillo@9: struct Node* last_node; meillo@9: struct Node* node; meillo@12: FILE* file; meillo@6: meillo@8: indent = 0; meillo@8: strcpy(name, ""); meillo@8: value = 0; meillo@9: last_indent = -1; meillo@34: last_node = NULL; meillo@12: file = fopen(filename, "r"); meillo@55: if (file == NULL) { meillo@55: perror("unable to open file"); meillo@55: exit(10); meillo@55: } meillo@6: meillo@12: while ((c = getc(file)) != EOF) { meillo@55: if (c == '#') { /* comment */ meillo@12: while ((c = getc(file)) != '\n') { meillo@7: } meillo@7: } meillo@7: meillo@8: if (c == ' ' || c == '\t') { /* indent if at start of line */ meillo@8: if (strlen(name) == 0) { meillo@8: indent++; meillo@8: } meillo@7: } meillo@6: meillo@8: if (c == '\n') { /* end of line: create node */ meillo@7: if (strlen(name) > 0) { meillo@8: /* create node */ meillo@9: node = newNode((char*) name, value); meillo@9: if (indent > last_indent) { /* down */ meillo@30: /* if it goes more than one level down -> error */ meillo@33: if (indent > last_indent + 1) { meillo@30: fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n"); meillo@31: exit(5); meillo@30: } meillo@34: if (last_node == NULL) { meillo@34: root = node; meillo@34: last_node = root; meillo@34: } else { meillo@34: last_node->down = node; meillo@34: } meillo@9: push(last_node); meillo@9: } else if (indent == last_indent) { /* right */ meillo@9: last_node->right = node; meillo@9: } else if (indent < last_indent) { /* up */ meillo@30: /* handle if it goes more than one level up */ meillo@30: while (indent < last_indent) { meillo@30: last_node = pull(); meillo@30: last_indent--; meillo@30: } meillo@9: last_node->right = node; meillo@9: } meillo@9: last_indent = indent; meillo@9: last_node = node; meillo@6: } meillo@6: indent = 0; meillo@6: strcpy(name, ""); meillo@6: value = 0; meillo@6: } meillo@7: meillo@8: if (c >= 'a' && c <= 'z') { /* name */ meillo@7: int i = 1; meillo@7: name[0] = (char) c; meillo@12: while ((c = getc(file)) != '(') { meillo@7: name[i] = (char) c; meillo@7: i++; meillo@8: if (i > 255) { meillo@33: fprintf(stderr, "error: node name too long, or no value given\n"); meillo@33: exit(6); meillo@8: } meillo@7: } meillo@7: name[i] = '\0'; meillo@7: } meillo@7: meillo@8: if (c == '(') { /* value */ meillo@12: fscanf(file, "%d)", &value); meillo@7: } meillo@7: meillo@6: } meillo@7: meillo@30: /* clear stack */ meillo@27: while (stack != NULL) { meillo@27: pull(); meillo@27: } meillo@27: meillo@12: fclose(file); meillo@26: } meillo@12: meillo@26: meillo@6: meillo@1: /* main */ meillo@0: int main(int argc, char* argv[]) { meillo@7: unsigned char shell_return = 0; meillo@38: meillo@38: option_verbose = 0; meillo@9: meillo@13: while (--argc > 0 && (*++argv)[0] == '-') { meillo@13: if (strcmp(argv[0], "--version") == 0) { meillo@61: printf("baum %s\n" meillo@61: "an esoteric programming language\n" meillo@61: "by markus schnalke and julian forster\n" meillo@61: "http://prog.marmaro.de/baum\n", VERSION); meillo@13: exit(0); meillo@13: } else if (strcmp(argv[0], "--help") == 0) { meillo@61: printf("baum --version print version information and exit\n" meillo@61: "baum --help print this output\n" meillo@61: "baum [-v] (verbosly) run file\n"); meillo@13: exit(0); meillo@13: } else if (strcmp(argv[0], "-v") == 0) { meillo@13: option_verbose = 1; meillo@13: /* meillo@13: } else if (strcmp(argv[0], "-W") == 0) { meillo@13: / * TODO: catch if no value given * / meillo@13: iDWarn = atoi((++argv)[0]); meillo@13: argc--; meillo@13: */ meillo@13: } else { meillo@13: fprintf(stderr, "unknown option: %s\n", argv[0]); meillo@42: exit(126); meillo@13: } meillo@13: } meillo@13: meillo@13: if (argc != 1) { meillo@13: fprintf(stderr, "%d source files given, please specify one.\n", argc); meillo@13: exit(3); meillo@13: } meillo@13: meillo@13: read_input(argv[0]); meillo@13: meillo@13: if (option_verbose) { meillo@53: fprintf(stderr, "\n\ntree read from input:\n"); meillo@53: printTree(root, 1); meillo@13: } meillo@1: meillo@5: shell_return = action(root); meillo@34: fflush(stdout); meillo@1: meillo@13: if (option_verbose) { meillo@53: fprintf(stderr, "\n\nmodified tree after execution:\n"); meillo@53: printTree(root, 1); meillo@13: } meillo@13: meillo@9: delete(root); meillo@5: exit(shell_return); meillo@0: }