view baum.c @ 23:a58214424c43

added TODO
author meillo@marmaro.de
date Wed, 13 Feb 2008 21:58:56 +0100
parents e2048e569891
children f0856c177403
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.1"

int option_check = 0;
int option_verbose = 0;

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;
}


void setValue(struct Node* node, unsigned char value) {
	node->value = value;
}


struct Node* nextNode(struct Node* node) {
	return node->right;
}

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) {
		if (node->down != NULL) {
			delete(node->down);
		}
		if (node->right != NULL) {
			delete(node->right);
		}
		free(node); node=0;
	}
}


/* print */
void printNode(struct Node* node) {
	if (node != NULL) {
		fprintf(stderr, "Node: %10s (%d|%c)\n", node->name, node->value, node->value);
	}
}

void printTree(struct Node* root) {
	if (root != NULL) {
		printNode(root);
		fprintf(stderr, "  down: ");
		if (root->down != NULL) {
			printTree(root->down);
		} else {
			fprintf(stderr, "NULL\n");
		}
		fprintf(stderr, "  right: ");
		if (root->right != NULL) {
			printTree(root->right);
		} else {
			fprintf(stderr, "NULL\n");
		}
	}
}



/* traverse */
void traverse(struct Node* root) {
	/* each node controlls the nodes below itself */
	action(root);
}




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;
	root = newNode("blackhole", 0);
	last_node = root;
	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) {
				if (option_verbose) {
					fprintf(stderr, " %d - %s - %d\n", indent, name, value);
				}
				/* create node */
				node = newNode((char*) name, value);
				if (indent > last_indent) { /* down */
					last_node->down = node;
					push(last_node);
				} else if (indent == last_indent) { /* right */
					last_node->right = node;
				} else if (indent < last_indent) { /* up */
					/* FIXME what if it goes more than one level up? */
					last_node = pull();
					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) {
					break;
				}
			}
			name[i] = '\0';
		}

		if (c == '(') {  /* value */
			fscanf(file, "%d)", &value);
		}

	}

	fclose(file);

}

/* main */
int main(int argc, char* argv[]) {
	unsigned char shell_return = 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] -c <file>   (verbosly) check file and return 1 if invalid\n\
baum [-v] <file>      (verbosly) run file\n\
					");
			exit(0);
		} else if (strcmp(argv[0], "-c") == 0) {
			option_check = 1;
		} 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(127);
		}
	}

	if (argc != 1) {
		fprintf(stderr, "%d source files given, please specify one.\n", argc);
		exit(3);
	}

	read_input(argv[0]);

	if (option_verbose) {
		printTree(root);
	}

	shell_return = action(root);

	if (option_verbose) {
		printTree(root);
	}

	delete(root);
	exit(shell_return);
}