diff --git a/tokenize.l b/tokenize.l index 26bab15..b47c405 100644 --- a/tokenize.l +++ b/tokenize.l @@ -26,6 +26,7 @@ struct ast { } v; struct ast *next; }; + enum asttype { AST_TOK = 400, @@ -88,101 +89,155 @@ make_token(enum yytokentype type, int num, char* str) } struct ast* -make_ast(enum asttype type, struct token *t, struct ast *n) { +make_ast(enum asttype type, struct token *t) +{ struct ast *a = (struct ast*) calloc(1, sizeof(struct ast)); if (a == NULL) err(1, "malloc failed"); a->type = type; if (type == AST_TOK) a->v.token = t; - else if (type == AST_LIST) - a->v.list = n; + /* else if (type == AST_LIST) */ + /* a->v.list = n; */ return a; } +struct token *next; struct ast* parse(struct token *t) { if (t == NULL) err(1, "Unexpected token: "); - if (t->type == LPAR) { - struct ast *head; - struct ast *a = head = make_ast(AST_LIST, NULL, NULL); + + if (t->type == LPAR) { + struct ast *head = make_ast(AST_LIST, NULL); + struct ast *a, *p; t = t->next; - assert (t != NULL); while (t->type != RPAR) { - a->next = parse(t); - t = t->next; + assert (t != NULL); + a = parse(t); + if (a == NULL) + err(1, "syntax error"); + if (head->v.list == NULL) { + p = head->v.list = a; + } else { + p->next = a; + } + p = a; + t = next; /* skip all tokens that are processed */ + assert(t != NULL); } + fprintf(stderr, "a=%p, t=%p\n", a, t); assert(t->type == RPAR); t = t->next; + next = t; return head; } else if (t->type == NUM) { printf("is a number %d\n", t->v.num); - return make_ast(AST_TOK, t, NULL); + next = t->next; + return make_ast(AST_TOK, t); } else if (t->type == SYM) { - printf("is a sym: %s\n", t->v.str); - return make_ast(AST_TOK, t, NULL); + printf("is a sym: %s (%p)\n", t->v.str, t); + next = t->next; + return make_ast(AST_TOK, t); } else if (t->type == STR) { + next = t->next; printf("is a str: %s\n", t->v.str); - return make_ast(AST_TOK, t, NULL); + return make_ast(AST_TOK, t); } return NULL; } + + void -debug_token(struct token *x) { - fprintf(stderr, "%d: ", x->type); - if (x->type == NUM) fprintf(stderr, "%d", x->v.num); +debug_token(struct token *x, indent) { + for (int i = 0; i < indent; i++) putc(' ', stderr); + fprintf(stderr, "%d: (%p)", x->type, x); + if (x->type == NUM) fprintf(stderr, "%d @ %p", x->v.num, x); if (x->type == STR || x->type == SYM) fprintf(stderr, "%s", x->v.str); putc('\n', stderr); } void -debug_ast(struct ast *a) { +debug_ast(struct ast *a, indent) { while (a) { - fprintf(stderr, "AST: %s", (a->type == AST_TOK) ? "AST_TOK" : - "AST_LIST"); - fprintf(stderr, " [%p]", (a->type == AST_TOK) ? a->v.list : - a->v.token); + for (int i = 0; i < indent; i++) putc(' ', stderr); + fprintf(stderr, "AST: %s,a=%p,list=%p,token=%p,next=%p", (a->type == AST_TOK) ? "AST_TOK" : + "AST_LIST", a, a->v.list, a->v.token, a->next); putc('\n', stderr); - if (a->type == AST_LIST) debug_ast(a->v.list); + if (a->type == AST_LIST) { + fprintf(stderr, "enter %p\n", a->v.list); + fprintf(stderr, "==\n"); + debug_ast(a->v.list, indent+4); + fprintf(stderr, "==\n"); + } else if(a->type == AST_TOK) - debug_token(a->v.token); + debug_token(a->v.token, indent); a = a->next; } } +struct ast * +eval(struct ast *a) +{ + if (a->type == AST_TOK) { + if (a->v.token->type == NUM) { + return make_ast(AST_TOK, a->v.token); + } + else if (a->v.token->type == SYM) { + if (strcmp(a->v.token->v.str, "def") == 0) { + printf("define: %s\n", a->next->v.token->v.str); + /* x = eval a->next->next */ + /* install: var:=x */ + } + + } else if (a->v.token->type == STR) + fprintf(stderr, "str\n"); + } else if (a->type == AST_LIST) { + eval(a->v.list); + } else { + fprintf(stderr, "%d\n", a->type); + assert(0); + } + return NULL; +} + +void +pr(struct ast *a) +{ + switch (a->type) { + case AST_TOK: + if (a->v.token->type == NUM) + printf("%d\n", a->v.token->v.num); + } +} + int main(void) { int tok; struct token *t, *u = NULL, *start = NULL; while(tok = yylex()) { - //printf("token: %d, %d, %s\n", tok, yylval, yytext); - //printf("t=%p\n", t); - //if(t->type == NUMBER) printf(" = %d\n", t->v.num); - - /* form=read_form() .. */ - /* eval(form) */ - + /* read token and create list */ t = make_token(tok, yylval, yytext); if (start == NULL) start = t; if (u == NULL) u = t; else u->next = t; u = t; + /* if EOL is reached, parse and evaluate form: */ if (t->type == EOL) { struct token *x = start; - while (x != NULL) { - debug_token(x); - x = x->next; - } + // while (x != NULL) {debug_token(x, 0); x = x->next;} - struct ast *tl = parse(start); - debug_ast(tl); - /* XXX: eval(parse(start)) */ + /* struct ast *tl = parse(start); */ + /* eval(tl); */ + eval(parse(start)); + //debug_ast(tl, 1); + + /* start anew: */ start = NULL; } }