Skip to content

Instantly share code, notes, and snippets.

@kawakami-o3
Created June 19, 2018 17:41
Show Gist options
  • Save kawakami-o3/a8f3166f562521e5d4bc26006fbae683 to your computer and use it in GitHub Desktop.
Save kawakami-o3/a8f3166f562521e5d4bc26006fbae683 to your computer and use it in GitHub Desktop.
/* 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