diff options
author | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2016-11-30 19:26:16 +0100 |
---|---|---|
committer | Robin Haberkorn <robin.haberkorn@googlemail.com> | 2016-11-30 19:26:16 +0100 |
commit | e4d5a995a037ae938d08480359a53dc097deec21 (patch) | |
tree | 22008b9228eee017c86a2eb8b4ca0772c2c953c9 /src/parser.cpp | |
parent | 8460f925248b99e94169bbfa9f2645de677f2e27 (diff) | |
download | sciteco-e4d5a995a037ae938d08480359a53dc097deec21.tar.gz |
allow dollar sign as another variant of ^[ (discard all arguments or return)
* some classic TECOs have this
* just like ^[, dollar works as a command only, not as a string terminator
* it improves the readability of macros using printable characters only
* it closes a gap in the language by allowing $$ (double-dollar) and
^[$ as printable ways to write the return from macro command.
^[^[ was not and is not possible.
* since command line termination is a regular interactive return-command
in SciTECO, double-dollar will also terminate the command line now.
This will be allowed unless it turns out to be a cause of trouble.
* The handling of unterminated commands has been cleaned up by
introducing State::end_of_macro().
Most commands (and thus states) except the start state cannot be
valid at the end of a macro since this indicates an unterminated/incomplete
command.
All lookahead-commands (currently only ^[) will end implicitly
at the end of a macro and so will need a way to perform their action.
The virtual method allows these actions to be defined with the rest
of the state's implementation.
Diffstat (limited to 'src/parser.cpp')
-rw-r--r-- | src/parser.cpp | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index db68c18..048389e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -244,22 +244,11 @@ Execute::macro(const gchar *macro, bool locals) throw Error("Label \"%s\" not found", Goto::skip_label); - if (States::current == &States::escape) { - /* - * Due to the deferred nature of ^[, - * it is valid to end in the "escape" state. - * FIXME: This could be avoided by signalling - * the state the end of macro using a new - * virtual method. - */ - expressions.discard_args(); - } else if (G_UNLIKELY(States::current != &States::start)) { - /* - * can only happen if we returned because - * of macro end - */ - throw Error("Unterminated command"); - } + /* + * Some states (esp. commands involving a + * "lookahead") are valid at the end of a macro. + */ + States::current->end_of_macro(); /* * This handles the problem of Q-Registers @@ -688,6 +677,7 @@ StateStart::StateStart() : State() transitions['\0'] = this; init(" \f\r\n\v"); + transitions['$'] = &States::escape; transitions['!'] = &States::label; transitions['O'] = &States::gotocmd; transitions['^'] = &States::control; @@ -2113,7 +2103,7 @@ StateEscape::StateEscape() State * StateEscape::custom(gchar chr) { - /*$ ^[^[ terminate return + /*$ ^[^[ ^[$ $$ terminate return * [a1,a2,...]$$ -- Terminate command line or return from macro * [a1,a2,...]^[$ * @@ -2143,11 +2133,13 @@ StateEscape::custom(gchar chr) * when terminating a command line \(em the new command line * will always start with a clean expression stack. * - * Only the first \fIescape\fP of \fB$$\fP may be typed - * in up-arrow mode as \fB^[$\fP \(em the second character - * must be a real escape character. + * The first \fIescape\fP of \fB$$\fP may be typed either + * as an escape character (ASCII 27), in up-arrow mode + * (e.g. \fB^[$\fP) or as a dollar character \(em the + * second character must be either a real escape character + * or a dollar character. */ - if (chr == CTL_KEY_ESC) { + if (chr == CTL_KEY_ESC || chr == '$') { BEGIN_EXEC(&States::start); States::current = &States::start; expressions.eval(); @@ -2155,9 +2147,9 @@ StateEscape::custom(gchar chr) } /* - * Alternatives: ^[, <CTRL/[>, <ESC> + * Alternatives: ^[, <CTRL/[>, <ESC>, $ (dollar) */ - /*$ ^[ escape discard + /*$ ^[ $ escape discard * $ -- Discard all arguments * ^[ * @@ -2173,12 +2165,24 @@ StateEscape::custom(gchar chr) * The up-arrow notation however is processed like any * ordinary command and only works at the begining of * a command. + * Additionally, this command may be written as a single + * dollar character. */ if (mode == MODE_NORMAL) expressions.discard_args(); return States::start.get_next_state(chr); } +void +StateEscape::end_of_macro(void) +{ + /* + * Due to the deferred nature of ^[, + * it is valid to end in the "escape" state. + */ + expressions.discard_args(); +} + StateECommand::StateECommand() : State() { transitions['\0'] = this; |