# HG changeset patch # User John Tsiombikas # Date 1426457634 -7200 # Node ID ae1c30fa39f389b57ce48802e0c3bb70c4459884 # Parent f167a743f34820cb29fc2f2e55fbae07f809b31c working on the control structures of tutorial5 diff -r f167a743f348 -r ae1c30fa39f3 src/main.c --- a/src/main.c Sun Mar 15 13:48:04 2015 +0200 +++ b/src/main.c Mon Mar 16 00:13:54 2015 +0200 @@ -12,11 +12,16 @@ }; void init(void); +void program(void); +void block(void); +void doif(void); +void dowhile(void); +void condition(void); void expression(void); void assignment(void); void term(void); void factor(void); -void ident(); +void ident(void); void add(void); void sub(void); void mul(void); @@ -33,6 +38,10 @@ void emitln(const char *fmt, ...); int is_addsub(char c); int add_symbol(char c, int type); +int newlabel(void); +const char *labelstr(int lb); +void postlabel(int lb); +void other(void); FILE *infile, *outfile; char look; @@ -60,10 +69,7 @@ /* output prologue */ fputs(prologue, outfile); - assignment(); - if(look != '\n') { - expected("newline"); - } + program(); /* output epilogue */ fputs(epilogue, outfile); @@ -86,6 +92,84 @@ skip_white(); } +void program(void) +{ + block(); + if(look != 'e') { + expected("End"); + } + emitln("# END"); +} + +void other(void) +{ + emitln("%c", get_name()); +} + +void block(void) +{ + while(look != 'e' && look != 'l') { + switch(look) { + case 'i': + doif(); + break; + + case 'w': + dowhile(); + break; + + default: + other(); + break; + } + } +} + +void doif(void) +{ + int lb1, lb2; + + match('i'); + condition(); + + lb1 = newlabel(); + lb2 = lb1; + + emitln("jz %s", labelstr(lb1)); + block(); + + if(look == 'l') { + match('l'); + lb2 = newlabel(); + emitln("jmp %s", labelstr(lb2)); + postlabel(lb1); + block(); + } + match('e'); + postlabel(lb2); +} + +void dowhile(void) +{ + int lbtop, lbend; + + match('w'); + lbtop = newlabel(); + lbend = newlabel(); + postlabel(lbtop); + condition(); + emitln("jz %s", labelstr(lbend)); + block(); + match('e'); + emitln("jmp %s", labelstr(lbtop)); + postlabel(lbend); +} + +void condition(void) +{ + emitln(""); +} + void expression(void) { if(is_addsub(look)) { @@ -149,7 +233,7 @@ } } -void ident() +void ident(void) { char name = get_name(); if(look == '(') { @@ -320,3 +404,21 @@ symlist = sym; return 0; } + +int newlabel(void) +{ + static int n; + return n++; +} + +const char *labelstr(int lb) +{ + static char buf[16]; + sprintf(buf, "L%02d", lb); + return buf; +} + +void postlabel(int lb) +{ + fprintf(outfile, "%s:\n", labelstr(lb)); +}