#include #include #include void err(char *p, int st){ printf("%s",p); exit(st); } void err_if_null(void *p, char *msg, int st){ if(p == NULL){ err(msg, st); } } #define SYM_MAX 256 #define FORM_T 1 #define GRAPH_T 2 #define SYMBOL_T 4 #define STRING_ST 1 typedef struct cell { int type; int subtype; union { struct cell* car; struct { int c; char* v; } str; } v; struct cell* cdr; } Cell; struct state { int type; int nested; int symlen; Cell* root; Cell* tail; char rbuff[SYM_MAX]; }; typedef struct token { int len; char* msg; } Token; typedef struct state state; #define STATE_OUT 0 #define STATE_IN 1 typedef void (*dfunc)(char*, state*); void cell_alloc(Cell **cell, int type){ *cell = (Cell*)calloc(1, sizeof(Cell)); if(*cell == NULL){ err("state is null", 123); } (*cell)->type = type; (*cell)->cdr = NULL; } void mk_string(char* str, int len, Cell* cell){ char *c; c = (char *)malloc(len+1); err_if_null(c, "alloc string for symbol failed", 123); memcpy(c, str, len); c[len] = '\0'; cell->type = SYMBOL_T; cell->subtype = STRING_ST; cell->v.str.c = len; cell->v.str.v = c; } void out(char* p, state* s){ char c = *p; write(1, "\n>:",3); write(1, &c, 1); } void in(char* p, state* s){ char c = *p; int n = s->nested; write(1,"\n",1); while(n--){ write(1, "(", 1); } write(1, &c,1); } void transition(state* s, int prev_type, int type){ int len; char msg[20]; if(type == STATE_IN){ s->nested++; s->type = type; cell_alloc(&s->tail->v.car, SYMBOL_T); s->tail = s->tail->v.car; len = snprintf(msg, 20, "form %d", s->nested); mk_string(msg, (len < 20) ? len : 20, s->tail); cell_alloc(&s->tail->cdr, FORM_T); s->tail = s->tail->cdr; }else if(type == STATE_OUT){ s->nested--; if(s->nested == 0){ s->type = type; } } printf("transitioning from %d to %d\n", prev_type, type); } dfunc evaluate(char* p, state* s){ if(*p == '('){ transition(s, s->type, STATE_IN); return NULL; } if(s->type == STATE_IN){ if(*p == ')'){ transition(s, s->type, STATE_OUT); return NULL; }else if(*p == '('){ transition(s, s->type, STATE_IN); return NULL; } return in; } return out; } void print_cell(Cell* cell , int indent){ int l = indent; while(l--){ printf(" "); } if(cell->type == FORM_T){ printf("cell of type %d\n", cell->type); }else if(cell->type == SYMBOL_T){ if(cell->subtype == STRING_ST){ printf("string symbol '%s'\n", cell->v.str.v); } } } void print_form(Cell* car, int indent){ int l = 2; while (car != NULL){ if(car->type == FORM_T){ print_cell(car, indent); indent += 4; print_form(car->v.car, indent); }else{ print_cell(car, indent); } car = car->cdr; } } int main(){ char c; dfunc d; state *s; s = calloc(1, sizeof(state)); if(s == NULL){ err("state is null", 123); } cell_alloc(&s->root, FORM_T); s->tail = s->root; s->type = STATE_OUT; while(read(1, &c, 1) != 0){ d = evaluate(&c, s); if(d != NULL){ d(&c, s); } } printf("-- printing form --\n"); print_form(s->root, 0); return 0; }