diff options
| author | Russ Cox <rsc@swtch.com> | 2017-04-03 23:12:14 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@swtch.com> | 2017-06-19 13:51:14 +0000 |
| commit | 3ebbd193dce0724e106ec9af627a3782676ae510 (patch) | |
| tree | 8624d9ceba59a4543754ab965117246949f1907a /src/cmd/svgpic/for.c | |
| parent | a9530c00e860cbbac75b03a1c6bce93ddf0a26f6 (diff) | |
| download | plan9port-3ebbd193dce0724e106ec9af627a3782676ae510.tar.gz plan9port-3ebbd193dce0724e106ec9af627a3782676ae510.zip | |
svgpic: new program to convert pic to svg
This is an experiment.
Like tpic it's a copy-and-paste fork of pic.
Change-Id: Ia22772bd5881c7904a6d8f8e0b46fde8cea89cbd
Reviewed-on: https://plan9port-review.googlesource.com/2920
Reviewed-by: Russ Cox <rsc@swtch.com>
Diffstat (limited to 'src/cmd/svgpic/for.c')
| -rw-r--r-- | src/cmd/svgpic/for.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/cmd/svgpic/for.c b/src/cmd/svgpic/for.c new file mode 100644 index 00000000..cece48b5 --- /dev/null +++ b/src/cmd/svgpic/for.c @@ -0,0 +1,95 @@ +#include <stdio.h> +#include <stdlib.h> +#include "pic.h" +#include "y.tab.h" + +#define SLOP 1.001 + +typedef struct { + char *var; /* index variable */ + double to; /* limit */ + double by; + int op; /* operator */ + char *str; /* string to push back */ +} For; + +For forstk[10]; /* stack of for loops */ +For *forp = forstk; /* pointer to current top */ + +void setfval(char *, double); +void nextfor(void); + +void forloop(char *var, double from, double to, int op, + double by, char *str) /* set up a for loop */ +{ + dprintf("# for %s from %g to %g by %c %g \n", + var, from, to, op, by); + if (++forp >= forstk+10) + ERROR "for loop nested too deep" FATAL; + forp->var = var; + forp->to = to; + forp->op = op; + forp->by = by; + forp->str = str; + setfval(var, from); + nextfor(); + unput('\n'); +} + +void nextfor(void) /* do one iteration of a for loop */ +{ + /* BUG: this should depend on op and direction */ + if (getfval(forp->var) > SLOP * forp->to) { /* loop is done */ + free(forp->str); + if (--forp < forstk) + ERROR "forstk popped too far" FATAL; + } else { /* another iteration */ + pushsrc(String, "\nEndfor\n"); + pushsrc(String, forp->str); + } +} + +void endfor(void) /* end one iteration of for loop */ +{ + struct symtab *p = lookup(forp->var); + + switch (forp->op) { + case '+': + case ' ': + p->s_val.f += forp->by; + break; + case '-': + p->s_val.f -= forp->by; + break; + case '*': + p->s_val.f *= forp->by; + break; + case '/': + p->s_val.f /= forp->by; + break; + } + nextfor(); +} + +char *ifstat(double expr, char *thenpart, char *elsepart) +{ + dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : ""); + if (expr) { + unput('\n'); + pushsrc(Free, thenpart); + pushsrc(String, thenpart); + unput('\n'); + if (elsepart) + free(elsepart); + return thenpart; /* to be freed later */ + } else { + free(thenpart); + if (elsepart) { + unput('\n'); + pushsrc(Free, elsepart); + pushsrc(String, elsepart); + unput('\n'); + } + return elsepart; + } +} |
