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@2: #include "actions.h" meillo@0: meillo@13: #define VERSION "0.1" meillo@13: meillo@13: int option_check = 0; meillo@13: int option_verbose = 0; meillo@0: meillo@5: struct Node* root = 0; meillo@10: struct Stackitem* stack = NULL; meillo@0: meillo@0: 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@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: void setValue(struct Node* node, unsigned char value) { meillo@3: node->value = value; meillo@3: } meillo@3: meillo@3: meillo@3: struct Node* nextNode(struct Node* node) { meillo@3: return node->right; meillo@3: } 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@1: /* delete */ meillo@1: void delete(struct Node* node) { meillo@5: if (node != NULL) { meillo@5: if (node->down != NULL) { meillo@5: delete(node->down); meillo@5: } meillo@5: if (node->right != NULL) { meillo@5: delete(node->right); meillo@5: } meillo@5: free(node); node=0; meillo@0: } meillo@0: } meillo@0: meillo@1: meillo@1: /* print */ meillo@0: void printNode(struct Node* node) { meillo@5: if (node != NULL) { meillo@9: fprintf(stderr, "Node: %10s (%d|%c)\n", node->name, node->value, node->value); meillo@5: } meillo@0: } meillo@0: meillo@0: void printTree(struct Node* root) { meillo@5: if (root != NULL) { meillo@5: printNode(root); meillo@5: fprintf(stderr, " down: "); meillo@5: if (root->down != NULL) { meillo@5: printTree(root->down); meillo@5: } else { meillo@5: fprintf(stderr, "NULL\n"); meillo@5: } meillo@5: fprintf(stderr, " right: "); meillo@5: if (root->right != NULL) { meillo@5: printTree(root->right); meillo@5: } else { meillo@5: fprintf(stderr, "NULL\n"); meillo@5: } meillo@0: } meillo@0: } meillo@0: meillo@0: meillo@1: meillo@1: /* traverse */ meillo@1: void traverse(struct Node* root) { meillo@1: /* each node controlls the nodes below itself */ meillo@1: action(root); meillo@1: } meillo@1: meillo@3: meillo@3: meillo@3: 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@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@9: root = newNode("blackhole", 0); meillo@9: last_node = root; meillo@12: file = fopen(filename, "r"); meillo@6: meillo@12: while ((c = getc(file)) != EOF) { meillo@8: 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@13: if (option_verbose) { meillo@13: fprintf(stderr, " %d - %s - %d\n", indent, name, value); meillo@13: } meillo@8: /* create node */ meillo@9: node = newNode((char*) name, value); meillo@9: if (indent > last_indent) { /* down */ meillo@9: last_node->down = node; 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@9: /* FIXME what if it goes more than one level up? */ meillo@9: last_node = pull(); 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@8: break; 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@12: fclose(file); meillo@12: meillo@6: } meillo@6: meillo@1: /* main */ meillo@0: int main(int argc, char* argv[]) { meillo@7: unsigned char shell_return = 0; meillo@9: meillo@13: while (--argc > 0 && (*++argv)[0] == '-') { meillo@13: if (strcmp(argv[0], "--version") == 0) { meillo@13: printf("baum %s\n\ meillo@13: an esoteric programming language\n\ meillo@13: by markus schnalke and julian forster\n\ meillo@13: http://prog.marmaro.de/baum\n", VERSION); meillo@13: exit(0); meillo@13: } else if (strcmp(argv[0], "--help") == 0) { meillo@13: printf("\ meillo@13: baum --version print version information and exit\n\ meillo@13: baum --help print this output\n\ meillo@13: baum [-v] -c (verbosly) check file and return 1 if invalid\n\ meillo@13: baum [-v] (verbosly) run file\n\ meillo@13: "); meillo@13: exit(0); meillo@13: } else if (strcmp(argv[0], "-c") == 0) { meillo@13: option_check = 1; 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@13: exit(127); 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@13: printTree(root); meillo@13: } meillo@1: meillo@5: shell_return = action(root); meillo@1: meillo@13: if (option_verbose) { meillo@13: printTree(root); meillo@13: } meillo@13: meillo@9: delete(root); meillo@5: exit(shell_return); meillo@0: }