home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume22 / gawk2.11 / part12 / eval.c < prev   
C/C++ Source or Header  |  1990-06-07  |  30KB  |  1,140 lines

  1. /*
  2.  * eval.c - gawk parse tree interpreter 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 1, or (at your option)
  14.  * any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. #include "awk.h"
  27.  
  28. extern void do_print();
  29. extern void do_printf();
  30. extern NODE *do_match();
  31. extern NODE *do_sub();
  32. extern NODE *do_getline();
  33. extern NODE *concat_exp();
  34. extern int in_array();
  35. extern void do_delete();
  36. extern double pow();
  37.  
  38. static int eval_condition();
  39. static NODE *op_assign();
  40. static NODE *func_call();
  41. static NODE *match_op();
  42.  
  43. NODE *_t;        /* used as a temporary in macros */
  44. #ifdef MSDOS
  45. double _msc51bug;    /* to get around a bug in MSC 5.1 */
  46. #endif
  47. NODE *ret_node;
  48.  
  49. /* More of that debugging stuff */
  50. #ifdef    DEBUG
  51. #define DBG_P(X) print_debug X
  52. #else
  53. #define DBG_P(X)
  54. #endif
  55.  
  56. /* Macros and variables to save and restore function and loop bindings */
  57. /*
  58.  * the val variable allows return/continue/break-out-of-context to be
  59.  * caught and diagnosed
  60.  */
  61. #define PUSH_BINDING(stack, x, val) (memcpy ((char *)(stack), (char *)(x), sizeof (jmp_buf)), val++)
  62. #define RESTORE_BINDING(stack, x, val) (memcpy ((char *)(x), (char *)(stack), sizeof (jmp_buf)), val--)
  63.  
  64. static jmp_buf loop_tag;    /* always the current binding */
  65. static int loop_tag_valid = 0;    /* nonzero when loop_tag valid */
  66. static int func_tag_valid = 0;
  67. static jmp_buf func_tag;
  68. extern int exiting, exit_val;
  69.  
  70. /*
  71.  * This table is used by the regexp routines to do case independant
  72.  * matching. Basically, every ascii character maps to itself, except
  73.  * uppercase letters map to lower case ones. This table has 256
  74.  * entries, which may be overkill. Note also that if the system this
  75.  * is compiled on doesn't use 7-bit ascii, casetable[] should not be
  76.  * defined to the linker, so gawk should not load.
  77.  *
  78.  * Do NOT make this array static, it is used in several spots, not
  79.  * just in this file.
  80.  */
  81. #if 'a' == 97    /* it's ascii */
  82. char casetable[] = {
  83.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  84.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  85.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  86.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  87.     /* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
  88.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  89.     /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
  90.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  91.     /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
  92.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  93.     /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
  94.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  95.     /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
  96.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  97.     /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
  98.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  99.     /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
  100.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  101.     /* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
  102.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  103.     /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
  104.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  105.     /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
  106.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  107.     /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
  108.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  109.     /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
  110.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  111.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  112.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  113.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  114.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  115.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  116.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  117.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  118.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  119.     '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
  120.     '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
  121.     '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
  122.     '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
  123.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  124.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  125.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  126.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  127. };
  128. #else
  129. #include "You lose. You will need a translation table for your character set."
  130. #endif
  131.  
  132. /*
  133.  * Tree is a bunch of rules to run. Returns zero if it hit an exit()
  134.  * statement 
  135.  */
  136. int
  137. interpret(tree)
  138. NODE *tree;
  139. {
  140.     volatile jmp_buf loop_tag_stack; /* shallow binding stack for loop_tag */
  141.     static jmp_buf rule_tag;/* tag the rule currently being run, for NEXT
  142.                  * and EXIT statements.  It is static because
  143.                  * there are no nested rules */
  144.     register NODE *t = NULL;/* temporary */
  145.     volatile NODE **lhs;    /* lhs == Left Hand Side for assigns, etc */
  146.     volatile struct search *l;    /* For array_for */
  147.     volatile NODE *stable_tree;
  148.  
  149.     if (tree == NULL)
  150.         return 1;
  151.     sourceline = tree->source_line;
  152.     source = tree->source_file;
  153.     switch (tree->type) {
  154.     case Node_rule_list:
  155.         for (t = tree; t != NULL; t = t->rnode) {
  156.             tree = t->lnode;
  157.         /* FALL THROUGH */
  158.     case Node_rule_node:
  159.             sourceline = tree->source_line;
  160.             source = tree->source_file;
  161.             switch (setjmp(rule_tag)) {
  162.             case 0:    /* normal non-jump */
  163.                 /* test pattern, if any */
  164.                 if (tree->lnode == NULL 
  165.                     || eval_condition(tree->lnode)) {
  166.                     DBG_P(("Found a rule", tree->rnode));
  167.                     if (tree->rnode == NULL) {
  168.                         /*
  169.                          * special case: pattern with
  170.                          * no action is equivalent to
  171.                          * an action of {print}
  172.                          */
  173.                         NODE printnode;
  174.  
  175.                         printnode.type = Node_K_print;
  176.                         printnode.lnode = NULL;
  177.                         printnode.rnode = NULL;
  178.                         do_print(&printnode);
  179.                     } else if (tree->rnode->type == Node_illegal) {
  180.                         /*
  181.                          * An empty statement
  182.                          * (``{ }'') is different
  183.                          * from a missing statement.
  184.                          * A missing statement is
  185.                          * equal to ``{ print }'' as
  186.                          * above, but an empty
  187.                          * statement is as in C, do
  188.                          * nothing.
  189.                          */
  190.                     } else
  191.                         (void) interpret(tree->rnode);
  192.                 }
  193.                 break;
  194.             case TAG_CONTINUE:    /* NEXT statement */
  195.                 return 1;
  196.             case TAG_BREAK:
  197.                 return 0;
  198.             default:
  199.                 cant_happen();
  200.             }
  201.             if (t == NULL)
  202.                 break;
  203.         }
  204.         break;
  205.  
  206.     case Node_statement_list:
  207.         for (t = tree; t != NULL; t = t->rnode) {
  208.             DBG_P(("Statements", t->lnode));
  209.             (void) interpret(t->lnode);
  210.         }
  211.         break;
  212.  
  213.     case Node_K_if:
  214.         DBG_P(("IF", tree->lnode));
  215.         if (eval_condition(tree->lnode)) {
  216.             DBG_P(("True", tree->rnode->lnode));
  217.             (void) interpret(tree->rnode->lnode);
  218.         } else {
  219.             DBG_P(("False", tree->rnode->rnode));
  220.             (void) interpret(tree->rnode->rnode);
  221.         }
  222.         break;
  223.  
  224.     case Node_K_while:
  225.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  226.  
  227.         DBG_P(("WHILE", tree->lnode));
  228.         stable_tree = tree;
  229.         while (eval_condition(stable_tree->lnode)) {
  230.             switch (setjmp(loop_tag)) {
  231.             case 0:    /* normal non-jump */
  232.                 DBG_P(("DO", stable_tree->rnode));
  233.                 (void) interpret(stable_tree->rnode);
  234.                 break;
  235.             case TAG_CONTINUE:    /* continue statement */
  236.                 break;
  237.             case TAG_BREAK:    /* break statement */
  238.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  239.                 return 1;
  240.             default:
  241.                 cant_happen();
  242.             }
  243.         }
  244.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  245.         break;
  246.  
  247.     case Node_K_do:
  248.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  249.         stable_tree = tree;
  250.         do {
  251.             switch (setjmp(loop_tag)) {
  252.             case 0:    /* normal non-jump */
  253.                 DBG_P(("DO", stable_tree->rnode));
  254.                 (void) interpret(stable_tree->rnode);
  255.                 break;
  256.             case TAG_CONTINUE:    /* continue statement */
  257.                 break;
  258.             case TAG_BREAK:    /* break statement */
  259.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  260.                 return 1;
  261.             default:
  262.                 cant_happen();
  263.             }
  264.             DBG_P(("WHILE", stable_tree->lnode));
  265.         } while (eval_condition(stable_tree->lnode));
  266.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  267.         break;
  268.  
  269.     case Node_K_for:
  270.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  271.         DBG_P(("FOR", tree->forloop->init));
  272.         (void) interpret(tree->forloop->init);
  273.         DBG_P(("FOR.WHILE", tree->forloop->cond));
  274.         stable_tree = tree;
  275.         while (eval_condition(stable_tree->forloop->cond)) {
  276.             switch (setjmp(loop_tag)) {
  277.             case 0:    /* normal non-jump */
  278.                 DBG_P(("FOR.DO", stable_tree->lnode));
  279.                 (void) interpret(stable_tree->lnode);
  280.                 /* fall through */
  281.             case TAG_CONTINUE:    /* continue statement */
  282.                 DBG_P(("FOR.INCR", stable_tree->forloop->incr));
  283.                 (void) interpret(stable_tree->forloop->incr);
  284.                 break;
  285.             case TAG_BREAK:    /* break statement */
  286.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  287.                 return 1;
  288.             default:
  289.                 cant_happen();
  290.             }
  291.         }
  292.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  293.         break;
  294.  
  295.     case Node_K_arrayfor:
  296. #define hakvar forloop->init
  297. #define arrvar forloop->incr
  298.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  299.         DBG_P(("AFOR.VAR", tree->hakvar));
  300.         lhs = (volatile NODE **) get_lhs(tree->hakvar, 1);
  301.         t = tree->arrvar;
  302.         if (t->type == Node_param_list)
  303.             t = stack_ptr[t->param_cnt];
  304.         stable_tree = tree;
  305.         for (l = assoc_scan(t); l; l = assoc_next((struct search *)l)) {
  306.             deref = *((NODE **) lhs);
  307.             do_deref();
  308.             *lhs = dupnode(l->retval);
  309.             if (field_num == 0)
  310.                 set_record(fields_arr[0]->stptr,
  311.                     fields_arr[0]->stlen);
  312.             DBG_P(("AFOR.NEXTIS", *lhs));
  313.             switch (setjmp(loop_tag)) {
  314.             case 0:
  315.                 DBG_P(("AFOR.DO", stable_tree->lnode));
  316.                 (void) interpret(stable_tree->lnode);
  317.             case TAG_CONTINUE:
  318.                 break;
  319.  
  320.             case TAG_BREAK:
  321.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  322.                 field_num = -1;
  323.                 return 1;
  324.             default:
  325.                 cant_happen();
  326.             }
  327.         }
  328.         field_num = -1;
  329.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  330.         break;
  331.  
  332.     case Node_K_break:
  333.         DBG_P(("BREAK", NULL));
  334.         if (loop_tag_valid == 0)
  335.             fatal("unexpected break");
  336.         longjmp(loop_tag, TAG_BREAK);
  337.         break;
  338.  
  339.     case Node_K_continue:
  340.         DBG_P(("CONTINUE", NULL));
  341.         if (loop_tag_valid == 0)
  342.             fatal("unexpected continue");
  343.         longjmp(loop_tag, TAG_CONTINUE);
  344.         break;
  345.  
  346.     case Node_K_print:
  347.         DBG_P(("PRINT", tree));
  348.         do_print(tree);
  349.         break;
  350.  
  351.     case Node_K_printf:
  352.         DBG_P(("PRINTF", tree));
  353.         do_printf(tree);
  354.         break;
  355.  
  356.     case Node_K_next:
  357.         DBG_P(("NEXT", NULL));
  358.         longjmp(rule_tag, TAG_CONTINUE);
  359.         break;
  360.  
  361.     case Node_K_exit:
  362.         /*
  363.          * In A,K,&W, p. 49, it says that an exit statement "...
  364.          * causes the program to behave as if the end of input had
  365.          * occurred; no more input is read, and the END actions, if
  366.          * any are executed." This implies that the rest of the rules
  367.          * are not done. So we immediately break out of the main loop.
  368.          */
  369.         DBG_P(("EXIT", NULL));
  370.         exiting = 1;
  371.         if (tree) {
  372.             t = tree_eval(tree->lnode);
  373.             exit_val = (int) force_number(t);
  374.         }
  375.         free_temp(t);
  376.         longjmp(rule_tag, TAG_BREAK);
  377.         break;
  378.  
  379.     case Node_K_return:
  380.         DBG_P(("RETURN", NULL));
  381.         t = tree_eval(tree->lnode);
  382.         ret_node = dupnode(t);
  383.         free_temp(t);
  384.         longjmp(func_tag, TAG_RETURN);
  385.         break;
  386.  
  387.     default:
  388.         /*
  389.          * Appears to be an expression statement.  Throw away the
  390.          * value. 
  391.          */
  392.         DBG_P(("E", NULL));
  393.         t = tree_eval(tree);
  394.         free_temp(t);
  395.         break;
  396.     }
  397.     return 1;
  398. }
  399.  
  400. /* evaluate a subtree, allocating strings on a temporary stack. */
  401.  
  402. NODE *
  403. r_tree_eval(tree)
  404. NODE *tree;
  405. {
  406.     register NODE *r, *t1, *t2;    /* return value & temporary subtrees */
  407.     int i;
  408.     register NODE **lhs;
  409.     int di;
  410.     AWKNUM x, x2;
  411.     long lx;
  412.     extern NODE **fields_arr;
  413.  
  414.     source = tree->source_file;
  415.     sourceline = tree->source_line;
  416.     switch (tree->type) {
  417.     case Node_and:
  418.         DBG_P(("AND", tree));
  419.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  420.                         && eval_condition(tree->rnode)));
  421.  
  422.     case Node_or:
  423.         DBG_P(("OR", tree));
  424.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  425.                         || eval_condition(tree->rnode)));
  426.  
  427.     case Node_not:
  428.         DBG_P(("NOT", tree));
  429.         return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
  430.  
  431.         /* Builtins */
  432.     case Node_builtin:
  433.         DBG_P(("builtin", tree));
  434.         return ((*tree->proc) (tree->subnode));
  435.  
  436.     case Node_K_getline:
  437.         DBG_P(("GETLINE", tree));
  438.         return (do_getline(tree));
  439.  
  440.     case Node_in_array:
  441.         DBG_P(("IN_ARRAY", tree));
  442.         return tmp_number((AWKNUM) in_array(tree->lnode, tree->rnode));
  443.  
  444.     case Node_func_call:
  445.         DBG_P(("func_call", tree));
  446.         return func_call(tree->rnode, tree->lnode);
  447.  
  448.     case Node_K_delete:
  449.         DBG_P(("DELETE", tree));
  450.         do_delete(tree->lnode, tree->rnode);
  451.         return Nnull_string;
  452.  
  453.         /* unary operations */
  454.  
  455.     case Node_var:
  456.     case Node_var_array:
  457.     case Node_param_list:
  458.     case Node_subscript:
  459.     case Node_field_spec:
  460.         DBG_P(("var_type ref", tree));
  461.         lhs = get_lhs(tree, 0);
  462.         field_num = -1;
  463.         deref = 0;
  464.         return *lhs;
  465.  
  466.     case Node_unary_minus:
  467.         DBG_P(("UMINUS", tree));
  468.         t1 = tree_eval(tree->subnode);
  469.         x = -force_number(t1);
  470.         free_temp(t1);
  471.         return tmp_number(x);
  472.  
  473.     case Node_cond_exp:
  474.         DBG_P(("?:", tree));
  475.         if (eval_condition(tree->lnode)) {
  476.             DBG_P(("True", tree->rnode->lnode));
  477.             return tree_eval(tree->rnode->lnode);
  478.         }
  479.         DBG_P(("False", tree->rnode->rnode));
  480.         return tree_eval(tree->rnode->rnode);
  481.  
  482.     case Node_match:
  483.     case Node_nomatch:
  484.     case Node_regex:
  485.         DBG_P(("[no]match_op", tree));
  486.         return match_op(tree);
  487.  
  488.     case Node_func:
  489.         fatal("function `%s' called with space between name and (,\n%s",
  490.             tree->lnode->param,
  491.             "or used in other expression context");
  492.  
  493.     /* assignments */
  494.     case Node_assign:
  495.         DBG_P(("ASSIGN", tree));
  496.         r = tree_eval(tree->rnode);
  497.         lhs = get_lhs(tree->lnode, 1);
  498.         *lhs = dupnode(r);
  499.         free_temp(r);
  500.         do_deref();
  501.         if (field_num == 0)
  502.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  503.         field_num = -1;
  504.         return *lhs;
  505.  
  506.     /* other assignment types are easier because they are numeric */
  507.     case Node_preincrement:
  508.     case Node_predecrement:
  509.     case Node_postincrement:
  510.     case Node_postdecrement:
  511.     case Node_assign_exp:
  512.     case Node_assign_times:
  513.     case Node_assign_quotient:
  514.     case Node_assign_mod:
  515.     case Node_assign_plus:
  516.     case Node_assign_minus:
  517.         return op_assign(tree);
  518.     default:
  519.         break;    /* handled below */
  520.     }
  521.  
  522.     /* evaluate subtrees in order to do binary operation, then keep going */
  523.     t1 = tree_eval(tree->lnode);
  524.     t2 = tree_eval(tree->rnode);
  525.  
  526.     switch (tree->type) {
  527.     case Node_concat:
  528.         DBG_P(("CONCAT", tree));
  529.         t1 = force_string(t1);
  530.         t2 = force_string(t2);
  531.  
  532.         r = newnode(Node_val);
  533.         r->flags |= (STR|TEMP);
  534.         r->stlen = t1->stlen + t2->stlen;
  535.         r->stref = 1;
  536.         emalloc(r->stptr, char *, r->stlen + 1, "tree_eval");
  537.         memcpy(r->stptr, t1->stptr, t1->stlen);
  538.         memcpy(r->stptr + t1->stlen, t2->stptr, t2->stlen + 1);
  539.         free_temp(t1);
  540.         free_temp(t2);
  541.         return r;
  542.  
  543.     case Node_geq:
  544.     case Node_leq:
  545.     case Node_greater:
  546.     case Node_less:
  547.     case Node_notequal:
  548.     case Node_equal:
  549.         di = cmp_nodes(t1, t2);
  550.         free_temp(t1);
  551.         free_temp(t2);
  552.         switch (tree->type) {
  553.         case Node_equal:
  554.             DBG_P(("EQUAL", tree));
  555.             return tmp_number((AWKNUM) (di == 0));
  556.         case Node_notequal:
  557.             DBG_P(("NOT_EQUAL", tree));
  558.             return tmp_number((AWKNUM) (di != 0));
  559.         case Node_less:
  560.             DBG_P(("LESS_THAN", tree));
  561.             return tmp_number((AWKNUM) (di < 0));
  562.         case Node_greater:
  563.             DBG_P(("GREATER_THAN", tree));
  564.             return tmp_number((AWKNUM) (di > 0));
  565.         case Node_leq:
  566.             DBG_P(("LESS_THAN_EQUAL", tree));
  567.             return tmp_number((AWKNUM) (di <= 0));
  568.         case Node_geq:
  569.             DBG_P(("GREATER_THAN_EQUAL", tree));
  570.             return tmp_number((AWKNUM) (di >= 0));
  571.         default:
  572.             cant_happen();
  573.         }
  574.         break;
  575.     default:
  576.         break;    /* handled below */
  577.     }
  578.  
  579.     (void) force_number(t1);
  580.     (void) force_number(t2);
  581.  
  582.     switch (tree->type) {
  583.     case Node_exp:
  584.         DBG_P(("EXPONENT", tree));
  585.         if ((lx = t2->numbr) == t2->numbr) {    /* integer exponent */
  586.             if (lx == 0)
  587.                 x = 1;
  588.             else if (lx == 1)
  589.                 x = t1->numbr;
  590.             else {
  591.                 /* doing it this way should be more precise */
  592.                 for (x = x2 = t1->numbr; --lx; )
  593.                     x *= x2;
  594.             }
  595.         } else
  596.             x = pow((double) t1->numbr, (double) t2->numbr);
  597.         free_temp(t1);
  598.         free_temp(t2);
  599.         return tmp_number(x);
  600.  
  601.     case Node_times:
  602.         DBG_P(("MULT", tree));
  603.         x = t1->numbr * t2->numbr;
  604.         free_temp(t1);
  605.         free_temp(t2);
  606.         return tmp_number(x);
  607.  
  608.     case Node_quotient:
  609.         DBG_P(("DIVIDE", tree));
  610.         x = t2->numbr;
  611.         free_temp(t2);
  612.         if (x == (AWKNUM) 0)
  613.             fatal("division by zero attempted");
  614.             /* NOTREACHED */
  615.         else {
  616.             x = t1->numbr / x;
  617.             free_temp(t1);
  618.             return tmp_number(x);
  619.         }
  620.  
  621.     case Node_mod:
  622.         DBG_P(("MODULUS", tree));
  623.         x = t2->numbr;
  624.         free_temp(t2);
  625.         if (x == (AWKNUM) 0)
  626.             fatal("division by zero attempted in mod");
  627.             /* NOTREACHED */
  628.         lx = t1->numbr / x;    /* assignment to long truncates */
  629.         x2 = lx * x;
  630.         x = t1->numbr - x2;
  631.         free_temp(t1);
  632.         return tmp_number(x);
  633.  
  634.     case Node_plus:
  635.         DBG_P(("PLUS", tree));
  636.         x = t1->numbr + t2->numbr;
  637.         free_temp(t1);
  638.         free_temp(t2);
  639.         return tmp_number(x);
  640.  
  641.     case Node_minus:
  642.         DBG_P(("MINUS", tree));
  643.         x = t1->numbr - t2->numbr;
  644.         free_temp(t1);
  645.         free_temp(t2);
  646.         return tmp_number(x);
  647.  
  648.     default:
  649.         fatal("illegal type (%d) in tree_eval", tree->type);
  650.     }
  651.     return 0;
  652. }
  653.  
  654. /*
  655.  * This makes numeric operations slightly more efficient. Just change the
  656.  * value of a numeric node, if possible 
  657.  */
  658. void
  659. assign_number(ptr, value)
  660. NODE **ptr;
  661. AWKNUM value;
  662. {
  663.     extern NODE *deref;
  664.     register NODE *n = *ptr;
  665.  
  666. #ifdef DEBUG
  667.     if (n->type != Node_val)
  668.         cant_happen();
  669. #endif
  670.     if (n == Nnull_string) {
  671.         *ptr = make_number(value);
  672.         deref = 0;
  673.         return;
  674.     }
  675.     if (n->stref > 1) {
  676.         *ptr = make_number(value);
  677.         return;
  678.     }
  679.     if ((n->flags & STR) && (n->flags & (MALLOC|TEMP)))
  680.         free(n->stptr);
  681.     n->numbr = value;
  682.     n->flags |= (NUM|NUMERIC);
  683.     n->flags &= ~STR;
  684.     n->stref = 0;
  685.     deref = 0;
  686. }
  687.  
  688.  
  689. /* Is TREE true or false?  Returns 0==false, non-zero==true */
  690. static int
  691. eval_condition(tree)
  692. NODE *tree;
  693. {
  694.     register NODE *t1;
  695.     int ret;
  696.  
  697.     if (tree == NULL)    /* Null trees are the easiest kinds */
  698.         return 1;
  699.     if (tree->type == Node_line_range) {
  700.         /*
  701.          * Node_line_range is kind of like Node_match, EXCEPT: the
  702.          * lnode field (more properly, the condpair field) is a node
  703.          * of a Node_cond_pair; whether we evaluate the lnode of that
  704.          * node or the rnode depends on the triggered word.  More
  705.          * precisely:  if we are not yet triggered, we tree_eval the
  706.          * lnode; if that returns true, we set the triggered word. 
  707.          * If we are triggered (not ELSE IF, note), we tree_eval the
  708.          * rnode, clear triggered if it succeeds, and perform our
  709.          * action (regardless of success or failure).  We want to be
  710.          * able to begin and end on a single input record, so this
  711.          * isn't an ELSE IF, as noted above.
  712.          */
  713.         if (!tree->triggered)
  714.             if (!eval_condition(tree->condpair->lnode))
  715.                 return 0;
  716.             else
  717.                 tree->triggered = 1;
  718.         /* Else we are triggered */
  719.         if (eval_condition(tree->condpair->rnode))
  720.             tree->triggered = 0;
  721.         return 1;
  722.     }
  723.  
  724.     /*
  725.      * Could just be J.random expression. in which case, null and 0 are
  726.      * false, anything else is true 
  727.      */
  728.  
  729.     t1 = tree_eval(tree);
  730.     if (t1->flags & NUMERIC)
  731.         ret = t1->numbr != 0.0;
  732.     else
  733.         ret = t1->stlen != 0;
  734.     free_temp(t1);
  735.     return ret;
  736. }
  737.  
  738. int
  739. cmp_nodes(t1, t2)
  740. NODE *t1, *t2;
  741. {
  742.     AWKNUM d;
  743.     AWKNUM d1;
  744.     AWKNUM d2;
  745.     int ret;
  746.     int len1, len2;
  747.  
  748.     if (t1 == t2)
  749.         return 0;
  750.     d1 = force_number(t1);
  751.     d2 = force_number(t2);
  752.     if ((t1->flags & NUMERIC) && (t2->flags & NUMERIC)) {
  753.         d = d1 - d2;
  754.         if (d == 0.0)    /* from profiling, this is most common */
  755.             return 0;
  756.         if (d > 0.0)
  757.             return 1;
  758.         return -1;
  759.     }
  760.     t1 = force_string(t1);
  761.     t2 = force_string(t2);
  762.     len1 = t1->stlen;
  763.     len2 = t2->stlen;
  764.     if (len1 == 0) {
  765.         if (len2 == 0)
  766.             return 0;
  767.         else
  768.             return -1;
  769.     } else if (len2 == 0)
  770.         return 1;
  771.     ret = memcmp(t1->stptr, t2->stptr, len1 <= len2 ? len1 : len2);
  772.     if (ret == 0 && len1 != len2)
  773.         return len1 < len2 ? -1: 1;
  774.     return ret;
  775. }
  776.  
  777. static NODE *
  778. op_assign(tree)
  779. NODE *tree;
  780. {
  781.     AWKNUM rval, lval;
  782.     NODE **lhs;
  783.     AWKNUM t1, t2;
  784.     long ltemp;
  785.     NODE *tmp;
  786.  
  787.     lhs = get_lhs(tree->lnode, 1);
  788.     lval = force_number(*lhs);
  789.  
  790.     switch(tree->type) {
  791.     case Node_preincrement:
  792.     case Node_predecrement:
  793.         DBG_P(("+-X", tree));
  794.         assign_number(lhs,
  795.             lval + (tree->type == Node_preincrement ? 1.0 : -1.0));
  796.         do_deref();
  797.         if (field_num == 0)
  798.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  799.         field_num = -1;
  800.         return *lhs;
  801.  
  802.     case Node_postincrement:
  803.     case Node_postdecrement:
  804.         DBG_P(("X+-", tree));
  805.         assign_number(lhs,
  806.             lval + (tree->type == Node_postincrement ? 1.0 : -1.0));
  807.         do_deref();
  808.         if (field_num == 0)
  809.             set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  810.         field_num = -1;
  811.         return tmp_number(lval);
  812.     default:
  813.         break;    /* handled below */
  814.     }
  815.  
  816.     tmp = tree_eval(tree->rnode);
  817.     rval = force_number(tmp);
  818.     free_temp(tmp);
  819.     switch(tree->type) {
  820.     case Node_assign_exp:
  821.         DBG_P(("ASSIGN_exp", tree));
  822.         if ((ltemp = rval) == rval) {    /* integer exponent */
  823.             if (ltemp == 0)
  824.                 assign_number(lhs, (AWKNUM) 1);
  825.             else if (ltemp == 1)
  826.                 assign_number(lhs, lval);
  827.             else {
  828.                 /* doing it this way should be more precise */
  829.                 for (t1 = t2 = lval; --ltemp; )
  830.                     t1 *= t2;
  831.                 assign_number(lhs, t1);
  832.             }
  833.         } else
  834.             assign_number(lhs, (AWKNUM) pow((double) lval, (double) rval));
  835.         break;
  836.  
  837.     case Node_assign_times:
  838.         DBG_P(("ASSIGN_times", tree));
  839.         assign_number(lhs, lval * rval);
  840.         break;
  841.  
  842.     case Node_assign_quotient:
  843.         DBG_P(("ASSIGN_quotient", tree));
  844.         if (rval == (AWKNUM) 0)
  845.             fatal("division by zero attempted in /=");
  846.         assign_number(lhs, lval / rval);
  847.         break;
  848.  
  849.     case Node_assign_mod:
  850.         DBG_P(("ASSIGN_mod", tree));
  851.         if (rval == (AWKNUM) 0)
  852.             fatal("division by zero attempted in %=");
  853.         ltemp = lval / rval;    /* assignment to long truncates */
  854.         t1 = ltemp * rval;
  855.         t2 = lval - t1;
  856.         assign_number(lhs, t2);
  857.         break;
  858.  
  859.     case Node_assign_plus:
  860.         DBG_P(("ASSIGN_plus", tree));
  861.         assign_number(lhs, lval + rval);
  862.         break;
  863.  
  864.     case Node_assign_minus:
  865.         DBG_P(("ASSIGN_minus", tree));
  866.         assign_number(lhs, lval - rval);
  867.         break;
  868.     default:
  869.         cant_happen();
  870.     }
  871.     do_deref();
  872.     if (field_num == 0)
  873.         set_record(fields_arr[0]->stptr, fields_arr[0]->stlen);
  874.     field_num = -1;
  875.     return *lhs;
  876. }
  877.  
  878. NODE **stack_ptr;
  879.  
  880. static NODE *
  881. func_call(name, arg_list)
  882. NODE *name;        /* name is a Node_val giving function name */
  883. NODE *arg_list;        /* Node_expression_list of calling args. */
  884. {
  885.     register NODE *arg, *argp, *r;
  886.     NODE *n, *f;
  887.     volatile jmp_buf func_tag_stack;
  888.     volatile jmp_buf loop_tag_stack;
  889.     volatile int save_loop_tag_valid = 0;
  890.     volatile NODE **save_stack, *save_ret_node;
  891.     NODE **local_stack, **sp;
  892.     int count;
  893.     extern NODE *ret_node;
  894.  
  895.     /*
  896.      * retrieve function definition node
  897.      */
  898.     f = lookup(variables, name->stptr);
  899.     if (!f || f->type != Node_func)
  900.         fatal("function `%s' not defined", name->stptr);
  901. #ifdef FUNC_TRACE
  902.     fprintf(stderr, "function %s called\n", name->stptr);
  903. #endif
  904.     count = f->lnode->param_cnt;
  905.     emalloc(local_stack, NODE **, count * sizeof(NODE *), "func_call");
  906.     sp = local_stack;
  907.  
  908.     /*
  909.      * for each calling arg. add NODE * on stack
  910.      */
  911.     for (argp = arg_list; count && argp != NULL; argp = argp->rnode) {
  912.         arg = argp->lnode;
  913.         r = newnode(Node_var);
  914.         /*
  915.          * call by reference for arrays; see below also
  916.          */
  917.         if (arg->type == Node_param_list)
  918.             arg = stack_ptr[arg->param_cnt];
  919.         if (arg->type == Node_var_array)
  920.             *r = *arg;
  921.         else {
  922.             n = tree_eval(arg);
  923.             r->lnode = dupnode(n);
  924.             r->rnode = (NODE *) NULL;
  925.             free_temp(n);
  926.           }
  927.         *sp++ = r;
  928.         count--;
  929.     }
  930.     if (argp != NULL)    /* left over calling args. */
  931.         warning(
  932.             "function `%s' called with more arguments than declared",
  933.             name->stptr);
  934.     /*
  935.      * add remaining params. on stack with null value
  936.      */
  937.     while (count-- > 0) {
  938.         r = newnode(Node_var);
  939.         r->lnode = Nnull_string;
  940.         r->rnode = (NODE *) NULL;
  941.         *sp++ = r;
  942.     }
  943.  
  944.     /*
  945.      * Execute function body, saving context, as a return statement
  946.      * will longjmp back here.
  947.      *
  948.      * Have to save and restore the loop_tag stuff so that a return
  949.      * inside a loop in a function body doesn't scrog any loops going
  950.      * on in the main program.  We save the necessary info in variables
  951.      * local to this function so that function nesting works OK.
  952.      * We also only bother to save the loop stuff if we're in a loop
  953.      * when the function is called.
  954.      */
  955.     if (loop_tag_valid) {
  956.         int junk = 0;
  957.  
  958.         save_loop_tag_valid = (volatile int) loop_tag_valid;
  959.         PUSH_BINDING(loop_tag_stack, loop_tag, junk);
  960.         loop_tag_valid = 0;
  961.     }
  962.     save_stack = (volatile NODE **) stack_ptr;
  963.     stack_ptr = local_stack;
  964.     PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
  965.     save_ret_node = (volatile NODE *) ret_node;
  966.     ret_node = Nnull_string;    /* default return value */
  967.     if (setjmp(func_tag) == 0)
  968.         (void) interpret(f->rnode);
  969.  
  970.     r = ret_node;
  971.     ret_node = (NODE *) save_ret_node;
  972.     RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
  973.     stack_ptr = (NODE **) save_stack;
  974.  
  975.     /*
  976.      * here, we pop each parameter and check whether
  977.      * it was an array.  If so, and if the arg. passed in was
  978.      * a simple variable, then the value should be copied back.
  979.      * This achieves "call-by-reference" for arrays.
  980.      */
  981.     sp = local_stack;
  982.     count = f->lnode->param_cnt;
  983.     for (argp = arg_list; count > 0 && argp != NULL; argp = argp->rnode) {
  984.         arg = argp->lnode;
  985.         n = *sp++;
  986.         if (arg->type == Node_var && n->type == Node_var_array) {
  987.             arg->var_array = n->var_array;
  988.             arg->type = Node_var_array;
  989.         }
  990.         deref = n->lnode;
  991.         do_deref();
  992.         freenode(n);
  993.         count--;
  994.     }
  995.     while (count-- > 0) {
  996.         n = *sp++;
  997.         deref = n->lnode;
  998.         do_deref();
  999.         freenode(n);
  1000.     }
  1001.     free((char *) local_stack);
  1002.  
  1003.     /* Restore the loop_tag stuff if necessary. */
  1004.     if (save_loop_tag_valid) {
  1005.         int junk = 0;
  1006.  
  1007.         loop_tag_valid = (int) save_loop_tag_valid;
  1008.         RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
  1009.     }
  1010.  
  1011.     if (!(r->flags & PERM))
  1012.         r->flags |= TEMP;
  1013.     return r;
  1014. }
  1015.  
  1016. /*
  1017.  * This returns a POINTER to a node pointer. get_lhs(ptr) is the current
  1018.  * value of the var, or where to store the var's new value 
  1019.  */
  1020.  
  1021. NODE **
  1022. get_lhs(ptr, assign)
  1023. NODE *ptr;
  1024. int assign;        /* this is being called for the LHS of an assign. */
  1025. {
  1026.     register NODE **aptr;
  1027.     NODE *n;
  1028.  
  1029. #ifdef DEBUG
  1030.     if (ptr == NULL)
  1031.         cant_happen();
  1032. #endif
  1033.     deref = NULL;
  1034.     field_num = -1;
  1035.     switch (ptr->type) {
  1036.     case Node_var:
  1037.     case Node_var_array:
  1038.         if (ptr == NF_node && (int) NF_node->var_value->numbr == -1)
  1039.             (void) get_field(HUGE-1, assign); /* parse record */
  1040.         deref = ptr->var_value;
  1041. #ifdef DEBUG
  1042.         if (deref->type != Node_val)
  1043.             cant_happen();
  1044.         if (deref->flags == 0)
  1045.             cant_happen();
  1046. #endif
  1047.         return &(ptr->var_value);
  1048.  
  1049.     case Node_param_list:
  1050.         n = stack_ptr[ptr->param_cnt];
  1051.         deref = n->var_value;
  1052. #ifdef DEBUG
  1053.         if (deref->type != Node_val)
  1054.             cant_happen();
  1055.         if (deref->flags == 0)
  1056.             cant_happen();
  1057. #endif
  1058.         return &(n->var_value);
  1059.  
  1060.     case Node_field_spec:
  1061.         n = tree_eval(ptr->lnode);
  1062.         field_num = (int) force_number(n);
  1063.         free_temp(n);
  1064.         if (field_num < 0)
  1065.             fatal("attempt to access field %d", field_num);
  1066.         aptr = get_field(field_num, assign);
  1067.         deref = *aptr;
  1068.         return aptr;
  1069.  
  1070.     case Node_subscript:
  1071.         n = ptr->lnode;
  1072.         if (n->type == Node_param_list)
  1073.             n = stack_ptr[n->param_cnt];
  1074.         aptr = assoc_lookup(n, concat_exp(ptr->rnode));
  1075.         deref = *aptr;
  1076. #ifdef DEBUG
  1077.         if (deref->type != Node_val)
  1078.             cant_happen();
  1079.         if (deref->flags == 0)
  1080.             cant_happen();
  1081. #endif
  1082.         return aptr;
  1083.     case Node_func:
  1084.         fatal ("`%s' is a function, assignment is not allowed",
  1085.             ptr->lnode->param);
  1086.     default:
  1087.         cant_happen();
  1088.     }
  1089.     return 0;
  1090. }
  1091.  
  1092. static NODE *
  1093. match_op(tree)
  1094. NODE *tree;
  1095. {
  1096.     NODE *t1;
  1097.     struct re_pattern_buffer *rp;
  1098.     int i;
  1099.     int match = 1;
  1100.  
  1101.     if (tree->type == Node_nomatch)
  1102.         match = 0;
  1103.     if (tree->type == Node_regex)
  1104.         t1 = WHOLELINE;
  1105.     else {
  1106.         if (tree->lnode)
  1107.             t1 = force_string(tree_eval(tree->lnode));
  1108.         else
  1109.             t1 = WHOLELINE;
  1110.         tree = tree->rnode;
  1111.     }
  1112.     if (tree->type == Node_regex) {
  1113.         rp = tree->rereg;
  1114.         if (!strict && ((IGNORECASE_node->var_value->numbr != 0)
  1115.             ^ (tree->re_case != 0))) {
  1116.             /* recompile since case sensitivity differs */
  1117.             rp = tree->rereg =
  1118.                 mk_re_parse(tree->re_text,
  1119.                 (IGNORECASE_node->var_value->numbr != 0));
  1120.             tree->re_case =
  1121.                 (IGNORECASE_node->var_value->numbr != 0);
  1122.         }
  1123.     } else {
  1124.         rp = make_regexp(force_string(tree_eval(tree)),
  1125.             (IGNORECASE_node->var_value->numbr != 0));
  1126.         if (rp == NULL)
  1127.             cant_happen();
  1128.     }
  1129.     i = re_search(rp, t1->stptr, t1->stlen, 0, t1->stlen,
  1130.         (struct re_registers *) NULL);
  1131.     i = (i == -1) ^ (match == 1);
  1132.     free_temp(t1);
  1133.     if (tree->type != Node_regex) {
  1134.         free(rp->buffer);
  1135.         free(rp->fastmap);
  1136.         free((char *) rp);
  1137.     }
  1138.     return tmp_number((AWKNUM) i);
  1139. }
  1140.