add first draft to eval a form

This commit is contained in:
Christian Barthel 2019-06-28 21:12:12 +02:00
parent 62cb03ebf0
commit 3ba49003f3
1 changed files with 92 additions and 37 deletions

View File

@ -26,6 +26,7 @@ struct ast {
} v; } v;
struct ast *next; struct ast *next;
}; };
enum asttype { enum asttype {
AST_TOK = 400, AST_TOK = 400,
@ -88,101 +89,155 @@ make_token(enum yytokentype type, int num, char* str)
} }
struct ast* 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)); struct ast *a = (struct ast*) calloc(1, sizeof(struct ast));
if (a == NULL) if (a == NULL)
err(1, "malloc failed"); err(1, "malloc failed");
a->type = type; a->type = type;
if (type == AST_TOK) if (type == AST_TOK)
a->v.token = t; a->v.token = t;
else if (type == AST_LIST) /* else if (type == AST_LIST) */
a->v.list = n; /* a->v.list = n; */
return a; return a;
} }
struct token *next;
struct ast* struct ast*
parse(struct token *t) parse(struct token *t)
{ {
if (t == NULL) if (t == NULL)
err(1, "Unexpected token: <NULL>"); err(1, "Unexpected token: <NULL>");
if (t->type == LPAR) {
struct ast *head; if (t->type == LPAR) {
struct ast *a = head = make_ast(AST_LIST, NULL, NULL); struct ast *head = make_ast(AST_LIST, NULL);
struct ast *a, *p;
t = t->next; t = t->next;
assert (t != NULL);
while (t->type != RPAR) { while (t->type != RPAR) {
a->next = parse(t); assert (t != NULL);
t = t->next; 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); assert(t->type == RPAR);
t = t->next; t = t->next;
next = t;
return head; return head;
} else if (t->type == NUM) { } else if (t->type == NUM) {
printf("is a number %d\n", t->v.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) { } else if (t->type == SYM) {
printf("is a sym: %s\n", t->v.str); printf("is a sym: %s (%p)\n", t->v.str, t);
return make_ast(AST_TOK, t, NULL); next = t->next;
return make_ast(AST_TOK, t);
} else if (t->type == STR) { } else if (t->type == STR) {
next = t->next;
printf("is a str: %s\n", t->v.str); printf("is a str: %s\n", t->v.str);
return make_ast(AST_TOK, t, NULL); return make_ast(AST_TOK, t);
} }
return NULL; return NULL;
} }
void void
debug_token(struct token *x) { debug_token(struct token *x, indent) {
fprintf(stderr, "%d: ", x->type); for (int i = 0; i < indent; i++) putc(' ', stderr);
if (x->type == NUM) fprintf(stderr, "%d", x->v.num); 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) if (x->type == STR || x->type == SYM)
fprintf(stderr, "%s", x->v.str); fprintf(stderr, "%s", x->v.str);
putc('\n', stderr); putc('\n', stderr);
} }
void void
debug_ast(struct ast *a) { debug_ast(struct ast *a, indent) {
while (a) { while (a) {
fprintf(stderr, "AST: %s", (a->type == AST_TOK) ? "AST_TOK" : for (int i = 0; i < indent; i++) putc(' ', stderr);
"AST_LIST"); fprintf(stderr, "AST: %s,a=%p,list=%p,token=%p,next=%p", (a->type == AST_TOK) ? "AST_TOK" :
fprintf(stderr, " [%p]", (a->type == AST_TOK) ? a->v.list : "AST_LIST", a, a->v.list, a->v.token, a->next);
a->v.token);
putc('\n', stderr); 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) else if(a->type == AST_TOK)
debug_token(a->v.token); debug_token(a->v.token, indent);
a = a->next; 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 main(void)
{ {
int tok; int tok;
struct token *t, *u = NULL, *start = NULL; struct token *t, *u = NULL, *start = NULL;
while(tok = yylex()) { while(tok = yylex()) {
//printf("token: %d, %d, %s\n", tok, yylval, yytext); /* read token and create list */
//printf("t=%p\n", t);
//if(t->type == NUMBER) printf(" = %d\n", t->v.num);
/* form=read_form() .. */
/* eval(form) */
t = make_token(tok, yylval, yytext); t = make_token(tok, yylval, yytext);
if (start == NULL) start = t; if (start == NULL) start = t;
if (u == NULL) u = t; if (u == NULL) u = t;
else u->next = t; else u->next = t;
u = t; u = t;
/* if EOL is reached, parse and evaluate form: */
if (t->type == EOL) { if (t->type == EOL) {
struct token *x = start; struct token *x = start;
while (x != NULL) { // while (x != NULL) {debug_token(x, 0); x = x->next;}
debug_token(x);
x = x->next;
}
struct ast *tl = parse(start); /* struct ast *tl = parse(start); */
debug_ast(tl); /* eval(tl); */
/* XXX: eval(parse(start)) */ eval(parse(start));
//debug_ast(tl, 1);
/* start anew: */
start = NULL; start = NULL;
} }
} }