diff options
Diffstat (limited to 'interpreter')
| -rw-r--r-- | interpreter/fuspel.c | 52 | ||||
| -rw-r--r-- | interpreter/fuspel.h | 6 | ||||
| -rw-r--r-- | interpreter/lex.c | 27 | ||||
| -rw-r--r-- | interpreter/parse.c | 28 | ||||
| -rw-r--r-- | interpreter/print.c | 5 | ||||
| -rw-r--r-- | interpreter/syntax.c | 4 | ||||
| -rw-r--r-- | interpreter/syntax.h | 1 | 
7 files changed, 93 insertions, 30 deletions
| diff --git a/interpreter/fuspel.c b/interpreter/fuspel.c index 0e1d82b..10319d0 100644 --- a/interpreter/fuspel.c +++ b/interpreter/fuspel.c @@ -7,17 +7,30 @@  #include "parse.h"  #include "print.h" -int main(void) { -	token_list* tokens; +#define LINE_LENGTH 139 + +fuspel* parse_file(fuspel* already_parsed, char* fname) { +	token_list* tokens = NULL;  	fuspel* pgm; -	expression* result; +	FILE* f; +	char* fname_; + +	fname_ = my_calloc(1, strlen(fname) + 6); +	strcpy(fname_, fname); +	strcat(fname_, ".fusp"); + +	f = fopen(fname_, "r"); +	if (!f) { +		fprintf(stderr, "Couldn't read %s\n", fname_); +		exit(EXIT_FAILURE); +	} -	tokens = NULL; +	printf("Lexing %s...\n", fname_); -	while (!feof(stdin)) { -		char program[79]; -		if (!fgets(program, 79, stdin)) { -			if (feof(stdin)) +	while (!feof(f)) { +		char program[LINE_LENGTH]; +		if (!fgets(program, LINE_LENGTH, f)) { +			if (feof(f))  				break;  			fprintf(stderr, "Couldn't read input.\n");  			exit(EXIT_FAILURE); @@ -29,10 +42,31 @@ int main(void) {  			exit(EXIT_FAILURE);  		}  	} -	 + +	printf("Parsing %s...\n", fname_); +  	pgm = parse(tokens);  	free_token_list(tokens);  	my_free(tokens); + +	concat_fuspel(pgm, already_parsed); + +	return pgm; +} + +int main(int argc, char* argv[]) { +	expression* result; +	fuspel* pgm = NULL; +	int i; + +	if (argc < 2) { +		fprintf(stderr, "Usage: %s file [file [file [..]]]\n", argv[0]); +		exit(EXIT_FAILURE); +	} + +	for (i = 1; i < argc; i++) { +		pgm = parse_file(pgm, argv[i]); +	}  	if (!pgm) {  		fprintf(stderr, "Couldn't parse program.\n"); diff --git a/interpreter/fuspel.h b/interpreter/fuspel.h new file mode 100644 index 0000000..fea191d --- /dev/null +++ b/interpreter/fuspel.h @@ -0,0 +1,6 @@ +#ifndef _H_FUSPEL +#define _H_FUSPEL + +fuspel* parse_file(fuspel* already_parsed, char* fname); + +#endif diff --git a/interpreter/lex.c b/interpreter/lex.c index 0d93bea..180c23e 100644 --- a/interpreter/lex.c +++ b/interpreter/lex.c @@ -34,9 +34,11 @@ unsigned char lex_name_length(char* input) {  token_list* lex(token_list* list, char* input) {  	token_list* first_list; +	unsigned create_new_token; -	if (input[0] == 0) { -		return NULL; +	while (*input && is_space_char(*input)) input++; +	if (*input == 0) { +		return list;  	}  	if (list) { @@ -48,9 +50,9 @@ token_list* lex(token_list* list, char* input) {  		first_list = list = my_calloc(1, sizeof(token_list));  	} -	while (*input) { -		unsigned create_new_token = 1; +	create_new_token = 1; +	while (*input) {  		list->elem.var = NULL;  		switch (*input) { @@ -63,15 +65,20 @@ token_list* lex(token_list* list, char* input) {  			case '=': list->elem.kind = TOKEN_EQUALS;    break;  			case ',': list->elem.kind = TOKEN_COMMA;     break;  			case '!': list->elem.kind = TOKEN_STRICT;    break; -			case 'c': -				if (input[1] == 'o' && input[2] == 'd' && input[3] == 'e' && -						is_space_char(input[4])) { +			default: +				if (input[0] == 'c' && input[1] == 'o' && input[2] == 'd' && +						input[3] == 'e' && is_space_char(input[4])) {  					list->elem.kind = TOKEN_CODE;  					input += 4;  					break;  				} -	 -			default: +				if (input[0] == 'i' && input[1] == 'm' && input[2] == 'p' && +						input[3] == 'o' && input[4] == 'r' && +						input[5] == 't' && is_space_char(input[6])) { +					list->elem.kind = TOKEN_IMPORT; +					input += 6; +					break; +				}  				if (is_int_char(*input)) {  					char* s;  					unsigned char len = lex_int_length(input); @@ -97,7 +104,7 @@ token_list* lex(token_list* list, char* input) {  				}  		} -		input++; +		do input++; while (*input && is_space_char(*input));  		if (*input && create_new_token) {  			list->rest = my_calloc(1, sizeof(token_list)); diff --git a/interpreter/parse.c b/interpreter/parse.c index 77ce731..f751321 100644 --- a/interpreter/parse.c +++ b/interpreter/parse.c @@ -3,6 +3,7 @@  #include <string.h>  #include "code.h" +#include "fuspel.h"  #include "log.h"  #include "mem.h" @@ -251,7 +252,8 @@ token_list* parse_rule(rewrite_rule* rule, token_list* list) {  }  fuspel* parse(token_list* list) { -	fuspel* rules; +	fuspel* rules = NULL; +	fuspel* return_rules;  	while (list && list->elem.kind == TOKEN_SEMICOLON)  		list = list->rest; @@ -259,13 +261,27 @@ fuspel* parse(token_list* list) {  	if (!list)  		return NULL; -	rules = my_calloc(1, sizeof(fuspel)); +	if (list->elem.kind == TOKEN_IMPORT) { +		list = list->rest; +		if (!list || list->elem.kind != TOKEN_NAME) +			return NULL; +		rules = parse_file(rules, list->elem.var); +		if (!rules) +			return NULL; -	list = parse_rule(&rules->rule, list); -	if (!list) -		return NULL; +		list = list->rest->rest; + +		return_rules = rules; +		while (rules->rest) rules = rules->rest; +	} else { +		return_rules = rules = my_calloc(1, sizeof(fuspel)); + +		list = parse_rule(&rules->rule, list); +		if (!list) +			return NULL; +	}  	rules->rest = parse(list); -	return rules; +	return return_rules;  } diff --git a/interpreter/print.c b/interpreter/print.c index 3f17475..d700101 100644 --- a/interpreter/print.c +++ b/interpreter/print.c @@ -16,9 +16,8 @@ void print_token(token* tk) {  		case TOKEN_EQUALS:    c = '='; break;  		case TOKEN_COMMA:     c = ','; break;  		case TOKEN_STRICT:    c = '!'; break; -		case TOKEN_CODE: -			printf("code "); -			return; +		case TOKEN_CODE:      printf("code "); return; +		case TOKEN_IMPORT:    printf("import "); return;  		case TOKEN_NAME:  			printf("%s", (char*) tk->var);  			return; diff --git a/interpreter/syntax.c b/interpreter/syntax.c index 6c6367f..b8ba0d2 100644 --- a/interpreter/syntax.c +++ b/interpreter/syntax.c @@ -109,13 +109,13 @@ expression** flatten_app_args(expression* from) {  }  void concat_fuspel(fuspel* start, fuspel* end) { -	do { +	while (start) {  		if (!start->rest) {  			start->rest = end;  			return;  		}  		start = start->rest; -	} while (start); +	}  }  fuspel* push_fuspel(fuspel* rules) { diff --git a/interpreter/syntax.h b/interpreter/syntax.h index e2accd4..b9f2a8a 100644 --- a/interpreter/syntax.h +++ b/interpreter/syntax.h @@ -14,6 +14,7 @@ typedef enum {  	TOKEN_COLON,     /* : */  	TOKEN_STRICT,    /* ! */  	TOKEN_CODE,      /* code */ +	TOKEN_IMPORT,    /* import */  	TOKEN_NAME,  	TOKEN_INT  } token_kind; | 
