comparison src/parse.y @ 3665:0689afb1d001

[project @ 2000-05-11 19:07:56 by jwe]
author jwe
date Thu, 11 May 2000 19:10:09 +0000
parents 71bd2d124119
children 7066a8065e7e
comparison
equal deleted inserted replaced
3664:d178e2bbd873 3665:0689afb1d001
44 #include "cmd-edit.h" 44 #include "cmd-edit.h"
45 #include "cmd-hist.h" 45 #include "cmd-hist.h"
46 #include "file-ops.h" 46 #include "file-ops.h"
47 #include "file-stat.h" 47 #include "file-stat.h"
48 48
49 #include "comment-list.h"
49 #include "defun.h" 50 #include "defun.h"
50 #include "dynamic-ld.h" 51 #include "dynamic-ld.h"
51 #include "error.h" 52 #include "error.h"
52 #include "input.h" 53 #include "input.h"
53 #include "lex.h" 54 #include "lex.h"
101 int current_input_column = 1; 102 int current_input_column = 1;
102 103
103 // Buffer for help text snagged from function files. 104 // Buffer for help text snagged from function files.
104 std::string help_buf; 105 std::string help_buf;
105 106
107 // Buffer for comments appearing before a function statement.
108 static std::string fcn_comment_header;
109
106 // TRUE means we are using readline. 110 // TRUE means we are using readline.
107 // (--no-line-editing) 111 // (--no-line-editing)
108 bool line_editing = true; 112 bool line_editing = true;
109 113
110 // TRUE means we printed messages about reading startup files. 114 // TRUE means we printed messages about reading startup files.
177 make_postfix_op (int op, tree_expression *op1, token *tok_val); 181 make_postfix_op (int op, tree_expression *op1, token *tok_val);
178 182
179 // Build an unwind-protect command. 183 // Build an unwind-protect command.
180 static tree_command * 184 static tree_command *
181 make_unwind_command (token *unwind_tok, tree_statement_list *body, 185 make_unwind_command (token *unwind_tok, tree_statement_list *body,
182 tree_statement_list *cleanup, token *end_tok); 186 tree_statement_list *cleanup, token *end_tok,
187 octave_comment_list *lc, octave_comment_list *mc);
183 188
184 // Build a try-catch command. 189 // Build a try-catch command.
185 static tree_command * 190 static tree_command *
186 make_try_command (token *try_tok, tree_statement_list *body, 191 make_try_command (token *try_tok, tree_statement_list *body,
187 tree_statement_list *cleanup, token *end_tok); 192 tree_statement_list *cleanup, token *end_tok,
193 octave_comment_list *lc, octave_comment_list *mc);
188 194
189 // Build a while command. 195 // Build a while command.
190 static tree_command * 196 static tree_command *
191 make_while_command (token *while_tok, tree_expression *expr, 197 make_while_command (token *while_tok, tree_expression *expr,
192 tree_statement_list *body, token *end_tok); 198 tree_statement_list *body, token *end_tok,
199 octave_comment_list *lc);
193 200
194 // Build a do-until command. 201 // Build a do-until command.
195 static tree_command * 202 static tree_command *
196 make_do_until_command (token *do_tok, tree_statement_list *body, 203 make_do_until_command (token *do_tok, tree_statement_list *body,
197 tree_expression *expr); 204 tree_expression *expr, octave_comment_list *lc);
198 205
199 // Build a for command. 206 // Build a for command.
200 static tree_command * 207 static tree_command *
201 make_for_command (token *for_tok, tree_argument_list *lhs, 208 make_for_command (token *for_tok, tree_argument_list *lhs,
202 tree_expression *expr, tree_statement_list *body, 209 tree_expression *expr, tree_statement_list *body,
203 token *end_tok); 210 token *end_tok, octave_comment_list *lc);
204 211
205 // Build a break command. 212 // Build a break command.
206 static tree_command * 213 static tree_command *
207 make_break_command (token *break_tok); 214 make_break_command (token *break_tok);
208 215
218 static tree_if_command_list * 225 static tree_if_command_list *
219 start_if_command (tree_expression *expr, tree_statement_list *list); 226 start_if_command (tree_expression *expr, tree_statement_list *list);
220 227
221 // Finish an if command. 228 // Finish an if command.
222 static tree_if_command * 229 static tree_if_command *
223 finish_if_command (token *if_tok, tree_if_command_list *list, token *end_tok); 230 finish_if_command (token *if_tok, tree_if_command_list *list,
231 token *end_tok, octave_comment_list *lc);
224 232
225 // Build an elseif clause. 233 // Build an elseif clause.
226 static tree_if_clause * 234 static tree_if_clause *
227 make_elseif_clause (tree_expression *expr, tree_statement_list *list); 235 make_elseif_clause (tree_expression *expr, tree_statement_list *list,
236 octave_comment_list *lc);
228 237
229 // Finish a switch command. 238 // Finish a switch command.
230 static tree_switch_command * 239 static tree_switch_command *
231 finish_switch_command (token *switch_tok, tree_expression *expr, 240 finish_switch_command (token *switch_tok, tree_expression *expr,
232 tree_switch_case_list *list, token *end_tok); 241 tree_switch_case_list *list, token *end_tok,
242 octave_comment_list *lc);
233 243
234 // Build a switch case. 244 // Build a switch case.
235 static tree_switch_case * 245 static tree_switch_case *
236 make_switch_case (tree_expression *expr, tree_statement_list *list); 246 make_switch_case (tree_expression *expr, tree_statement_list *list,
247 octave_comment_list *lc);
237 248
238 // Build an assignment to a variable. 249 // Build an assignment to a variable.
239 static tree_expression * 250 static tree_expression *
240 make_assign_op (int op, tree_argument_list *lhs, token *eq_tok, 251 make_assign_op (int op, tree_argument_list *lhs, token *eq_tok,
241 tree_expression *rhs); 252 tree_expression *rhs);
248 static octave_user_function * 259 static octave_user_function *
249 frob_function (tree_identifier *id, octave_user_function *fcn); 260 frob_function (tree_identifier *id, octave_user_function *fcn);
250 261
251 // Finish defining a function. 262 // Finish defining a function.
252 static octave_user_function * 263 static octave_user_function *
253 finish_function (tree_identifier *id, octave_user_function *fcn); 264 finish_function (tree_identifier *id, octave_user_function *fcn,
265 octave_comment_list *lc);
254 266
255 // Finish defining a function a different way. 267 // Finish defining a function a different way.
256 static octave_user_function * 268 static octave_user_function *
257 finish_function (tree_parameter_list *ret_list, octave_user_function *fcn); 269 finish_function (tree_parameter_list *ret_list,
270 octave_user_function *fcn, octave_comment_list *lc);
258 271
259 // Reset state after parsing function. 272 // Reset state after parsing function.
260 static void 273 static void
261 recover_from_parsing_function (void); 274 recover_from_parsing_function (void);
262 275
306 319
307 %union 320 %union
308 { 321 {
309 // The type of the basic tokens returned by the lexer. 322 // The type of the basic tokens returned by the lexer.
310 token *tok_val; 323 token *tok_val;
324
325 // Comment strings that we need to deal with mid-rule.
326 octave_comment_list *comment_type;
311 327
312 // Types for the nonterminals we generate. 328 // Types for the nonterminals we generate.
313 char sep_type; 329 char sep_type;
314 tree *tree_type; 330 tree *tree_type;
315 tree_matrix *tree_matrix_type; 331 tree_matrix *tree_matrix_type;
373 %token END_OF_INPUT LEXICAL_ERROR 389 %token END_OF_INPUT LEXICAL_ERROR
374 %token FCN ELLIPSIS ALL_VA_ARGS 390 %token FCN ELLIPSIS ALL_VA_ARGS
375 %token USING TITLE WITH AXES COLON OPEN_BRACE CLOSE_BRACE CLEAR 391 %token USING TITLE WITH AXES COLON OPEN_BRACE CLOSE_BRACE CLEAR
376 392
377 // Nonterminals we construct. 393 // Nonterminals we construct.
394 %type <comment_type> stash_comment function_beg
378 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep 395 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep
379 %type <tree_type> input 396 %type <tree_type> input
380 %type <tree_constant_type> constant magic_colon 397 %type <tree_constant_type> constant magic_colon
381 %type <tree_matrix_type> matrix_rows matrix_rows1 398 %type <tree_matrix_type> matrix_rows matrix_rows1
382 %type <tree_cell_type> cell_rows cell_rows1 399 %type <tree_cell_type> cell_rows cell_rows1
508 $$ = $1; 525 $$ = $1;
509 } 526 }
510 ; 527 ;
511 528
512 statement : expression 529 statement : expression
513 { $$ = new tree_statement ($1); } 530 {
531 octave_comment_list *comment
532 = octave_comment_buffer::get_comment ();
533
534 $$ = new tree_statement ($1, comment);
535 }
514 | command 536 | command
515 { $$ = new tree_statement ($1); } 537 {
538 octave_comment_list *comment
539 = octave_comment_buffer::get_comment ();
540
541 $$ = new tree_statement ($1, comment);
542 }
516 | PLOT CLEAR 543 | PLOT CLEAR
517 { 544 {
518 symbol_record *sr = lookup_by_name ("clearplot", 0); 545 symbol_record *sr = lookup_by_name ("clearplot", 0);
519 tree_identifier *id = new tree_identifier (sr); 546 tree_identifier *id = new tree_identifier (sr);
520 $$ = new tree_statement (id); 547
548 octave_comment_list *comment
549 = octave_comment_buffer::get_comment ();
550
551 $$ = new tree_statement (id, comment);
521 } 552 }
522 ; 553 ;
523 554
524 // =========== 555 // ===========
525 // Expressions 556 // Expressions
878 909
879 // ============ 910 // ============
880 // If statement 911 // If statement
881 // ============ 912 // ============
882 913
883 if_command : IF if_cmd_list END 914 if_command : IF stash_comment if_cmd_list END
884 { 915 {
885 if (! ($$ = finish_if_command ($1, $2, $3))) 916 if (! ($$ = finish_if_command ($1, $3, $4, $2)))
886 ABORT_PARSE; 917 ABORT_PARSE;
887 } 918 }
888 ; 919 ;
889 920
890 if_cmd_list : if_cmd_list1 921 if_cmd_list : if_cmd_list1
903 $1->append ($2); 934 $1->append ($2);
904 $$ = $1; 935 $$ = $1;
905 } 936 }
906 ; 937 ;
907 938
908 elseif_clause : ELSEIF opt_sep expression opt_sep opt_list 939 elseif_clause : ELSEIF stash_comment opt_sep expression opt_sep opt_list
909 { $$ = make_elseif_clause ($3, $5); } 940 { $$ = make_elseif_clause ($4, $6, $2); }
910 ; 941 ;
911 942
912 else_clause : ELSE opt_sep opt_list 943 else_clause : ELSE stash_comment opt_sep opt_list
913 { $$ = new tree_if_clause ($3); } 944 {
945 $$ = new tree_if_clause ($4, $2);
946 }
914 ; 947 ;
915 948
916 // ================ 949 // ================
917 // Switch statement 950 // Switch statement
918 // ================ 951 // ================
919 952
920 switch_command : SWITCH expression opt_sep case_list END 953 switch_command : SWITCH stash_comment expression opt_sep case_list END
921 { 954 {
922 if (! ($$ = finish_switch_command ($1, $2, $4, $5))) 955 if (! ($$ = finish_switch_command ($1, $3, $5, $6, $2)))
923 ABORT_PARSE; 956 ABORT_PARSE;
924 } 957 }
925 ; 958 ;
926 959
927 case_list : case_list1 960 case_list : case_list1
940 $1->append ($2); 973 $1->append ($2);
941 $$ = $1; 974 $$ = $1;
942 } 975 }
943 ; 976 ;
944 977
945 switch_case : CASE opt_sep expression opt_sep list 978 switch_case : CASE stash_comment opt_sep expression opt_sep list
946 { $$ = make_switch_case ($3, $5); } 979 { $$ = make_switch_case ($4, $6, $2); }
947 ; 980 ;
948 981
949 default_case : OTHERWISE opt_sep opt_list 982 default_case : OTHERWISE stash_comment opt_sep opt_list
950 { $$ = new tree_switch_case ($3); } 983 {
984 $$ = new tree_switch_case ($4, $2);
985 }
951 ; 986 ;
952 987
953 // ======= 988 // =======
954 // Looping 989 // Looping
955 // ======= 990 // =======
956 991
957 loop_command : WHILE expression opt_sep opt_list END 992 loop_command : WHILE stash_comment expression opt_sep opt_list END
958 { 993 {
959 if (! ($$ = make_while_command ($1, $2, $4, $5))) 994 if (! ($$ = make_while_command ($1, $3, $5, $6, $2)))
960 ABORT_PARSE; 995 ABORT_PARSE;
961 } 996 }
962 | DO opt_sep opt_list UNTIL expression 997 | DO stash_comment opt_sep opt_list UNTIL expression
963 { 998 {
964 if (! ($$ = make_do_until_command ($1, $3, $5))) 999 if (! ($$ = make_do_until_command ($1, $4, $6, $2)))
965 ABORT_PARSE; 1000 ABORT_PARSE;
966 } 1001 }
967 | FOR assign_lhs '=' expression opt_sep opt_list END 1002 | FOR stash_comment assign_lhs '=' expression opt_sep opt_list END
968 { 1003 {
969 if (! ($$ = make_for_command ($1, $2, $4, $6, $7))) 1004 if (! ($$ = make_for_command ($1, $3, $5, $7, $8, $2)))
970 ABORT_PARSE; 1005 ABORT_PARSE;
971 } 1006 }
972 ; 1007 ;
973 1008
974 // ======= 1009 // =======
994 1029
995 // ========== 1030 // ==========
996 // Exceptions 1031 // Exceptions
997 // ========== 1032 // ==========
998 1033
999 except_command : UNWIND opt_sep opt_list CLEANUP opt_sep opt_list END 1034 except_command : UNWIND stash_comment opt_sep opt_list CLEANUP
1000 { 1035 stash_comment opt_sep opt_list END
1001 if (! ($$ = make_unwind_command ($1, $3, $6, $7))) 1036 {
1037 if (! ($$ = make_unwind_command ($1, $4, $8, $9, $2, $6)))
1002 ABORT_PARSE; 1038 ABORT_PARSE;
1003 } 1039 }
1004 | TRY opt_sep opt_list CATCH opt_sep opt_list END 1040 | TRY stash_comment opt_sep opt_list CATCH
1005 { 1041 stash_comment opt_sep opt_list END
1006 if (! ($$ = make_try_command ($1, $3, $6, $7))) 1042 {
1043 if (! ($$ = make_try_command ($1, $4, $8, $9, $2, $6)))
1007 ABORT_PARSE; 1044 ABORT_PARSE;
1008 } 1045 }
1009 ; 1046 ;
1010 1047
1011 // =========================================== 1048 // ===========================================
1134 1171
1135 // =================== 1172 // ===================
1136 // Function definition 1173 // Function definition
1137 // =================== 1174 // ===================
1138 1175
1139 function_beg : FCN global_symtab 1176 function_beg : FCN stash_comment global_symtab
1177 { $$ = $2; }
1140 ; 1178 ;
1141 1179
1142 function : function_beg function2 1180 function : function_beg function2
1143 { 1181 {
1182 $2->stash_leading_comment ($1);
1144 recover_from_parsing_function (); 1183 recover_from_parsing_function ();
1145 $$ = 0; 1184 $$ = 0;
1146 } 1185 }
1147 | function_beg identifier function1 1186 | function_beg identifier function1
1148 { 1187 {
1149 finish_function ($2, $3); 1188 finish_function ($2, $3, $1);
1150 recover_from_parsing_function (); 1189 recover_from_parsing_function ();
1151 $$ = 0; 1190 $$ = 0;
1152 } 1191 }
1153 | function_beg return_list function1 1192 | function_beg return_list function1
1154 { 1193 {
1155 finish_function ($2, $3); 1194 finish_function ($2, $3, $1);
1156 recover_from_parsing_function (); 1195 recover_from_parsing_function ();
1157 $$ = 0; 1196 $$ = 0;
1158 } 1197 }
1159 ; 1198 ;
1160 1199
1353 1392
1354 // ============= 1393 // =============
1355 // Miscellaneous 1394 // Miscellaneous
1356 // ============= 1395 // =============
1357 1396
1397 stash_comment : // empty
1398 { $$ = octave_comment_buffer::get_comment (); }
1399 ;
1400
1358 parse_error : LEXICAL_ERROR 1401 parse_error : LEXICAL_ERROR
1359 { yyerror ("parse error"); } 1402 { yyerror ("parse error"); }
1360 | error 1403 | error
1361 ; 1404 ;
1362 1405
2028 2071
2029 // Build an unwind-protect command. 2072 // Build an unwind-protect command.
2030 2073
2031 static tree_command * 2074 static tree_command *
2032 make_unwind_command (token *unwind_tok, tree_statement_list *body, 2075 make_unwind_command (token *unwind_tok, tree_statement_list *body,
2033 tree_statement_list *cleanup, token *end_tok) 2076 tree_statement_list *cleanup, token *end_tok,
2077 octave_comment_list *lc, octave_comment_list *mc)
2034 { 2078 {
2035 tree_command *retval = 0; 2079 tree_command *retval = 0;
2036 2080
2037 if (end_token_ok (end_tok, token::unwind_protect_end)) 2081 if (end_token_ok (end_tok, token::unwind_protect_end))
2038 { 2082 {
2083 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2084
2039 int l = unwind_tok->line (); 2085 int l = unwind_tok->line ();
2040 int c = unwind_tok->column (); 2086 int c = unwind_tok->column ();
2041 2087
2042 retval = new tree_unwind_protect_command (body, cleanup, l, c); 2088 retval = new tree_unwind_protect_command (body, cleanup,
2089 lc, mc, tc, l, c);
2043 } 2090 }
2044 2091
2045 return retval; 2092 return retval;
2046 } 2093 }
2047 2094
2048 // Build a try-catch command. 2095 // Build a try-catch command.
2049 2096
2050 static tree_command * 2097 static tree_command *
2051 make_try_command (token *try_tok, tree_statement_list *body, 2098 make_try_command (token *try_tok, tree_statement_list *body,
2052 tree_statement_list *cleanup, token *end_tok) 2099 tree_statement_list *cleanup, token *end_tok,
2100 octave_comment_list *lc, octave_comment_list *mc)
2053 { 2101 {
2054 tree_command *retval = 0; 2102 tree_command *retval = 0;
2055 2103
2056 if (end_token_ok (end_tok, token::try_catch_end)) 2104 if (end_token_ok (end_tok, token::try_catch_end))
2057 { 2105 {
2106 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2107
2058 int l = try_tok->line (); 2108 int l = try_tok->line ();
2059 int c = try_tok->column (); 2109 int c = try_tok->column ();
2060 2110
2061 retval = new tree_try_catch_command (body, cleanup, l, c); 2111 retval = new tree_try_catch_command (body, cleanup,
2112 lc, mc, tc, l, c);
2062 } 2113 }
2063 2114
2064 return retval; 2115 return retval;
2065 } 2116 }
2066 2117
2067 // Build a while command. 2118 // Build a while command.
2068 2119
2069 static tree_command * 2120 static tree_command *
2070 make_while_command (token *while_tok, tree_expression *expr, 2121 make_while_command (token *while_tok, tree_expression *expr,
2071 tree_statement_list *body, token *end_tok) 2122 tree_statement_list *body, token *end_tok,
2123 octave_comment_list *lc)
2072 { 2124 {
2073 tree_command *retval = 0; 2125 tree_command *retval = 0;
2074 2126
2075 maybe_warn_assign_as_truth_value (expr); 2127 maybe_warn_assign_as_truth_value (expr);
2076 2128
2077 if (end_token_ok (end_tok, token::while_end)) 2129 if (end_token_ok (end_tok, token::while_end))
2078 { 2130 {
2131 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2132
2079 lexer_flags.looping--; 2133 lexer_flags.looping--;
2080 2134
2081 int l = while_tok->line (); 2135 int l = while_tok->line ();
2082 int c = while_tok->column (); 2136 int c = while_tok->column ();
2083 2137
2084 retval = new tree_while_command (expr, body, l, c); 2138 retval = new tree_while_command (expr, body, lc, tc, l, c);
2085 } 2139 }
2086 2140
2087 return retval; 2141 return retval;
2088 } 2142 }
2089 2143
2090 // Build a do-until command. 2144 // Build a do-until command.
2091 2145
2092 static tree_command * 2146 static tree_command *
2093 make_do_until_command (token *do_tok, tree_statement_list *body, 2147 make_do_until_command (token *do_tok, tree_statement_list *body,
2094 tree_expression *expr) 2148 tree_expression *expr, octave_comment_list *lc)
2095 { 2149 {
2096 tree_command *retval = 0; 2150 tree_command *retval = 0;
2097 2151
2098 maybe_warn_assign_as_truth_value (expr); 2152 maybe_warn_assign_as_truth_value (expr);
2153
2154 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2099 2155
2100 lexer_flags.looping--; 2156 lexer_flags.looping--;
2101 2157
2102 int l = do_tok->line (); 2158 int l = do_tok->line ();
2103 int c = do_tok->column (); 2159 int c = do_tok->column ();
2104 2160
2105 retval = new tree_do_until_command (expr, body, l, c); 2161 retval = new tree_do_until_command (expr, body, lc, tc, l, c);
2106 2162
2107 return retval; 2163 return retval;
2108 } 2164 }
2109 2165
2110 // Build a for command. 2166 // Build a for command.
2111 2167
2112 static tree_command * 2168 static tree_command *
2113 make_for_command (token *for_tok, tree_argument_list *lhs, 2169 make_for_command (token *for_tok, tree_argument_list *lhs,
2114 tree_expression *expr, tree_statement_list *body, 2170 tree_expression *expr, tree_statement_list *body,
2115 token *end_tok) 2171 token *end_tok, octave_comment_list *lc)
2116 { 2172 {
2117 tree_command *retval = 0; 2173 tree_command *retval = 0;
2118 2174
2119 if (end_token_ok (end_tok, token::for_end)) 2175 if (end_token_ok (end_tok, token::for_end))
2120 { 2176 {
2177 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2178
2121 lexer_flags.looping--; 2179 lexer_flags.looping--;
2122 2180
2123 int l = for_tok->line (); 2181 int l = for_tok->line ();
2124 int c = for_tok->column (); 2182 int c = for_tok->column ();
2125 2183
2126 if (lhs->length () == 1) 2184 if (lhs->length () == 1)
2127 { 2185 {
2128 tree_expression *tmp = lhs->remove_front (); 2186 tree_expression *tmp = lhs->remove_front ();
2129 2187
2130 retval = new tree_simple_for_command (tmp, expr, body, l, c); 2188 retval = new tree_simple_for_command (tmp, expr, body,
2189 lc, tc, l, c);
2131 2190
2132 delete lhs; 2191 delete lhs;
2133 } 2192 }
2134 else 2193 else
2135 retval = new tree_complex_for_command (lhs, expr, body, l, c); 2194 retval = new tree_complex_for_command (lhs, expr, body,
2195 lc, tc, l, c);
2136 } 2196 }
2137 2197
2138 return retval; 2198 return retval;
2139 } 2199 }
2140 2200
2208 2268
2209 // Finish an if command. 2269 // Finish an if command.
2210 2270
2211 static tree_if_command * 2271 static tree_if_command *
2212 finish_if_command (token *if_tok, tree_if_command_list *list, 2272 finish_if_command (token *if_tok, tree_if_command_list *list,
2213 token *end_tok) 2273 token *end_tok, octave_comment_list *lc)
2214 { 2274 {
2215 tree_if_command *retval = 0; 2275 tree_if_command *retval = 0;
2216 2276
2217 if (end_token_ok (end_tok, token::if_end)) 2277 if (end_token_ok (end_tok, token::if_end))
2218 { 2278 {
2279 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2280
2219 int l = if_tok->line (); 2281 int l = if_tok->line ();
2220 int c = if_tok->column (); 2282 int c = if_tok->column ();
2221 2283
2222 retval = new tree_if_command (list, l, c); 2284 retval = new tree_if_command (list, lc, tc, l, c);
2223 } 2285 }
2224 2286
2225 return retval; 2287 return retval;
2226 } 2288 }
2227 2289
2228 // Build an elseif clause. 2290 // Build an elseif clause.
2229 2291
2230 static tree_if_clause * 2292 static tree_if_clause *
2231 make_elseif_clause (tree_expression *expr, tree_statement_list *list) 2293 make_elseif_clause (tree_expression *expr, tree_statement_list *list,
2294 octave_comment_list *lc)
2232 { 2295 {
2233 maybe_warn_assign_as_truth_value (expr); 2296 maybe_warn_assign_as_truth_value (expr);
2234 2297
2235 return new tree_if_clause (expr, list); 2298 return new tree_if_clause (expr, list, lc);
2236 } 2299 }
2237 2300
2238 // Finish a switch command. 2301 // Finish a switch command.
2239 2302
2240 static tree_switch_command * 2303 static tree_switch_command *
2241 finish_switch_command (token *switch_tok, tree_expression *expr, 2304 finish_switch_command (token *switch_tok, tree_expression *expr,
2242 tree_switch_case_list *list, token *end_tok) 2305 tree_switch_case_list *list, token *end_tok,
2306 octave_comment_list *lc)
2243 { 2307 {
2244 tree_switch_command *retval = 0; 2308 tree_switch_command *retval = 0;
2245 2309
2246 if (end_token_ok (end_tok, token::switch_end)) 2310 if (end_token_ok (end_tok, token::switch_end))
2247 { 2311 {
2312 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2313
2248 int l = switch_tok->line (); 2314 int l = switch_tok->line ();
2249 int c = switch_tok->column (); 2315 int c = switch_tok->column ();
2250 2316
2251 retval = new tree_switch_command (expr, list, l, c); 2317 retval = new tree_switch_command (expr, list, lc, tc, l, c);
2252 } 2318 }
2253 2319
2254 return retval; 2320 return retval;
2255 } 2321 }
2256 2322
2257 // Build a switch case. 2323 // Build a switch case.
2258 2324
2259 static tree_switch_case * 2325 static tree_switch_case *
2260 make_switch_case (tree_expression *expr, tree_statement_list *list) 2326 make_switch_case (tree_expression *expr, tree_statement_list *list,
2327 octave_comment_list *lc)
2261 { 2328 {
2262 maybe_warn_variable_switch_label (expr); 2329 maybe_warn_variable_switch_label (expr);
2263 2330
2264 return new tree_switch_case (expr, list); 2331 return new tree_switch_case (expr, list, lc);
2265 } 2332 }
2266 2333
2267 // Build an assignment to a variable. 2334 // Build an assignment to a variable.
2268 2335
2269 static tree_expression * 2336 static tree_expression *
2359 2426
2360 // We'll fill in the return list later. 2427 // We'll fill in the return list later.
2361 2428
2362 octave_user_function *fcn 2429 octave_user_function *fcn
2363 = new octave_user_function (param_list, 0, body, curr_sym_tab); 2430 = new octave_user_function (param_list, 0, body, curr_sym_tab);
2431
2432 if (fcn)
2433 {
2434 octave_comment_list *tc = octave_comment_buffer::get_comment ();
2435
2436 fcn->stash_trailing_comment (tc);
2437 }
2364 2438
2365 return fcn; 2439 return fcn;
2366 } 2440 }
2367 2441
2368 // Do most of the work for defining a function. 2442 // Do most of the work for defining a function.
2437 } 2511 }
2438 2512
2439 // Finish defining a function. 2513 // Finish defining a function.
2440 2514
2441 static octave_user_function * 2515 static octave_user_function *
2442 finish_function (tree_identifier *id, octave_user_function *fcn) 2516 finish_function (tree_identifier *id, octave_user_function *fcn,
2517 octave_comment_list *lc)
2443 { 2518 {
2444 tree_parameter_list *tpl = new tree_parameter_list (id); 2519 tree_parameter_list *tpl = new tree_parameter_list (id);
2445 2520
2446 tpl->mark_as_formal_parameters (); 2521 tpl->mark_as_formal_parameters ();
2447 2522
2523 fcn->stash_leading_comment (lc);
2524
2448 return fcn->define_ret_list (tpl); 2525 return fcn->define_ret_list (tpl);
2449 } 2526 }
2450 2527
2451 // Finish defining a function a different way. 2528 // Finish defining a function a different way.
2452 2529
2453 static octave_user_function * 2530 static octave_user_function *
2454 finish_function (tree_parameter_list *ret_list, octave_user_function *fcn) 2531 finish_function (tree_parameter_list *ret_list,
2532 octave_user_function *fcn, octave_comment_list *lc)
2455 { 2533 {
2456 ret_list->mark_as_formal_parameters (); 2534 ret_list->mark_as_formal_parameters ();
2535
2536 fcn->stash_leading_comment (lc);
2457 2537
2458 return fcn->define_ret_list (ret_list); 2538 return fcn->define_ret_list (ret_list);
2459 } 2539 }
2460 2540
2461 static void 2541 static void
2783 2863
2784 // Eat whitespace and comments from FFILE, returning the text of the 2864 // Eat whitespace and comments from FFILE, returning the text of the
2785 // comments read if it doesn't look like a copyright notice. If 2865 // comments read if it doesn't look like a copyright notice. If
2786 // IN_PARTS, consider each block of comments separately; otherwise, 2866 // IN_PARTS, consider each block of comments separately; otherwise,
2787 // grab them all at once. If UPDATE_POS is TRUE, line and column 2867 // grab them all at once. If UPDATE_POS is TRUE, line and column
2788 // number information is updated. 2868 // number information is updated. If SAVE_COPYRIGHT is TRUE, then
2869 // comments that are recognized as a copyright notice are saved in the
2870 // comment buffer.
2789 2871
2790 // XXX FIXME XXX -- grab_help_text() in lex.l duplicates some of this 2872 // XXX FIXME XXX -- grab_help_text() in lex.l duplicates some of this
2791 // code! 2873 // code!
2792 2874
2793 static std::string 2875 static std::string
2794 gobble_leading_white_space (FILE *ffile, bool in_parts, bool update_pos) 2876 gobble_leading_white_space (FILE *ffile, bool in_parts,
2877 bool update_pos, bool save_copyright)
2795 { 2878 {
2796 std::string help_txt; 2879 std::string help_txt;
2797 2880
2798 bool first_comments_seen = false; 2881 bool first_comments_seen = false;
2799 bool begin_comment = false; 2882 bool begin_comment = false;
2891 2974
2892 done: 2975 done:
2893 2976
2894 if (! help_txt.empty ()) 2977 if (! help_txt.empty ())
2895 { 2978 {
2896 if (looks_like_octave_copyright (help_txt)) 2979 if (looks_like_octave_copyright (help_txt))
2897 help_txt.resize (0); 2980 {
2981 if (save_copyright)
2982 octave_comment_buffer::append (help_txt);
2983
2984 help_txt.resize (0);
2985 }
2898 2986
2899 if (in_parts && help_txt.empty ()) 2987 if (in_parts && help_txt.empty ())
2900 help_txt = gobble_leading_white_space (ffile, in_parts, update_pos); 2988 help_txt = gobble_leading_white_space (ffile, in_parts,
2989 update_pos, false);
2901 } 2990 }
2902 2991
2903 return help_txt; 2992 return help_txt;
2904 } 2993 }
2905 2994
2914 3003
2915 if (fptr) 3004 if (fptr)
2916 { 3005 {
2917 unwind_protect::add (safe_fclose, (void *) fptr); 3006 unwind_protect::add (safe_fclose, (void *) fptr);
2918 3007
2919 retval = gobble_leading_white_space (fptr, true, true); 3008 retval = gobble_leading_white_space (fptr, true, true, false);
2920 3009
2921 unwind_protect::run (); 3010 unwind_protect::run ();
2922 } 3011 }
2923 } 3012 }
2924 3013
2930 { 3019 {
2931 int status = 0; 3020 int status = 0;
2932 3021
2933 long pos = ftell (ffile); 3022 long pos = ftell (ffile);
2934 3023
2935 gobble_leading_white_space (ffile, false, false); 3024 gobble_leading_white_space (ffile, false, false, false);
2936 3025
2937 char buf [10]; 3026 char buf [10];
2938 fgets (buf, 10, ffile); 3027 fgets (buf, 10, ffile);
2939 int len = strlen (buf); 3028 int len = strlen (buf);
2940 if (len > 8 && strncmp (buf, "function", 8) == 0 3029 if (len > 8 && strncmp (buf, "function", 8) == 0
3029 3118
3030 unwind_protect_ptr (curr_sym_tab); 3119 unwind_protect_ptr (curr_sym_tab);
3031 3120
3032 reset_parser (); 3121 reset_parser ();
3033 3122
3034 help_buf = gobble_leading_white_space (ffile, true, true); 3123 help_buf = gobble_leading_white_space (ffile, true, true, true);
3124
3125 octave_comment_buffer::append (help_buf);
3035 3126
3036 // XXX FIXME XXX -- this should not be necessary. 3127 // XXX FIXME XXX -- this should not be necessary.
3037 gobble_leading_white_space (ffile, false, true); 3128 gobble_leading_white_space (ffile, false, true, false);
3038 3129
3039 int status = yyparse (); 3130 int status = yyparse ();
3040 3131
3041 if (status != 0) 3132 if (status != 0)
3042 { 3133 {