comparison src/lex.l @ 146:edfa5a96c5f1

[project @ 1993-10-05 04:02:15 by jwe] (handle_identifier): New function. ({IDENT}/{S}*=, {IDENT}{S}*): Use it instead of duplicating code.
author jwe
date Tue, 05 Oct 1993 04:02:15 +0000
parents 7849db4b6dbc
children 8f91a9cbf451
comparison
equal deleted inserted replaced
145:6beb84c3320e 146:edfa5a96c5f1
80 // 1 -> brace, spaces are important (they can turn into commas) 80 // 1 -> brace, spaces are important (they can turn into commas)
81 // 0 -> paren, spaces are not important 81 // 0 -> paren, spaces are not important
82 // 82 //
83 static SLStack <int> in_brace_or_paren; 83 static SLStack <int> in_brace_or_paren;
84 84
85 // Forward declarations for functions defined at the bottom of this
86 // file.
87
85 static void do_string_escapes (char *s); 88 static void do_string_escapes (char *s);
86 static void fixup_column_count (char *s); 89 static void fixup_column_count (char *s);
87 static int do_comma_insert_check (void); 90 static void do_comma_insert_check (void);
88 static int is_plot_keyword (char *s); 91 static int is_plot_keyword (char *s);
89 static int is_keyword (char *s); 92 static int is_keyword (char *s);
90 static char *plot_style_token (char *s); 93 static char *plot_style_token (char *s);
91 static symbol_record *lookup_identifier (char *s); 94 static symbol_record *lookup_identifier (char *s);
92 static void grab_help_text (void); 95 static void grab_help_text (void);
93 static int match_any (char c, char *s); 96 static int match_any (char c, char *s);
94 static int next_token_is_bin_op (int spc_prev, char *yytext); 97 static int next_token_is_bin_op (int spc_prev, char *yytext);
95 static int next_token_is_postfix_unary_op (int spc_prev, char *yytext); 98 static int next_token_is_postfix_unary_op (int spc_prev, char *yytext);
96 static char *strip_trailing_whitespace (char *s); 99 static char *strip_trailing_whitespace (char *s);
100 static int handle_identifier (char *s, int next_tok_is_eq);
97 101
98 %} 102 %}
99 103
100 D [0-9] 104 D [0-9]
101 S [ \t] 105 S [ \t]
425 yylval.tok_val = new token (value, 429 yylval.tok_val = new token (value,
426 input_line_number, 430 input_line_number,
427 current_input_column); 431 current_input_column);
428 token_stack.push (yylval.tok_val); 432 token_stack.push (yylval.tok_val);
429 current_input_column += yyleng; 433 current_input_column += yyleng;
430 DO_COMMA_INSERT_CHECK; 434 do_comma_insert_check ();
431 return IMAG_NUM; 435 return IMAG_NUM;
432 } 436 }
433 437
434 {D}+{EXPON}? | 438 {D}+{EXPON}? |
435 {D}+\.{D}*{EXPON}? | 439 {D}+\.{D}*{EXPON}? |
446 yylval.tok_val = new token (value, 450 yylval.tok_val = new token (value,
447 input_line_number, 451 input_line_number,
448 current_input_column); 452 current_input_column);
449 token_stack.push (yylval.tok_val); 453 token_stack.push (yylval.tok_val);
450 current_input_column += yyleng; 454 current_input_column += yyleng;
451 DO_COMMA_INSERT_CHECK; 455 do_comma_insert_check ();
452 return NUM; 456 return NUM;
453 } 457 }
454 458
455 \[{S}* { 459 \[{S}* {
456 in_brace_or_paren.push (1); 460 in_brace_or_paren.push (1);
497 // directly on yytext. 501 // directly on yytext.
498 502
499 static char *tok = (char *) NULL; 503 static char *tok = (char *) NULL;
500 delete [] tok; 504 delete [] tok;
501 tok = strip_trailing_whitespace (yytext); 505 tok = strip_trailing_whitespace (yytext);
502 506 return handle_identifier (tok, 0);
503 int kw_token = is_keyword (tok);
504 if (kw_token)
505 TOK_RETURN (kw_token);
506
507 if (plotting && cant_be_identifier)
508 {
509 int plot_option_kw = is_plot_keyword (tok);
510 if (plot_option_kw)
511 {
512 quote_is_transpose = 0;
513 cant_be_identifier = 0;
514 convert_spaces_to_comma = 1;
515 current_input_column += yyleng;
516 return plot_option_kw;
517 }
518 }
519
520 if (plotting && ! in_plot_range)
521 past_plot_range = 1;
522
523 if (plotting && in_plot_style)
524 {
525 char *sty = plot_style_token (&tok[1]);
526 if (sty != (char *) NULL)
527 {
528 yylval.tok_val = new token (sty);
529 token_stack.push (yylval.tok_val);
530 if (in_plot_style)
531 {
532 in_plot_style = 0;
533 TOK_RETURN (STYLE);
534 }
535 }
536 }
537
538 cant_be_identifier = 1;
539
540 // If we are looking at a text style function, set up to gobble its
541 // arguments. These are also reserved words, but only because it
542 // would be very difficult to do anything intelligent with them if
543 // they were not reserved.
544
545 if (is_text_function_name (tok))
546 {
547 BEGIN TEXT_FCN;
548
549 if (strcmp (tok, "clear") == 0)
550 {
551 symbol_record *sr =
552 global_sym_tab->lookup ("clear", 1, 0);
553 assert (sr != (symbol_record *) NULL);
554 yylval.tok_val = new token (sr, input_line_number,
555 current_input_column);
556 token_stack.push (yylval.tok_val);
557 return CLEAR;
558 }
559 else if (strcmp (tok, "help") == 0)
560 BEGIN HELP_FCN;
561 else if (strcmp (tok, "set") == 0)
562 doing_set = 1;
563 }
564
565 yylval.tok_val = new token (lookup_identifier (tok),
566 input_line_number,
567 current_input_column);
568 token_stack.push (yylval.tok_val);
569
570 quote_is_transpose = 1;
571 current_input_column += yyleng;
572 DO_COMMA_INSERT_CHECK;
573
574 if (! in_brace_or_paren.empty ()
575 && in_brace_or_paren.top ())
576 {
577 int c0 = yytext[yyleng-1];
578 int spc_prev = (c0 == ' ' || c0 == '\t');
579 int bin_op = next_token_is_bin_op (spc_prev, yytext);
580
581 int postfix_un_op
582 = next_token_is_postfix_unary_op (spc_prev, yytext);
583
584 int c1 = yyinput ();
585 unput (c1);
586 int other_op = match_any (c1, ",;\n](");
587
588 if (! (postfix_un_op || bin_op || other_op))
589 unput (',');
590 }
591
592 convert_spaces_to_comma = 1;
593 return NAME;
594 } 507 }
595 508
596 {IDENT}/{S}*= { 509 {IDENT}/{S}*= { return handle_identifier (yytext, 1); }
597
598 // We've found an identifier followed by some space and an equals
599 // sign. If we are working on a function definition and the previous
600 // token was `function', we have something like this
601 //
602 // function x = y <list> end
603 //
604 // which is a function named y returning a variable named x. The
605 // symbol y belongs in the global symbol table (nested function
606 // definitions are illegal) and the symbol x belongs in the
607 // symbol table local to the function.
608 //
609 // If we're not defining a function, this should function exactly like
610 // the case above. I suppose it would be nice to avoid duplicating
611 // all the code, eh?
612
613 int kw_token = is_keyword (yytext);
614 if (kw_token)
615 TOK_RETURN (kw_token);
616
617 if (plotting && cant_be_identifier)
618 {
619 int plot_option_kw = is_plot_keyword (yytext);
620 if (plot_option_kw)
621 {
622 quote_is_transpose = 0;
623 convert_spaces_to_comma = 1;
624 current_input_column += yyleng;
625 return plot_option_kw;
626 }
627 }
628
629 cant_be_identifier = 1;
630
631 // If we are looking at a text style function, set up to gobble its
632 // arguments. These are also reserved words, but only because it
633 // would be very difficult to do anything intelligent with them if
634 // they were not reserved.
635
636 if (is_text_function_name (yytext))
637 {
638 BEGIN TEXT_FCN;
639
640 if (strcmp (yytext, "clear") == 0)
641 {
642 symbol_record *sr =
643 global_sym_tab->lookup ("clear", 1, 0);
644 assert (sr != (symbol_record *) NULL);
645 yylval.tok_val = new token (sr, input_line_number,
646 current_input_column);
647 token_stack.push (yylval.tok_val);
648 return CLEAR;
649 }
650 else if (strcmp (yytext, "help") == 0)
651 BEGIN HELP_FCN;
652 else if (strcmp (yytext, "set") == 0)
653 doing_set = 1;
654 }
655
656 if (defining_func && maybe_screwed)
657 curr_sym_tab = tmp_local_sym_tab;
658
659 yylval.tok_val = new token (lookup_identifier (yytext),
660 input_line_number,
661 current_input_column);
662 token_stack.push (yylval.tok_val);
663
664 convert_spaces_to_comma = 1;
665 current_input_column += yyleng;
666 if (defining_func && maybe_screwed)
667 {
668 return SCREW;
669 }
670 else
671 {
672 quote_is_transpose = 1;
673 DO_COMMA_INSERT_CHECK;
674 return NAME;
675 }
676 }
677 510
678 "\n" { 511 "\n" {
679 quote_is_transpose = 0; 512 quote_is_transpose = 0;
680 cant_be_identifier = 0; 513 cant_be_identifier = 0;
681 current_input_column = 1; 514 current_input_column = 1;
687 current_input_column++; 520 current_input_column++;
688 convert_spaces_to_comma = 1; 521 convert_spaces_to_comma = 1;
689 522
690 if (quote_is_transpose) 523 if (quote_is_transpose)
691 { 524 {
692 DO_COMMA_INSERT_CHECK; 525 do_comma_insert_check ();
693 return QUOTE; 526 return QUOTE;
694 } 527 }
695 else 528 else
696 BEGIN STRING; 529 BEGIN STRING;
697 } 530 }
707 ".**" { BIN_OP_RETURN (EPOW, 0); } 540 ".**" { BIN_OP_RETURN (EPOW, 0); }
708 ".*" { BIN_OP_RETURN (EMUL, 0); } 541 ".*" { BIN_OP_RETURN (EMUL, 0); }
709 "./" { BIN_OP_RETURN (EDIV, 0); } 542 "./" { BIN_OP_RETURN (EDIV, 0); }
710 ".\\" { BIN_OP_RETURN (ELEFTDIV, 0); } 543 ".\\" { BIN_OP_RETURN (ELEFTDIV, 0); }
711 ".^" { BIN_OP_RETURN (EPOW, 0); } 544 ".^" { BIN_OP_RETURN (EPOW, 0); }
712 ".'" { DO_COMMA_INSERT_CHECK; BIN_OP_RETURN (TRANSPOSE, 1); } 545 ".'" { do_comma_insert_check (); BIN_OP_RETURN (TRANSPOSE, 1); }
713 "++" { DO_COMMA_INSERT_CHECK; BIN_OP_RETURN (PLUS_PLUS, 1); } 546 "++" { do_comma_insert_check (); BIN_OP_RETURN (PLUS_PLUS, 1); }
714 "--" { DO_COMMA_INSERT_CHECK; BIN_OP_RETURN (MINUS_MINUS, 1); } 547 "--" { do_comma_insert_check (); BIN_OP_RETURN (MINUS_MINUS, 1); }
715 "<=" { BIN_OP_RETURN (EXPR_LE, 0); } 548 "<=" { BIN_OP_RETURN (EXPR_LE, 0); }
716 "==" { BIN_OP_RETURN (EXPR_EQ, 0); } 549 "==" { BIN_OP_RETURN (EXPR_EQ, 0); }
717 "~=" { BIN_OP_RETURN (EXPR_NE, 0); } 550 "~=" { BIN_OP_RETURN (EXPR_NE, 0); }
718 "!=" { BIN_OP_RETURN (EXPR_NE, 0); } 551 "!=" { BIN_OP_RETURN (EXPR_NE, 0); }
719 "<>" { BIN_OP_RETURN (EXPR_NE, 0); } 552 "<>" { BIN_OP_RETURN (EXPR_NE, 0); }
759 TOK_RETURN ('('); 592 TOK_RETURN ('(');
760 } 593 }
761 ")" { 594 ")" {
762 if (! in_brace_or_paren.empty ()) 595 if (! in_brace_or_paren.empty ())
763 in_brace_or_paren.pop (); 596 in_brace_or_paren.pop ();
764 DO_COMMA_INSERT_CHECK; 597 do_comma_insert_check ();
765 current_input_column++; 598 current_input_column++;
766 quote_is_transpose = 1; 599 quote_is_transpose = 1;
767 return ')'; 600 return ')';
768 } 601 }
769 602
781 * GAG. 614 * GAG.
782 * 615 *
783 * If we're reading a matrix and the next character is '[', make sure 616 * If we're reading a matrix and the next character is '[', make sure
784 * that we insert a comma ahead of it. 617 * that we insert a comma ahead of it.
785 */ 618 */
786 int 619 void
787 do_comma_insert_check (void) 620 do_comma_insert_check (void)
788 { 621 {
789 int tmp_len = yyleng;
790 int c = yyinput (); 622 int c = yyinput ();
623 yyunput (c, yytext);
791 do_comma_insert = (braceflag && c == '['); 624 do_comma_insert = (braceflag && c == '[');
792 return tmp_len;
793 } 625 }
794 626
795 /* 627 /*
796 * Fix things up for errors or interrupts. This could use a few 628 * Fix things up for errors or interrupts. This could use a few
797 * comments now, eh? 629 * comments now, eh?
829 while (! token_stack.empty ()) 661 while (! token_stack.empty ())
830 delete token_stack.pop (); 662 delete token_stack.pop ();
831 yyrestart (stdin); 663 yyrestart (stdin);
832 } 664 }
833 665
666 /*
667 * Replace backslash escapes in a string with the real values.
668 */
834 static void 669 static void
835 do_string_escapes (char *s) 670 do_string_escapes (char *s)
836 { 671 {
837 char *p1 = s; 672 char *p1 = s;
838 char *p2 = s; 673 char *p2 = s;
894 } 729 }
895 730
896 *p1 = '\0'; 731 *p1 = '\0';
897 } 732 }
898 733
734 /*
735 * If we read some newlines, we need figure out what column we're
736 * really looking at.
737 */
899 static void 738 static void
900 fixup_column_count (char *s) 739 fixup_column_count (char *s)
901 { 740 {
902 char c; 741 char c;
903 while ((c = *s++) != '\0') 742 while ((c = *s++) != '\0')
970 delete_input_buffer (void *buf) 809 delete_input_buffer (void *buf)
971 { 810 {
972 delete_buffer ((YY_BUFFER_STATE) buf); 811 delete_buffer ((YY_BUFFER_STATE) buf);
973 } 812 }
974 813
975 static char *plot_styles[] = 814 /*
976 { 815 * Check to see if a character string matches any of the possible line
977 "dots", 816 * styles for plots.
978 "dots", 817 */
979 "errorbars",
980 "impulses",
981 "lines",
982 "linespoints",
983 "points",
984 (char *) NULL,
985 };
986
987 static char * 818 static char *
988 plot_style_token (char *s) 819 plot_style_token (char *s)
989 { 820 {
821 static char *plot_styles[] =
822 {
823 "dots",
824 "errorbars",
825 "impulses",
826 "lines",
827 "linespoints",
828 "points",
829 (char *) NULL,
830 };
831
990 char **tmp = plot_styles; 832 char **tmp = plot_styles;
991 while (*tmp != (char *) NULL) 833 while (*tmp != (char *) NULL)
992 { 834 {
993 if (almost_match (*tmp, s)) 835 if (almost_match (*tmp, s))
994 return *tmp; 836 return *tmp;
997 } 839 }
998 840
999 return (char *) NULL; 841 return (char *) NULL;
1000 } 842 }
1001 843
844 /*
845 * Check to see if a character string matches any one of the plot
846 * option keywords.
847 */
1002 static int 848 static int
1003 is_plot_keyword (char *s) 849 is_plot_keyword (char *s)
1004 { 850 {
1005 if (almost_match ("title", s)) 851 if (almost_match ("title", s))
1006 return TITLE; 852 {
853 return TITLE;
854 }
1007 else if (almost_match ("using", s)) 855 else if (almost_match ("using", s))
1008 { in_plot_using = 1; past_plot_range = 1; return USING; } 856 {
857 in_plot_using = 1;
858 past_plot_range = 1;
859 return USING;
860 }
1009 else if (almost_match ("with", s)) 861 else if (almost_match ("with", s))
1010 { in_plot_style = 1; past_plot_range = 1; return WITH; } 862 {
863 in_plot_style = 1;
864 past_plot_range = 1;
865 return WITH;
866 }
1011 else 867 else
1012 return 0; 868 {
869 return 0;
870 }
1013 } 871 }
1014 872
1015 /* 873 /*
1016 * Handle keywords. Could probably be more efficient... 874 * Handle keywords. Could probably be more efficient...
1017 */ 875 */
1147 } 1005 }
1148 1006
1149 return 0; 1007 return 0;
1150 } 1008 }
1151 1009
1010 /*
1011 * Try to find an identifier in one symbol table or another. Insert
1012 * it in the local symbol table it is is not already there and it does
1013 * not already have global scope.
1014 */
1152 static symbol_record * 1015 static symbol_record *
1153 lookup_identifier (char *name) 1016 lookup_identifier (char *name)
1154 { 1017 {
1155 symbol_record *lsr = curr_sym_tab->lookup (name, 0, 0); 1018 symbol_record *lsr = curr_sym_tab->lookup (name, 0, 0);
1156 if (lsr != (symbol_record *) NULL) 1019 if (lsr != (symbol_record *) NULL)
1161 return gsr; 1024 return gsr;
1162 1025
1163 return curr_sym_tab->lookup (name, 1, 0); 1026 return curr_sym_tab->lookup (name, 1, 0);
1164 } 1027 }
1165 1028
1029 /*
1030 * Grab the help text from an M-file.
1031 */
1166 static void 1032 static void
1167 grab_help_text (void) 1033 grab_help_text (void)
1168 { 1034 {
1169 int max_len = HELP_BUF_LENGTH - 1; 1035 int max_len = HELP_BUF_LENGTH - 1;
1170 1036
1215 yyunput ('\n', yytext); 1081 yyunput ('\n', yytext);
1216 1082
1217 help_buf[len] = '\0'; 1083 help_buf[len] = '\0';
1218 } 1084 }
1219 1085
1086 /*
1087 * Return 1 if the given character matches any character in the given
1088 * string.
1089 */
1220 static int 1090 static int
1221 match_any (char c, char *s) 1091 match_any (char c, char *s)
1222 { 1092 {
1223 char tmp; 1093 char tmp;
1224 while ((tmp = *s++) != '\0') 1094 while ((tmp = *s++) != '\0')
1227 return 1; 1097 return 1;
1228 } 1098 }
1229 return 0; 1099 return 0;
1230 } 1100 }
1231 1101
1102 /*
1103 * Given information about the spacing surrounding an operator,
1104 * return 1 if it looks like it should be treated as a binary
1105 * operator. For example,
1106 *
1107 * [ 1 + 2 ] or [ 1+2 ] ==> binary
1108 *
1109 * The case of [ 1+ 2 ] should also be treated as a binary operator,
1110 * but it is handled by the caller.
1111 */
1232 static int 1112 static int
1233 looks_like_bin_op (int spc_prev, int spc_next) 1113 looks_like_bin_op (int spc_prev, int spc_next)
1234 { 1114 {
1235 return ((spc_prev && spc_next) || ! (spc_prev || spc_next)); 1115 return ((spc_prev && spc_next) || ! (spc_prev || spc_next));
1236 } 1116 }
1237 1117
1118 /*
1119 * Duh.
1120 */
1238 static int 1121 static int
1239 next_char_is_space (void) 1122 next_char_is_space (void)
1240 { 1123 {
1241 int c = yyinput (); 1124 int c = yyinput ();
1242 yyunput (c, yytext); 1125 yyunput (c, yytext);
1243 return (c == ' ' || c == '\t'); 1126 return (c == ' ' || c == '\t');
1244 } 1127 }
1245 1128
1129 /*
1130 * Try to determine if the next token should be treated as a postfix
1131 * unary operator. This is ugly, but it seems to do the right thing.
1132 */
1246 static int 1133 static int
1247 next_token_is_postfix_unary_op (int spc_prev, char *yytext) 1134 next_token_is_postfix_unary_op (int spc_prev, char *yytext)
1248 { 1135 {
1249 int un_op = 0; 1136 int un_op = 0;
1250 1137
1260 un_op = (transpose || (hermitian && ! spc_prev)); 1147 un_op = (transpose || (hermitian && ! spc_prev));
1261 1148
1262 return un_op; 1149 return un_op;
1263 } 1150 }
1264 1151
1152 /*
1153 * Try to determine if the next token should be treated as a binary
1154 * operator. This is even uglier, but it also seems to do the right
1155 * thing.
1156 */
1265 static int 1157 static int
1266 next_token_is_bin_op (int spc_prev, char *yytext) 1158 next_token_is_bin_op (int spc_prev, char *yytext)
1267 { 1159 {
1268 int bin_op = 0; 1160 int bin_op = 0;
1269 int spc_next = 0; 1161 int spc_next = 0;
1347 yyunput (c0, yytext); 1239 yyunput (c0, yytext);
1348 1240
1349 return bin_op; 1241 return bin_op;
1350 } 1242 }
1351 1243
1352 char * 1244 /*
1245 * Used to delete trailing white space from tokens.
1246 */
1247 static char *
1353 strip_trailing_whitespace (char *s) 1248 strip_trailing_whitespace (char *s)
1354 { 1249 {
1355 char *retval = strsave (s); 1250 char *retval = strsave (s);
1356 1251
1357 char *t = strchr (retval, ' '); 1252 char *t = strchr (retval, ' ');
1363 *t = '\0'; 1258 *t = '\0';
1364 1259
1365 return retval; 1260 return retval;
1366 } 1261 }
1367 1262
1263 /*
1264 * Figure out exactly what kind of token to return when we have seen
1265 * an identifier. Handles keywords.
1266 */
1267 static int
1268 handle_identifier (char *tok, int next_tok_is_eq)
1269 {
1270 // If we have a regular keyword, or a plot STYLE, return it. STYLE is
1271 // special only because it can't be followed by an identifier.
1272
1273 int kw_token = is_keyword (tok);
1274 if (kw_token)
1275 {
1276 if (kw_token == STYLE)
1277 {
1278 current_input_column += yyleng;
1279 quote_is_transpose = 0;
1280 cant_be_identifier = 1;
1281 convert_spaces_to_comma = 1;
1282 return kw_token;
1283 }
1284 else
1285 TOK_RETURN (kw_token);
1286 }
1287
1288 // See if we have a plot keyword (title, using, or with).
1289
1290 if (plotting && cant_be_identifier && is_plot_keyword (tok);
1291 TOK_RETURN (plot_option_kw);
1292
1293 // Yes, we really do need both of these plot_range variables. One
1294 // is used to mark when we are past all possiblity of a plot range,
1295 // the other is used to mark when we are actually between the square
1296 // brackets that surround the range.
1297
1298 if (plotting && ! in_plot_range)
1299 past_plot_range = 1;
1300
1301 // It is always an error for an identifier to be followed directly by
1302 // another identifier.
1303
1304 cant_be_identifier = 1;
1305
1306 // If we are looking at a text style function, set up to gobble its
1307 // arguments. These are also reserved words, but only because it
1308 // would be very difficult to do anything intelligent with them if
1309 // they were not reserved.
1310
1311 if (is_text_function_name (tok))
1312 {
1313 BEGIN TEXT_FCN;
1314
1315 if (strcmp (tok, "clear") == 0)
1316 {
1317 symbol_record *sr = global_sym_tab->lookup ("clear", 1, 0);
1318
1319 assert (sr != (symbol_record *) NULL);
1320
1321 yylval.tok_val = new token (sr, input_line_number,
1322 current_input_column);
1323
1324 token_stack.push (yylval.tok_val);
1325
1326 return CLEAR;
1327 }
1328 else if (strcmp (tok, "help") == 0)
1329 BEGIN HELP_FCN;
1330 else if (strcmp (tok, "set") == 0)
1331 doing_set = 1;
1332 }
1333
1334 // Make sure we put the return values of a function in the symbol
1335 // table that is local to the function.
1336
1337 if (next_tok_is_eq && defining_func && maybe_screwed)
1338 curr_sym_tab = tmp_local_sym_tab;
1339
1340 // Find the token in the symbol table.
1341
1342 yylval.tok_val = new token (lookup_identifier (tok),
1343 input_line_number,
1344 current_input_column);
1345
1346 token_stack.push (yylval.tok_val);
1347
1348 // After seeing an identifer, it is ok to convert spaces to a comma
1349 // (if needed).
1350
1351 convert_spaces_to_comma = 1;
1352 current_input_column += yyleng;
1353
1354 // If we are defining a function and we have not seen the parameter
1355 // list yet and the next token is `=', return a token that represents
1356 // the only return value for the function. For example,
1357 //
1358 // function SCREW = f (args);
1359 //
1360 // The variable maybe_screwed is reset in parse.y.
1361
1362 if (next_tok_is_eq)
1363 {
1364 if (defining_func && maybe_screwed)
1365 return SCREW;
1366 else
1367 return NAME;
1368 }
1369
1370 // At this point, we are only dealing with identifiers that are not
1371 // followed by `=' (if the next token is `=', there is no need to
1372 // check to see if we should insert a comma (invalid syntax), or allow
1373 // a following `'' to be treated as a transpose (the next token is
1374 // `=', so it can't be `''.
1375
1376 quote_is_transpose = 1;
1377 do_comma_insert_check ();
1378
1379 // Check to see if we should insert a comma.
1380
1381 if (! in_brace_or_paren.empty () && in_brace_or_paren.top ())
1382 {
1383 int c0 = yytext[yyleng-1];
1384 int spc_prev = (c0 == ' ' || c0 == '\t');
1385 int bin_op = next_token_is_bin_op (spc_prev, yytext);
1386
1387 int postfix_un_op = next_token_is_postfix_unary_op (spc_prev,
1388 yytext);
1389
1390 int c1 = yyinput ();
1391 unput (c1);
1392 int other_op = match_any (c1, ",;\n](");
1393
1394 if (! (postfix_un_op || bin_op || other_op))
1395 unput (',');
1396 }
1397
1398 return NAME;
1399 }
1400
1401 /*
1402 * Print a warning if an M-file that defines a function has anything
1403 * other than comments and whitespace following the END token that
1404 * matches the FUNCTION statement.
1405 */
1368 void 1406 void
1369 check_for_garbage_after_fcn_def (void) 1407 check_for_garbage_after_fcn_def (void)
1370 { 1408 {
1371 // By making a newline be the next character to be read, we will force 1409 // By making a newline be the next character to be read, we will force
1372 // the parser to return after reading the function. Calling yyunput 1410 // the parser to return after reading the function. Calling yyunput