for.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include "pic.h"
  12. #include "y.tab.h"
  13. #define SLOP 1.001
  14. typedef struct {
  15. char *var; /* index variable */
  16. double to; /* limit */
  17. double by;
  18. int op; /* operator */
  19. char *str; /* string to push back */
  20. } For;
  21. For forstk[10]; /* stack of for loops */
  22. For *forp = forstk; /* pointer to current top */
  23. void setfval(char *, double);
  24. void nextfor(void);
  25. void forloop(char *var, double from, double to, int op,
  26. double by, char *str) /* set up a for loop */
  27. {
  28. dprintf("# for %s from %g to %g by %c %g \n",
  29. var, from, to, op, by);
  30. if (++forp >= forstk+10)
  31. ERROR "for loop nested too deep" FATAL;
  32. forp->var = var;
  33. forp->to = to;
  34. forp->op = op;
  35. forp->by = by;
  36. forp->str = str;
  37. setfval(var, from);
  38. nextfor();
  39. unput('\n');
  40. }
  41. void nextfor(void) /* do one iteration of a for loop */
  42. {
  43. /* BUG: this should depend on op and direction */
  44. if (getfval(forp->var) > SLOP * forp->to) { /* loop is done */
  45. free(forp->str);
  46. if (--forp < forstk)
  47. ERROR "forstk popped too far" FATAL;
  48. } else { /* another iteration */
  49. pushsrc(String, "\nEndfor\n");
  50. pushsrc(String, forp->str);
  51. }
  52. }
  53. void endfor(void) /* end one iteration of for loop */
  54. {
  55. struct symtab *p = lookup(forp->var);
  56. switch (forp->op) {
  57. case '+':
  58. case ' ':
  59. p->s_val.f += forp->by;
  60. break;
  61. case '-':
  62. p->s_val.f -= forp->by;
  63. break;
  64. case '*':
  65. p->s_val.f *= forp->by;
  66. break;
  67. case '/':
  68. p->s_val.f /= forp->by;
  69. break;
  70. }
  71. nextfor();
  72. }
  73. char *ifstat(double expr, char *thenpart, char *elsepart)
  74. {
  75. dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : "");
  76. if (expr) {
  77. unput('\n');
  78. pushsrc(Free, thenpart);
  79. pushsrc(String, thenpart);
  80. unput('\n');
  81. if (elsepart)
  82. free(elsepart);
  83. return thenpart; /* to be freed later */
  84. } else {
  85. free(thenpart);
  86. if (elsepart) {
  87. unput('\n');
  88. pushsrc(Free, elsepart);
  89. pushsrc(String, elsepart);
  90. unput('\n');
  91. }
  92. return elsepart;
  93. }
  94. }