Commit e1b72cc1 authored by Radford Neal's avatar Radford Neal

substantial revision to the 'else' mods

parent 5784b3b8
......@@ -13,9 +13,10 @@
\item This release has many significant performance improvements.
It also has some feature changes, including some from later R
Core versions, and some bug fixes. One notable new feature is
that in code read from a file, an error is no longer produced
that when code is read with \code{source}, or done with \code{Rscript},
or parsed from text strings or a file, an error is no longer produced
when an \code{else} at the top level appears at the beginning
of a line.
of a line. See below for more details.
\item With the performance improvements in this release, it is
generally no longer desirable to use the bytecode compiler.
......@@ -235,14 +236,14 @@
\subsection{FEATURE CHANGES}{
\itemize{
\item It is no longer necessary to avoid putting the \code{else}
clause of a top-level \code{if} statement at the start of a line
clause of an unenclosed \code{if} statement at the start of a line
when code is read from a file with \code{source} or
\code{parse}, or is parsed from a vector of character strings,
or is run with \code{Rscript}, or is read from standard input
in a non-interactive R session. When code is entered interactively,
an \code{else} clause must still not start on a new line,
since in that context checking whether an \code{else} is on
the next line would require waiting for the user to input a
or is run with \code{Rscript}, or when the \code{--peek-for-else}
option is used when starting an R session. In interactive sessions,
it is still by default necessary to not start an \code{else} clause
on a new line, since in that context checking whether an \code{else}
is on the next line would require waiting for the user to input a
line which they may not intend to enter.
\item The \code{along}, \code{across}, and \code{down} forms of
the \code{for} statement (introduced in pqR-2016-06-24 and
......
......@@ -29,6 +29,7 @@ Copyright @copyright{} 1997 R.@: Gentleman & R.@: Ihaka@*
Copyright @copyright{} 1997, 1998 M.@: Maechler@*
Copyright @copyright{} 1997-- R Core Development Team@*
@Rcopyright{1999}
Copyright @copyright{} 2018 Radford M. Neal
@end macro
@end ifnottex
......@@ -41,6 +42,7 @@ Copyright @copyright{} 1997 R.@: Gentleman & R.@: Ihaka
Copyright @copyright{} 1997, 1998 M.@: Maechler
Copyright @copyright{} 1997-- R Core Development Team@*
@Rcopyright{1999}
Copyright @copyright{} 2018 Radford M. Neal
@end macro
@end iftex
......@@ -68,7 +70,7 @@ This is an introduction to R.
@titlepage
@title An Introduction to R
@subtitle Notes on @R{}: A Programming Environment for Data Analysis and Graphics
@subtitle Version @value{VERSION}
@subtitle Version @value{VERSION}, modified for pqR
@author W. N. Venables, D. M. Smith
@author and the R Development Core Team
......@@ -6973,6 +6975,15 @@ Make @R{} run as quietly as possible. This option is intended to
support programs which use @R{} to compute results for them. It implies
@option{--quiet} and @option{--no-save}.
@item --peek-for-else
In the main interpreter loop that reads and evaluates expressions,
peek ahead for an @code{else} after the expression following the
condition in an @code{if} expression. Without this option, an
@code{else} in an unenclosed @code{if} expression must not start at
the beginning of a line. However, if peeking for an @code{else} is
enabled, and the user did not intend to enter an @code{else} as part
of an @code{if}, they may need to enter a line with just a semicolon.
@item --interactive
(UNIX only) Assert that @R{} really is being run interactively even if
input has been redirected: use if input is from a FIFO or pipe and fed
......
Modifications to parser to fix the problem of outer-level "else" being
rejected when sourcing a file (or parsing from text variable).
rejected when sourcing a file (or parsing from file or text variable, or
in Rscript). Also --peek-for-else option to control this in other
contexts.
Other parsing cleanup as well. Also slight performance tweak to getOptions.
/*
* pqR : A pretty quick version of R
* Copyright (C) 2015 by Radford M. Neal
* Copyright (C) 2015, 2018 by Radford M. Neal
*
* Based on R : A Computer Language for Statistical Data Analysis
* Copyright (C) 2010 R Development Core Team
......
......@@ -1078,6 +1078,7 @@ LibExtern Rboolean R_Interactive INI_as(TRUE); /* TRUE during interactive use*/
extern0 Rboolean R_Quiet INI_as(FALSE); /* Be as quiet as possible */
extern Rboolean R_Slave INI_as(FALSE); /* Run as a slave process */
extern0 Rboolean R_Verbose INI_as(FALSE); /* Be verbose */
LibExtern Rboolean R_PeekForElse INI_as(FALSE); /* Look ahead for 'else'? */
/* extern int R_Console; */ /* Console active flag */
/* IoBuffer R_ConsoleIob; : --> ./IOStuff.h */
/* R_Consolefile is used in the internet module */
......
/*
* R : A Computer Language for Statistical Data Analysis
* pqR : A pretty quick version of R
* Copyright (C) 2018 by Radford M. Neal
*
* Based on R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1999-2010 The R Core Team
*
* This program is free software; you can redistribute it and/or modify
......@@ -56,6 +59,7 @@ typedef struct
Rboolean R_Slave;
Rboolean R_Interactive;
Rboolean R_Verbose;
Rboolean R_PeekForElse;
Rboolean LoadSiteFile;
Rboolean LoadInitFile;
Rboolean DebugInitFile;
......@@ -80,6 +84,7 @@ typedef struct
UImode CharacterMode;
blah7 WriteConsoleEx; /* used only if WriteConsole is NULL */
#endif
} structRstart;
typedef structRstart *Rstart;
......
......@@ -21,7 +21,8 @@
\description{
These are the basic control-flow constructs of the \R language. They
function in much the same way as control statements in any Algol-like
language. They are all (except \code{along}) \link{reserved} words.
language. Except \code{along}, \code{down}, and \code{across}), the
words used in these constructs are \link{reserved}.
}
\usage{
if (cond) expr
......@@ -62,28 +63,36 @@ next
}
}
\details{
\code{break} breaks out of a \code{for}, \code{while} or \code{repeat}
loop; control is transferred to the first statement outside the
inner-most loop. \code{next} halts the processing of the current
iteration and advances the looping index. Both \code{break} and
\code{next} apply only to the innermost of nested loops.
The \code{if} expression evaluates one expression or another, depending
on a condition, as described below.
The \code{for}, \code{while}, and \code{repeat} expressions are used
for looping, as described below. \code{break} breaks out of a loop,
after which control passes to the next expression following the
loop (or to the outer expression if there is no such expression).
\code{next} halts the processing of the current iteration and
(advancing the looping index in the case of \code{for}). Both
\code{break} and \code{next} apply only to the innermost of nested
loops.
Note that it is a common mistake to forget to put braces (\code{\{ .. \}})
around your statements, e.g., after \code{if (..)} or \code{for (....)}.
For that reason, one (somewhat extreme) attitude of defensive programming
is to always use braces, e.g., for \code{if} clauses.
To avoid a syntax error in entering an \code{if ... else} construct
at the keyboard, you need to avoid putting a newline between the end
of \code{cons.expr} (often a \code{\}}) and \code{else} --- this is a
requirement so that the intepreter will not be waiting for keyboard input when
the user does not intend to enter an \code{else} clause. For R Core
versions of R, a newline before \code{else} must also be avoided for code
read with \code{source}, or parsed from a file or a character vector with
\code{parse}, or run with \code{Rscript}, or read from standard input
in a non-interactive R session, even though there is then no reason not
to always peek ahead looking for an \code{else} clause, but pqR parses
an \code{else} properly without giving an error in this situation.
Note that the expressions in alternatives for an \code{if} expression and
the body of a loop are single expressions. If evaluation of more than one
expression is desired, they must be encosed in braces (\code{\{ ... \}}).
To avoid a syntax error during keyboard entry of expressions, an
\code{if...else...} construct that is not enclosed in another
syntactic unit must not have the \code{else} at the start of a line
--- this is a requirement so that the intepreter will not be waiting
for keyboard input when the user does not intend to enter the
optional \code{else} clause. For pqR, this restriction is not
present for code read with \code{source}, or parsed from a file or a
character vector with the \code{parse} function, or run with
\code{Rscript}, or if the \code{--peek-for-else} option is used (which
may have undesired effects even for non-interactive sessions).
Note, however, that R Core implementations always give an error when an
unenclosed \code{else} is at the start of a line, even when reading
code with \code{source}, and in other contexts where this would cause
no problems.
The \code{seq}, \code{vector}, \code{matrix}, or \code{array} in a
\code{for} loop is evaluated at the start of
......
/*
* pqR : A pretty quick version of R
* Copyright (C) 2013 by Radford M. Neal
* Copyright (C) 2013, 2018 by Radford M. Neal
*
* Based on R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1997-2012 The R Core Team
......@@ -34,25 +34,21 @@
#include <R_ext/RStartup.h>
/* Remove and process common command-line arguments
* Formally part of ../unix/sys-common.c.
*/
/* Remove and process common command-line arguments. */
/*
This copies the command line arguments to the Rstart
structure. The memory is obtained from calloc, etc.
since these are permanent and it is not intended that
they be modified. This is why they are copied before
being processed and removed from the list.
/* This copies the command line arguments to the Rstart
structure. The memory is obtained from calloc, etc.
since these are permanent and it is not intended that
they be modified. This is why they are copied before
being processed and removed from the list.
We might store these as a SEXP. I have no strong opinion
about this.
*/
We might store these as a SEXP. I have no strong opinion
about this. */
/* Permanent copy of the command line arguments and the number
of them passed to the application.
These are populated via the routine R_set_command_line_arguments().
*/
These are populated via the routine R_set_command_line_arguments(). */
static int NumCommandLineArgs = 0;
static char **CommandLineArgs = NULL;
......@@ -159,6 +155,9 @@ R_common_command_line(int *pac, char **argv, Rstart Rp)
Rp->R_Slave = TRUE;
Rp->SaveAction = SA_NOSAVE;
}
else if (!strcmp(*av, "--peek-for-else")) {
Rp->R_PeekForElse = TRUE;
}
else if (!strcmp(*av, "--no-site-file")) {
Rp->LoadSiteFile = FALSE;
}
......
......@@ -333,7 +333,7 @@ static int REPL_iter (SEXP rho, R_ReplState *state, int first, char *saved_ps)
R_CurrentExpr = R_Parse1Stream (ReplGetc, (void *) state,
&state->status, &ParseState,
saved_ps == NULL, !first, saved_ps);
!R_PeekForElse, !first, saved_ps);
if (keepSource) {
int buflen = R_IoBufferWriteOffset(&R_ConsoleIob);
char buf[buflen+1];
......
/*
pqR : A pretty quick version of R
Copyright (C) 2013, 2014 by Radford M. Neal
Copyright (C) 2013, 2014, 2018 by Radford M. Neal
Based on R : A Computer Language for Statistical Data Analysis
Copyright (C) 1995-1996 Robert Gentleman and Ross Ihaka
......@@ -154,6 +154,7 @@ void R_DefParams(Rstart Rp)
Rp->R_Slave = FALSE;
Rp->R_Interactive = TRUE;
Rp->R_Verbose = FALSE;
Rp->R_PeekForElse = FALSE;
Rp->RestoreAction = SA_RESTORE;
Rp->SaveAction = SA_SAVEASK;
Rp->LoadSiteFile = TRUE;
......@@ -228,6 +229,7 @@ void R_SetParams(Rstart Rp)
R_Slave = Rp->R_Slave;
R_Interactive = Rp->R_Interactive;
R_Verbose = Rp->R_Verbose;
R_PeekForElse = Rp->R_PeekForElse;
RestoreAction = Rp->RestoreAction;
SaveAction = Rp->SaveAction;
LoadSiteFile = Rp->LoadSiteFile;
......
......@@ -74,6 +74,7 @@ Options:
-q, --quiet Don't print startup message
--silent Same as --quiet
--slave Make R run as quietly as possible
--peek-for-else Look ahead for an 'else' on the start of a new line
--interactive Force an interactive session
--verbose Print more information about progress
-d, --debugger=NAME Run R through debugger NAME
......
/*
* R : A Computer Language for Statistical Data Analysis
* pqR : A pretty quick version of R
* Copyright (C) 2018 by Radford M. Neal
*
* Based on R : A Computer Language for Statistical Data Analysis
* Copyright (C) 2006-10 The R Development Core Team
*
* This program is free software; you can redistribute it and/or modify
......@@ -24,7 +27,7 @@ commandArgs(TRUE)
q(status=7)
This invokes R with a command line like
R --slave --no-restore --vanilla --file=foo [script_args]
R --slave --peek-for-else --no-restore --vanilla --file=foo [script_args]
*/
......@@ -94,7 +97,7 @@ void usage(void)
fprintf(stderr, " --default-packages=list\n");
fprintf(stderr, " Where 'list' is a comma-separated set\n");
fprintf(stderr, " of package names, or 'NULL'\n");
fprintf(stderr, "or options to R, in addition to --slave --no-restore, such as\n");
fprintf(stderr, "or options to R, in addition to --slave --peek-for-else, --no-restore, such as\n");
fprintf(stderr, " --save Do save workspace at the end of the session\n");
fprintf(stderr, " --no-environ Don't read the site and user environment files\n");
fprintf(stderr, " --no-site-file Don't read the site-wide Rprofile\n");
......@@ -117,7 +120,7 @@ int main(int argc, char *argv[])
usage();
exit(1);
}
av = (char **) malloc((size_t) (argc+4)*sizeof(char *));
av = (char **) malloc((size_t) (argc+5)*sizeof(char *));
if(!av) {
fprintf(stderr, "malloc failure\n");
exit(1);
......@@ -146,6 +149,7 @@ int main(int argc, char *argv[])
#endif
av[ac++] = cmd;
av[ac++] = "--slave";
av[ac++] = "--peek-for-else";
av[ac++] = "--no-restore";
if(argc == 2) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment