for.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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 "grap.h"
  12. #include "y.tab.h"
  13. typedef struct {
  14. Obj *var; /* index variable */
  15. double to; /* limit */
  16. double by;
  17. int op; /* operator */
  18. char *str; /* string to push back */
  19. } For;
  20. #define MAXFOR 10
  21. For forstk[MAXFOR]; /* stack of for loops */
  22. For *forp = forstk; /* pointer to current top */
  23. void forloop(Obj *var, double from, double to, int op, double by, char *str) /* set up a for loop */
  24. {
  25. fprintf(tfd, "# for %s from %g to %g by %c %g \n",
  26. var->name, from, to, op, by);
  27. if (++forp >= forstk+MAXFOR)
  28. ERROR "for loop nested too deep" FATAL;
  29. forp->var = var;
  30. forp->to = to;
  31. forp->op = op;
  32. forp->by = by;
  33. forp->str = str;
  34. setvar(var, from);
  35. nextfor();
  36. unput('\n');
  37. }
  38. void nextfor(void) /* do one iteration of a for loop */
  39. {
  40. /* BUG: this should depend on op and direction */
  41. if (forp->var->fval > SLOP * forp->to) { /* loop is done */
  42. free(forp->str);
  43. if (--forp < forstk)
  44. ERROR "forstk popped too far" FATAL;
  45. } else { /* another iteration */
  46. pushsrc(String, "\nEndfor\n");
  47. pushsrc(String, forp->str);
  48. }
  49. }
  50. void endfor(void) /* end one iteration of for loop */
  51. {
  52. switch (forp->op) {
  53. case '+':
  54. case ' ':
  55. forp->var->fval += forp->by;
  56. break;
  57. case '-':
  58. forp->var->fval -= forp->by;
  59. break;
  60. case '*':
  61. forp->var->fval *= forp->by;
  62. break;
  63. case '/':
  64. forp->var->fval /= forp->by;
  65. break;
  66. }
  67. nextfor();
  68. }
  69. char *ifstat(double expr, char *thenpart, char *elsepart)
  70. {
  71. dprintf("if %g then <%s> else <%s>\n", expr, thenpart, elsepart? elsepart : "");
  72. if (expr) {
  73. unput('\n');
  74. pushsrc(Free, thenpart);
  75. pushsrc(String, thenpart);
  76. unput('\n');
  77. if (elsepart)
  78. free(elsepart);
  79. return thenpart; /* to be freed later */
  80. } else {
  81. free(thenpart);
  82. if (elsepart) {
  83. unput('\n');
  84. pushsrc(Free, elsepart);
  85. pushsrc(String, elsepart);
  86. unput('\n');
  87. }
  88. return elsepart;
  89. }
  90. }