comparison src/parse.y @ 4935:4fc993a4e072

[project @ 2004-08-06 03:17:12 by jwe]
author jwe
date Fri, 06 Aug 2004 03:17:13 +0000
parents bdb307dc8613
children c0d8e8afa82f
comparison
equal deleted inserted replaced
4934:ca6c86504105 4935:4fc993a4e072
56 #include "dynamic-ld.h" 56 #include "dynamic-ld.h"
57 #include "error.h" 57 #include "error.h"
58 #include "input.h" 58 #include "input.h"
59 #include "lex.h" 59 #include "lex.h"
60 #include "oct-hist.h" 60 #include "oct-hist.h"
61 #include "ov-fcn-handle.h"
61 #include "ov-usr-fcn.h" 62 #include "ov-usr-fcn.h"
62 #include "toplev.h" 63 #include "toplev.h"
63 #include "pager.h" 64 #include "pager.h"
64 #include "parse.h" 65 #include "parse.h"
65 #include "pt-all.h" 66 #include "pt-all.h"
180 make_constant (int op, token *tok_val); 181 make_constant (int op, token *tok_val);
181 182
182 // Build a function handle. 183 // Build a function handle.
183 static tree_fcn_handle * 184 static tree_fcn_handle *
184 make_fcn_handle (token *tok_val); 185 make_fcn_handle (token *tok_val);
186
187 // Build an anonymous function handle.
188 static tree_constant *
189 make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt);
185 190
186 // Build a binary expression. 191 // Build a binary expression.
187 static tree_expression * 192 static tree_expression *
188 make_binary_op (int op, tree_expression *op1, token *tok_val, 193 make_binary_op (int op, tree_expression *op1, token *tok_val,
189 tree_expression *op2); 194 tree_expression *op2);
430 435
431 // Nonterminals we construct. 436 // Nonterminals we construct.
432 %type <comment_type> stash_comment function_beg 437 %type <comment_type> stash_comment function_beg
433 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep 438 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep
434 %type <tree_type> input 439 %type <tree_type> input
435 %type <tree_constant_type> constant magic_colon 440 %type <tree_constant_type> constant magic_colon anon_fcn_handle
436 %type <tree_fcn_handle_type> fcn_handle 441 %type <tree_fcn_handle_type> fcn_handle
437 %type <tree_matrix_type> matrix_rows matrix_rows1 442 %type <tree_matrix_type> matrix_rows matrix_rows1
438 %type <tree_cell_type> cell_rows cell_rows1 443 %type <tree_cell_type> cell_rows cell_rows1
439 %type <tree_expression_type> title matrix cell 444 %type <tree_expression_type> title matrix cell
440 %type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr 445 %type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr
443 %type <octave_user_function_type> function1 function2 function3 448 %type <octave_user_function_type> function1 function2 function3
444 %type <tree_index_expression_type> word_list_cmd 449 %type <tree_index_expression_type> word_list_cmd
445 %type <tree_colon_expression_type> colon_expr1 450 %type <tree_colon_expression_type> colon_expr1
446 %type <tree_argument_list_type> arg_list word_list assign_lhs 451 %type <tree_argument_list_type> arg_list word_list assign_lhs
447 %type <tree_argument_list_type> cell_or_matrix_row 452 %type <tree_argument_list_type> cell_or_matrix_row
448 %type <tree_parameter_list_type> param_list param_list1 453 %type <tree_parameter_list_type> param_list param_list1 param_list2
449 %type <tree_parameter_list_type> return_list return_list1 454 %type <tree_parameter_list_type> return_list return_list1
450 %type <tree_command_type> command select_command loop_command 455 %type <tree_command_type> command select_command loop_command
451 %type <tree_command_type> jump_command except_command function 456 %type <tree_command_type> jump_command except_command function
452 %type <tree_if_command_type> if_command 457 %type <tree_if_command_type> if_command
453 %type <tree_if_clause_type> elseif_clause else_clause 458 %type <tree_if_clause_type> elseif_clause else_clause
677 $$ = make_fcn_handle ($2); 682 $$ = make_fcn_handle ($2);
678 lexer_flags.looking_at_function_handle--; 683 lexer_flags.looking_at_function_handle--;
679 } 684 }
680 ; 685 ;
681 686
682 fcn_handle : FCN_HANDLE 687 anon_fcn_handle : '@' param_list statement
683 { $$ = make_fcn_handle ($1); } 688 { $$ = make_anon_fcn_handle ($2, $3); }
684 ; 689 ;
685 690
686 primary_expr : identifier 691 primary_expr : identifier
687 { $$ = $1; } 692 { $$ = $1; }
688 | constant 693 | constant
936 { $$ = $1; } 941 { $$ = $1; }
937 | word_list_cmd 942 | word_list_cmd
938 { $$ = $1; } 943 { $$ = $1; }
939 | assign_expr 944 | assign_expr
940 { $$ = $1; } 945 { $$ = $1; }
946 | anon_fcn_handle
947 { $$ = $1; }
941 ; 948 ;
942 949
943 // ================================================ 950 // ================================================
944 // Commands, declarations, and function definitions 951 // Commands, declarations, and function definitions
945 // ================================================ 952 // ================================================
1158 // =========================== 1165 // ===========================
1159 // List of function parameters 1166 // List of function parameters
1160 // =========================== 1167 // ===========================
1161 1168
1162 param_list_beg : '(' 1169 param_list_beg : '('
1163 { lexer_flags.looking_at_parameter_list = true; } 1170 {
1171 lexer_flags.looking_at_parameter_list = true;
1172
1173 if (lexer_flags.looking_at_function_handle)
1174 {
1175 symtab_context.push (curr_sym_tab);
1176
1177 tmp_local_sym_tab = new symbol_table ();
1178 curr_sym_tab = tmp_local_sym_tab;
1179
1180 lexer_flags.looking_at_function_handle--;
1181 }
1182 }
1164 ; 1183 ;
1165 1184
1166 param_list_end : ')' 1185 param_list_end : ')'
1167 { lexer_flags.looking_at_parameter_list = false; } 1186 { lexer_flags.looking_at_parameter_list = false; }
1168 ; 1187 ;
1169 1188
1170 param_list : param_list_beg param_list_end 1189 param_list : param_list_beg param_list1 param_list_end
1171 { 1190 {
1172 lexer_flags.quote_is_transpose = false; 1191 lexer_flags.quote_is_transpose = false;
1192 $$ = $2;
1193 }
1194 | param_list_beg error
1195 {
1196 yyerror ("invalid parameter list");
1173 $$ = 0; 1197 $$ = 0;
1174 } 1198 ABORT_PARSE;
1175 | param_list_beg VARARGIN param_list_end 1199 }
1176 { 1200 ;
1177 lexer_flags.quote_is_transpose = false; 1201
1202 param_list1 : // empty
1203 { $$ = 0; }
1204 | param_list2
1205 {
1206 $1->mark_as_formal_parameters ();
1207 $$ = $1;
1208 }
1209 | VARARGIN
1210 {
1178 tree_parameter_list *tmp = new tree_parameter_list (); 1211 tree_parameter_list *tmp = new tree_parameter_list ();
1179 tmp->mark_varargs_only (); 1212 tmp->mark_varargs_only ();
1180 $$ = tmp; 1213 $$ = tmp;
1181 } 1214 }
1182 | param_list1 param_list_end 1215 | param_list2 ',' VARARGIN
1183 { 1216 {
1184 lexer_flags.quote_is_transpose = false;
1185 $1->mark_as_formal_parameters ();
1186 $$ = $1;
1187 }
1188 | param_list1 ',' VARARGIN param_list_end
1189 {
1190 lexer_flags.quote_is_transpose = false;
1191 $1->mark_as_formal_parameters (); 1217 $1->mark_as_formal_parameters ();
1192 $1->mark_varargs (); 1218 $1->mark_varargs ();
1193 $$ = $1; 1219 $$ = $1;
1194 } 1220 }
1195 ; 1221 ;
1196 1222
1197 param_list1 : param_list_beg identifier 1223 param_list2 : identifier
1198 { $$ = new tree_parameter_list ($2); } 1224 { $$ = new tree_parameter_list ($1); }
1199 | param_list1 ',' identifier 1225 | param_list2 ',' identifier
1200 { 1226 {
1201 $1->append ($3); 1227 $1->append ($3);
1202 $$ = $1; 1228 $$ = $1;
1203 }
1204 | param_list_beg error
1205 {
1206 yyerror ("invalid parameter list");
1207 $$ = 0;
1208 ABORT_PARSE;
1209 }
1210 | param_list1 ',' error
1211 {
1212 yyerror ("invalid parameter list");
1213 $$ = 0;
1214 ABORT_PARSE;
1215 } 1229 }
1216 ; 1230 ;
1217 1231
1218 // =================================== 1232 // ===================================
1219 // List of function return value names 1233 // List of function return value names
1975 { 1989 {
1976 int l = tok_val->line (); 1990 int l = tok_val->line ();
1977 int c = tok_val->column (); 1991 int c = tok_val->column ();
1978 1992
1979 tree_fcn_handle *retval = new tree_fcn_handle (tok_val->text (), l, c); 1993 tree_fcn_handle *retval = new tree_fcn_handle (tok_val->text (), l, c);
1994
1995 return retval;
1996 }
1997
1998 // Make an anonymous function handle.
1999
2000 static tree_constant *
2001 make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt)
2002 {
2003 // XXX FIXME XXX -- need to get these from the location of the @ symbol.
2004
2005 int l = -1;
2006 int c = -1;
2007
2008 tree_parameter_list *ret_list = 0;
2009
2010 if (stmt && stmt->is_expression ())
2011 {
2012 symbol_record *sr = curr_sym_tab->lookup ("__retval__", true);
2013
2014 tree_expression *e = stmt->expression ();
2015
2016 tree_identifier *id = new tree_identifier (sr);
2017
2018 tree_simple_assignment *asn = new tree_simple_assignment (id, e);
2019
2020 stmt->set_expression (asn);
2021
2022 stmt->set_print_flag (false);
2023
2024 // XXX FIXME XXX -- would like to delete old_stmt here or
2025 // replace expression inside it with the new expression we just
2026 // created so we don't have to create a new statement at all.
2027
2028 id = new tree_identifier (sr);
2029
2030 ret_list = new tree_parameter_list (id);
2031 }
2032
2033 tree_statement_list *body = new tree_statement_list (stmt);
2034
2035 body->mark_as_function_body ();
2036
2037 octave_user_function *fcn
2038 = new octave_user_function (param_list, ret_list, body, curr_sym_tab);
2039
2040 if (symtab_context.empty ())
2041 panic_impossible ();
2042
2043 curr_sym_tab = symtab_context.top ();
2044 symtab_context.pop ();
2045
2046 octave_value fh (new octave_fcn_handle (fcn, "@<anonymous>"));
2047
2048 tree_constant *retval = new tree_constant (fh, l, c);
1980 2049
1981 return retval; 2050 return retval;
1982 } 2051 }
1983 2052
1984 // Build a binary expression. 2053 // Build a binary expression.