Created
June 19, 2018 17:41
-
-
Save kawakami-o3/a8f3166f562521e5d4bc26006fbae683 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* test.lisp | |
| (define a 1) | |
| (define b 10) | |
| (print a) | |
| (print b) | |
| */ | |
| #include<stdio.h> | |
| #include<stdlib.h> | |
| #include<stdbool.h> | |
| #include<string.h> | |
| enum { | |
| LIST_CHAR, | |
| LIST_LIST, | |
| }; | |
| typedef struct List_ { | |
| int type; | |
| union { | |
| char *chars; | |
| struct List_ **lists; | |
| }; | |
| int nalloc; | |
| int len; | |
| } List; | |
| List *list_to_string(List *s); | |
| #define INIT_SIZE 8 | |
| List *make_string(void) { | |
| List *r = malloc(sizeof(List)); | |
| r->chars = malloc(INIT_SIZE); | |
| r->nalloc = INIT_SIZE; | |
| r->len = 0; | |
| r->type = LIST_CHAR; | |
| r->chars[0] = '\0'; | |
| return r; | |
| } | |
| List *make_list(void) { | |
| List *r = malloc(sizeof(List)); | |
| r->chars = malloc(INIT_SIZE); | |
| r->nalloc = INIT_SIZE; | |
| r->len = 0; | |
| r->type = LIST_LIST; | |
| r->lists[0] = NULL; | |
| return r; | |
| } | |
| static void realloc_list(List *s) { | |
| int newsize = s->nalloc * 2; | |
| switch (s->type) { | |
| case LIST_CHAR: | |
| { | |
| char *chars = malloc(newsize); | |
| strcpy(chars, s->chars); | |
| s->chars = chars; | |
| } | |
| break; | |
| case LIST_LIST: | |
| { | |
| printf("realloc list\n"); | |
| List **lists = malloc(newsize); | |
| for (int i=0 ; i<s->len ; i++) { | |
| lists[i] = s->lists[i]; | |
| } | |
| s->lists = lists; | |
| } | |
| break; | |
| } | |
| s->nalloc = newsize; | |
| } | |
| char *get_cstring(List *s) { | |
| if (s->type == LIST_CHAR) { | |
| return s->chars; | |
| } else { | |
| return NULL; | |
| } | |
| } | |
| bool list_valid(List *s) { | |
| switch (s->type) { | |
| case LIST_CHAR: | |
| return true; | |
| case LIST_LIST: | |
| { | |
| for (int i=0 ; i<s->len ; i++) { | |
| bool result = list_valid(s->lists[i]); | |
| if (!result) { | |
| return result; | |
| } | |
| } | |
| return true; | |
| } | |
| default: | |
| return false; | |
| } | |
| } | |
| void string_append(List *s, char c) { | |
| if (s->type != LIST_CHAR) { | |
| return; // error | |
| } | |
| if (s->nalloc == (s->len + 1)) { | |
| realloc_list(s); | |
| } | |
| s->chars[s->len++] = c; | |
| s->chars[s->len] = '\0'; | |
| } | |
| void list_append(List *s, List *c) { | |
| if (s->type != LIST_LIST) { | |
| return; // error | |
| } | |
| { | |
| bool result = list_valid(s); | |
| printf("1 s valid?... %d\n", result); | |
| if (!result) { | |
| exit(0); | |
| } | |
| } | |
| if (s->nalloc == (s->len + 1)) { | |
| realloc_list(s); | |
| } | |
| { | |
| bool result = list_valid(s); | |
| printf("2 s valid?... %d\n", result); | |
| if (!result) { | |
| exit(0); | |
| } | |
| } | |
| s->lists[s->len++] = c; | |
| { | |
| bool result = list_valid(s); | |
| printf("3 s valid?... %d\n", result); | |
| if (!result) { | |
| printf("... %s\n", (list_to_string(s))->chars); | |
| exit(0); | |
| } | |
| } | |
| s->lists[s->len] = NULL; | |
| { | |
| bool result = list_valid(c); | |
| printf("c valid? ... %d\n", result); | |
| if (!result) { | |
| exit(0); | |
| } | |
| } | |
| { | |
| bool result = list_valid(s); | |
| printf("s valid?... %d\n", result); | |
| if (!result) { | |
| exit(0); | |
| } | |
| } | |
| } | |
| List *list_to_string(List *s) { | |
| printf("to_string\n"); | |
| switch (s->type) { | |
| case LIST_CHAR: | |
| printf("string\n"); | |
| return s; | |
| case LIST_LIST: | |
| printf("list\n"); | |
| { | |
| List *ret = make_string(); | |
| string_append(ret, '['); | |
| for (int i=0 ; i<s->len ; i++) { | |
| List *str = list_to_string(s->lists[i]); | |
| for (int j=0 ; j<str->len ; j++) { | |
| string_append(ret, str->chars[j]); | |
| } | |
| string_append(ret, ','); | |
| } | |
| string_append(ret, ']'); | |
| string_append(ret, ','); | |
| return ret; | |
| } | |
| default: | |
| printf("to_string error\n"); | |
| { | |
| List *ret = make_string(); | |
| string_append(ret, '('); | |
| string_append(ret, 'e'); | |
| string_append(ret, 'r'); | |
| string_append(ret, 'r'); | |
| string_append(ret, ')'); | |
| return ret; | |
| } | |
| } | |
| } | |
| List *tokenize(List *code) { | |
| List *ret = make_list(); | |
| List *str = make_string(); | |
| for (int i=0 ; i<code->len ; i++) { | |
| char c = code->chars[i]; | |
| if (c == ' ' || c == '\n' || c == '\t') { | |
| if (str->len > 0) { | |
| list_append(ret, str); | |
| str = make_string(); | |
| } | |
| } else { | |
| string_append(str, c); | |
| } | |
| } | |
| if (str->len > 0) { | |
| list_append(ret, str); | |
| } | |
| return ret; | |
| } | |
| int main() { | |
| List *code = make_string(); | |
| char ch; | |
| FILE *fp; | |
| fp = fopen("test.lisp", "r"); | |
| if (fp==NULL) { | |
| perror("failed to open the file"); | |
| return 1; | |
| } | |
| while ((ch=fgetc(fp)) != EOF) { | |
| string_append(code, ch); | |
| } | |
| printf("%s\n", list_to_string(tokenize(code))->chars); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment