comparison libinterp/parse-tree/oct-parse.in.yy @ 16287:04a7953496a7

create base class for parser; use reference for curr_lexer * lex.h, lex.ll (octave_base_parser): New base class for parser class. Move most of previous octave_parser class here. Use reference for curr_lexer object instead of pointer. Change all uses. (octave_parser): Derive from octave_base_parser.
author John W. Eaton <jwe@octave.org>
date Tue, 12 Mar 2013 00:18:28 -0400
parents 3389152014ca
children fe3b9a51e625
comparison
equal deleted inserted replaced
16285:3389152014ca 16287:04a7953496a7
105 static std::map<std::string, std::string> autoload_map; 105 static std::map<std::string, std::string> autoload_map;
106 106
107 // Forward declarations for some functions defined at the bottom of 107 // Forward declarations for some functions defined at the bottom of
108 // the file. 108 // the file.
109 109
110 static void yyerror (octave_parser& curr_parser, const char *s); 110 static void yyerror (octave_base_parser& curr_parser, const char *s);
111 111
112 // Finish building a statement. 112 // Finish building a statement.
113 template <class T> 113 template <class T>
114 static tree_statement * 114 static tree_statement *
115 make_statement (T *arg) 115 make_statement (T *arg)
124 { \ 124 { \
125 yyerrok; \ 125 yyerrok; \
126 if (! parser_symtab_context.empty ()) \ 126 if (! parser_symtab_context.empty ()) \
127 parser_symtab_context.pop (); \ 127 parser_symtab_context.pop (); \
128 if ((interactive || forced_interactive) \ 128 if ((interactive || forced_interactive) \
129 && ! (curr_lexer)->input_from_eval_string ()) \ 129 && ! curr_lexer.input_from_eval_string ()) \
130 YYACCEPT; \ 130 YYACCEPT; \
131 else \ 131 else \
132 YYABORT; \ 132 YYABORT; \
133 } \ 133 } \
134 while (0) 134 while (0)
135 135
136 #define curr_lexer curr_parser.curr_lexer 136 #define curr_lexer curr_parser.curr_lexer
137 #define scanner curr_lexer->scanner 137 #define scanner curr_lexer.scanner
138 138
139 %} 139 %}
140 140
141 // Bison declarations. 141 // Bison declarations.
142 142
154 // care to properly save and restore (typically with an unwind_protect 154 // care to properly save and restore (typically with an unwind_protect
155 // object) relevant global values before and after the nested call. 155 // object) relevant global values before and after the nested call.
156 156
157 %define api.pure 157 %define api.pure
158 %PUSH_PULL_DECL% 158 %PUSH_PULL_DECL%
159 %parse-param { octave_parser& curr_parser } 159 %parse-param { octave_base_parser& curr_parser }
160 %lex-param { void *scanner } 160 %lex-param { void *scanner }
161 161
162 %union 162 %union
163 { 163 {
164 // The type of the basic tokens returned by the lexer. 164 // The type of the basic tokens returned by the lexer.
324 324
325 input1 : '\n' 325 input1 : '\n'
326 { $$ = 0; } 326 { $$ = 0; }
327 | END_OF_INPUT 327 | END_OF_INPUT
328 { 328 {
329 curr_lexer->end_of_input = true; 329 curr_lexer.end_of_input = true;
330 $$ = 0; 330 $$ = 0;
331 } 331 }
332 | simple_list 332 | simple_list
333 { $$ = $1; } 333 { $$ = $1; }
334 | simple_list '\n' 334 | simple_list '\n'
482 ; 482 ;
483 483
484 fcn_handle : '@' FCN_HANDLE 484 fcn_handle : '@' FCN_HANDLE
485 { 485 {
486 $$ = curr_parser.make_fcn_handle ($2); 486 $$ = curr_parser.make_fcn_handle ($2);
487 curr_lexer->looking_at_function_handle--; 487 curr_lexer.looking_at_function_handle--;
488 } 488 }
489 ; 489 ;
490 490
491 anon_fcn_handle : '@' param_list statement 491 anon_fcn_handle : '@' param_list statement
492 { 492 {
493 $$ = curr_parser.make_anon_fcn_handle ($2, $3); 493 $$ = curr_parser.make_anon_fcn_handle ($2, $3);
494 curr_lexer->nesting_level.remove (); 494 curr_lexer.nesting_level.remove ();
495 } 495 }
496 ; 496 ;
497 497
498 primary_expr : identifier 498 primary_expr : identifier
499 { $$ = $1; } 499 { $$ = $1; }
501 { $$ = $1; } 501 { $$ = $1; }
502 | fcn_handle 502 | fcn_handle
503 { $$ = $1; } 503 { $$ = $1; }
504 | matrix 504 | matrix
505 { 505 {
506 curr_lexer->looking_at_matrix_or_assign_lhs = false; 506 curr_lexer.looking_at_matrix_or_assign_lhs = false;
507 $$ = $1; 507 $$ = $1;
508 } 508 }
509 | cell 509 | cell
510 { $$ = $1; } 510 { $$ = $1; }
511 | meta_identifier 511 | meta_identifier
551 $$ = $1; 551 $$ = $1;
552 } 552 }
553 ; 553 ;
554 554
555 indirect_ref_op : '.' 555 indirect_ref_op : '.'
556 { curr_lexer->looking_at_indirect_ref = true; } 556 { curr_lexer.looking_at_indirect_ref = true; }
557 ; 557 ;
558 558
559 oper_expr : primary_expr 559 oper_expr : primary_expr
560 { $$ = $1; } 560 { $$ = $1; }
561 | oper_expr PLUS_PLUS 561 | oper_expr PLUS_PLUS
658 assign_lhs : simple_expr 658 assign_lhs : simple_expr
659 { 659 {
660 $$ = curr_parser.validate_matrix_for_assignment ($1); 660 $$ = curr_parser.validate_matrix_for_assignment ($1);
661 661
662 if ($$) 662 if ($$)
663 { curr_lexer->looking_at_matrix_or_assign_lhs = false; } 663 { curr_lexer.looking_at_matrix_or_assign_lhs = false; }
664 else 664 else
665 { 665 {
666 // validate_matrix_for_assignment deleted $1. 666 // validate_matrix_for_assignment deleted $1.
667 ABORT_PARSE; 667 ABORT_PARSE;
668 } 668 }
749 // ===================== 749 // =====================
750 750
751 declaration : GLOBAL decl1 751 declaration : GLOBAL decl1
752 { 752 {
753 $$ = curr_parser.make_decl_command (GLOBAL, $1, $2); 753 $$ = curr_parser.make_decl_command (GLOBAL, $1, $2);
754 curr_lexer->looking_at_decl_list = false; 754 curr_lexer.looking_at_decl_list = false;
755 } 755 }
756 | PERSISTENT decl1 756 | PERSISTENT decl1
757 { 757 {
758 $$ = curr_parser.make_decl_command (PERSISTENT, $1, $2); 758 $$ = curr_parser.make_decl_command (PERSISTENT, $1, $2);
759 curr_lexer->looking_at_decl_list = false; 759 curr_lexer.looking_at_decl_list = false;
760 } 760 }
761 ; 761 ;
762 762
763 decl1 : decl2 763 decl1 : decl2
764 { $$ = new tree_decl_init_list ($1); } 764 { $$ = new tree_decl_init_list ($1); }
768 $$ = $1; 768 $$ = $1;
769 } 769 }
770 ; 770 ;
771 771
772 decl_param_init : // empty 772 decl_param_init : // empty
773 { curr_lexer->looking_at_initializer_expression = true; } 773 { curr_lexer.looking_at_initializer_expression = true; }
774 774
775 decl2 : identifier 775 decl2 : identifier
776 { $$ = new tree_decl_elt ($1); } 776 { $$ = new tree_decl_elt ($1); }
777 | identifier '=' decl_param_init expression 777 | identifier '=' decl_param_init expression
778 { 778 {
779 curr_lexer->looking_at_initializer_expression = false; 779 curr_lexer.looking_at_initializer_expression = false;
780 $$ = new tree_decl_elt ($1, $4); 780 $$ = new tree_decl_elt ($1, $4);
781 } 781 }
782 | magic_tilde 782 | magic_tilde
783 { 783 {
784 $$ = new tree_decl_elt ($1); 784 $$ = new tree_decl_elt ($1);
815 } 815 }
816 ; 816 ;
817 817
818 if_cmd_list1 : expression opt_sep opt_list 818 if_cmd_list1 : expression opt_sep opt_list
819 { 819 {
820 $1->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); 820 $1->mark_braindead_shortcircuit (curr_lexer.fcn_file_full_name);
821 821
822 $$ = curr_parser.start_if_command ($1, $3); 822 $$ = curr_parser.start_if_command ($1, $3);
823 } 823 }
824 | if_cmd_list1 elseif_clause 824 | if_cmd_list1 elseif_clause
825 { 825 {
828 } 828 }
829 ; 829 ;
830 830
831 elseif_clause : ELSEIF stash_comment opt_sep expression opt_sep opt_list 831 elseif_clause : ELSEIF stash_comment opt_sep expression opt_sep opt_list
832 { 832 {
833 $4->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); 833 $4->mark_braindead_shortcircuit (curr_lexer.fcn_file_full_name);
834 834
835 $$ = curr_parser.make_elseif_clause ($1, $4, $6, $2); 835 $$ = curr_parser.make_elseif_clause ($1, $4, $6, $2);
836 } 836 }
837 ; 837 ;
838 838
887 // Looping 887 // Looping
888 // ======= 888 // =======
889 889
890 loop_command : WHILE stash_comment expression opt_sep opt_list END 890 loop_command : WHILE stash_comment expression opt_sep opt_list END
891 { 891 {
892 $3->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); 892 $3->mark_braindead_shortcircuit (curr_lexer.fcn_file_full_name);
893 893
894 if (! ($$ = curr_parser.make_while_command ($1, $3, $5, $6, $2))) 894 if (! ($$ = curr_parser.make_while_command ($1, $3, $5, $6, $2)))
895 ABORT_PARSE; 895 ABORT_PARSE;
896 } 896 }
897 | DO stash_comment opt_sep opt_list UNTIL expression 897 | DO stash_comment opt_sep opt_list UNTIL expression
984 984
985 symbol_table::set_scope (symbol_table::alloc_scope ()); 985 symbol_table::set_scope (symbol_table::alloc_scope ());
986 986
987 curr_parser.function_scopes.push_back (symbol_table::current_scope ()); 987 curr_parser.function_scopes.push_back (symbol_table::current_scope ());
988 988
989 if (! curr_lexer->reading_script_file 989 if (! curr_lexer.reading_script_file
990 && curr_parser.curr_fcn_depth == 1 990 && curr_parser.curr_fcn_depth == 1
991 && ! curr_parser.parsing_subfunctions) 991 && ! curr_parser.parsing_subfunctions)
992 curr_parser.primary_fcn_scope = symbol_table::current_scope (); 992 curr_parser.primary_fcn_scope = symbol_table::current_scope ();
993 993
994 if (curr_lexer->reading_script_file 994 if (curr_lexer.reading_script_file
995 && curr_parser.curr_fcn_depth > 1) 995 && curr_parser.curr_fcn_depth > 1)
996 curr_parser.bison_error ("nested functions not implemented in this context"); 996 curr_parser.bison_error ("nested functions not implemented in this context");
997 } 997 }
998 ; 998 ;
999 999
1001 // List of function parameters 1001 // List of function parameters
1002 // =========================== 1002 // ===========================
1003 1003
1004 param_list_beg : '(' 1004 param_list_beg : '('
1005 { 1005 {
1006 curr_lexer->looking_at_parameter_list = true; 1006 curr_lexer.looking_at_parameter_list = true;
1007 1007
1008 if (curr_lexer->looking_at_function_handle) 1008 if (curr_lexer.looking_at_function_handle)
1009 { 1009 {
1010 parser_symtab_context.push (); 1010 parser_symtab_context.push ();
1011 symbol_table::set_scope (symbol_table::alloc_scope ()); 1011 symbol_table::set_scope (symbol_table::alloc_scope ());
1012 curr_lexer->looking_at_function_handle--; 1012 curr_lexer.looking_at_function_handle--;
1013 curr_lexer->looking_at_anon_fcn_args = true; 1013 curr_lexer.looking_at_anon_fcn_args = true;
1014 } 1014 }
1015 } 1015 }
1016 ; 1016 ;
1017 1017
1018 param_list_end : ')' 1018 param_list_end : ')'
1019 { 1019 {
1020 curr_lexer->looking_at_parameter_list = false; 1020 curr_lexer.looking_at_parameter_list = false;
1021 curr_lexer->looking_for_object_index = false; 1021 curr_lexer.looking_for_object_index = false;
1022 } 1022 }
1023 ; 1023 ;
1024 1024
1025 param_list : param_list_beg param_list1 param_list_end 1025 param_list : param_list_beg param_list1 param_list_end
1026 { $$ = $2; } 1026 { $$ = $2; }
1057 // List of function return value names 1057 // List of function return value names
1058 // =================================== 1058 // ===================================
1059 1059
1060 return_list : '[' ']' 1060 return_list : '[' ']'
1061 { 1061 {
1062 curr_lexer->looking_at_return_list = false; 1062 curr_lexer.looking_at_return_list = false;
1063 $$ = new tree_parameter_list (); 1063 $$ = new tree_parameter_list ();
1064 } 1064 }
1065 | return_list1 1065 | return_list1
1066 { 1066 {
1067 curr_lexer->looking_at_return_list = false; 1067 curr_lexer.looking_at_return_list = false;
1068 if ($1->validate (tree_parameter_list::out)) 1068 if ($1->validate (tree_parameter_list::out))
1069 $$ = $1; 1069 $$ = $1;
1070 else 1070 else
1071 ABORT_PARSE; 1071 ABORT_PARSE;
1072 } 1072 }
1073 | '[' return_list1 ']' 1073 | '[' return_list1 ']'
1074 { 1074 {
1075 curr_lexer->looking_at_return_list = false; 1075 curr_lexer.looking_at_return_list = false;
1076 if ($2->validate (tree_parameter_list::out)) 1076 if ($2->validate (tree_parameter_list::out))
1077 $$ = $2; 1077 $$ = $2;
1078 else 1078 else
1079 ABORT_PARSE; 1079 ABORT_PARSE;
1080 } 1080 }
1093 // Script or function file 1093 // Script or function file
1094 // ======================= 1094 // =======================
1095 1095
1096 file : INPUT_FILE opt_nl opt_list END_OF_INPUT 1096 file : INPUT_FILE opt_nl opt_list END_OF_INPUT
1097 { 1097 {
1098 if (! curr_lexer->reading_fcn_file) 1098 if (! curr_lexer.reading_fcn_file)
1099 { 1099 {
1100 tree_statement *end_of_script 1100 tree_statement *end_of_script
1101 = curr_parser.make_end ("endscript", 1101 = curr_parser.make_end ("endscript",
1102 curr_lexer->input_line_number, 1102 curr_lexer.input_line_number,
1103 curr_lexer->current_input_column); 1103 curr_lexer.current_input_column);
1104 1104
1105 curr_parser.make_script ($3, end_of_script); 1105 curr_parser.make_script ($3, end_of_script);
1106 } 1106 }
1107 1107
1108 $$ = 0; 1108 $$ = 0;
1114 // =================== 1114 // ===================
1115 1115
1116 function_beg : push_fcn_symtab FCN stash_comment 1116 function_beg : push_fcn_symtab FCN stash_comment
1117 { 1117 {
1118 $$ = $3; 1118 $$ = $3;
1119 if (curr_lexer->reading_classdef_file 1119 if (curr_lexer.reading_classdef_file
1120 || curr_lexer->parsing_classdef) 1120 || curr_lexer.parsing_classdef)
1121 curr_lexer->maybe_classdef_get_set_method = true; 1121 curr_lexer.maybe_classdef_get_set_method = true;
1122 } 1122 }
1123 ; 1123 ;
1124 1124
1125 function : function_beg function1 1125 function : function_beg function1
1126 { 1126 {
1136 1136
1137 fcn_name : identifier 1137 fcn_name : identifier
1138 { 1138 {
1139 std::string id_name = $1->name (); 1139 std::string id_name = $1->name ();
1140 1140
1141 curr_lexer->parsed_function_name.top () = true; 1141 curr_lexer.parsed_function_name.top () = true;
1142 curr_lexer->maybe_classdef_get_set_method = false; 1142 curr_lexer.maybe_classdef_get_set_method = false;
1143 1143
1144 $$ = $1; 1144 $$ = $1;
1145 } 1145 }
1146 | GET '.' identifier 1146 | GET '.' identifier
1147 { 1147 {
1148 curr_lexer->parsed_function_name.top () = true; 1148 curr_lexer.parsed_function_name.top () = true;
1149 curr_lexer->maybe_classdef_get_set_method = false; 1149 curr_lexer.maybe_classdef_get_set_method = false;
1150 $$ = $3; 1150 $$ = $3;
1151 } 1151 }
1152 | SET '.' identifier 1152 | SET '.' identifier
1153 { 1153 {
1154 curr_lexer->parsed_function_name.top () = true; 1154 curr_lexer.parsed_function_name.top () = true;
1155 curr_lexer->maybe_classdef_get_set_method = false; 1155 curr_lexer.maybe_classdef_get_set_method = false;
1156 $$ = $3; 1156 $$ = $3;
1157 } 1157 }
1158 ; 1158 ;
1159 1159
1160 function1 : fcn_name function2 1160 function1 : fcn_name function2
1183 ABORT_PARSE; 1183 ABORT_PARSE;
1184 } 1184 }
1185 | END_OF_INPUT 1185 | END_OF_INPUT
1186 { 1186 {
1187 // A lot of tests are based on the assumption that this is OK 1187 // A lot of tests are based on the assumption that this is OK
1188 // if (curr_lexer->reading_script_file) 1188 // if (curr_lexer.reading_script_file)
1189 // { 1189 // {
1190 // curr_parser.bison_error ("function body open at end of script"); 1190 // curr_parser.bison_error ("function body open at end of script");
1191 // YYABORT; 1191 // YYABORT;
1192 // } 1192 // }
1193 1193
1197 "if one function is explicitly ended, " 1197 "if one function is explicitly ended, "
1198 "so must all the others"); 1198 "so must all the others");
1199 YYABORT; 1199 YYABORT;
1200 } 1200 }
1201 1201
1202 if (! (curr_lexer->reading_fcn_file || curr_lexer->reading_script_file 1202 if (! (curr_lexer.reading_fcn_file || curr_lexer.reading_script_file
1203 || (curr_lexer)->input_from_eval_string ())) 1203 || curr_lexer.input_from_eval_string ()))
1204 { 1204 {
1205 curr_parser.bison_error ("function body open at end of input"); 1205 curr_parser.bison_error ("function body open at end of input");
1206 YYABORT; 1206 YYABORT;
1207 } 1207 }
1208 1208
1209 if (curr_lexer->reading_classdef_file) 1209 if (curr_lexer.reading_classdef_file)
1210 { 1210 {
1211 curr_parser.bison_error ("classdef body open at end of input"); 1211 curr_parser.bison_error ("classdef body open at end of input");
1212 YYABORT; 1212 YYABORT;
1213 } 1213 }
1214 1214
1215 $$ = curr_parser.make_end ("endfunction", 1215 $$ = curr_parser.make_end ("endfunction",
1216 curr_lexer->input_line_number, 1216 curr_lexer.input_line_number,
1217 curr_lexer->current_input_column); 1217 curr_lexer.current_input_column);
1218 } 1218 }
1219 ; 1219 ;
1220 1220
1221 // ======== 1221 // ========
1222 // Classdef 1222 // Classdef
1223 // ======== 1223 // ========
1224 1224
1225 classdef_beg : CLASSDEF stash_comment 1225 classdef_beg : CLASSDEF stash_comment
1226 { 1226 {
1227 $$ = 0; 1227 $$ = 0;
1228 curr_lexer->parsing_classdef = true; 1228 curr_lexer.parsing_classdef = true;
1229 } 1229 }
1230 ; 1230 ;
1231 1231
1232 classdef_end : END 1232 classdef_end : END
1233 { 1233 {
1234 curr_lexer->parsing_classdef = false; 1234 curr_lexer.parsing_classdef = false;
1235 1235
1236 if (curr_parser.end_token_ok ($1, token::classdef_end)) 1236 if (curr_parser.end_token_ok ($1, token::classdef_end))
1237 $$ = curr_parser.make_end ("endclassdef", $1->line (), $1->column ()); 1237 $$ = curr_parser.make_end ("endclassdef", $1->line (), $1->column ());
1238 else 1238 else
1239 ABORT_PARSE; 1239 ABORT_PARSE;
1441 // Generic error messages. 1441 // Generic error messages.
1442 1442
1443 #undef curr_lexer 1443 #undef curr_lexer
1444 1444
1445 static void 1445 static void
1446 yyerror (octave_parser& curr_parser, const char *s) 1446 yyerror (octave_base_parser& curr_parser, const char *s)
1447 { 1447 {
1448 curr_parser.bison_error (s); 1448 curr_parser.bison_error (s);
1449 } 1449 }
1450 1450
1451 octave_parser::~octave_parser (void) 1451 octave_base_parser::~octave_base_parser (void)
1452 { 1452 {
1453 #if defined (OCTAVE_USE_PUSH_PARSER) 1453 #if defined (OCTAVE_USE_PUSH_PARSER)
1454 yypstate_delete (static_cast<yypstate *> (parser_state)); 1454 yypstate_delete (static_cast<yypstate *> (parser_state));
1455 #endif 1455 #endif
1456 1456
1457 delete stmt_list; 1457 delete stmt_list;
1458 1458
1459 delete curr_lexer; 1459 delete &curr_lexer;
1460 } 1460 }
1461 void octave_parser::init (void) 1461
1462 void octave_base_parser::init (void)
1462 { 1463 {
1463 #if defined (OCTAVE_USE_PUSH_PARSER) 1464 #if defined (OCTAVE_USE_PUSH_PARSER)
1464 parser_state = yypstate_new (); 1465 parser_state = yypstate_new ();
1465 #endif 1466 #endif
1466 1467
1467 CURR_LEXER = curr_lexer; 1468 CURR_LEXER = &curr_lexer;
1468 } 1469 }
1469 1470
1470 void 1471 void
1471 octave_parser::reset (void) 1472 octave_base_parser::reset (void)
1472 { 1473 {
1473 delete stmt_list; 1474 delete stmt_list;
1474 1475
1475 stmt_list = 0; 1476 stmt_list = 0;
1476 1477
1477 curr_lexer->reset (); 1478 curr_lexer.reset ();
1478 }
1479
1480 int
1481 octave_parser::run (void)
1482 {
1483 int status = 0;
1484
1485 #if defined (OCTAVE_USE_PUSH_PARSER)
1486
1487 do
1488 {
1489 YYSTYPE lval;
1490
1491 int token = octave_lex (&lval, scanner);
1492
1493 yypstate *pstate = static_cast<yypstate *> (parser_state);
1494
1495 status = octave_push_parse (pstate, token, &lval, *this);
1496 }
1497 while (status == YYPUSH_MORE);
1498
1499 #else
1500
1501 status = octave_parse (*this);
1502
1503 #endif
1504
1505 return status;
1506 } 1479 }
1507 1480
1508 // Error mesages for mismatched end tokens. 1481 // Error mesages for mismatched end tokens.
1509 1482
1510 void 1483 void
1511 octave_parser::end_error (const char *type, token::end_tok_type ettype, 1484 octave_base_parser::end_error (const char *type, token::end_tok_type ettype,
1512 int l, int c) 1485 int l, int c)
1513 { 1486 {
1514 static const char *fmt 1487 static const char *fmt
1515 = "'%s' command matched by '%s' near line %d column %d"; 1488 = "'%s' command matched by '%s' near line %d column %d";
1516 1489
1517 switch (ettype) 1490 switch (ettype)
1559 } 1532 }
1560 1533
1561 // Check to see that end tokens are properly matched. 1534 // Check to see that end tokens are properly matched.
1562 1535
1563 bool 1536 bool
1564 octave_parser::end_token_ok (token *tok, token::end_tok_type expected) 1537 octave_base_parser::end_token_ok (token *tok, token::end_tok_type expected)
1565 { 1538 {
1566 bool retval = true; 1539 bool retval = true;
1567 1540
1568 token::end_tok_type ettype = tok->ettype (); 1541 token::end_tok_type ettype = tok->ettype ();
1569 1542
1629 1602
1630 // Maybe print a warning if an assignment expression is used as the 1603 // Maybe print a warning if an assignment expression is used as the
1631 // test in a logical expression. 1604 // test in a logical expression.
1632 1605
1633 void 1606 void
1634 octave_parser::maybe_warn_assign_as_truth_value (tree_expression *expr) 1607 octave_base_parser::maybe_warn_assign_as_truth_value (tree_expression *expr)
1635 { 1608 {
1636 if (expr->is_assignment_expression () 1609 if (expr->is_assignment_expression ()
1637 && expr->paren_count () < 2) 1610 && expr->paren_count () < 2)
1638 { 1611 {
1639 if (curr_lexer->fcn_file_full_name.empty ()) 1612 if (curr_lexer.fcn_file_full_name.empty ())
1640 warning_with_id 1613 warning_with_id
1641 ("Octave:assign-as-truth-value", 1614 ("Octave:assign-as-truth-value",
1642 "suggest parenthesis around assignment used as truth value"); 1615 "suggest parenthesis around assignment used as truth value");
1643 else 1616 else
1644 warning_with_id 1617 warning_with_id
1645 ("Octave:assign-as-truth-value", 1618 ("Octave:assign-as-truth-value",
1646 "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'", 1619 "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'",
1647 expr->line (), expr->column (), curr_lexer->fcn_file_full_name.c_str ()); 1620 expr->line (), expr->column (), curr_lexer.fcn_file_full_name.c_str ());
1648 } 1621 }
1649 } 1622 }
1650 1623
1651 // Maybe print a warning about switch labels that aren't constants. 1624 // Maybe print a warning about switch labels that aren't constants.
1652 1625
1653 void 1626 void
1654 octave_parser::maybe_warn_variable_switch_label (tree_expression *expr) 1627 octave_base_parser::maybe_warn_variable_switch_label (tree_expression *expr)
1655 { 1628 {
1656 if (! expr->is_constant ()) 1629 if (! expr->is_constant ())
1657 { 1630 {
1658 if (curr_lexer->fcn_file_full_name.empty ()) 1631 if (curr_lexer.fcn_file_full_name.empty ())
1659 warning_with_id ("Octave:variable-switch-label", 1632 warning_with_id ("Octave:variable-switch-label",
1660 "variable switch label"); 1633 "variable switch label");
1661 else 1634 else
1662 warning_with_id 1635 warning_with_id
1663 ("Octave:variable-switch-label", 1636 ("Octave:variable-switch-label",
1664 "variable switch label near line %d, column %d in file '%s'", 1637 "variable switch label near line %d, column %d in file '%s'",
1665 expr->line (), expr->column (), curr_lexer->fcn_file_full_name.c_str ()); 1638 expr->line (), expr->column (), curr_lexer.fcn_file_full_name.c_str ());
1666 } 1639 }
1667 } 1640 }
1668 1641
1669 static tree_expression * 1642 static tree_expression *
1670 fold (tree_binary_expression *e) 1643 fold (tree_binary_expression *e)
1756 } 1729 }
1757 1730
1758 // Finish building a range. 1731 // Finish building a range.
1759 1732
1760 tree_expression * 1733 tree_expression *
1761 octave_parser::finish_colon_expression (tree_colon_expression *e) 1734 octave_base_parser::finish_colon_expression (tree_colon_expression *e)
1762 { 1735 {
1763 tree_expression *retval = e; 1736 tree_expression *retval = e;
1764 1737
1765 unwind_protect frame; 1738 unwind_protect frame;
1766 1739
1820 } 1793 }
1821 1794
1822 // Make a constant. 1795 // Make a constant.
1823 1796
1824 tree_constant * 1797 tree_constant *
1825 octave_parser::make_constant (int op, token *tok_val) 1798 octave_base_parser::make_constant (int op, token *tok_val)
1826 { 1799 {
1827 int l = tok_val->line (); 1800 int l = tok_val->line ();
1828 int c = tok_val->column (); 1801 int c = tok_val->column ();
1829 1802
1830 tree_constant *retval = 0; 1803 tree_constant *retval = 0;
1883 } 1856 }
1884 1857
1885 // Make a function handle. 1858 // Make a function handle.
1886 1859
1887 tree_fcn_handle * 1860 tree_fcn_handle *
1888 octave_parser::make_fcn_handle (token *tok_val) 1861 octave_base_parser::make_fcn_handle (token *tok_val)
1889 { 1862 {
1890 int l = tok_val->line (); 1863 int l = tok_val->line ();
1891 int c = tok_val->column (); 1864 int c = tok_val->column ();
1892 1865
1893 tree_fcn_handle *retval = new tree_fcn_handle (tok_val->text (), l, c); 1866 tree_fcn_handle *retval = new tree_fcn_handle (tok_val->text (), l, c);
1896 } 1869 }
1897 1870
1898 // Make an anonymous function handle. 1871 // Make an anonymous function handle.
1899 1872
1900 tree_anon_fcn_handle * 1873 tree_anon_fcn_handle *
1901 octave_parser::make_anon_fcn_handle (tree_parameter_list *param_list, 1874 octave_base_parser::make_anon_fcn_handle (tree_parameter_list *param_list,
1902 tree_statement *stmt) 1875 tree_statement *stmt)
1903 { 1876 {
1904 // FIXME -- need to get these from the location of the @ symbol. 1877 // FIXME -- need to get these from the location of the @ symbol.
1905 int l = curr_lexer->input_line_number; 1878 int l = curr_lexer.input_line_number;
1906 int c = curr_lexer->current_input_column; 1879 int c = curr_lexer.current_input_column;
1907 1880
1908 tree_parameter_list *ret_list = 0; 1881 tree_parameter_list *ret_list = 0;
1909 1882
1910 symbol_table::scope_id fcn_scope = symbol_table::current_scope (); 1883 symbol_table::scope_id fcn_scope = symbol_table::current_scope ();
1911 1884
1922 1895
1923 tree_anon_fcn_handle *retval 1896 tree_anon_fcn_handle *retval
1924 = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, l, c); 1897 = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, l, c);
1925 // FIXME: Stash the filename. This does not work and produces 1898 // FIXME: Stash the filename. This does not work and produces
1926 // errors when executed. 1899 // errors when executed.
1927 //retval->stash_file_name (curr_lexer->fcn_file_name); 1900 //retval->stash_file_name (curr_lexer.fcn_file_name);
1928 1901
1929 return retval; 1902 return retval;
1930 } 1903 }
1931 1904
1932 // Build a binary expression. 1905 // Build a binary expression.
1933 1906
1934 tree_expression * 1907 tree_expression *
1935 octave_parser::make_binary_op (int op, tree_expression *op1, token *tok_val, 1908 octave_base_parser::make_binary_op (int op, tree_expression *op1,
1936 tree_expression *op2) 1909 token *tok_val, tree_expression *op2)
1937 { 1910 {
1938 octave_value::binary_op t = octave_value::unknown_binary_op; 1911 octave_value::binary_op t = octave_value::unknown_binary_op;
1939 1912
1940 switch (op) 1913 switch (op)
1941 { 1914 {
2034 } 2007 }
2035 2008
2036 // Build a boolean expression. 2009 // Build a boolean expression.
2037 2010
2038 tree_expression * 2011 tree_expression *
2039 octave_parser::make_boolean_op (int op, tree_expression *op1, token *tok_val, 2012 octave_base_parser::make_boolean_op (int op, tree_expression *op1,
2040 tree_expression *op2) 2013 token *tok_val, tree_expression *op2)
2041 { 2014 {
2042 tree_boolean_expression::type t; 2015 tree_boolean_expression::type t;
2043 2016
2044 switch (op) 2017 switch (op)
2045 { 2018 {
2066 } 2039 }
2067 2040
2068 // Build a prefix expression. 2041 // Build a prefix expression.
2069 2042
2070 tree_expression * 2043 tree_expression *
2071 octave_parser::make_prefix_op (int op, tree_expression *op1, token *tok_val) 2044 octave_base_parser::make_prefix_op (int op, tree_expression *op1,
2045 token *tok_val)
2072 { 2046 {
2073 octave_value::unary_op t = octave_value::unknown_unary_op; 2047 octave_value::unary_op t = octave_value::unknown_unary_op;
2074 2048
2075 switch (op) 2049 switch (op)
2076 { 2050 {
2109 } 2083 }
2110 2084
2111 // Build a postfix expression. 2085 // Build a postfix expression.
2112 2086
2113 tree_expression * 2087 tree_expression *
2114 octave_parser::make_postfix_op (int op, tree_expression *op1, token *tok_val) 2088 octave_base_parser::make_postfix_op (int op, tree_expression *op1,
2089 token *tok_val)
2115 { 2090 {
2116 octave_value::unary_op t = octave_value::unknown_unary_op; 2091 octave_value::unary_op t = octave_value::unknown_unary_op;
2117 2092
2118 switch (op) 2093 switch (op)
2119 { 2094 {
2148 } 2123 }
2149 2124
2150 // Build an unwind-protect command. 2125 // Build an unwind-protect command.
2151 2126
2152 tree_command * 2127 tree_command *
2153 octave_parser::make_unwind_command (token *unwind_tok, 2128 octave_base_parser::make_unwind_command (token *unwind_tok,
2154 tree_statement_list *body, 2129 tree_statement_list *body,
2155 tree_statement_list *cleanup_stmts, 2130 tree_statement_list *cleanup_stmts,
2156 token *end_tok, 2131 token *end_tok,
2157 octave_comment_list *lc, 2132 octave_comment_list *lc,
2158 octave_comment_list *mc) 2133 octave_comment_list *mc)
2159 { 2134 {
2160 tree_command *retval = 0; 2135 tree_command *retval = 0;
2161 2136
2162 if (end_token_ok (end_tok, token::unwind_protect_end)) 2137 if (end_token_ok (end_tok, token::unwind_protect_end))
2163 { 2138 {
2174 } 2149 }
2175 2150
2176 // Build a try-catch command. 2151 // Build a try-catch command.
2177 2152
2178 tree_command * 2153 tree_command *
2179 octave_parser::make_try_command (token *try_tok, tree_statement_list *body, 2154 octave_base_parser::make_try_command (token *try_tok,
2180 tree_statement_list *cleanup_stmts, 2155 tree_statement_list *body,
2181 token *end_tok, 2156 tree_statement_list *cleanup_stmts,
2182 octave_comment_list *lc, 2157 token *end_tok,
2183 octave_comment_list *mc) 2158 octave_comment_list *lc,
2159 octave_comment_list *mc)
2184 { 2160 {
2185 tree_command *retval = 0; 2161 tree_command *retval = 0;
2186 2162
2187 if (end_token_ok (end_tok, token::try_catch_end)) 2163 if (end_token_ok (end_tok, token::try_catch_end))
2188 { 2164 {
2199 } 2175 }
2200 2176
2201 // Build a while command. 2177 // Build a while command.
2202 2178
2203 tree_command * 2179 tree_command *
2204 octave_parser::make_while_command (token *while_tok, tree_expression *expr, 2180 octave_base_parser::make_while_command (token *while_tok,
2205 tree_statement_list *body, token *end_tok, 2181 tree_expression *expr,
2206 octave_comment_list *lc) 2182 tree_statement_list *body,
2183 token *end_tok,
2184 octave_comment_list *lc)
2207 { 2185 {
2208 tree_command *retval = 0; 2186 tree_command *retval = 0;
2209 2187
2210 maybe_warn_assign_as_truth_value (expr); 2188 maybe_warn_assign_as_truth_value (expr);
2211 2189
2212 if (end_token_ok (end_tok, token::while_end)) 2190 if (end_token_ok (end_tok, token::while_end))
2213 { 2191 {
2214 octave_comment_list *tc = octave_comment_buffer::get_comment (); 2192 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2215 2193
2216 curr_lexer->looping--; 2194 curr_lexer.looping--;
2217 2195
2218 int l = while_tok->line (); 2196 int l = while_tok->line ();
2219 int c = while_tok->column (); 2197 int c = while_tok->column ();
2220 2198
2221 retval = new tree_while_command (expr, body, lc, tc, l, c); 2199 retval = new tree_while_command (expr, body, lc, tc, l, c);
2225 } 2203 }
2226 2204
2227 // Build a do-until command. 2205 // Build a do-until command.
2228 2206
2229 tree_command * 2207 tree_command *
2230 octave_parser::make_do_until_command (token *until_tok, 2208 octave_base_parser::make_do_until_command (token *until_tok,
2231 tree_statement_list *body, 2209 tree_statement_list *body,
2232 tree_expression *expr, 2210 tree_expression *expr,
2233 octave_comment_list *lc) 2211 octave_comment_list *lc)
2234 { 2212 {
2235 tree_command *retval = 0; 2213 tree_command *retval = 0;
2236 2214
2237 maybe_warn_assign_as_truth_value (expr); 2215 maybe_warn_assign_as_truth_value (expr);
2238 2216
2239 octave_comment_list *tc = octave_comment_buffer::get_comment (); 2217 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2240 2218
2241 curr_lexer->looping--; 2219 curr_lexer.looping--;
2242 2220
2243 int l = until_tok->line (); 2221 int l = until_tok->line ();
2244 int c = until_tok->column (); 2222 int c = until_tok->column ();
2245 2223
2246 retval = new tree_do_until_command (expr, body, lc, tc, l, c); 2224 retval = new tree_do_until_command (expr, body, lc, tc, l, c);
2249 } 2227 }
2250 2228
2251 // Build a for command. 2229 // Build a for command.
2252 2230
2253 tree_command * 2231 tree_command *
2254 octave_parser::make_for_command (int tok_id, token *for_tok, 2232 octave_base_parser::make_for_command (int tok_id, token *for_tok,
2255 tree_argument_list *lhs, 2233 tree_argument_list *lhs,
2256 tree_expression *expr, 2234 tree_expression *expr,
2257 tree_expression *maxproc, 2235 tree_expression *maxproc,
2258 tree_statement_list *body, token *end_tok, 2236 tree_statement_list *body,
2259 octave_comment_list *lc) 2237 token *end_tok,
2238 octave_comment_list *lc)
2260 { 2239 {
2261 tree_command *retval = 0; 2240 tree_command *retval = 0;
2262 2241
2263 bool parfor = tok_id == PARFOR; 2242 bool parfor = tok_id == PARFOR;
2264 2243
2265 if (end_token_ok (end_tok, parfor ? token::parfor_end : token::for_end)) 2244 if (end_token_ok (end_tok, parfor ? token::parfor_end : token::for_end))
2266 { 2245 {
2267 octave_comment_list *tc = octave_comment_buffer::get_comment (); 2246 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2268 2247
2269 curr_lexer->looping--; 2248 curr_lexer.looping--;
2270 2249
2271 int l = for_tok->line (); 2250 int l = for_tok->line ();
2272 int c = for_tok->column (); 2251 int c = for_tok->column ();
2273 2252
2274 if (lhs->length () == 1) 2253 if (lhs->length () == 1)
2294 } 2273 }
2295 2274
2296 // Build a break command. 2275 // Build a break command.
2297 2276
2298 tree_command * 2277 tree_command *
2299 octave_parser::make_break_command (token *break_tok) 2278 octave_base_parser::make_break_command (token *break_tok)
2300 { 2279 {
2301 tree_command *retval = 0; 2280 tree_command *retval = 0;
2302 2281
2303 int l = break_tok->line (); 2282 int l = break_tok->line ();
2304 int c = break_tok->column (); 2283 int c = break_tok->column ();
2309 } 2288 }
2310 2289
2311 // Build a continue command. 2290 // Build a continue command.
2312 2291
2313 tree_command * 2292 tree_command *
2314 octave_parser::make_continue_command (token *continue_tok) 2293 octave_base_parser::make_continue_command (token *continue_tok)
2315 { 2294 {
2316 tree_command *retval = 0; 2295 tree_command *retval = 0;
2317 2296
2318 int l = continue_tok->line (); 2297 int l = continue_tok->line ();
2319 int c = continue_tok->column (); 2298 int c = continue_tok->column ();
2324 } 2303 }
2325 2304
2326 // Build a return command. 2305 // Build a return command.
2327 2306
2328 tree_command * 2307 tree_command *
2329 octave_parser::make_return_command (token *return_tok) 2308 octave_base_parser::make_return_command (token *return_tok)
2330 { 2309 {
2331 tree_command *retval = 0; 2310 tree_command *retval = 0;
2332 2311
2333 int l = return_tok->line (); 2312 int l = return_tok->line ();
2334 int c = return_tok->column (); 2313 int c = return_tok->column ();
2339 } 2318 }
2340 2319
2341 // Start an if command. 2320 // Start an if command.
2342 2321
2343 tree_if_command_list * 2322 tree_if_command_list *
2344 octave_parser::start_if_command (tree_expression *expr, 2323 octave_base_parser::start_if_command (tree_expression *expr,
2345 tree_statement_list *list) 2324 tree_statement_list *list)
2346 { 2325 {
2347 maybe_warn_assign_as_truth_value (expr); 2326 maybe_warn_assign_as_truth_value (expr);
2348 2327
2349 tree_if_clause *t = new tree_if_clause (expr, list); 2328 tree_if_clause *t = new tree_if_clause (expr, list);
2350 2329
2352 } 2331 }
2353 2332
2354 // Finish an if command. 2333 // Finish an if command.
2355 2334
2356 tree_if_command * 2335 tree_if_command *
2357 octave_parser::finish_if_command (token *if_tok, tree_if_command_list *list, 2336 octave_base_parser::finish_if_command (token *if_tok,
2358 token *end_tok, octave_comment_list *lc) 2337 tree_if_command_list *list,
2338 token *end_tok,
2339 octave_comment_list *lc)
2359 { 2340 {
2360 tree_if_command *retval = 0; 2341 tree_if_command *retval = 0;
2361 2342
2362 if (end_token_ok (end_tok, token::if_end)) 2343 if (end_token_ok (end_tok, token::if_end))
2363 { 2344 {
2384 } 2365 }
2385 2366
2386 // Build an elseif clause. 2367 // Build an elseif clause.
2387 2368
2388 tree_if_clause * 2369 tree_if_clause *
2389 octave_parser::make_elseif_clause (token *elseif_tok, tree_expression *expr, 2370 octave_base_parser::make_elseif_clause (token *elseif_tok,
2390 tree_statement_list *list, 2371 tree_expression *expr,
2391 octave_comment_list *lc) 2372 tree_statement_list *list,
2373 octave_comment_list *lc)
2392 { 2374 {
2393 maybe_warn_assign_as_truth_value (expr); 2375 maybe_warn_assign_as_truth_value (expr);
2394 2376
2395 int l = elseif_tok->line (); 2377 int l = elseif_tok->line ();
2396 int c = elseif_tok->column (); 2378 int c = elseif_tok->column ();
2399 } 2381 }
2400 2382
2401 // Finish a switch command. 2383 // Finish a switch command.
2402 2384
2403 tree_switch_command * 2385 tree_switch_command *
2404 octave_parser::finish_switch_command (token *switch_tok, tree_expression *expr, 2386 octave_base_parser::finish_switch_command (token *switch_tok,
2405 tree_switch_case_list *list, 2387 tree_expression *expr,
2406 token *end_tok, octave_comment_list *lc) 2388 tree_switch_case_list *list,
2389 token *end_tok,
2390 octave_comment_list *lc)
2407 { 2391 {
2408 tree_switch_command *retval = 0; 2392 tree_switch_command *retval = 0;
2409 2393
2410 if (end_token_ok (end_tok, token::switch_end)) 2394 if (end_token_ok (end_tok, token::switch_end))
2411 { 2395 {
2432 } 2416 }
2433 2417
2434 // Build a switch case. 2418 // Build a switch case.
2435 2419
2436 tree_switch_case * 2420 tree_switch_case *
2437 octave_parser::make_switch_case (token *case_tok, tree_expression *expr, 2421 octave_base_parser::make_switch_case (token *case_tok,
2438 tree_statement_list *list, 2422 tree_expression *expr,
2439 octave_comment_list *lc) 2423 tree_statement_list *list,
2424 octave_comment_list *lc)
2440 { 2425 {
2441 maybe_warn_variable_switch_label (expr); 2426 maybe_warn_variable_switch_label (expr);
2442 2427
2443 int l = case_tok->line (); 2428 int l = case_tok->line ();
2444 int c = case_tok->column (); 2429 int c = case_tok->column ();
2447 } 2432 }
2448 2433
2449 // Build an assignment to a variable. 2434 // Build an assignment to a variable.
2450 2435
2451 tree_expression * 2436 tree_expression *
2452 octave_parser::make_assign_op (int op, tree_argument_list *lhs, token *eq_tok, 2437 octave_base_parser::make_assign_op (int op, tree_argument_list *lhs,
2453 tree_expression *rhs) 2438 token *eq_tok, tree_expression *rhs)
2454 { 2439 {
2455 tree_expression *retval = 0; 2440 tree_expression *retval = 0;
2456 2441
2457 octave_value::assign_op t = octave_value::unknown_assign_op; 2442 octave_value::assign_op t = octave_value::unknown_assign_op;
2458 2443
2543 } 2528 }
2544 2529
2545 // Define a script. 2530 // Define a script.
2546 2531
2547 void 2532 void
2548 octave_parser::make_script (tree_statement_list *cmds, 2533 octave_base_parser::make_script (tree_statement_list *cmds,
2549 tree_statement *end_script) 2534 tree_statement *end_script)
2550 { 2535 {
2551 if (! cmds) 2536 if (! cmds)
2552 cmds = new tree_statement_list (); 2537 cmds = new tree_statement_list ();
2553 2538
2554 cmds->append (end_script); 2539 cmds->append (end_script);
2555 2540
2556 octave_user_script *script 2541 octave_user_script *script
2557 = new octave_user_script (curr_lexer->fcn_file_full_name, 2542 = new octave_user_script (curr_lexer.fcn_file_full_name,
2558 curr_lexer->fcn_file_name, 2543 curr_lexer.fcn_file_name,
2559 cmds, curr_lexer->help_text); 2544 cmds, curr_lexer.help_text);
2560 2545
2561 curr_lexer->help_text = ""; 2546 curr_lexer.help_text = "";
2562 2547
2563 octave_time now; 2548 octave_time now;
2564 2549
2565 script->stash_fcn_file_time (now); 2550 script->stash_fcn_file_time (now);
2566 2551
2568 } 2553 }
2569 2554
2570 // Begin defining a function. 2555 // Begin defining a function.
2571 2556
2572 octave_user_function * 2557 octave_user_function *
2573 octave_parser::start_function (tree_parameter_list *param_list, 2558 octave_base_parser::start_function (tree_parameter_list *param_list,
2574 tree_statement_list *body, 2559 tree_statement_list *body,
2575 tree_statement *end_fcn_stmt) 2560 tree_statement *end_fcn_stmt)
2576 { 2561 {
2577 // We'll fill in the return list later. 2562 // We'll fill in the return list later.
2578 2563
2579 if (! body) 2564 if (! body)
2580 body = new tree_statement_list (); 2565 body = new tree_statement_list ();
2594 2579
2595 return fcn; 2580 return fcn;
2596 } 2581 }
2597 2582
2598 tree_statement * 2583 tree_statement *
2599 octave_parser::make_end (const std::string& type, int l, int c) 2584 octave_base_parser::make_end (const std::string& type, int l, int c)
2600 { 2585 {
2601 return make_statement (new tree_no_op_command (type, l, c)); 2586 return make_statement (new tree_no_op_command (type, l, c));
2602 } 2587 }
2603 2588
2604 // Do most of the work for defining a function. 2589 // Do most of the work for defining a function.
2605 2590
2606 octave_user_function * 2591 octave_user_function *
2607 octave_parser::frob_function (const std::string& fname, 2592 octave_base_parser::frob_function (const std::string& fname,
2608 octave_user_function *fcn) 2593 octave_user_function *fcn)
2609 { 2594 {
2610 std::string id_name = fname; 2595 std::string id_name = fname;
2611 2596
2612 // If input is coming from a file, issue a warning if the name of 2597 // If input is coming from a file, issue a warning if the name of
2613 // the file does not match the name of the function stated in the 2598 // the file does not match the name of the function stated in the
2614 // file. Matlab doesn't provide a diagnostic (it ignores the stated 2599 // file. Matlab doesn't provide a diagnostic (it ignores the stated
2615 // name). 2600 // name).
2616 if (! autoloading && curr_lexer->reading_fcn_file 2601 if (! autoloading && curr_lexer.reading_fcn_file
2617 && curr_fcn_depth == 1 && ! parsing_subfunctions) 2602 && curr_fcn_depth == 1 && ! parsing_subfunctions)
2618 { 2603 {
2619 // FIXME -- should curr_lexer->fcn_file_name already be 2604 // FIXME -- should curr_lexer.fcn_file_name already be
2620 // preprocessed when we get here? It seems to only be a 2605 // preprocessed when we get here? It seems to only be a
2621 // problem with relative file names. 2606 // problem with relative file names.
2622 2607
2623 std::string nm = curr_lexer->fcn_file_name; 2608 std::string nm = curr_lexer.fcn_file_name;
2624 2609
2625 size_t pos = nm.find_last_of (file_ops::dir_sep_chars ()); 2610 size_t pos = nm.find_last_of (file_ops::dir_sep_chars ());
2626 2611
2627 if (pos != std::string::npos) 2612 if (pos != std::string::npos)
2628 nm = curr_lexer->fcn_file_name.substr (pos+1); 2613 nm = curr_lexer.fcn_file_name.substr (pos+1);
2629 2614
2630 if (nm != id_name) 2615 if (nm != id_name)
2631 { 2616 {
2632 warning_with_id 2617 warning_with_id
2633 ("Octave:function-name-clash", 2618 ("Octave:function-name-clash",
2634 "function name '%s' does not agree with function file name '%s'", 2619 "function name '%s' does not agree with function file name '%s'",
2635 id_name.c_str (), curr_lexer->fcn_file_full_name.c_str ()); 2620 id_name.c_str (), curr_lexer.fcn_file_full_name.c_str ());
2636 2621
2637 id_name = nm; 2622 id_name = nm;
2638 } 2623 }
2639 } 2624 }
2640 2625
2641 if (curr_lexer->reading_fcn_file || curr_lexer->reading_classdef_file || autoloading) 2626 if (curr_lexer.reading_fcn_file || curr_lexer.reading_classdef_file || autoloading)
2642 { 2627 {
2643 octave_time now; 2628 octave_time now;
2644 2629
2645 fcn->stash_fcn_file_name (curr_lexer->fcn_file_full_name); 2630 fcn->stash_fcn_file_name (curr_lexer.fcn_file_full_name);
2646 fcn->stash_fcn_file_time (now); 2631 fcn->stash_fcn_file_time (now);
2647 fcn->mark_as_system_fcn_file (); 2632 fcn->mark_as_system_fcn_file ();
2648 2633
2649 if (fcn_file_from_relative_lookup) 2634 if (fcn_file_from_relative_lookup)
2650 fcn->mark_relative (); 2635 fcn->mark_relative ();
2651 2636
2652 if (curr_fcn_depth > 1 || parsing_subfunctions) 2637 if (curr_fcn_depth > 1 || parsing_subfunctions)
2653 { 2638 {
2654 fcn->stash_parent_fcn_name (curr_lexer->fcn_file_name); 2639 fcn->stash_parent_fcn_name (curr_lexer.fcn_file_name);
2655 2640
2656 if (curr_fcn_depth > 1) 2641 if (curr_fcn_depth > 1)
2657 fcn->stash_parent_fcn_scope (function_scopes[function_scopes.size ()-2]); 2642 fcn->stash_parent_fcn_scope (function_scopes[function_scopes.size ()-2]);
2658 else 2643 else
2659 fcn->stash_parent_fcn_scope (primary_fcn_scope); 2644 fcn->stash_parent_fcn_scope (primary_fcn_scope);
2660 } 2645 }
2661 2646
2662 if (curr_lexer->parsing_class_method) 2647 if (curr_lexer.parsing_class_method)
2663 { 2648 {
2664 if (curr_class_name == id_name) 2649 if (curr_class_name == id_name)
2665 fcn->mark_as_class_constructor (); 2650 fcn->mark_as_class_constructor ();
2666 else 2651 else
2667 fcn->mark_as_class_method (); 2652 fcn->mark_as_class_method ();
2676 if (fs && fs.is_newer (now)) 2661 if (fs && fs.is_newer (now))
2677 warning_with_id ("Octave:future-time-stamp", 2662 warning_with_id ("Octave:future-time-stamp",
2678 "time stamp for '%s' is in the future", nm.c_str ()); 2663 "time stamp for '%s' is in the future", nm.c_str ());
2679 } 2664 }
2680 else if (! input_from_tmp_history_file 2665 else if (! input_from_tmp_history_file
2681 && ! curr_lexer->force_script 2666 && ! curr_lexer.force_script
2682 && curr_lexer->reading_script_file 2667 && curr_lexer.reading_script_file
2683 && curr_lexer->fcn_file_name == id_name) 2668 && curr_lexer.fcn_file_name == id_name)
2684 { 2669 {
2685 warning ("function '%s' defined within script file '%s'", 2670 warning ("function '%s' defined within script file '%s'",
2686 id_name.c_str (), curr_lexer->fcn_file_full_name.c_str ()); 2671 id_name.c_str (), curr_lexer.fcn_file_full_name.c_str ());
2687 } 2672 }
2688 2673
2689 fcn->stash_function_name (id_name); 2674 fcn->stash_function_name (id_name);
2690 fcn->stash_fcn_location (curr_lexer->input_line_number, 2675 fcn->stash_fcn_location (curr_lexer.input_line_number,
2691 curr_lexer->current_input_column); 2676 curr_lexer.current_input_column);
2692 2677
2693 if (! curr_lexer->help_text.empty () && curr_fcn_depth == 1 2678 if (! curr_lexer.help_text.empty () && curr_fcn_depth == 1
2694 && ! parsing_subfunctions) 2679 && ! parsing_subfunctions)
2695 { 2680 {
2696 fcn->document (curr_lexer->help_text); 2681 fcn->document (curr_lexer.help_text);
2697 2682
2698 curr_lexer->help_text = ""; 2683 curr_lexer.help_text = "";
2699 } 2684 }
2700 2685
2701 if (curr_lexer->reading_fcn_file && curr_fcn_depth == 1 2686 if (curr_lexer.reading_fcn_file && curr_fcn_depth == 1
2702 && ! parsing_subfunctions) 2687 && ! parsing_subfunctions)
2703 primary_fcn_ptr = fcn; 2688 primary_fcn_ptr = fcn;
2704 2689
2705 return fcn; 2690 return fcn;
2706 } 2691 }
2707 2692
2708 tree_function_def * 2693 tree_function_def *
2709 octave_parser::finish_function (tree_parameter_list *ret_list, 2694 octave_base_parser::finish_function (tree_parameter_list *ret_list,
2710 octave_user_function *fcn, 2695 octave_user_function *fcn,
2711 octave_comment_list *lc) 2696 octave_comment_list *lc)
2712 { 2697 {
2713 tree_function_def *retval = 0; 2698 tree_function_def *retval = 0;
2714 2699
2715 if (ret_list) 2700 if (ret_list)
2716 ret_list->mark_as_formal_parameters (); 2701 ret_list->mark_as_formal_parameters ();
2749 } 2734 }
2750 2735
2751 if (curr_fcn_depth == 1 && fcn) 2736 if (curr_fcn_depth == 1 && fcn)
2752 symbol_table::update_nest (fcn->scope ()); 2737 symbol_table::update_nest (fcn->scope ());
2753 2738
2754 if (! curr_lexer->reading_fcn_file && curr_fcn_depth == 1) 2739 if (! curr_lexer.reading_fcn_file && curr_fcn_depth == 1)
2755 { 2740 {
2756 // We are either reading a script file or defining a function 2741 // We are either reading a script file or defining a function
2757 // at the command line, so this definition creates a 2742 // at the command line, so this definition creates a
2758 // tree_function object that is placed in the parse tree. 2743 // tree_function object that is placed in the parse tree.
2759 // Otherwise, it is just inserted in the symbol table, 2744 // Otherwise, it is just inserted in the symbol table,
2769 2754
2770 return retval; 2755 return retval;
2771 } 2756 }
2772 2757
2773 void 2758 void
2774 octave_parser::recover_from_parsing_function (void) 2759 octave_base_parser::recover_from_parsing_function (void)
2775 { 2760 {
2776 if (parser_symtab_context.empty ()) 2761 if (parser_symtab_context.empty ())
2777 panic_impossible (); 2762 panic_impossible ();
2778 2763
2779 parser_symtab_context.pop (); 2764 parser_symtab_context.pop ();
2780 2765
2781 if (curr_lexer->reading_fcn_file && curr_fcn_depth == 1 2766 if (curr_lexer.reading_fcn_file && curr_fcn_depth == 1
2782 && ! parsing_subfunctions) 2767 && ! parsing_subfunctions)
2783 parsing_subfunctions = true; 2768 parsing_subfunctions = true;
2784 2769
2785 curr_fcn_depth--; 2770 curr_fcn_depth--;
2786 function_scopes.pop_back (); 2771 function_scopes.pop_back ();
2787 2772
2788 curr_lexer->defining_func--; 2773 curr_lexer.defining_func--;
2789 curr_lexer->parsed_function_name.pop (); 2774 curr_lexer.parsed_function_name.pop ();
2790 curr_lexer->looking_at_return_list = false; 2775 curr_lexer.looking_at_return_list = false;
2791 curr_lexer->looking_at_parameter_list = false; 2776 curr_lexer.looking_at_parameter_list = false;
2792 } 2777 }
2793 2778
2794 // Make an index expression. 2779 // Make an index expression.
2795 2780
2796 tree_index_expression * 2781 tree_index_expression *
2797 octave_parser::make_index_expression (tree_expression *expr, 2782 octave_base_parser::make_index_expression (tree_expression *expr,
2798 tree_argument_list *args, char type) 2783 tree_argument_list *args,
2784 char type)
2799 { 2785 {
2800 tree_index_expression *retval = 0; 2786 tree_index_expression *retval = 0;
2801 2787
2802 if (args && args->has_magic_tilde ()) 2788 if (args && args->has_magic_tilde ())
2803 { 2789 {
2825 } 2811 }
2826 2812
2827 // Make an indirect reference expression. 2813 // Make an indirect reference expression.
2828 2814
2829 tree_index_expression * 2815 tree_index_expression *
2830 octave_parser::make_indirect_ref (tree_expression *expr, 2816 octave_base_parser::make_indirect_ref (tree_expression *expr,
2831 const std::string& elt) 2817 const std::string& elt)
2832 { 2818 {
2833 tree_index_expression *retval = 0; 2819 tree_index_expression *retval = 0;
2834 2820
2835 int l = expr->line (); 2821 int l = expr->line ();
2836 int c = expr->column (); 2822 int c = expr->column ();
2844 retval = tmp; 2830 retval = tmp;
2845 } 2831 }
2846 else 2832 else
2847 retval = new tree_index_expression (expr, elt, l, c); 2833 retval = new tree_index_expression (expr, elt, l, c);
2848 2834
2849 curr_lexer->looking_at_indirect_ref = false; 2835 curr_lexer.looking_at_indirect_ref = false;
2850 2836
2851 return retval; 2837 return retval;
2852 } 2838 }
2853 2839
2854 // Make an indirect reference expression with dynamic field name. 2840 // Make an indirect reference expression with dynamic field name.
2855 2841
2856 tree_index_expression * 2842 tree_index_expression *
2857 octave_parser::make_indirect_ref (tree_expression *expr, tree_expression *elt) 2843 octave_base_parser::make_indirect_ref (tree_expression *expr, tree_expression *elt)
2858 { 2844 {
2859 tree_index_expression *retval = 0; 2845 tree_index_expression *retval = 0;
2860 2846
2861 int l = expr->line (); 2847 int l = expr->line ();
2862 int c = expr->column (); 2848 int c = expr->column ();
2870 retval = tmp; 2856 retval = tmp;
2871 } 2857 }
2872 else 2858 else
2873 retval = new tree_index_expression (expr, elt, l, c); 2859 retval = new tree_index_expression (expr, elt, l, c);
2874 2860
2875 curr_lexer->looking_at_indirect_ref = false; 2861 curr_lexer.looking_at_indirect_ref = false;
2876 2862
2877 return retval; 2863 return retval;
2878 } 2864 }
2879 2865
2880 // Make a declaration command. 2866 // Make a declaration command.
2881 2867
2882 tree_decl_command * 2868 tree_decl_command *
2883 octave_parser::make_decl_command (int tok, token *tok_val, 2869 octave_base_parser::make_decl_command (int tok, token *tok_val,
2884 tree_decl_init_list *lst) 2870 tree_decl_init_list *lst)
2885 { 2871 {
2886 tree_decl_command *retval = 0; 2872 tree_decl_command *retval = 0;
2887 2873
2888 int l = tok_val->line (); 2874 int l = tok_val->line ();
2889 int c = tok_val->column (); 2875 int c = tok_val->column ();
2897 case PERSISTENT: 2883 case PERSISTENT:
2898 if (curr_fcn_depth > 0) 2884 if (curr_fcn_depth > 0)
2899 retval = new tree_persistent_command (lst, l, c); 2885 retval = new tree_persistent_command (lst, l, c);
2900 else 2886 else
2901 { 2887 {
2902 if (curr_lexer->reading_script_file) 2888 if (curr_lexer.reading_script_file)
2903 warning ("ignoring persistent declaration near line %d of file '%s'", 2889 warning ("ignoring persistent declaration near line %d of file '%s'",
2904 l, curr_lexer->fcn_file_full_name.c_str ()); 2890 l, curr_lexer.fcn_file_full_name.c_str ());
2905 else 2891 else
2906 warning ("ignoring persistent declaration near line %d", l); 2892 warning ("ignoring persistent declaration near line %d", l);
2907 } 2893 }
2908 break; 2894 break;
2909 2895
2914 2900
2915 return retval; 2901 return retval;
2916 } 2902 }
2917 2903
2918 bool 2904 bool
2919 octave_parser::validate_array_list (tree_expression *e) 2905 octave_base_parser::validate_array_list (tree_expression *e)
2920 { 2906 {
2921 bool retval = true; 2907 bool retval = true;
2922 2908
2923 tree_array_list *al = dynamic_cast<tree_array_list *> (e); 2909 tree_array_list *al = dynamic_cast<tree_array_list *> (e);
2924 2910
2939 2925
2940 return retval; 2926 return retval;
2941 } 2927 }
2942 2928
2943 tree_argument_list * 2929 tree_argument_list *
2944 octave_parser::validate_matrix_for_assignment (tree_expression *e) 2930 octave_base_parser::validate_matrix_for_assignment (tree_expression *e)
2945 { 2931 {
2946 tree_argument_list *retval = 0; 2932 tree_argument_list *retval = 0;
2947 2933
2948 if (e->is_constant ()) 2934 if (e->is_constant ())
2949 { 2935 {
2993 } 2979 }
2994 2980
2995 // Finish building an array_list. 2981 // Finish building an array_list.
2996 2982
2997 tree_expression * 2983 tree_expression *
2998 octave_parser::finish_array_list (tree_array_list *array_list) 2984 octave_base_parser::finish_array_list (tree_array_list *array_list)
2999 { 2985 {
3000 tree_expression *retval = array_list; 2986 tree_expression *retval = array_list;
3001 2987
3002 unwind_protect frame; 2988 unwind_protect frame;
3003 2989
3038 } 3024 }
3039 3025
3040 // Finish building a matrix list. 3026 // Finish building a matrix list.
3041 3027
3042 tree_expression * 3028 tree_expression *
3043 octave_parser::finish_matrix (tree_matrix *m) 3029 octave_base_parser::finish_matrix (tree_matrix *m)
3044 { 3030 {
3045 return finish_array_list (m); 3031 return finish_array_list (m);
3046 } 3032 }
3047 3033
3048 // Finish building a cell list. 3034 // Finish building a cell list.
3049 3035
3050 tree_expression * 3036 tree_expression *
3051 octave_parser::finish_cell (tree_cell *c) 3037 octave_base_parser::finish_cell (tree_cell *c)
3052 { 3038 {
3053 return finish_array_list (c); 3039 return finish_array_list (c);
3054 } 3040 }
3055 3041
3056 void 3042 void
3057 octave_parser::maybe_warn_missing_semi (tree_statement_list *t) 3043 octave_base_parser::maybe_warn_missing_semi (tree_statement_list *t)
3058 { 3044 {
3059 if (curr_fcn_depth > 0) 3045 if (curr_fcn_depth > 0)
3060 { 3046 {
3061 tree_statement *tmp = t->back (); 3047 tree_statement *tmp = t->back ();
3062 3048
3063 if (tmp->is_expression ()) 3049 if (tmp->is_expression ())
3064 warning_with_id 3050 warning_with_id
3065 ("Octave:missing-semicolon", 3051 ("Octave:missing-semicolon",
3066 "missing semicolon near line %d, column %d in file '%s'", 3052 "missing semicolon near line %d, column %d in file '%s'",
3067 tmp->line (), tmp->column (), curr_lexer->fcn_file_full_name.c_str ()); 3053 tmp->line (), tmp->column (), curr_lexer.fcn_file_full_name.c_str ());
3068 } 3054 }
3069 } 3055 }
3070 3056
3071 tree_statement_list * 3057 tree_statement_list *
3072 octave_parser::set_stmt_print_flag (tree_statement_list *list, char sep, 3058 octave_base_parser::set_stmt_print_flag (tree_statement_list *list,
3073 bool warn_missing_semi) 3059 char sep, bool warn_missing_semi)
3074 { 3060 {
3075 tree_statement *tmp = list->back (); 3061 tree_statement *tmp = list->back ();
3076 3062
3077 switch (sep) 3063 switch (sep)
3078 { 3064 {
3104 3090
3105 return list; 3091 return list;
3106 } 3092 }
3107 3093
3108 tree_statement_list * 3094 tree_statement_list *
3109 octave_parser::make_statement_list (tree_statement *stmt) 3095 octave_base_parser::make_statement_list (tree_statement *stmt)
3110 { 3096 {
3111 return new tree_statement_list (stmt); 3097 return new tree_statement_list (stmt);
3112 } 3098 }
3113 3099
3114 tree_statement_list * 3100 tree_statement_list *
3115 octave_parser::append_statement_list (tree_statement_list *list, char sep, 3101 octave_base_parser::append_statement_list (tree_statement_list *list,
3116 tree_statement *stmt, 3102 char sep, tree_statement *stmt,
3117 bool warn_missing_semi) 3103 bool warn_missing_semi)
3118 { 3104 {
3119 set_stmt_print_flag (list, sep, warn_missing_semi); 3105 set_stmt_print_flag (list, sep, warn_missing_semi);
3120 3106
3121 list->append (stmt); 3107 list->append (stmt);
3122 3108
3123 return list; 3109 return list;
3124 } 3110 }
3125 3111
3126 void 3112 void
3127 octave_parser::bison_error (const char *s) 3113 octave_base_parser::bison_error (const char *s)
3128 { 3114 {
3129 int err_col = curr_lexer->current_input_column - 1; 3115 int err_col = curr_lexer.current_input_column - 1;
3130 3116
3131 std::ostringstream output_buf; 3117 std::ostringstream output_buf;
3132 3118
3133 if (curr_lexer->reading_fcn_file || curr_lexer->reading_script_file || curr_lexer->reading_classdef_file) 3119 if (curr_lexer.reading_fcn_file || curr_lexer.reading_script_file || curr_lexer.reading_classdef_file)
3134 output_buf << "parse error near line " << curr_lexer->input_line_number 3120 output_buf << "parse error near line " << curr_lexer.input_line_number
3135 << " of file " << curr_lexer->fcn_file_full_name; 3121 << " of file " << curr_lexer.fcn_file_full_name;
3136 else 3122 else
3137 output_buf << "parse error:"; 3123 output_buf << "parse error:";
3138 3124
3139 if (s && strcmp (s, "parse error") != 0) 3125 if (s && strcmp (s, "parse error") != 0)
3140 output_buf << "\n\n " << s; 3126 output_buf << "\n\n " << s;
3141 3127
3142 output_buf << "\n\n"; 3128 output_buf << "\n\n";
3143 3129
3144 std::string curr_line = curr_lexer->current_input_line; 3130 std::string curr_line = curr_lexer.current_input_line;
3145 3131
3146 if (! curr_line.empty ()) 3132 if (! curr_line.empty ())
3147 { 3133 {
3148 size_t len = curr_line.length (); 3134 size_t len = curr_line.length ();
3149 3135
3166 output_buf << "\n"; 3152 output_buf << "\n";
3167 3153
3168 std::string msg = output_buf.str (); 3154 std::string msg = output_buf.str ();
3169 3155
3170 parse_error ("%s", msg.c_str ()); 3156 parse_error ("%s", msg.c_str ());
3157 }
3158
3159 int
3160 octave_parser::run (void)
3161 {
3162 return octave_parse (*this);
3171 } 3163 }
3172 3164
3173 static void 3165 static void
3174 safe_fclose (FILE *f) 3166 safe_fclose (FILE *f)
3175 { 3167 {
3214 3206
3215 frame.add_fcn (safe_fclose, ffile); 3207 frame.add_fcn (safe_fclose, ffile);
3216 3208
3217 if (ffile) 3209 if (ffile)
3218 { 3210 {
3219 // octave_parser constructor sets this for us. 3211 // octave_base_parser constructor sets this for us.
3220 frame.protect_var (CURR_LEXER); 3212 frame.protect_var (CURR_LEXER);
3221 3213
3222 octave_parser curr_parser (ffile); 3214 octave_parser curr_parser (ffile);
3223 3215
3224 curr_parser.curr_class_name = dispatch_type; 3216 curr_parser.curr_class_name = dispatch_type;
3225 curr_parser.autoloading = autoload; 3217 curr_parser.autoloading = autoload;
3226 curr_parser.fcn_file_from_relative_lookup = relative_lookup; 3218 curr_parser.fcn_file_from_relative_lookup = relative_lookup;
3227 3219
3228 curr_parser.curr_lexer->force_script = force_script; 3220 curr_parser.curr_lexer.force_script = force_script;
3229 curr_parser.curr_lexer->prep_for_file (); 3221 curr_parser.curr_lexer.prep_for_file ();
3230 curr_parser.curr_lexer->parsing_class_method = ! dispatch_type.empty (); 3222 curr_parser.curr_lexer.parsing_class_method = ! dispatch_type.empty ();
3231 3223
3232 curr_parser.curr_lexer->fcn_file_name = file; 3224 curr_parser.curr_lexer.fcn_file_name = file;
3233 curr_parser.curr_lexer->fcn_file_full_name = full_file; 3225 curr_parser.curr_lexer.fcn_file_full_name = full_file;
3234 3226
3235 int status = curr_parser.run (); 3227 int status = curr_parser.run ();
3236 3228
3237 fcn_ptr = curr_parser.primary_fcn_ptr; 3229 fcn_ptr = curr_parser.primary_fcn_ptr;
3238 3230
3910 { 3902 {
3911 octave_value_list retval; 3903 octave_value_list retval;
3912 3904
3913 unwind_protect frame; 3905 unwind_protect frame;
3914 3906
3915 // octave_parser constructor sets this for us. 3907 // octave_base_parser constructor sets this for us.
3916 frame.protect_var (CURR_LEXER); 3908 frame.protect_var (CURR_LEXER);
3917 3909
3918 octave_parser curr_parser (eval_str); 3910 octave_parser curr_parser (eval_str);
3919 3911
3920 do 3912 do
3970 || tree_return_command::returning 3962 || tree_return_command::returning
3971 || tree_break_command::breaking 3963 || tree_break_command::breaking
3972 || tree_continue_command::continuing) 3964 || tree_continue_command::continuing)
3973 break; 3965 break;
3974 } 3966 }
3975 else if (curr_parser.curr_lexer->end_of_input) 3967 else if (curr_parser.curr_lexer.end_of_input)
3976 break; 3968 break;
3977 } 3969 }
3978 } 3970 }
3979 while (parse_status == 0); 3971 while (parse_status == 0);
3980 3972