|
CS456 - Systems Programming
| Displaying exercises/e8/files/lang.c
#include "lang.h"
extern struct cur_tok _cur;
var_t *vars;
char *tokstr[] = {
"+", "-", "*", "/", "%", "||", "&&", "<", ">", "==", "=", "(", ")",
"#", "var", "if", "else", "while", "print", "break", "continue",
"{", "}", ";", "EOI", "?"
};
stnode_t *new_stnode(stmt_t type)
{
stnode_t *n = malloc(sizeof(stnode_t));
n->type = type;
switch(type) {
case ST_WHILE:
n->w = malloc(sizeof(struct while_st));
break;
case ST_IF:
n->i = malloc(sizeof(struct if_st));
break;
default:
break;
}
n->next = NULL;
return n;
}
void match(token_t tok)
{
if (tok == _cur.tok) _cur.tok = lex(&_cur.value, _cur.buf);
else {
printf("Syntax error. Expected %s, got %s\n", tokstr[tok], tokstr[_cur.tok]);
exit(1);
}
}
int accept(token_t tok)
{
if (_cur.tok == tok) {
match(tok);
return TRUE;
}
return FALSE;
}
stnode_t *parse_stmt(void) {
bool empty;
stnode_t *hp = NULL, *ep = NULL, *st;
switch(_cur.tok) {
case T_WHILE:
match(T_WHILE);
st = new_stnode(ST_WHILE);
match(T_OPAREN);
st->w->expr = expr(&empty);
match(T_CPAREN);
st->w->body = parse_stmt();
break;
case T_IF:
match(T_IF);
st = new_stnode(ST_IF);
match(T_OPAREN);
st->i->expr = expr(&empty);
match(T_CPAREN);
st->i->body = parse_stmt();
st->i->elsebody = NULL;
if (accept(T_ELSE)) {
st->i->elsebody = parse_stmt();
}
break;
case T_PRINT:
match(T_PRINT);
st = new_stnode(ST_PRINT);
match(T_OPAREN);
st->expr = expr(&empty);
match(T_CPAREN);
match(T_EOS);
break;
case T_BREAK:
match(T_BREAK);
st = new_stnode(ST_BREAK);
match(T_EOS);
break;
case T_CONTINUE:
match(T_CONTINUE);
st = new_stnode(ST_CONTINUE);
match(T_EOS);
break;
case T_OCBRACE:
match(T_OCBRACE);
while (!accept(T_CCBRACE)) {
st = parse_stmt();
if (hp == NULL) hp = ep = st;
else {
ep->next = st;
ep = st;
}
}
st = hp;
break;
default:
st = new_stnode(ST_EXPRESSION);
st->expr = expr(&empty);
match(T_EOS);
break;
}
return st;
}
void catfile(char *path)
{
char buf[K];
FILE *fp = fopen(path, "r");
if (fp == NULL) return;
while (fgets(buf, K, fp) != NULL)
printf("%s", buf);
fclose(fp);
return;
}
int main(int argc, char *argv[])
{
FILE *fp = stdin;
stnode_t *hp = NULL, *ep = NULL, *st;
if (argc > 1) {
if ((fp = fopen(argv[1], "r")) == NULL) {
perror("fopen");
exit(1);
}
}
startlex(fp);
while(_cur.tok != T_EOI) {
st = parse_stmt();
if (hp == NULL) hp = ep = st;
else {
ep->next = st;
ep = st;
}
}
if (fp != stdin) fclose(fp);
#ifdef INTERPRETER
int cont = 0, brk = 0;
run(hp, &cont, &brk);
#else
printf("%%include \"syscalls.h\"\n");
printf("extern printnumnl, exit\n");
printf("SECTION .data\n");
for(var_t *v = vars; v; v=v->next) {
printf("\t%s: dq 0\n", v->name);
}
printf("\nSECTION .text\n");
printf("\nGLOBAL _start\n_start:\n");
assemble(hp, NULL, NULL);
printf("\ncall\texit\n");
#endif
return 0;
}
|