Mercurial > baum
view baum.c @ 43:c7dca4a1dc37
added test programs; added another example program
author | meillo@marmaro.de |
---|---|
date | Sat, 01 Mar 2008 21:13:12 +0100 |
parents | 233ac9bea4f1 |
children | 0b82169d4129 |
line wrap: on
line source
/* * baum - an esoteric programming language * * (c) markus schnalke <meillo@marmaro.de> * and julian forster * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "baum.h" #include "actions.h" #define VERSION "0.3" void printNode(struct Node* node, int level); void printTree(struct Node* root, int level); struct Node* lastNode(struct Node* node); void delete(struct Node* node); struct Stackitem { struct Node* node; struct Stackitem* next; }; struct Node* root = 0; struct Stackitem* stack = NULL; void logit(char* text) { if (option_verbose) { fprintf(stderr, "[%s]\n", text); } } /* new */ struct Node* newNode(char* name, unsigned char value) { struct Node* node; node = (struct Node*) malloc(sizeof(struct Node)); strcpy(node->name, name); node->value = value; node->right = 0; node->down = 0; return node; } struct Node* lastNode(struct Node* node) { while (node->right != NULL) { node = node->right; } return node; } struct Node* insertLast(struct Node* node, struct Node* insert) { node = lastNode(node); node->right = insert; return insert; } /* delete */ void delete(struct Node* node) { if (node == NULL) { return; } delete(node->down); delete(node->right); free(node); node=0; } /* print */ void printNode(struct Node* node, int level) { if (node != NULL) { while (level-- > 0) { fprintf(stderr, "\t"); } fprintf(stderr, "%s (%d|%c)\n", node->name, node->value, node->value); } } void printTree(struct Node* root, int level) { if (root == NULL) { return; } printNode(root, level); printTree(root->down, level+1); printTree(root->right, level); } /* stack for read_input */ void push(struct Node* node) { struct Stackitem* tmp; struct Stackitem* new; new = (struct Stackitem*) malloc(sizeof(struct Stackitem)); new->node = node; tmp = stack; stack = new; stack->next = tmp; } struct Node* pull() { if (stack == NULL) { return NULL; } struct Stackitem* tmp; struct Node* node; tmp = stack; stack = stack->next; node = tmp->node; free(tmp); tmp=0; return node; } /* read input */ void read_input(char* filename) { int c; int indent; char name[256]; int value; int last_indent; struct Node* last_node; struct Node* node; FILE* file; indent = 0; strcpy(name, ""); value = 0; last_indent = -1; last_node = NULL; file = fopen(filename, "r"); while ((c = getc(file)) != EOF) { if (c == '#') { /* comment */ while ((c = getc(file)) != '\n') { } } if (c == ' ' || c == '\t') { /* indent if at start of line */ if (strlen(name) == 0) { indent++; } } if (c == '\n') { /* end of line: create node */ if (strlen(name) > 0) { /* create node */ node = newNode((char*) name, value); if (indent > last_indent) { /* down */ /* if it goes more than one level down -> error */ if (indent > last_indent + 1) { fprintf(stderr, "error: Indention over more than one level. Only indent by one!\n"); exit(5); } if (last_node == NULL) { root = node; last_node = root; } else { last_node->down = node; } push(last_node); } else if (indent == last_indent) { /* right */ last_node->right = node; } else if (indent < last_indent) { /* up */ /* handle if it goes more than one level up */ while (indent < last_indent) { last_node = pull(); last_indent--; } last_node->right = node; } last_indent = indent; last_node = node; } indent = 0; strcpy(name, ""); value = 0; } if (c >= 'a' && c <= 'z') { /* name */ int i = 1; name[0] = (char) c; while ((c = getc(file)) != '(') { name[i] = (char) c; i++; if (i > 255) { fprintf(stderr, "error: node name too long, or no value given\n"); exit(6); } } name[i] = '\0'; } if (c == '(') { /* value */ fscanf(file, "%d)", &value); } } /* clear stack */ while (stack != NULL) { pull(); } fclose(file); } /* main */ int main(int argc, char* argv[]) { unsigned char shell_return = 0; option_verbose = 0; while (--argc > 0 && (*++argv)[0] == '-') { if (strcmp(argv[0], "--version") == 0) { printf("\ baum %s\n\ an esoteric programming language\n\ by markus schnalke and julian forster\n\ http://prog.marmaro.de/baum\n\ ", VERSION); exit(0); } else if (strcmp(argv[0], "--help") == 0) { printf("\ baum --version print version information and exit\n\ baum --help print this output\n\ baum [-v] <file> (verbosly) run file\n\ "); exit(0); } else if (strcmp(argv[0], "-v") == 0) { option_verbose = 1; /* } else if (strcmp(argv[0], "-W") == 0) { / * TODO: catch if no value given * / iDWarn = atoi((++argv)[0]); argc--; */ } else { fprintf(stderr, "unknown option: %s\n", argv[0]); exit(126); } } if (argc != 1) { fprintf(stderr, "%d source files given, please specify one.\n", argc); exit(3); } read_input(argv[0]); if (option_verbose) { fprintf(stderr, "\n\ntree read from input\n(should be the same without comments and empty lines)\n\n"); printTree(root, 0); } shell_return = action(root); fflush(stdout); if (option_verbose) { fprintf(stderr, "\n\ntree after execution of the program\n\n"); printTree(root, 0); } delete(root); exit(shell_return); }