home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / awk / awk320sr.zip / AWKGEN.C < prev    next >
C/C++ Source or Header  |  1991-04-28  |  8KB  |  394 lines

  1. /*
  2.  * Awk code generator
  3.  *
  4.  * Copyright (C) 1988, 1989, 1990, 1991 by Rob Duff
  5.  * All rights reserved
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <mem.h>
  10. #include "awk.h"
  11. #include "awklex.h"
  12.  
  13. short linenum = 0;                  /* line number for next opcode */
  14. short lastptr = 0;                  /* index to previous opcode */
  15. short codeptr = 0;                  /* index into code buffer */
  16. short lastlabel = 0;                /* index into jump target list */
  17. short nextlabel = 1;
  18. LABLE labels[MAXLABEL];             /* table to hold jump targets */
  19.  
  20. TRIX trix;
  21.  
  22. void putline(void);
  23. void genline(void);
  24.  
  25. int
  26. getlabel()
  27. {
  28.     int     label;
  29.  
  30.     if (lastlabel >= MAXLABEL)
  31.         yyerror("label overflow");
  32.     label = lastlabel++;
  33.     labels[label].where = 0;
  34.     labels[label].label = nextlabel++;
  35. #ifdef LDEBUG
  36.     print_label("get", label);
  37. #endif
  38.     return(label);
  39. }
  40.  
  41. void putlabel(int label)
  42. {
  43. #ifdef LDEBUG
  44.     print_label("put", label);
  45. #endif
  46.     lastlabel--;
  47.     if (labels[label].where < 0)
  48.         yyerror("undefined label");
  49.     if (label != lastlabel)
  50.         yyerror("lost label");
  51. }
  52.  
  53. void uselabel(int label, int value)
  54. {
  55.     int     i;
  56.  
  57. #ifdef LDEBUG
  58.     print_label("use", label);
  59.     print_label("for", value);
  60. #endif
  61.     i = labels[label].where;
  62.     labels[label].where = labels[value].where;
  63.     labels[value].where = i;
  64. }
  65.  
  66. void genlabel(int label)
  67. {
  68.     int     i, loc, tmp;
  69.  
  70.     loc = -labels[label].where;
  71.     labels[label].where = codeptr + 1;
  72.     while (loc > 0) {
  73.         for (i = 0; i < sizeof(short); i++)
  74.             trix.sval[i] = code[loc+i];
  75.         tmp = trix.ival;
  76.         trix.ival = codeptr - (loc + sizeof(short));
  77.         for (i = 0; i < sizeof(short); i++)
  78.             code[loc+i] = trix.sval[i];
  79.         loc = tmp;
  80.     }
  81. #ifdef LDEBUG
  82.     printf("set %d(%d)\n", labels[label].label, labels[label].where);
  83. #endif
  84.     genline();
  85. }
  86.  
  87. LINK*
  88. genact(char *cp)
  89. {
  90.     LINK *lp;
  91.  
  92.     lp = yyalloc(sizeof(LINK));
  93.     lp->cnext = NULL;
  94.     lp->ccode = cp;
  95.     return lp;
  96. }
  97.  
  98. RULE*
  99. genrule(char *start, char *stop)
  100. {
  101.     RULE *rp;
  102.  
  103.     rp = yyalloc(sizeof(RULE));
  104.     rp->start = start;
  105.     rp->stop = stop;
  106.     rp->seen = 0;
  107.     rp->flag = 0;
  108.     rp->action = NULL;
  109.     rp->next = NULL;
  110.     return rp;
  111. }
  112.  
  113. char*
  114. gencode()
  115. {
  116.     char    *cp;
  117.  
  118. #ifdef CDEBUG
  119.     print_code(code);
  120. #endif
  121.     cp = yyalloc(codeptr);
  122.     memcpy(cp, code, codeptr);
  123.     code[0] = C_END;
  124.     codeptr = 0;
  125.     lastptr = 0;
  126.     lastlabel = 0;
  127.     stackptr = stacktop;
  128.     return cp;
  129. }
  130.  
  131. void putline()
  132. {
  133.     int     i;
  134.  
  135.     if (awkline > 0 && linenum > 0) {
  136.         code[codeptr++] = C_LINE;
  137.         trix.sptr = yyname;
  138.         for (i = 0; i < sizeof(char*); i++)
  139.             code[codeptr++] = trix.sval[i];
  140.         trix.ival = linenum;
  141.         for (i = 0; i < sizeof(short); i++)
  142.             code[codeptr++] = trix.sval[i];
  143.         linenum = 0;
  144.     }
  145. }
  146.  
  147. void genline()
  148. {
  149.     linenum = yyline;
  150. }
  151.  
  152. void gendrop(void)
  153. {
  154.     int     op;
  155.  
  156.     op = code[lastptr];
  157.     if (op == C__PRE || op == C__POST || op == C__STORE || op == C__COPY)
  158.         code[lastptr] = op + 1; 
  159.     else {
  160.         putline();
  161.         lastptr = codeptr;
  162.         code[codeptr++] = C_DROP;
  163.     }
  164. }
  165.  
  166. void genstore(int arg)
  167. {
  168.     int     op;
  169.  
  170.     putline();
  171.     if (code[lastptr] == C_LOAD) {
  172.         codeptr = lastptr;
  173.         op = C__COPY;
  174.     }
  175.     else if (code[lastptr] == C_FETCH) {
  176.         code[lastptr] = C_ADDR;
  177.         op = C__COPY;
  178.     }
  179.     else if (code[lastptr] == C_PLUCK) {
  180.         code[lastptr] = C_FIELD;
  181.         op = C__COPY;
  182.     }
  183.     else
  184.         op = C__STORE;
  185.     lastptr = codeptr;
  186.     code[codeptr++] = op;
  187.     code[codeptr++] = arg;
  188. }
  189.  
  190. void genbyte(int op)
  191. {
  192.     putline();
  193.     lastptr = codeptr;
  194.     code[codeptr++] = op;
  195. }
  196.  
  197. void gentwo(int op, int arg)
  198. {
  199.     putline();
  200.     lastptr = codeptr;
  201.     code[codeptr++] = op;
  202.     code[codeptr++] = arg;
  203. }
  204.  
  205. void gendcon(double dcon)
  206. {
  207.     int     i;
  208.  
  209.     putline();
  210.     lastptr = codeptr;
  211.     code[codeptr++] = C_DCON;
  212.     trix.dval = dcon;
  213.     for (i = 0; i < sizeof(double); i++)
  214.         code[codeptr++] = trix.sval[i];
  215. }
  216.  
  217. void genicon(int icon)
  218. {
  219.     int     i;
  220.  
  221.     putline();
  222.     lastptr = codeptr;
  223.     if (icon <= 255)  {
  224.         code[codeptr++] = C_CCON;
  225.         trix.cval = (char)icon;
  226.         for (i = 0; i < sizeof(char); i++)
  227.             code[codeptr++] = trix.sval[i];
  228.     }
  229.     else {
  230.         code[codeptr++] = C_ICON;
  231.         trix.ival = (int)icon;
  232.         for (i = 0; i < sizeof(short); i++)
  233.             code[codeptr++] = trix.sval[i];
  234.     }
  235. }
  236.  
  237. void genlcon(long lcon)
  238. {
  239.     int     i;
  240.  
  241.     putline();
  242.     lastptr = codeptr;
  243.     code[codeptr++] = C_LCON;
  244.     trix.lval = (long)lcon;
  245.     for (i = 0; i < sizeof(long); i++)
  246.         code[codeptr++] = trix.sval[i];
  247. }
  248.  
  249. void genscon(char *scon)
  250. {
  251.     int     i;
  252.  
  253.     putline();
  254.     lastptr = codeptr;
  255.     code[codeptr++] = C_SCON;
  256.     trix.sptr = scon;
  257.     for (i = 0; i < sizeof(char*); i++)
  258.         code[codeptr++] = trix.sval[i];
  259. }
  260.  
  261. void genrcon(char *rcon)
  262. {
  263.     int     i;
  264.  
  265.     putline();
  266.     lastptr = codeptr;
  267.     code[codeptr++] = C_RCON;
  268.     trix.vptr = rcon;
  269.     for (i = 0; i < sizeof(void*); i++)
  270.         code[codeptr++] = trix.sval[i];
  271. }
  272.  
  273. void genfield(double field)
  274. {
  275.     int     i;
  276.  
  277.     if ( field < 0 || field >= MAXFIELD )
  278.         yyerror("Field number out of range");
  279.     putline();
  280.     lastptr = codeptr;
  281.     code[codeptr++] = C_FIELD;
  282.     trix.vptr = fieldtab + (int)field;
  283.     for (i = 0; i < sizeof(void*); i++)
  284.         code[codeptr++] = trix.sval[i];
  285. }
  286.  
  287. void genfcon(int fcon)
  288. {
  289.     int     i;
  290.  
  291.     putline();
  292.     lastptr = codeptr;
  293.     code[codeptr++] = C_FCON;
  294.     trix.vptr = files + fcon;
  295.     for (i = 0; i < sizeof(void*); i++)
  296.         code[codeptr++] = trix.sval[i];
  297. }
  298.  
  299. void genaddr(IDENT *var)
  300. {
  301.     int     i;
  302.     LIST    *lp;
  303.  
  304.     putline();
  305.     lastptr = codeptr;
  306.     i = 0;
  307.     for (lp = yydisplay; lp != NULL; lp = lp->lnext) {
  308.         if (lp->litem == var) {
  309.             code[codeptr++] = C_AUTO;
  310.             trix.ival = i;
  311.             for (i = 0; i < sizeof(int); i++)
  312.                 code[codeptr++] = trix.sval[i];
  313.             return;
  314.         }
  315.         i++;
  316.     }
  317.     if (var->vitem == NULL) {
  318.         var->vitem = nextvar++;
  319.         code[codeptr++] = C_ADDR;
  320.     }
  321.     else if ((ITEM*)(var->vitem) - vartab < builtin)
  322.         code[codeptr++] = C_BUILT;
  323.     else
  324.         code[codeptr++] = C_ADDR;
  325.     trix.vptr = var->vitem;
  326.     for (i = 0; i < sizeof(void*); i++)
  327.         code[codeptr++] = trix.sval[i];
  328. }
  329.  
  330. void gencall(int func, int args)
  331. {
  332.     putline();
  333.     lastptr = codeptr;
  334.     code[codeptr++] = C_CALL;
  335.     code[codeptr++] = func;
  336.     code[codeptr++] = args;
  337. }
  338.  
  339. void genuser(IDENT *func, int args)
  340. {
  341.     int     i;
  342.  
  343.     putline();
  344.     lastptr = codeptr;
  345.     code[codeptr++] = C_USER;
  346.     trix.vptr = func;
  347.     for (i = 0; i < sizeof(void*); i++)
  348.         code[codeptr++] = trix.sval[i];
  349.     code[codeptr++] = args;
  350. }
  351.  
  352. void genjump(int kind, int label)
  353. {
  354.     int     i, loc;
  355.  
  356.     putline();
  357.     lastptr = codeptr;
  358.     code[codeptr++] = kind;
  359.     loc = labels[label].where;
  360.     if (loc <= 0) {
  361.         trix.ival = -loc;
  362.         labels[label].where = -codeptr;
  363.     }
  364.     else
  365.         trix.ival = loc - (codeptr + sizeof(short) + 1);
  366.     for (i = 0; i < sizeof(short); i++)
  367.         code[codeptr++] = trix.sval[i];
  368. }
  369.  
  370. int
  371. lastcode()
  372. {
  373.     return code[lastptr];
  374. }
  375.  
  376. double
  377. lastdcon()
  378. {
  379.     codeptr = lastptr;
  380.     return *(double*)(&code[lastptr+1]);
  381. }
  382.  
  383. void
  384. lastvoid()
  385. {
  386.     codeptr = lastptr;
  387. }
  388.  
  389. void
  390. lastop(int op)
  391. {
  392.     code[lastptr] = op;
  393. }
  394.