Mercurial > hg > octave-lyh
diff src/parse.y @ 578:d169be9237fb
[project @ 1994-08-03 20:06:54 by jwe]
author | jwe |
---|---|
date | Wed, 03 Aug 1994 20:07:26 +0000 |
parents | 94fd73d1a0bc |
children | bc813f5eb025 |
line wrap: on
line diff
--- a/src/parse.y +++ b/src/parse.y @@ -44,6 +44,7 @@ #include "input.h" #include "utils.h" #include "tree.h" +#include "tree-misc.h" #include "tree-plot.h" #include "tree-const.h" #include "symtab.h" @@ -111,10 +112,10 @@ // Generic error messages. static void yyerror (char *s); -// Error mesages for mismatched end statements. +// Error mesages for mismatched end tokens. static void end_error (char *type, token::end_tok_type ettype, int l, int c); -// Check to see that end statements are properly matched. +// Check to see that end tokens are properly matched. static int check_end (token *tok, token::end_tok_type expected); // Try to figure out early if an expression should become an @@ -125,6 +126,23 @@ // test in a logical expression. static void maybe_warn_assign_as_truth_value (tree_expression *expr); +// Build a binary expression. +static tree_expression *make_binary_op (int op, tree_expression *op1, + token *tok_val, + tree_expression *op2); + +// Build a prefix expression. +static tree_expression *make_prefix_op (int op, tree_identifier *op1, + token *tok_val); + +// Build a postfix expression. +static tree_expression *make_postfix_op (int op, tree_identifier *op1, + token *tok_val); + +// Build a binary expression. +static tree_expression *make_unary_op (int op, tree_expression *op1, + token *tok_val); + #define ABORT_PARSE \ do \ { \ @@ -161,14 +179,20 @@ tree_parameter_list *tree_parameter_list_type; tree_command *tree_command_type; tree_if_command *tree_if_command_type; + tree_if_clause *tree_if_clause_type; + tree_if_command_list *tree_if_command_list_type; + tree_global *tree_global_type; + tree_global_init_list *tree_global_init_list_type; tree_global_command *tree_global_command_type; - tree_command_list *tree_command_list_type; + tree_statement *tree_statement_type; + tree_statement_list *tree_statement_list_type; tree_plot_command *tree_plot_command_type; - tree_subplot_list *tree_subplot_list_type; - tree_plot_limits *tree_plot_limits_type; - tree_plot_range *tree_plot_range_type; - tree_subplot_using *tree_subplot_using_type; - tree_subplot_style *tree_subplot_style_type; + subplot *subplot_type; + subplot_list *subplot_list_type; + plot_limits *plot_limits_type; + plot_range *plot_range_type; + subplot_using *subplot_using_type; + subplot_style *subplot_style_type; } // Tokens with line and column information. @@ -184,35 +208,41 @@ %token <tok_val> PLOT %token <tok_val> TEXT STYLE %token <tok_val> FOR WHILE IF ELSEIF ELSE BREAK CONTINUE FUNC_RET +%token <tok_val> GLOBAL // Other tokens. %token FCN SCREW_TWO -%token GLOBAL %token ELLIPSIS %token END_OF_INPUT %token USING TITLE WITH COLON OPEN_BRACE CLOSE_BRACE // Nonterminals we construct. -%type <tree_type> input command +%type <tree_type> input %type <tree_expression_type> expression simple_expr simple_expr1 %type <tree_expression_type> ans_expression title %type <tree_matrix_type> matrix %type <tree_identifier_type> identifier -%type <tree_function_type> func_def func_def1 func_def2 func_def3 +%type <tree_function_type> func_def1 func_def2 func_def3 %type <tree_index_expression_type> variable word_list_cmd %type <tree_colon_expression_type> colon_expr -%type <tree_argument_list_type> arg_list arg_list1 word_list word_list1 +%type <tree_argument_list_type> arg_list word_list %type <tree_parameter_list_type> param_list param_list1 func_def1a -%type <tree_command_type> statement -%type <tree_if_command_type> elseif -%type <tree_global_command_type> global_decl global_decl1 -%type <tree_command_list_type> simple_list simple_list1 list list1 opt_list +%type <tree_command_type> command func_def +%type <tree_if_command_type> if_command +%type <tree_if_clause_type> elseif_clause else_clause +%type <tree_if_command_list_type> if_cmd_list1 if_cmd_list +%type <tree_global_type> global_decl2 +%type <tree_global_init_list_type> global_decl1 +%type <tree_global_command_type> global_decl +%type <tree_statement_type> statement +%type <tree_statement_list_type> simple_list simple_list1 list list1 opt_list %type <tree_plot_command_type> plot_command -%type <tree_subplot_list_type> plot_command1 plot_command2 plot_options -%type <tree_plot_limits_type> ranges -%type <tree_plot_range_type> ranges1 -%type <tree_subplot_using_type> using using1 -%type <tree_subplot_style_type> style +%type <subplot_type> plot_command2 plot_options +%type <subplot_list_type> plot_command1 +%type <plot_limits_type> ranges +%type <plot_range_type> ranges1 +%type <subplot_using_type> using using1 +%type <subplot_style_type> style // Precedence and associativity. %left ';' ',' '\n' @@ -287,29 +317,30 @@ | comma_semi { $$ = 0; } | simple_list1 - { $$ = $1->reverse (); } + { $$ = $1; } | simple_list1 semi_comma { - $1->set_print_flag (0); - $$ = $1->reverse (); + tree_statement *tmp = $1->rear (); + tmp->set_print_flag (0); } | simple_list1 comma_semi - { $$ = $1->reverse (); } + { $$ = $1; } ; -simple_list1 : command - { $$ = new tree_command_list ($1); } - | semi_comma command - { $$ = new tree_command_list ($2); } - | comma_semi command - { $$ = new tree_command_list ($2); } - | simple_list1 semi_comma command +simple_list1 : statement + { $$ = new tree_statement_list ($1); } + | semi_comma statement + { $$ = new tree_statement_list ($2); } + | comma_semi statement + { $$ = new tree_statement_list ($2); } + | simple_list1 semi_comma statement { - $1->set_print_flag (0); - $$ = $1->chain ($3); + tree_statement *tmp = $1->rear (); + tmp->set_print_flag (0); + $1->append ($3); } - | simple_list1 comma_semi command - { $$ = $1->chain ($3); } + | simple_list1 comma_semi statement + { $1->append ($3); } ; semi_comma : ';' @@ -332,62 +363,53 @@ ; opt_list : // empty - { $$ = new tree_command_list (); } + { $$ = new tree_statement_list (); } | list { $$ = $1; } ; list : list1 - { $$ = $1->reverse (); } + { $$ = $1; } | list1 comma_nl_sep - { $$ = $1->reverse (); } + { $$ = $1; } | list1 semi_sep { - $1->set_print_flag (0); - $$ = $1->reverse (); + tree_statement *tmp = $1->rear (); + tmp->set_print_flag (0); } ; -list1 : command +list1 : statement { beginning_of_function = 0; - $$ = new tree_command_list ($1); + $$ = new tree_statement_list ($1); } - | list1 comma_nl_sep command - { $$ = $1->chain ($3); } - | list1 semi_sep command + | list1 comma_nl_sep statement + { $1->append ($3); } + | list1 semi_sep statement { - $1->set_print_flag (0); - $$ = $1->chain ($3); + tree_statement *tmp = $1->rear (); + tmp->set_print_flag (0); + $1->append ($3); } ; -command : plot_command - { $$ = $1; } - | statement - { $$ = $1; } +statement : command + { $$ = new tree_statement ($1); } | ans_expression - { $$ = $1; } - | func_def - { $$ = $1; } - | global_decl - { $$ = $1; } + { $$ = new tree_statement ($1); } ; plot_command : PLOT plot_command1 { - tree_subplot_list *tmp = 0; - if ($2) - tmp = $2->reverse (); - - if (! tmp && $1->pttype () != token::replot) + if (! $2 && $1->pttype () != token::replot) { yyerror ("must have something to plot"); ABORT_PARSE; } else { - $$ = new tree_plot_command (tmp, $1->pttype ()); + $$ = new tree_plot_command ($2, $1->pttype ()); plotting = 0; past_plot_range = 0; in_plot_range = 0; @@ -404,8 +426,7 @@ } else { - tree_subplot_list *tmp = $3->reverse (); - $$ = new tree_plot_command (tmp, $2, $1->pttype ()); + $$ = new tree_plot_command ($3, $2, $1->pttype ()); plotting = 0; past_plot_range = 0; in_plot_range = 0; @@ -416,69 +437,72 @@ ; ranges : ranges1 - { $$ = new tree_plot_limits ($1); } + { $$ = new plot_limits ($1); } | ranges1 ranges1 - { $$ = new tree_plot_limits ($1, $2); } + { $$ = new plot_limits ($1, $2); } | ranges1 ranges1 ranges1 - { $$ = new tree_plot_limits ($1, $2, $3); } + { $$ = new plot_limits ($1, $2, $3); } ; ranges1 : OPEN_BRACE expression COLON expression CLOSE_BRACE - { $$ = new tree_plot_range ($2, $4); } + { $$ = new plot_range ($2, $4); } | OPEN_BRACE COLON expression CLOSE_BRACE - { $$ = new tree_plot_range (0, $3); } + { $$ = new plot_range (0, $3); } | OPEN_BRACE expression COLON CLOSE_BRACE - { $$ = new tree_plot_range ($2, 0); } + { $$ = new plot_range ($2, 0); } | OPEN_BRACE COLON CLOSE_BRACE - { $$ = new tree_plot_range (); } + { $$ = new plot_range (); } | OPEN_BRACE CLOSE_BRACE - { $$ = new tree_plot_range (); } + { $$ = new plot_range (); } ; plot_command1 : // empty { $$ = 0; } | plot_command2 - { $$ = $1; } + { $$ = new subplot_list ($1); } | plot_command1 ',' plot_command2 - { $$ = $1->chain ($3); } + { $1->append ($3); } ; plot_command2 : expression - { $$ = new tree_subplot_list ($1); } + { $$ = new subplot ($1); } | expression plot_options - { $$ = $2->set_data ($1); } + { + $2->set_data ($1); + $$ = $2; + } ; plot_options : using - { $$ = new tree_subplot_list ($1, 0, 0); } + { $$ = new subplot ($1, 0, 0); } | title - { $$ = new tree_subplot_list (0, $1, 0); } + { $$ = new subplot (0, $1, 0); } | style - { $$ = new tree_subplot_list (0, 0, $1); } + { $$ = new subplot (0, 0, $1); } | using title - { $$ = new tree_subplot_list ($1, $2, 0); } - | title using - { $$ = new tree_subplot_list ($2, $1, 0); } - | using style - { $$ = new tree_subplot_list ($1, 0, $2); } - | style using - { $$ = new tree_subplot_list ($2, 0, $1); } - | title style - { $$ = new tree_subplot_list (0, $1, $2); } - | style title - { $$ = new tree_subplot_list (0, $2, $1); } - | using title style - { $$ = new tree_subplot_list ($1, $2, $3); } - | using style title - { $$ = new tree_subplot_list ($1, $3, $2); } - | title using style - { $$ = new tree_subplot_list ($2, $1, $3); } - | title style using - { $$ = new tree_subplot_list ($3, $1, $2); } - | style using title - { $$ = new tree_subplot_list ($2, $3, $1); } - | style title using - { $$ = new tree_subplot_list ($3, $2, $1); } + { $$ = new subplot ($1, $2, 0); } + | title using + { $$ = new subplot ($2, $1, 0); } + | using style + { $$ = new subplot ($1, 0, $2); } + | style using + { $$ = new subplot ($2, 0, $1); } + | title style + { $$ = new subplot (0, $1, $2); } + | style title + { $$ = new subplot (0, $2, $1); } + | using title style + { $$ = new subplot ($1, $2, $3); } + | using style title + { $$ = new subplot ($1, $3, $2); } + | title using style + { $$ = new subplot ($2, $1, $3); } + | title style using + { $$ = new subplot ($3, $1, $2); } + | style using title + { $$ = new subplot ($2, $3, $1); } + | style title using + { $$ = new subplot ($3, $2, $1); } ; using : using1 @@ -495,7 +519,7 @@ using1 : USING expression { - tree_subplot_using *tmp = new tree_subplot_using (); + subplot_using *tmp = new subplot_using (); $$ = tmp->add_qualifier ($2); } | using1 COLON expression @@ -507,11 +531,11 @@ ; style : WITH STYLE - { $$ = new tree_subplot_style ($2->string ()); } + { $$ = new subplot_style ($2->string ()); } | WITH STYLE expression - { $$ = new tree_subplot_style ($2->string (), $3); } + { $$ = new subplot_style ($2->string (), $3); } | WITH STYLE expression bogus_syntax expression - { $$ = new tree_subplot_style ($2->string (), $3, $5); } + { $$ = new subplot_style ($2->string (), $3, $5); } ; bogus_syntax : // empty @@ -522,30 +546,25 @@ ; global_decl : GLOBAL global_decl1 - { $$ = $2->reverse (); } - | GLOBAL global_decl1 ',' - { $$ = $2->reverse (); } + { + $$ = new tree_global_command ($2, $1->line (), + $1->column ()); + } ; -global_decl1 : NAME - { - $$ = new tree_global_command - ($1->sym_rec (), $1->line (), $1->column ()); - } - | NAME '=' expression +global_decl1 : global_decl2 + { $$ = new tree_global_init_list ($1); } + | global_decl1 optcomma global_decl2 + { $1->append ($3); } + +global_decl2 : identifier + { $$ = new tree_global ($1); } + | identifier '=' expression { - $$ = new tree_global_command - ($1->sym_rec (), $3, $1->line (), $1->column ()); - } - | global_decl1 optcomma NAME - { - $$ = $1->chain ($3->sym_rec (), $3->line (), - $3->column ()); - } - | global_decl1 optcomma NAME '=' expression - { - $$ = $1->chain ($3->sym_rec (), $5, $3->line (), - $3->column ()); + tree_simple_assignment_expression *tmp_ass; + tmp_ass = new tree_simple_assignment_expression + ($1, $3, 0, $2->line (), $2->column ()); + $$ = new tree_global (tmp_ass); } ; @@ -558,7 +577,18 @@ } ; -statement : WHILE expression optsep opt_list END +command : plot_command + { $$ = $1; } + | func_def + { $$ = $1; } + | global_decl + { $$ = $1; } + | if_command + { + iffing--; + $$ = $1; + } + | WHILE expression optsep opt_list END { maybe_warn_assign_as_truth_value ($2); if (check_end ($5, token::while_end)) @@ -575,51 +605,6 @@ $$ = new tree_for_command ($2, $4, $6, $1->line (), $1->column ()); } - | IF expression optsep opt_list END - { - maybe_warn_assign_as_truth_value ($2); - if (check_end ($5, token::if_end)) - ABORT_PARSE; - iffing--; - $$ = new tree_if_command ($2, $4, - $1->line (), $1->column ()); - } - | IF expression optsep opt_list ELSE optsep opt_list END - { - maybe_warn_assign_as_truth_value ($2); - if (check_end ($8, token::if_end)) - ABORT_PARSE; - iffing--; - tree_if_command *t1 = new tree_if_command - ($7, $5->line (), $5->column ()); - $$ = t1->chain ($2, $4, $1->line (), $1->column ()); - } - | IF expression optsep opt_list elseif END - { - maybe_warn_assign_as_truth_value ($2); - if (check_end ($6, token::if_end)) - ABORT_PARSE; - iffing--; - tree_if_command *t1 = $5->reverse (); - // Add the if list to the new head of the elseif - // list, and return the list. - $$ = t1->chain ($2, $4, $1->line (), $1->column ()); - } - | IF expression optsep opt_list elseif ELSE optsep opt_list END - { - maybe_warn_assign_as_truth_value ($2); - if (check_end ($9, token::if_end)) - ABORT_PARSE; - iffing--; - // Add the else list to the head of the elseif list, - // then reverse the list. - tree_if_command *t1 = $5->chain ($8, $6->line (), - $6->column ()); - t1 = t1->reverse (); - // Add the if list to the new head of the elseif - // list, and return the list. - $$ = t1->chain ($2, $4, $1->line (), $1->column ()); - } | BREAK { if (!looping) @@ -655,17 +640,39 @@ } ; -elseif : ELSEIF optsep expression optsep opt_list +if_command : IF if_cmd_list END + { + if (check_end ($3, token::if_end)) + ABORT_PARSE; + $$ = new tree_if_command ($2, $1->line (), $1->column ()); + } + ; + +if_cmd_list : if_cmd_list1 + { $$ = $1 } + | if_cmd_list1 else_clause + { $1->append ($2); } + ; + +if_cmd_list1 : expression optsep opt_list + { + maybe_warn_assign_as_truth_value ($1); + tree_if_clause *t = new tree_if_clause ($1, $3); + $$ = new tree_if_command_list (t); + } + | if_cmd_list1 elseif_clause + { $1->append ($2); } + ; + +elseif_clause : ELSEIF optsep expression optsep opt_list { maybe_warn_assign_as_truth_value ($3); - $$ = new tree_if_command ($3, $5, $1->line (), - $1->column ()); + $$ = new tree_if_clause ($3, $5); } - | elseif ELSEIF optsep expression optsep opt_list - { - maybe_warn_assign_as_truth_value ($4); - $$ = $1->chain ($4, $6, $2->line (), $2->column ()); - } + ; + +else_clause : ELSE optsep opt_list + { $$ = new tree_if_clause ($3); } ; optsep : // empty @@ -686,7 +693,7 @@ expression : variable '=' expression { $$ = new tree_simple_assignment_expression - ($1, $3, $2->line (), $2->column ()); } + ($1, $3, 0, $2->line (), $2->column ()); } | '[' screwed_again matrix_row SCREW_TWO '=' expression { @@ -727,77 +734,53 @@ simple_expr : simple_expr1 { $$ = $1; } | identifier PLUS_PLUS - { $$ = new tree_postfix_expression - ($1, tree::increment, $2->line (), $2->column ()); } + { $$ = make_postfix_op (PLUS_PLUS, $1, $2); } | identifier MINUS_MINUS - { $$ = new tree_postfix_expression - ($1, tree::decrement, $2->line (), $2->column ()); } + { $$ = make_postfix_op (MINUS_MINUS, $1, $2); } | simple_expr QUOTE - { $$ = new tree_unary_expression - ($1, tree::hermitian, $2->line (), $2->column ()); } + { $$ = make_unary_op (QUOTE, $1, $2); } | simple_expr TRANSPOSE - { $$ = new tree_unary_expression - ($1, tree::transpose, $2->line (), $2->column ()); } + { $$ = make_unary_op (TRANSPOSE, $1, $2); } | simple_expr POW simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::power, $2->line (), $2->column ()); } + { $$ = make_binary_op (POW, $1, $2, $3); } | simple_expr EPOW simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::elem_pow, $2->line (), $2->column ()); } + { $$ = make_binary_op (EPOW, $1, $2, $3); } | simple_expr '+' simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::add, $2->line (), $2->column ()); } + { $$ = make_binary_op ('+', $1, $2, $3); } | simple_expr '-' simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::subtract, $2->line (), $2->column ()); } + { $$ = make_binary_op ('-', $1, $2, $3); } | simple_expr '*' simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::multiply, $2->line (), $2->column ()); } + { $$ = make_binary_op ('*', $1, $2, $3); } | simple_expr '/' simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::divide, $2->line (), $2->column ()); } + { $$ = make_binary_op ('/', $1, $2, $3); } | simple_expr EMUL simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::el_mul, $2->line (), $2->column ()); } + { $$ = make_binary_op (EMUL, $1, $2, $3); } | simple_expr EDIV simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::el_div, $2->line (), $2->column ()); } + { $$ = make_binary_op (EDIV, $1, $2, $3); } | simple_expr LEFTDIV simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::leftdiv, $2->line (), $2->column ()); } + { $$ = make_binary_op (LEFTDIV, $1, $2, $3); } | simple_expr ELEFTDIV simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::el_leftdiv, $2->line (), $2->column ()); } + { $$ = make_binary_op (ELEFTDIV, $1, $2, $3); } | simple_expr EXPR_LT simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::cmp_lt, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_LT, $1, $2, $3); } | simple_expr EXPR_LE simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::cmp_le, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_LE, $1, $2, $3); } | simple_expr EXPR_EQ simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::cmp_eq, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_EQ, $1, $2, $3); } | simple_expr EXPR_GE simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::cmp_ge, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_GE, $1, $2, $3); } | simple_expr EXPR_GT simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::cmp_gt, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_GT, $1, $2, $3); } | simple_expr EXPR_NE simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::cmp_ne, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_NE, $1, $2, $3); } | simple_expr EXPR_AND_AND simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::and_and, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_AND_AND, $1, $2, $3); } | simple_expr EXPR_OR_OR simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::or_or, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_OR_OR, $1, $2, $3); } | simple_expr EXPR_AND simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::and, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_AND, $1, $2, $3); } | simple_expr EXPR_OR simple_expr - { $$ = new tree_binary_expression - ($1, $3, tree::or, $2->line (), $2->column ()); } + { $$ = make_binary_op (EXPR_OR, $1, $2, $3); } ; simple_expr1 : NUM @@ -831,19 +814,15 @@ | colon_expr { $$ = $1; } | PLUS_PLUS identifier %prec UNARY - { $$ = new tree_prefix_expression - ($2, tree::increment, $1->line (), $1->column ()); } + { $$ = make_prefix_op (PLUS_PLUS, $2, $1); } | MINUS_MINUS identifier %prec UNARY - { $$ = new tree_prefix_expression - ($2, tree::decrement, $1->line (), $1->column ()); } + { $$ = make_prefix_op (MINUS_MINUS, $2, $1); } | EXPR_NOT simple_expr - { $$ = new tree_unary_expression - ($2, tree::not, $1->line (), $1->column ()); } + { $$ = make_unary_op (EXPR_NOT, $2, $1); } | '+' simple_expr %prec UNARY { $$ = $2; } | '-' simple_expr %prec UNARY - { $$ = new tree_unary_expression - ($2, tree::uminus, $1->line (), $1->column ()); } + { $$ = make_unary_op ('-', $2, $1); } ; colon_expr : simple_expr ':' simple_expr @@ -867,19 +846,15 @@ } ; -word_list : word_list1 - { $$ = $1->reverse (); } - ; - -word_list1 : TEXT +word_list : TEXT { tree_constant *tmp = new tree_constant ($1->string ()); $$ = new tree_argument_list (tmp); } - | word_list1 TEXT + | word_list TEXT { tree_constant *tmp = new tree_constant ($2->string ()); - $$ = $1->chain (tmp); + $1->append (tmp); } ; @@ -920,22 +895,20 @@ tree_identifier *tmp = new tree_identifier ($1->sym_rec (), $1->line (), $1->column ()); tree_parameter_list *tpl = new tree_parameter_list (tmp); - tpl = tpl->reverse (); tpl->mark_as_formal_parameters (); $$ = $5->define_ret_list (tpl); } | func_def1a ']' g_symtab '=' func_def2 { - tree_parameter_list *tpl = $1->reverse (); - tpl->mark_as_formal_parameters (); - $$ = $5->define_ret_list (tpl); + $1->mark_as_formal_parameters (); + $$ = $5->define_ret_list ($1); } ; func_def1a : '[' safe local_symtab identifier { $$ = new tree_parameter_list ($4); } | func_def1a ',' identifier - { $$ = $1->chain ($3); } + { $1->append ($3); } ; func_def2 : identifier safe local_symtab func_def3 @@ -1053,24 +1026,20 @@ | param_list1 ')' { quote_is_transpose = 0; - tree_parameter_list *tmp = $1->reverse (); - tmp->mark_as_formal_parameters (); - $$ = tmp; + $1->mark_as_formal_parameters (); } | param_list1 ',' ELLIPSIS ')' { quote_is_transpose = 0; - tree_parameter_list *tmp = $1->reverse (); - tmp->mark_as_formal_parameters (); - tmp->mark_varargs (); - $$ = tmp; + $1->mark_as_formal_parameters (); + $1->mark_varargs (); } ; param_list1 : '(' identifier { $$ = new tree_parameter_list ($2); } | param_list1 ',' identifier - { $$ = $1->chain ($3); } + { $1->append ($3); } | '(' error { yyerror ("parse error"); @@ -1092,38 +1061,22 @@ } ; -arg_list : arg_list1 - { $$ = $1->reverse (); } - ; - -arg_list1 : ':' +arg_list : ':' { tree_constant *colon; colon = new tree_constant (tree_constant_rep::magic_colon); $$ = new tree_argument_list (colon); } - | arg_list1 ',' ':' + | arg_list ',' ':' { tree_constant *colon; colon = new tree_constant (tree_constant_rep::magic_colon); - $$ = $1->chain (colon); - if (! $$) - { - yyerror ("parse error"); - ABORT_PARSE; - } + $1->append (colon); } | expression { $$ = new tree_argument_list ($1); } - | arg_list1 ',' expression - { - $$ = $1->chain ($3); - if (! $$) - { - yyerror ("parse error"); - ABORT_PARSE; - } - } + | arg_list ',' expression + { $1->append ($3); } ; matrix : '[' screwed_again rows ']' @@ -1146,13 +1099,14 @@ { mlnm.pop (); mlnm.push (0); - tree_matrix *tmp = new tree_matrix ($1, tree::md_none); + tree_matrix *tmp = new tree_matrix + ($1, tree_matrix::md_none); ml.push (tmp); } else { tree_matrix *tmp = ml.pop (); - tmp = tmp->chain ($1, tree::md_down); + tmp = tmp->chain ($1, tree_matrix::md_down); ml.push (tmp); } } @@ -1160,7 +1114,7 @@ | matrix_row ',' expression { tree_matrix *tmp = ml.pop (); - tmp = tmp->chain ($3, tree::md_right); + tmp = tmp->chain ($3, tree_matrix::md_right); ml.push (tmp); } ; @@ -1312,3 +1266,156 @@ warning ("suggest parenthesis around assignment used as truth value"); } } + +static tree_expression * +make_binary_op (int op, tree_expression *op1, token *tok_val, + tree_expression *op2) +{ + tree_expression::type t; + switch (op) + { + case POW: + t = tree_expression::power; + break; + case EPOW: + t = tree_expression::elem_pow; + break; + case '+': + t = tree_expression::add; + break; + case '-': + t = tree_expression::subtract; + break; + case '*': + t = tree_expression::multiply; + break; + case '/': + t = tree_expression::divide; + break; + case EMUL: + t = tree_expression::el_mul; + break; + case EDIV: + t = tree_expression::el_div; + break; + case LEFTDIV: + t = tree_expression::leftdiv; + break; + case ELEFTDIV: + t = tree_expression::el_leftdiv; + break; + case EXPR_LT: + t = tree_expression::cmp_lt; + break; + case EXPR_LE: + t = tree_expression::cmp_le; + break; + case EXPR_EQ: + t = tree_expression::cmp_eq; + break; + case EXPR_GE: + t = tree_expression::cmp_ge; + break; + case EXPR_GT: + t = tree_expression::cmp_gt; + break; + case EXPR_NE: + t = tree_expression::cmp_ne; + break; + case EXPR_AND_AND: + t = tree_expression::and_and; + break; + case EXPR_OR_OR: + t = tree_expression::or_or; + break; + case EXPR_AND: + t = tree_expression::and; + break; + case EXPR_OR: + t = tree_expression::or; + break; + default: + panic_impossible (); + break; + } + + int l = tok_val->line (); + int c = tok_val->column (); + + return new tree_binary_expression (op1, op2, t, l, c); +} + +static tree_expression * +make_prefix_op (int op, tree_identifier *op1, token *tok_val) +{ + tree_expression::type t; + switch (op) + { + case PLUS_PLUS: + t = tree_expression::increment; + break; + case MINUS_MINUS: + t = tree_expression::decrement; + break; + default: + panic_impossible (); + break; + } + + int l = tok_val->line (); + int c = tok_val->column (); + + return new tree_prefix_expression (op1, t, l, c); +} + +static tree_expression * +make_postfix_op (int op, tree_identifier *op1, token *tok_val) +{ + tree_expression::type t; + switch (op) + { + case PLUS_PLUS: + t = tree_expression::increment; + break; + case MINUS_MINUS: + t = tree_expression::decrement; + break; + default: + panic_impossible (); + break; + } + + int l = tok_val->line (); + int c = tok_val->column (); + + return new tree_postfix_expression (op1, t, l, c); +} + +static tree_expression * +make_unary_op (int op, tree_expression *op1, token *tok_val) +{ + tree_expression::type t; + switch (op) + { + case QUOTE: + t = tree_expression::hermitian; + break; + case TRANSPOSE: + t = tree_expression::transpose; + break; + case EXPR_NOT: + t = tree_expression::not; + break; + case '-': + t = tree_expression::uminus; + break; + default: + panic_impossible (); + break; + } + + int l = tok_val->line (); + int c = tok_val->column (); + + return new tree_unary_expression (op1, t, l, c); +}