Mercurial > hg > octave-max
changeset 916:2f35156aa18b
[project @ 1994-11-11 00:36:31 by jwe]
author | jwe |
---|---|
date | Fri, 11 Nov 1994 00:36:31 +0000 |
parents | b632b159b4ed |
children | b843a65fa977 |
files | src/lex.l src/parse.y src/pt-cmd.cc src/pt-cmd.h |
diffstat | 4 files changed, 151 insertions(+), 9 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lex.l +++ b/src/lex.l @@ -1107,6 +1107,25 @@ token_stack.push (yylval.tok_val); return WHILE; } + else if (strcmp ("unwind_protect", s) == 0) + { + promptflag--; + yylval.tok_val = new token (l, c); + token_stack.push (yylval.tok_val); + return UNWIND_PROTECT; + } + else if (strcmp ("unwind_protect_cleanup", s) == 0) + { + yylval.tok_val = new token (l, c); + token_stack.push (yylval.tok_val); + return UNWIND_PROTECT_CLEANUP; + } + else if (strcmp ("end_unwind_protect", s) == 0) + { + end_found = 1; + yylval.tok_val = new token (token::unwind_protect_end, l, c); + token_stack.push (yylval.tok_val); + } if (end_found) {
--- a/src/parse.y +++ b/src/parse.y @@ -223,6 +223,7 @@ %token <tok_val> PLOT %token <tok_val> TEXT STYLE %token <tok_val> FOR WHILE IF ELSEIF ELSE BREAK CONTINUE FUNC_RET +%token <tok_val> UNWIND_PROTECT UNWIND_PROTECT_CLEANUP %token <tok_val> GLOBAL %token <tok_val> TEXT_ID @@ -601,6 +602,15 @@ iffing--; $$ = $1; } + + | UNWIND_PROTECT opt_list UNWIND_PROTECT_CLEANUP opt_list END + { + if (check_end ($5, token::unwind_protect_end)) + ABORT_PARSE; + + $$ = new tree_unwind_protect_command ($2, $4, $1->line (), + $1->column ()); + } | WHILE expression optsep opt_list END { maybe_warn_assign_as_truth_value ($2);
--- a/src/pt-cmd.cc +++ b/src/pt-cmd.cc @@ -47,6 +47,7 @@ #include "tree-cmd.h" #include "tree-misc.h" #include "tree-const.h" +#include "unwind-prot.h" // Decide if it's time to quit a for or while loop. static int @@ -433,6 +434,85 @@ os << "endif"; } +// Simple exception handling. + +tree_unwind_protect_command::~tree_unwind_protect_command (void) +{ + delete unwind_protect_code; + delete cleanup_code; +} + +static void +do_unwind_protect_cleanup_code (void *ptr) +{ + tree_statement_list *list = (tree_statement_list *) ptr; + +// We want to run the cleanup code without error_state being set, but +// we need to restore its value, so that any errors encountered in +// the first part of the unwind_protect are not completely ignored. + + unwind_protect_int (error_state); + + error_state = 0; + + if (list) + list->eval (1); + +// We don't want to ignore errors that occur in the cleanup code, so +// if an error is encountered there, leave error_state alone. +// Otherwise, set it back to what it was before. + + if (error_state) + discard_unwind_protect (); + else + run_unwind_protect (); +} + +void +tree_unwind_protect_command::eval (void) +{ + add_unwind_protect (do_unwind_protect_cleanup_code, cleanup_code); + + if (unwind_protect_code) + unwind_protect_code->eval (1); + + run_unwind_protect (); +} + +void +tree_unwind_protect_command::print_code (ostream& os) +{ + print_code_indent (os); + + os << "unwind_protect"; + + print_code_new_line (os); + + if (unwind_protect_code) + { + increment_indent_level (); + unwind_protect_code->print_code (os); + decrement_indent_level (); + } + + print_code_indent (os); + + os << "cleanup_code"; + + print_code_new_line (os); + + if (cleanup_code) + { + increment_indent_level (); + cleanup_code->print_code (os); + decrement_indent_level (); + } + + print_code_indent (os); + + os << "end_unwind_protect"; +} + // Break. void
--- a/src/pt-cmd.h +++ b/src/pt-cmd.h @@ -39,6 +39,7 @@ class tree_while_command; class tree_for_command; class tree_if_command; +class tree_unwind_protect_command; class tree_break_command; class tree_continue_command; class tree_return_command; @@ -59,7 +60,7 @@ class tree_global_command : public tree_command { - public: +public: tree_global_command (int l = -1, int c = -1) : tree_command (l, c) { init_list = 0; } @@ -82,7 +83,7 @@ class tree_while_command : public tree_command { - public: +public: tree_while_command (int l = -1, int c = -1) : tree_command (l, c) { expr = 0; @@ -112,7 +113,7 @@ void print_code (ostream& os); - private: +private: tree_expression *expr; // Expression to test. tree_statement_list *list; // List of commands to execute. }; @@ -122,7 +123,7 @@ class tree_for_command : public tree_command { - public: +public: tree_for_command (int l = -1, int c = -1) : tree_command (l, c) { id = 0; @@ -147,7 +148,7 @@ void print_code (ostream& os); - private: +private: void do_for_loop_once (tree_constant *rhs, int& quit); tree_index_expression *id; // Identifier to modify. @@ -160,7 +161,7 @@ class tree_if_command : public tree_command { - public: +public: tree_if_command (int l = -1, int c = -1) : tree_command (l, c) { list = 0; } @@ -176,16 +177,48 @@ void print_code (ostream& os); - private: +private: tree_if_command_list *list; }; +// Simple exception handling. + +class +tree_unwind_protect_command : public tree_command +{ +public: + tree_unwind_protect_command (int l = -1, int c = -1) : tree_command (l, c) + { + unwind_protect_code = 0; + cleanup_code = 0; + } + + tree_unwind_protect_command (tree_statement_list *tc, + tree_statement_list *cc, + int l = -1, int c = -1) + : tree_command (l, c) + { + unwind_protect_code = tc; + cleanup_code = cc; + } + + ~tree_unwind_protect_command (void); + + void eval (void); + + void print_code (ostream& os); + +private: + tree_statement_list *unwind_protect_code; + tree_statement_list *cleanup_code; +}; + // Break. class tree_break_command : public tree_command { - public: +public: tree_break_command (int l = -1, int c = -1) : tree_command (l, c) { } ~tree_break_command (void) { } @@ -200,7 +233,7 @@ class tree_continue_command : public tree_command { - public: +public: tree_continue_command (int l = -1, int c = -1) : tree_command (l, c) { } ~tree_continue_command (void) { }