aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/list-test.fusp2
-rw-r--r--interpreter/fuspel.c52
-rw-r--r--interpreter/fuspel.h6
-rw-r--r--interpreter/lex.c27
-rw-r--r--interpreter/parse.c28
-rw-r--r--interpreter/print.c5
-rw-r--r--interpreter/syntax.c4
-rw-r--r--interpreter/syntax.h1
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;