diff options
-rw-r--r-- | examples/list-test.fusp | 2 | ||||
-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 |
8 files changed, 95 insertions, 30 deletions
diff --git a/examples/list-test.fusp b/examples/list-test.fusp index e71e07d..d90a252 100644 --- a/examples/list-test.fusp +++ b/examples/list-test.fusp @@ -1,2 +1,4 @@ +import list; + main = flatten [[1:[2:[3:[]]]]:[[4:[5:[6:[]]]]:[]]]; main = append [1:[2:[3:[]]]] [4:[5:[6:[]]]]; 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; |