Merge pull request #27 from 0x0dea/invisible

add INVISIBLE operator for writing to stderr
This commit is contained in:
Justin J. Meza 2015-08-30 15:36:27 -07:00
commit b1ae721da5
4 changed files with 29 additions and 8 deletions

View File

@ -3087,12 +3087,12 @@ ReturnObject *interpretPrintStmtNode(StmtNode *node,
deleteValueObject(use);
return NULL;
}
printf("%s", getString(use));
fprintf(stmt->file, "%s", getString(use));
deleteValueObject(val);
deleteValueObject(use);
}
if (!stmt->nonl)
printf("\n");
putc('\n', stmt->file);
return createReturnObject(RT_DEFAULT, NULL);
}

View File

@ -629,6 +629,8 @@ void deleteCastStmtNode(CastStmtNode *node)
*
* \param [in] args The expressions to print.
*
* \param [in] file Where to print (\c stdout or \c stderr).
*
* \param [in] nonl Whether an ending newline should be surpressed.
*
* \return A pointer to the print statement with the desired properties.
@ -636,6 +638,7 @@ void deleteCastStmtNode(CastStmtNode *node)
* \retval NULL Memory allocation failed.
*/
PrintStmtNode *createPrintStmtNode(ExprNodeList *args,
FILE *file,
int nonl)
{
PrintStmtNode *p = malloc(sizeof(PrintStmtNode));
@ -644,6 +647,7 @@ PrintStmtNode *createPrintStmtNode(ExprNodeList *args,
return NULL;
}
p->args = args;
p->file = file;
p->nonl = nonl;
return p;
}
@ -2477,6 +2481,7 @@ StmtNode *parsePrintStmtNode(Token ***tokenp)
{
ExprNode *arg = NULL;
ExprNodeList *args = NULL;
FILE *file = stdout;
int nonl = 0;
PrintStmtNode *stmt = NULL;
StmtNode *ret = NULL;
@ -2489,13 +2494,21 @@ StmtNode *parsePrintStmtNode(Token ***tokenp)
debug("ST_PRINT");
#endif
/* Remove the print keyword from the token stream */
/**
* Remove the print keyword from the token stream
* A "quad-bool" is used to indicate whether we succeeded or failed to
* accept either a \c TT_VISIBLE or \c TT_INVISIBLE token.
*/
status = acceptToken(&tokens, TT_VISIBLE);
if (!status) {
parser_error_expected_token(TT_VISIBLE, tokens);
if (!status) status = acceptToken(&tokens, TT_INVISIBLE) ? 2 : -1;
if (status < 1) {
parser_error_expected_token(TT_VISIBLE - status, tokens);
goto parsePrintStmtNodeAbort;
}
/* Use standard error if we accepted a \c TT_INVISIBLE above */
if (status == 2) file = stderr;
/* Parse the arguments to the print statement */
args = createExprNodeList();
if (!args) goto parsePrintStmtNodeAbort;
@ -2515,7 +2528,7 @@ StmtNode *parsePrintStmtNode(Token ***tokenp)
&& !peekToken(&tokens, TT_BANG));
/* Check for the no-newline token */
if(acceptToken(&tokens, TT_BANG)) nonl = 1;
if (acceptToken(&tokens, TT_BANG)) nonl = 1;
/* Make sure the statement ends with a newline */
status = acceptToken(&tokens, TT_NEWLINE);
@ -2525,7 +2538,7 @@ StmtNode *parsePrintStmtNode(Token ***tokenp)
}
/* Create the new PrintStmtNode structure */
stmt = createPrintStmtNode(args, nonl);
stmt = createPrintStmtNode(args, file, nonl);
if (!stmt) goto parsePrintStmtNodeAbort;
/* Create the new StmtNode structure */
@ -3963,6 +3976,10 @@ StmtNode *parseStmtNode(Token ***tokenp)
else if (peekToken(&tokens, TT_VISIBLE)) {
ret = parsePrintStmtNode(tokenp);
}
/* Warn */
else if (peekToken(&tokens, TT_INVISIBLE)) {
ret = parsePrintStmtNode(tokenp);
}
/* Input */
else if (peekToken(&tokens, TT_GIMMEH)) {
ret = parseInputStmtNode(tokenp);

View File

@ -70,6 +70,7 @@
*
* \par
* PrintStmtNode ::= \c TT_VISIBLE ExprNodeList \c TT_BANG ? \c TT_NEWLINE
* | \c TT_INVISIBLE ExprNodeList \c TT_BANG ? \c TT_NEWLINE
*
* \par
* InputStmtNode ::= \c TT_GIMMEH IdentifierNode \c TT_NEWLINE
@ -395,6 +396,7 @@ typedef struct {
*/
typedef struct {
ExprNodeList *args; /**< The expressions to print. */
FILE *file; /**< Where to print (\c stdout or \c stderr). */
int nonl; /**< Whether to print an ending newline. */
} PrintStmtNode;
@ -612,7 +614,7 @@ void deleteCastStmtNode(CastStmtNode *);
* Functions for creating and deleting PrintStmtNodes.
*/
/**@{*/
PrintStmtNode *createPrintStmtNode(ExprNodeList *, int);
PrintStmtNode *createPrintStmtNode(ExprNodeList *, FILE *, int);
void deletePrintStmtNode(PrintStmtNode *);
/**@}*/

View File

@ -76,6 +76,7 @@ typedef enum {
TT_A, /**< Cast target separator. */
TT_ISNOWA, /**< In-place cast. */
TT_VISIBLE, /**< Print. */
TT_INVISIBLE, /**< Print to standard error. */
TT_SMOOSH, /**< String concatenation. */
TT_BANG, /**< Exclamation point (!) */
TT_GIMMEH, /**< Input. */
@ -153,6 +154,7 @@ static const char *keywords[] = {
"A", /* TT_A */
"IS NOW A", /* TT_ISNOWA */
"VISIBLE", /* TT_VISIBLE */
"INVISIBLE", /* TT_INVISIBLE */
"SMOOSH", /* TT_SMOOSH */
"!", /* TT_BANG */
"GIMMEH", /* TT_GIMMEH */