home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / TOP / USR / SRC / gawk2.0.t.Z / gawk2.0.t / awk2.c < prev    next >
Text File  |  1988-12-31  |  30KB  |  1,083 lines

  1. /*
  2.  * awk2 --- gawk parse tree interpreter 
  3.  *
  4.  * Copyright (C) 1986 Free Software Foundation Written by Paul Rubin, August
  5.  * 1986 
  6.  *
  7.  * $Log:    awk2.c,v $
  8.  * Revision 1.36  88/12/08  10:51:37  david
  9.  * small correction to source file code
  10.  * 
  11.  * Revision 1.35  88/12/07  20:00:35  david
  12.  * changes for incorporating source filename into error messages
  13.  * 
  14.  * Revision 1.34  88/12/01  15:04:48  david
  15.  * cleanup and additions for source line number printing in error messages
  16.  * 
  17.  * Revision 1.33  88/11/30  15:16:10  david
  18.  * merge FREE_ONE_REFERENCE into do_deref()
  19.  * free more in do_deref
  20.  * in for (i in array) loops, make sure value of i gets freed on each iteration
  21.  * 
  22.  * Revision 1.32  88/11/29  09:55:04  david
  23.  * corrections to code that tracks value of NF -- this needs cleanup
  24.  * 
  25.  * Revision 1.31  88/11/23  21:40:47  david
  26.  * Arnold: comment cleanup
  27.  * 
  28.  * Revision 1.30  88/11/22  13:49:09  david
  29.  * Arnold: changes for case-insensitive matching
  30.  * 
  31.  * Revision 1.29  88/11/15  10:22:42  david
  32.  * Arnold: cleanup of comments and #include's
  33.  * 
  34.  * Revision 1.28  88/11/14  21:55:38  david
  35.  * Arnold: misc. cleanup and error message on bad regexp
  36.  * 
  37.  * Revision 1.27  88/11/14  21:26:52  david
  38.  * update NF on assignment to a field greater than current NF
  39.  * 
  40.  * Revision 1.26  88/11/03  15:26:20  david
  41.  * simplify call to in_array(); extensive revision of cmp_nodes and is_a_number
  42.  * 
  43.  * Revision 1.25  88/11/01  12:11:57  david
  44.  * DEBUG macro becomes DBG_P; added some debugging code; moved all the
  45.  * compound assignments (+= etc.) into op_assign()
  46.  * 
  47.  * Revision 1.24  88/10/25  10:43:05  david
  48.  * intermediate state: more code movement; Node_string et al. -> Node_val;
  49.  * add more debugging code; improve cmp_nodes
  50.  * 
  51.  * Revision 1.22  88/10/19  21:57:41  david
  52.  * replace malloc and realloc with error checking versions
  53.  * start to change handling of $0
  54.  * 
  55.  * Revision 1.21  88/10/17  20:56:13  david
  56.  * Arnold: better error messages for use of a function in the wrong context
  57.  * 
  58.  * Revision 1.20  88/10/13  21:56:41  david
  59.  * cleanup of previous changes
  60.  * change panic() to fatal()
  61.  * detect and bomb on function call with space between name and opening (
  62.  * 
  63.  * Revision 1.19  88/10/11  22:19:20  david
  64.  * cleanup 
  65.  * 
  66.  * Revision 1.18  88/10/04  21:31:33  david
  67.  * minor cleanup
  68.  * 
  69.  * Revision 1.17  88/08/22  14:01:19  david
  70.  * fix to set_field() from Jay Finlayson
  71.  * 
  72.  * Revision 1.16  88/08/09  14:51:34  david
  73.  * removed bad call to obstack_free() -- there is a lot of memory that is
  74.  * not being properly freed -- this area needs major work
  75.  * changed semantics in eval_condition -- if(expr) should test true if
  76.  * expr is a non-null string, even if the num,erical value is zero -- counter-
  77.  * intuitive but that's what's in the book
  78.  * 
  79.  * Revision 1.15  88/06/13  18:02:58  david
  80.  * separate exit value from fact that exit has been called [from Arnold]
  81.  * 
  82.  * Revision 1.14  88/06/07  23:39:48  david
  83.  * insubstantial changes
  84.  * 
  85.  * Revision 1.13  88/06/06  11:26:39  david
  86.  * get rid of some obsolete code
  87.  * change interface of set_field()
  88.  * 
  89.  * Revision 1.12  88/06/05  22:21:36  david
  90.  * local variables are now kept on a stack
  91.  * 
  92.  * Revision 1.11  88/06/01  22:06:50  david
  93.  * make sure incases of Node_param_list that the variable is looked up
  94.  * 
  95.  * Revision 1.10  88/05/31  09:29:47  david
  96.  * expunge Node_local_var
  97.  * 
  98.  * Revision 1.9  88/05/30  09:52:55  david
  99.  * be prepared for NULL return from make_regexp()
  100.  * fix fatal() call
  101.  * 
  102.  * Revision 1.8  88/05/26  22:48:48  david
  103.  * fixed regexp matching code
  104.  * 
  105.  * Revision 1.7  88/05/16  21:27:09  david
  106.  * comment out obstack_free in interpret() -- it is done in do_file() anyway
  107.  * and was definitely free'ing stuff it shouldn't have
  108.  * change call of func_call() a bit
  109.  * allow get_lhs to be called with other Node types -- return 0; used in
  110.  * do_sub()
  111.  * 
  112.  * Revision 1.6  88/05/13  22:00:03  david
  113.  * generalized *_BINDING macros and moved them to awk.h
  114.  * changes to function calling (mostly elsewhere)
  115.  * put into use the Node_var_array type
  116.  * 
  117.  * Revision 1.5  88/05/09  21:22:27  david
  118.  * finally (I hope) got the code right in assign_number
  119.  * 
  120.  * Revision 1.4  88/05/04  12:23:30  david
  121.  * fflush(stdout) on prints if FAST not def'ed
  122.  * all the assign_* cases were returning the wrong thing
  123.  * fixed Node_in_array code
  124.  * code in assign_number was freeing memory it shouldn't have
  125.  * 
  126.  * Revision 1.3  88/04/15  13:12:38  david
  127.  * additional error message
  128.  * 
  129.  * Revision 1.2  88/04/12  16:03:24  david
  130.  * fixed previously intoduced bug: all matches succeeded
  131.  * 
  132.  * Revision 1.1  88/04/08  15:15:01  david
  133.  * Initial revision
  134.  *  Revision 1.7  88/04/08  14:48:33  david changes from
  135.  * Arnold Robbins 
  136.  *
  137.  * Revision 1.6  88/03/28  14:13:50  david *** empty log message *** 
  138.  *
  139.  * Revision 1.5  88/03/23  22:17:37  david mostly delinting -- a couple of bug
  140.  * fixes 
  141.  *
  142.  * Revision 1.4  88/03/18  21:00:10  david Baseline -- hoefully all the
  143.  * functionality of the new awk added. Just debugging and tuning to do. 
  144.  *
  145.  * Revision 1.3  87/11/14  15:16:21  david added user-defined functions with
  146.  * return and do-while loops 
  147.  *
  148.  * Revision 1.2  87/10/29  21:45:44  david added support for array membership
  149.  * test, as in:  if ("yes" in answers) ... this involved one more case: for
  150.  * Node_in_array and rearrangment of the code in assoc_lookup, so thatthe
  151.  * element can be located without being created 
  152.  *
  153.  * Revision 1.1  87/10/27  15:23:28  david Initial revision 
  154.  *
  155.  */
  156.  
  157. /*
  158.  * GAWK is distributed in the hope that it will be useful, but WITHOUT ANY
  159.  * WARRANTY.  No author or distributor accepts responsibility to anyone for
  160.  * the consequences of using it or for whether it serves any particular
  161.  * purpose or works at all, unless he says so in writing. Refer to the GAWK
  162.  * General Public License for full details. 
  163.  *
  164.  * Everyone is granted permission to copy, modify and redistribute GAWK, but
  165.  * only under the conditions described in the GAWK General Public License.  A
  166.  * copy of this license is supposed to have been given to you along with GAWK
  167.  * so you can know your rights and responsibilities.  It should be in a file
  168.  * named COPYING.  Among other things, the copyright notice and this notice
  169.  * must be preserved on all copies. 
  170.  *
  171.  * In other words, go ahead and share GAWK, but don't try to stop anyone else
  172.  * from sharing it farther.  Help stamp out software hoarding! 
  173.  */
  174.  
  175. #include "awk.h"
  176.  
  177. NODE *ret_node;
  178. extern NODE *OFMT_node;
  179.  
  180. /*
  181.  * BEGIN and END blocks need special handling, because we are handed them as
  182.  * raw Node_statement_lists, not as Node_rule_lists.
  183.  */
  184. extern NODE *begin_block, *end_block;
  185. NODE *do_sprintf();
  186. extern struct obstack other_stack;
  187.  
  188. /* More of that debugging stuff */
  189. #ifdef    DEBUG
  190. #define DBG_P(X) print_debug X
  191. #else
  192. #define DBG_P(X)
  193. #endif
  194.  
  195. NODE *func_call();
  196. extern jmp_buf func_tag;
  197.  
  198. /*
  199.  * This table is used by the regexp routines to do case independant
  200.  * matching. Basically, every ascii character maps to itself, except
  201.  * uppercase letters map to lower case ones. This table has 256
  202.  * entries, which may be overkill. Note also that if the system this
  203.  * is compiled on doesn't use 7-bit ascii, casetable[] should not be
  204.  * defined to the linker, so gawk should not load.
  205.  */
  206. #if 'a' == 97    /* it's ascii */
  207. static char casetable[] = {
  208.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  209.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  210.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  211.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  212.     /* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
  213.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  214.     /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
  215.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  216.     /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
  217.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  218.     /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
  219.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  220.     /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
  221.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  222.     /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
  223.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  224.     /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
  225.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  226.     /* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
  227.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  228.     /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
  229.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  230.     /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
  231.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  232.     /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
  233.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  234.     /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
  235.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  236.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  237.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  238.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  239.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  240.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  241.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  242.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  243.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  244.     '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
  245.     '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
  246.     '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
  247.     '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
  248.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  249.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  250.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  251.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  252. };
  253. #else
  254. /* You lose. You will need a translation table for your character set. */
  255. #endif
  256.  
  257. /*
  258.  * Tree is a bunch of rules to run. Returns zero if it hit an exit()
  259.  * statement 
  260.  */
  261. interpret(tree)
  262. NODE *tree;
  263. {
  264.     register NODE *t;    /* temporary */
  265.  
  266.     auto jmp_buf loop_tag_stack;    /* shallow binding stack for loop_tag */
  267.     static jmp_buf loop_tag;/* always the current binding */
  268.     static int loop_tag_valid = 0;    /* nonzero when loop_tag valid */
  269.  
  270.     static jmp_buf rule_tag;/* tag the rule currently being run, for NEXT
  271.                  * and EXIT statements.  It is static because
  272.                  * there are no nested rules */
  273.  
  274.     register NODE **lhs;    /* lhs == Left Hand Side for assigns, etc */
  275.     register struct search *l;    /* For array_for */
  276.  
  277.  
  278.     extern struct obstack temp_strings;
  279.     extern NODE **fields_arr;
  280.     extern char *ob_dummy;
  281.     extern int exiting, exit_val;
  282.     NODE *do_printf();
  283.     extern NODE *lookup();
  284.  
  285.     /*
  286.      * clean up temporary strings created by evaluating expressions in
  287.      * previous recursive calls 
  288.      */
  289.     /* obstack_free(&temp_strings, ob_dummy); */
  290.  
  291.     if (tree == NULL)
  292.         return 1;
  293.     sourceline = tree->source_line;
  294.     source = tree->source_file;
  295.     switch (tree->type) {
  296.     case Node_rule_list:
  297.         for (t = tree; t != NULL; t = t->rnode) {
  298.             tree = t->lnode;
  299.             switch (_setjmp(rule_tag)) {
  300.             case 0:    /* normal non-jump */
  301.                 if (eval_condition(tree->lnode)) { /* pattern */
  302.                     DBG_P(("Found a rule", tree->rnode));
  303.                     if (tree->rnode == NULL) {
  304.                         /*
  305.                          * special case: pattern with
  306.                          * no action is equivalent to
  307.                          * an action of {print}
  308.                          */
  309.                         NODE printnode;
  310.  
  311.                         printnode.type = Node_K_print;
  312.                         printnode.lnode = NULL;
  313.                         printnode.rnode = NULL;
  314.                         do_print(&printnode);
  315.                     } else if (tree->rnode->type == Node_illegal) {
  316.                         /*
  317.                          * An empty statement
  318.                          * (``{ }'') is different
  319.                          * from a missing statement.
  320.                          * A missing statement is
  321.                          * equal to ``{ print }'' as
  322.                          * above, but an empty
  323.                          * statement is as in C, do
  324.                          * nothing.
  325.                          */
  326.                     } else
  327.                         (void) interpret(t->lnode->rnode);
  328.                 }
  329.                 break;
  330.             case TAG_CONTINUE:    /* NEXT statement */
  331.                 return 1;
  332.             case TAG_BREAK:
  333.                 return 0;
  334.             }
  335.         }
  336.         break;
  337.  
  338.     case Node_statement_list:
  339.         /*
  340.          * because BEGIN and END do not have Node_rule_list nature,
  341.          * yet can have exits and nexts, we special-case a setjmp of
  342.          * rule_tag here.
  343.          */
  344.         if (tree == begin_block || tree == end_block) {
  345.             switch (_setjmp(rule_tag)) {
  346.             case TAG_CONTINUE:    /* next */
  347.                 fatal("unexpected \"next\" in %s block",
  348.                       tree == begin_block ? "BEGIN" : "END");
  349.                 return 1;
  350.             case TAG_BREAK:
  351.                 return 0;
  352.             }
  353.         }
  354.         for (t = tree; t != NULL; t = t->rnode) {
  355.             DBG_P(("Statements", t->lnode));
  356.             (void) interpret(t->lnode);
  357.         }
  358.         break;
  359.  
  360.     case Node_K_if:
  361.         DBG_P(("IF", tree->lnode));
  362.         if (eval_condition(tree->lnode)) {
  363.             DBG_P(("True", tree->rnode->lnode));
  364.             (void) interpret(tree->rnode->lnode);
  365.         } else {
  366.             DBG_P(("False", tree->rnode->rnode));
  367.             (void) interpret(tree->rnode->rnode);
  368.         }
  369.         break;
  370.  
  371.     case Node_K_while:
  372.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  373.  
  374.         DBG_P(("WHILE", tree->lnode));
  375.         while (eval_condition(tree->lnode)) {
  376.             switch (_setjmp(loop_tag)) {
  377.             case 0:    /* normal non-jump */
  378.                 DBG_P(("DO", tree->rnode));
  379.                 (void) interpret(tree->rnode);
  380.                 break;
  381.             case TAG_CONTINUE:    /* continue statement */
  382.                 break;
  383.             case TAG_BREAK:    /* break statement */
  384.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  385.                 return 1;
  386.             default:
  387.                 cant_happen();
  388.             }
  389.         }
  390.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  391.         break;
  392.  
  393.     case Node_K_do:
  394.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  395.  
  396.         do {
  397.             switch (_setjmp(loop_tag)) {
  398.             case 0:    /* normal non-jump */
  399.                 DBG_P(("DO", tree->rnode));
  400.                 (void) interpret(tree->rnode);
  401.                 break;
  402.             case TAG_CONTINUE:    /* continue statement */
  403.                 break;
  404.             case TAG_BREAK:    /* break statement */
  405.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  406.                 return 1;
  407.             default:
  408.                 cant_happen();
  409.             }
  410.             DBG_P(("WHILE", tree->lnode));
  411.         } while (eval_condition(tree->lnode));
  412.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  413.         break;
  414.  
  415.     case Node_K_for:
  416.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  417.  
  418.         DBG_P(("FOR", tree->forloop->init));
  419.         (void) interpret(tree->forloop->init);
  420.  
  421.         DBG_P(("FOR.WHILE", tree->forloop->cond));
  422.         while (eval_condition(tree->forloop->cond)) {
  423.             switch (_setjmp(loop_tag)) {
  424.             case 0:    /* normal non-jump */
  425.                 DBG_P(("FOR.DO", tree->lnode));
  426.                 (void) interpret(tree->lnode);
  427.                 /* fall through */
  428.             case TAG_CONTINUE:    /* continue statement */
  429.                 DBG_P(("FOR.INCR", tree->forloop->incr));
  430.                 (void) interpret(tree->forloop->incr);
  431.                 break;
  432.             case TAG_BREAK:    /* break statement */
  433.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  434.                 return 1;
  435.             default:
  436.                 cant_happen();
  437.             }
  438.         }
  439.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  440.         break;
  441.  
  442.     case Node_K_arrayfor:
  443. #define hakvar forloop->init
  444. #define arrvar forloop->incr
  445.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  446.         DBG_P(("AFOR.VAR", tree->hakvar));
  447.         lhs = get_lhs(tree->hakvar);
  448.         t = tree->arrvar;
  449.         if (tree->arrvar->type == Node_param_list)
  450.             t = stack_ptr[tree->arrvar->param_cnt];
  451.         for (l = assoc_scan(t); l; l = assoc_next(l)) {
  452.             deref = *lhs;
  453.             do_deref();
  454.             *lhs = dupnode(l->retval);
  455.             if (field_num == 0)
  456.                 set_record(fields_arr[0]->stptr,
  457.                     fields_arr[0]->stlen);
  458.             else if (field_num > 0) {
  459.                 node0_valid = 0;
  460.                 if (NF_node->var_value->numbr == -1 &&
  461.                         field_num > NF_node->var_value->numbr)
  462.                     assign_number(&(NF_node->var_value),
  463.                         (AWKNUM) field_num);
  464.             }
  465.             DBG_P(("AFOR.NEXTIS", *lhs));
  466.             switch (_setjmp(loop_tag)) {
  467.             case 0:
  468.                 DBG_P(("AFOR.DO", tree->lnode));
  469.                 (void) interpret(tree->lnode);
  470.             case TAG_CONTINUE:
  471.                 break;
  472.  
  473.             case TAG_BREAK:
  474.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  475.                 field_num = -1;
  476.                 return 1;
  477.             default:
  478.                 cant_happen();
  479.             }
  480.         }
  481.         field_num = -1;
  482.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  483.         break;
  484.  
  485.     case Node_K_break:
  486.         DBG_P(("BREAK", NULL));
  487.         if (loop_tag_valid == 0)
  488.             fatal("unexpected break");
  489.         _longjmp(loop_tag, TAG_BREAK);
  490.         break;
  491.  
  492.     case Node_K_continue:
  493.         DBG_P(("CONTINUE", NULL));
  494.         if (loop_tag_valid == 0)
  495.             fatal("unexpected continue");
  496.         _longjmp(loop_tag, TAG_CONTINUE);
  497.         break;
  498.  
  499.     case Node_K_print:
  500.         DBG_P(("PRINT", tree));
  501.         (void) do_print(tree);
  502.         break;
  503.  
  504.     case Node_K_printf:
  505.         DBG_P(("PRINTF", tree));
  506.         (void) do_printf(tree);
  507.         break;
  508.  
  509.     case Node_K_next:
  510.         DBG_P(("NEXT", NULL));
  511.         _longjmp(rule_tag, TAG_CONTINUE);
  512.         break;
  513.  
  514.     case Node_K_exit:
  515.         /*
  516.          * In A,K,&W, p. 49, it says that an exit statement "...
  517.          * causes the program to behave as if the end of input had
  518.          * occurred; no more input is read, and the END actions, if
  519.          * any are executed." This implies that the rest of the rules
  520.          * are not done. So we immediately break out of the main loop.
  521.          */
  522.         DBG_P(("EXIT", NULL));
  523.         exiting = 1;
  524.         if (tree)
  525.             exit_val = (int) force_number(tree_eval(tree->lnode));
  526.         _longjmp(rule_tag, TAG_BREAK);
  527.         break;
  528.  
  529.     case Node_K_function:
  530.         break;
  531.  
  532.     case Node_K_return:
  533.         DBG_P(("RETURN", NULL));
  534.         ret_node = tree_eval(tree->lnode);
  535.         _longjmp(func_tag, TAG_RETURN);
  536.         break;
  537.  
  538.     default:
  539.         /*
  540.          * Appears to be an expression statement.  Throw away the
  541.          * value. 
  542.          */
  543.         DBG_P(("E", NULL));
  544.         (void) tree_eval(tree);
  545.         break;
  546.     }
  547.     return 1;
  548. }
  549.  
  550. /* evaluate a subtree, allocating strings on a temporary stack. */
  551.  
  552. NODE *
  553. tree_eval(tree)
  554. NODE *tree;
  555. {
  556.     NODE *op_assign();
  557.     register NODE *r, *t1, *t2;    /* return value & temporary subtrees */
  558.     int i;
  559.     register NODE **lhs;
  560.     int di;
  561.     AWKNUM x;
  562.     int samecase = 0;
  563.     extern int ignorecase;
  564.     struct re_pattern_buffer *rp;
  565.     extern NODE **fields_arr;
  566.     extern struct obstack temp_strings;
  567.     extern NODE *do_getline();
  568.     extern NODE *do_match();
  569.     extern NODE *do_sub();
  570.     extern double pow();
  571.  
  572.     if (tree == NULL) {
  573.         DBG_P(("NULL", NULL));
  574.         return Nnull_string;
  575.     }
  576.     if (tree->type == Node_val)
  577.         return tree;
  578.     if (tree->type != Node_var)
  579.         source = tree->source_file;
  580.     sourceline = tree->source_line;
  581.     switch (tree->type) {
  582.     case Node_and:
  583.         DBG_P(("AND", tree));
  584.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  585.                         && eval_condition(tree->rnode)));
  586.  
  587.     case Node_or:
  588.         DBG_P(("OR", tree));
  589.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  590.                         || eval_condition(tree->rnode)));
  591.  
  592.     case Node_not:
  593.         DBG_P(("NOT", tree));
  594.         return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
  595.  
  596.         /* Builtins */
  597.     case Node_builtin:
  598.         DBG_P(("builtin", tree));
  599.         return ((*tree->proc) (tree->subnode));
  600.  
  601.     case Node_K_getline:
  602.         DBG_P(("GETLINE", tree));
  603.         return (do_getline(tree));
  604.  
  605.     case Node_in_array:
  606.         DBG_P(("IN_ARRAY", tree));
  607.         return tmp_number((AWKNUM) in_array(tree->lnode, tree->rnode));
  608.  
  609.     case Node_K_match:
  610.         DBG_P(("MATCH", tree));
  611.         return do_match(tree);
  612.  
  613.     case Node_sub:
  614.     case Node_gsub:
  615.         DBG_P(("SUB", tree));
  616.         return do_sub(tree);
  617.  
  618.     case Node_func_call:
  619.         DBG_P(("func_call", tree));
  620.         return func_call(tree->rnode, tree->lnode);
  621.  
  622.     case Node_K_delete:
  623.         DBG_P(("DELETE", tree));
  624.         do_delete(tree->lnode, tree->rnode);
  625.         return Nnull_string;
  626.  
  627.         /* unary operations */
  628.  
  629.     case Node_var:
  630.     case Node_var_array:
  631.     case Node_param_list:
  632.     case Node_subscript:
  633.     case Node_field_spec:
  634.         DBG_P(("var_type ref", tree));
  635.         lhs = get_lhs(tree);
  636.         field_num = -1;
  637.         deref = 0;
  638.         return *lhs;
  639.  
  640.     case Node_unary_minus:
  641.         DBG_P(("UMINUS", tree));
  642.         return tmp_number(-force_number(tree_eval(tree->subnode)));
  643.  
  644.     case Node_cond_exp:
  645.         DBG_P(("?:", tree));
  646.         if (eval_condition(tree->lnode)) {
  647.             DBG_P(("True", tree->rnode->lnode));
  648.             return tree_eval(tree->rnode->lnode);
  649.         } else {
  650.             DBG_P(("False", tree->rnode->rnode));
  651.             return tree_eval(tree->rnode->rnode);
  652.         }
  653.         break;
  654.  
  655.     case Node_case_match:
  656.     case Node_case_nomatch:
  657.         samecase = 1;
  658.         /* fall through */
  659.     case Node_match:
  660.     case Node_nomatch:
  661.         DBG_P(("ASSIGN_[no]match", tree));
  662.         t1 = tree_eval(tree->lnode);
  663.         t1 = force_string(t1);
  664.         if (tree->rnode->type == Node_regex)
  665.             rp = tree->rnode->rereg;
  666.         else {
  667.             rp = make_regexp(force_string(tree_eval(tree->rnode)));
  668.             if (rp == NULL)
  669.                 cant_happen();
  670.         }
  671.         if (! strict && (ignorecase || samecase))
  672.             rp->translate = casetable;
  673.         i = re_search(rp, t1->stptr, t1->stlen, 0, t1->stlen,
  674.             (struct re_registers *) NULL);
  675.         i = (i == -1) ^ (tree->type == Node_match ||
  676.                     tree->type == Node_case_match);
  677.         return tmp_number((AWKNUM) i);
  678.  
  679.     case Node_func:
  680.         fatal("function `%s' called with space between name and (,\n%s",
  681.             tree->lnode->param,
  682.             "or used in other expression context");
  683.  
  684.         /* assignments */
  685.     case Node_assign:
  686.         DBG_P(("ASSIGN", tree));
  687.         r = tree_eval(tree->rnode);
  688.         lhs = get_lhs(tree->lnode);
  689.         *lhs = dupnode(r);
  690.         if (field_num == 0)
  691.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  692.         else if (field_num > 0) {
  693.             node0_valid = 0;
  694.             if (NF_node->var_value->numbr == -1 &&
  695.                 field_num > NF_node->var_value->numbr)
  696.                 assign_number(&(NF_node->var_value),
  697.                     (AWKNUM) field_num);
  698.         }
  699.         field_num = -1;
  700.         do_deref();
  701.         return *lhs;
  702.  
  703.         /* other assignment types are easier because they are numeric */
  704.     case Node_preincrement:
  705.     case Node_predecrement:
  706.     case Node_postincrement:
  707.     case Node_postdecrement:
  708.     case Node_assign_exp:
  709.     case Node_assign_times:
  710.     case Node_assign_quotient:
  711.     case Node_assign_mod:
  712.     case Node_assign_plus:
  713.     case Node_assign_minus:
  714.         return op_assign(tree);
  715.     }
  716.  
  717.     /*
  718.      * Note that if TREE is invalid, gawk will probably bomb in one of
  719.      * these tree_evals here.  
  720.      */
  721.     /* evaluate subtrees in order to do binary operation, then keep going */
  722.     t1 = tree_eval(tree->lnode);
  723.     t2 = tree_eval(tree->rnode);
  724.  
  725.     switch (tree->type) {
  726.  
  727.     case Node_concat:
  728.         DBG_P(("CONCAT", tree));
  729.         t1 = force_string(t1);
  730.         t2 = force_string(t2);
  731.  
  732.         emalloc(r, NODE *, sizeof(NODE), "tree_eval");
  733.         r->type = Node_val;
  734.         r->flags = (STR|TEMP);
  735.         r->stlen = t1->stlen + t2->stlen;
  736.         r->stref = 1;
  737.         emalloc(r->stptr, char *, r->stlen + 1, "tree_eval");
  738.         bcopy(t1->stptr, r->stptr, t1->stlen);
  739.         bcopy(t2->stptr, r->stptr + t1->stlen, t2->stlen);
  740.         r->stptr[r->stlen] = '\0';
  741.         return r;
  742.  
  743.     case Node_exp:
  744.         DBG_P(("EXPONENT", tree));
  745.         return tmp_number((AWKNUM) pow((double) force_number(t1), (double) force_number(t2)));
  746.  
  747.     case Node_times:
  748.         DBG_P(("MULT", tree));
  749.         return tmp_number(force_number(t1) * force_number(t2));
  750.  
  751.     case Node_quotient:
  752.         DBG_P(("DIVIDE", tree));
  753.         x = force_number(t2);
  754.         if (x == (AWKNUM) 0)
  755.             return tmp_number((AWKNUM) 0);
  756.         else
  757.             return tmp_number(force_number(t1) / x);
  758.  
  759.     case Node_mod:
  760.         DBG_P(("MODULUS", tree));
  761.         x = force_number(t2);
  762.         if (x == (AWKNUM) 0)
  763.             return tmp_number((AWKNUM) 0);
  764.         return tmp_number((AWKNUM)    /* uggh... */
  765.                   (((int) force_number(t1)) % ((int) x)));
  766.  
  767.     case Node_plus:
  768.         DBG_P(("PLUS", tree));
  769.         return tmp_number(force_number(t1) + force_number(t2));
  770.  
  771.     case Node_minus:
  772.         DBG_P(("MINUS", tree));
  773.         return tmp_number(force_number(t1) - force_number(t2));
  774.  
  775.     case Node_geq:
  776.     case Node_leq:
  777.     case Node_greater:
  778.     case Node_less:
  779.     case Node_notequal:
  780.     case Node_equal:
  781.         di = cmp_nodes(t1, t2);
  782.         switch (tree->type) {
  783.         case Node_equal:
  784.             DBG_P(("EQUAL", tree));
  785.             return tmp_number((AWKNUM) (di == 0));
  786.         case Node_notequal:
  787.             DBG_P(("NOT_EQUAL", tree));
  788.             return tmp_number((AWKNUM) (di != 0));
  789.         case Node_less:
  790.             DBG_P(("LESS_THAN", tree));
  791.             return tmp_number((AWKNUM) (di < 0));
  792.         case Node_greater:
  793.             DBG_P(("GREATER_THAN", tree));
  794.             return tmp_number((AWKNUM) (di > 0));
  795.         case Node_leq:
  796.             DBG_P(("LESS_THAN_EQUAL", tree));
  797.             return tmp_number((AWKNUM) (di <= 0));
  798.         case Node_geq:
  799.             DBG_P(("GREATER_THAN_EQUAL", tree));
  800.             return tmp_number((AWKNUM) (di >= 0));
  801.         }
  802.         break;
  803.  
  804.     default:
  805.         fatal("illegal type (%d) in tree_eval", tree->type);
  806.     }
  807.     return 0;
  808. }
  809.  
  810. /*
  811.  * This makes numeric operations slightly more efficient. Just change the
  812.  * value of a numeric node, if possible 
  813.  */
  814. assign_number(ptr, value)
  815. NODE **ptr;
  816. AWKNUM value;
  817. {
  818.     extern NODE *deref;
  819.  
  820. #ifdef DEBUG
  821.     if ((*ptr)->type != Node_val)
  822.         cant_happen();
  823. #endif
  824.     if (*ptr == Nnull_string) {
  825.         *ptr = make_number(value);
  826.         deref = 0;
  827.         return;
  828.     }
  829.     if ((*ptr)->stref > 1) {
  830.             *ptr = make_number(value);
  831.             return;
  832.         }
  833.     (*ptr)->numbr = value;
  834.     (*ptr)->flags |= NUM;
  835.     (*ptr)->flags &= ~STR;
  836.     (*ptr)->stref = 0;
  837.     deref = 0;
  838. }
  839.  
  840.  
  841. /* Is TREE true or false?  Returns 0==false, non-zero==true */
  842. int
  843. eval_condition(tree)
  844. NODE *tree;
  845. {
  846.     register NODE *t1;
  847.     extern double atof();
  848.  
  849.     if (tree == NULL)    /* Null trees are the easiest kinds */
  850.         return 1;
  851.     switch (tree->type) {
  852.         /* Maybe it's easy; check and see. */
  853.         /* BEGIN and END are always false */
  854.     case Node_K_BEGIN:
  855.     case Node_K_END:
  856.         return 0;
  857.         break;
  858.  
  859.         /*
  860.          * Node_line_range is kind of like Node_match, EXCEPT: the
  861.          * lnode field (more properly, the condpair field) is a node
  862.          * of a Node_cond_pair; whether we evaluate the lnode of that
  863.          * node or the rnode depends on the triggered word.  More
  864.          * precisely:  if we are not yet triggered, we tree_eval the
  865.          * lnode; if that returns true, we set the triggered word. 
  866.          * If we are triggered (not ELSE IF, note), we tree_eval the
  867.          * rnode, clear triggered if it succeeds, and perform our
  868.          * action (regardless of success or failure).  We want to be
  869.          * able to begin and end on a single input record, so this
  870.          * isn't an ELSE IF, as noted above.
  871.          */
  872.     case Node_line_range:
  873.         if (!tree->triggered)
  874.             if (!eval_condition(tree->condpair->lnode))
  875.                 return 0;
  876.             else
  877.                 tree->triggered = 1;
  878.         /* Else we are triggered */
  879.         if (eval_condition(tree->condpair->rnode))
  880.             tree->triggered = 0;
  881.         return 1;
  882.     }
  883.  
  884.     /*
  885.      * Could just be J.random expression. in which case, null and 0 are
  886.      * false, anything else is true 
  887.      */
  888.  
  889.     t1 = tree_eval(tree);
  890. #ifdef DEBUG
  891.     if (t1->type != Node_val)
  892.         cant_happen();
  893. #endif
  894.     if (t1->flags & STR)
  895.         return t1->stlen != 0;
  896.     else
  897.         return t1->numbr != 0.0;
  898. }
  899.  
  900. /*
  901.  * strtod() would have been better, except (1) real awk is needlessly
  902.  * restrictive in what strings it will consider to be numbers, and (2) I
  903.  * couldn't find the public domain version anywhere handy. 
  904.  */
  905. static int
  906. is_a_number(str)    /* does the string str have pure-numeric syntax? */
  907. char *str;        /* don't convert it, assume that atof is better */
  908. {
  909.     if (*str == 0)
  910.         return 0;    /* null string is not equal to 0 */
  911.  
  912.     if (*str == '-')
  913.         str++;
  914.     if (*str == 0)
  915.         return 0;
  916.     /* must be either . or digits (.4 is legal) */
  917.     if (*str != '.' && !isdigit(*str))
  918.         return 0;
  919.     while (isdigit(*str))
  920.         str++;
  921.     if (*str == '.') {
  922.         str++;
  923.         while (isdigit(*str))
  924.             str++;
  925.     }
  926.  
  927.     /*
  928.      * curiously, real awk DOESN'T consider "1E1" to be equal to 10! Or
  929.      * even equal to 1E1 for that matter!  For a laugh, try:
  930.      * awk 'BEGIN {if ("1E1" == 1E1) print "eq"; else print "neq"; exit}'
  931.      * Since this behavior is QUITE curious, I include the code for the
  932.      * adventurous. One might also feel like skipping leading whitespace
  933.      * (awk doesn't) and allowing a leading + (awk doesn't).
  934.      */
  935. #ifdef Allow_Exponents
  936.     if (*str == 'e' || *str == 'E') {
  937.         str++;
  938.         if (*str == '+' || *str == '-')
  939.             str++;
  940.         if (!isdigit(*str))
  941.             return 0;
  942.         while (isdigit(*str))
  943.             str++;
  944.     }
  945. #endif
  946.     /*
  947.      * if we have digested the whole string, we are
  948.      * successful 
  949.      */
  950.     return (*str == 0);
  951. }
  952.  
  953. int
  954. cmp_nodes(t1, t2)
  955. NODE *t1, *t2;
  956. {
  957.     AWKNUM d;
  958.  
  959.     if (t1 == t2)
  960.         return 0;
  961.     if ((t1->flags & NUM)) {
  962.         if ((t2->flags & NUM))
  963.             d = t1->numbr - t2->numbr;
  964.         else if (is_a_number(t2->stptr))
  965.             d = t1->numbr - force_number(t2);
  966.         else {
  967.             t1 = force_string(t1);
  968.             goto strings;
  969.         }
  970.         if (d < 0.0)
  971.             return -1;
  972.         if (d > 0.0)
  973.             return 1;
  974.         return 0;
  975.     }
  976.     if ((t2->flags & NUM)) {
  977.         if (is_a_number(t1->stptr))
  978.             d = force_number(t1) - t2->numbr;
  979.         else {
  980.             t2 = force_string(t2);
  981.             goto strings;
  982.         }
  983.         if (d < 0.0)
  984.             return -1;
  985.         if (d > 0.0)
  986.             return 1;
  987.         return 0;
  988.     }
  989.     if (is_a_number(t1->stptr) && is_a_number(t2->stptr)) {
  990.         d = force_number(t1) - force_number(t2);
  991.         if (d < 0.0)
  992.             return -1;
  993.         if (d > 0.0)
  994.             return 1;
  995.         return 0;
  996.     }
  997.  
  998. strings:
  999.     return strcmp(t1->stptr, t2->stptr);
  1000. }
  1001.  
  1002. NODE *
  1003. op_assign(tree)
  1004. NODE *tree;
  1005. {
  1006.     AWKNUM rval, lval;
  1007.     NODE **lhs;
  1008.  
  1009.     rval = force_number(tree_eval(tree->rnode));
  1010.     lhs = get_lhs(tree->lnode);
  1011.     lval = force_number(*lhs);
  1012.  
  1013.     switch(tree->type) {
  1014.     case Node_preincrement:
  1015.     case Node_predecrement:
  1016.         DBG_P(("+-X", tree));
  1017.         assign_number(lhs,
  1018.             lval + (tree->type == Node_preincrement ? 1.0 : -1.0));
  1019.         break;
  1020.  
  1021.     case Node_postincrement:
  1022.     case Node_postdecrement:
  1023.         DBG_P(("X+-", tree));
  1024.         assign_number(lhs,
  1025.             lval + (tree->type == Node_postincrement ? 1.0 : -1.0));
  1026.         if (field_num == 0)
  1027.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  1028.         else if (field_num > 0) {
  1029.             node0_valid = 0;
  1030.             if (NF_node->var_value->numbr == -1 &&
  1031.                 field_num > NF_node->var_value->numbr)
  1032.                 assign_number(&(NF_node->var_value),
  1033.                     (AWKNUM) field_num);
  1034.         }
  1035.         field_num = -1;
  1036.         do_deref();
  1037.         return tmp_number(lval);
  1038.  
  1039.     case Node_assign_exp:
  1040.         DBG_P(("ASSIGN_exp", tree));
  1041.         assign_number(lhs, (AWKNUM) pow((double) lval, (double) rval));
  1042.         break;
  1043.  
  1044.     case Node_assign_times:
  1045.         DBG_P(("ASSIGN_times", tree));
  1046.         assign_number(lhs, lval * rval);
  1047.         break;
  1048.  
  1049.     case Node_assign_quotient:
  1050.         DBG_P(("ASSIGN_quotient", tree));
  1051.         assign_number(lhs, lval / rval);
  1052.         break;
  1053.  
  1054.     case Node_assign_mod:
  1055.         DBG_P(("ASSIGN_mod", tree));
  1056.         assign_number(lhs, (AWKNUM) (((int) lval) % ((int) rval)));
  1057.         break;
  1058.  
  1059.     case Node_assign_plus:
  1060.         DBG_P(("ASSIGN_plus", tree));
  1061.         assign_number(lhs, lval + rval);
  1062.         break;
  1063.  
  1064.     case Node_assign_minus:
  1065.         DBG_P(("ASSIGN_minus", tree));
  1066.         assign_number(lhs, lval - rval);
  1067.         break;
  1068.     }
  1069.     if (field_num == 0)
  1070.         set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  1071.     else if (field_num > 0) {
  1072.         node0_valid = 0;
  1073.         if (NF_node->var_value->numbr == -1 &&
  1074.             field_num > NF_node->var_value->numbr)
  1075.             assign_number(&(NF_node->var_value),
  1076.                 (AWKNUM) field_num);
  1077.     }
  1078.     field_num = -1;
  1079.     do_deref();
  1080.     return *lhs;
  1081. }
  1082.  
  1083.