203 lines
4.4 KiB
Plaintext
203 lines
4.4 KiB
Plaintext
/*
|
|
* flex tokenize.l
|
|
* cc lex.yy.c -lfl
|
|
*/
|
|
%{
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <err.h>
|
|
struct token;
|
|
struct token {
|
|
int type;
|
|
union {
|
|
char *str;
|
|
int num;
|
|
} v;
|
|
struct token *next;
|
|
};
|
|
|
|
struct ast;
|
|
struct ast {
|
|
int type;
|
|
union {
|
|
struct token *token;
|
|
struct ast *list;
|
|
} v;
|
|
struct ast *next;
|
|
};
|
|
|
|
enum asttype {
|
|
AST_TOK = 400,
|
|
AST_LIST = 401
|
|
};
|
|
enum yytokentype {
|
|
NUM = 258,
|
|
LPAR = 259,
|
|
RPAR = 260,
|
|
SYM = 261,
|
|
STR = 262,
|
|
EOL = 263
|
|
};
|
|
|
|
struct token *make_token(enum yytokentype, int, char*);
|
|
int yylval;
|
|
char *yystr;
|
|
%}
|
|
|
|
%%
|
|
"(" { return LPAR; }
|
|
")" { return RPAR; }
|
|
[0-9]+ { yylval = atoi(yytext); return NUM; }
|
|
\n { return EOL; }
|
|
[ \t\n] { /* ignore white space */ }
|
|
\".*\" { return STR; }
|
|
[a-zA-Z][a-zA-Z0-9]* { return SYM; }
|
|
. { err(1, "invalid symbol: %s\n", yytext); }
|
|
%%
|
|
|
|
/*
|
|
* Goal: write LISP read-eval-print Loop and support
|
|
* @ Function
|
|
* 0,1 boolean (nand 0 1) -> boolean
|
|
* (eq 0 0) -> boolean
|
|
* "str" Strings (streq str1 str2) -> boolean
|
|
* abc Symboles (symeq s1 s2) -> boolean
|
|
* 1234 Number/Integer [add,sub,div,mul,mod] -> number
|
|
* [lt, numeq] -> boolean
|
|
* [num2bool] -> boolean
|
|
*
|
|
* (def <var> <symbol,number,#function)
|
|
* (lambda (<symbol> ..) (<sym..> ))
|
|
* (if <bool> <body> <else>)
|
|
*/
|
|
|
|
struct token*
|
|
make_token(enum yytokentype type, int num, char* str)
|
|
{
|
|
struct token *t =
|
|
(struct token*) calloc(1, sizeof(struct token));
|
|
if (t == NULL)
|
|
err(1, "malloc failed");
|
|
t->type = type;
|
|
if (type == NUM)
|
|
t->v.num = num;
|
|
else if (type == SYM || type == STR)
|
|
t->v.str = strdup(str);
|
|
return t;
|
|
}
|
|
|
|
struct ast*
|
|
make_ast(enum asttype type, struct token *t, struct ast *n) {
|
|
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;
|
|
return a;
|
|
}
|
|
|
|
struct ast*
|
|
parse(struct token *t)
|
|
{
|
|
if (t == NULL)
|
|
err(1, "Unexpected token: <NULL>");
|
|
if (t->type == LPAR) {
|
|
struct ast *head;
|
|
struct ast *a = head = make_ast(AST_LIST, NULL, NULL);
|
|
t = t->next;
|
|
assert (t != NULL);
|
|
while (t->type != RPAR) {
|
|
a->next = parse(t);
|
|
t = t->next;
|
|
}
|
|
assert(t->type == RPAR);
|
|
t = t->next;
|
|
return head;
|
|
} else if (t->type == NUM) {
|
|
printf("is a number %d\n", t->v.num);
|
|
return make_ast(AST_TOK, t, NULL);
|
|
} else if (t->type == SYM) {
|
|
printf("is a sym: %s\n", t->v.str);
|
|
return make_ast(AST_TOK, t, NULL);
|
|
} else if (t->type == STR) {
|
|
printf("is a str: %s\n", t->v.str);
|
|
return make_ast(AST_TOK, t, NULL);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
debug_token(struct token *x) {
|
|
fprintf(stderr, "%d: ", x->type);
|
|
if (x->type == NUM) fprintf(stderr, "%d", x->v.num);
|
|
if (x->type == STR || x->type == SYM)
|
|
fprintf(stderr, "%s", x->v.str);
|
|
putc('\n', stderr);
|
|
}
|
|
|
|
void
|
|
debug_ast(struct ast *a) {
|
|
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);
|
|
putc('\n', stderr);
|
|
if (a->type == AST_LIST) debug_ast(a->v.list);
|
|
else if(a->type == AST_TOK)
|
|
debug_token(a->v.token);
|
|
a = a->next;
|
|
}
|
|
}
|
|
|
|
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) */
|
|
|
|
t = make_token(tok, yylval, yytext);
|
|
if (start == NULL) start = t;
|
|
if (u == NULL) u = t;
|
|
else u->next = t;
|
|
u = t;
|
|
|
|
if (t->type == EOL) {
|
|
struct token *x = start;
|
|
while (x != NULL) {
|
|
debug_token(x);
|
|
x = x->next;
|
|
}
|
|
|
|
struct ast *tl = parse(start);
|
|
debug_ast(tl);
|
|
/* XXX: eval(parse(start)) */
|
|
start = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Local Variables:
|
|
* mode: c;
|
|
* eval: (message "main()")
|
|
* fill-column: 80
|
|
* comment-column: 40
|
|
* indent-tabs-mode: nil
|
|
* tab-width: 2
|
|
* c-basic-offset: 2
|
|
* End:
|
|
*/
|