aboutsummaryrefslogtreecommitdiffstats
path: root/awkgram.y
diff options
context:
space:
mode:
Diffstat (limited to 'awkgram.y')
-rw-r--r--awkgram.y331
1 files changed, 213 insertions, 118 deletions
diff --git a/awkgram.y b/awkgram.y
index fb394600..b7a3b37d 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -3,7 +3,7 @@
*/
/*
- * Copyright (C) 1986, 1988, 1989, 1991-2011 the Free Software Foundation, Inc.
+ * Copyright (C) 1986, 1988, 1989, 1991-2012 the Free Software Foundation, Inc.
*
* This file is part of GAWK, the GNU implementation of the
* AWK Programming Language.
@@ -694,16 +694,16 @@ statement
} else {
INSTRUCTION *tbreak, *tcont;
- /* [ Op_push_array a ]
- * [ Op_arrayfor_init | ib ]
- * ic:[ Op_arrayfor_incr | ib ]
- * [ Op_var_assign if any ]
- *
- * body
- *
- * [Op_jmp | ic ]
- * ib:[Op_arrayfor_final ]
- */
+ /* [ Op_push_array a ]
+ * [ Op_arrayfor_init | ib ]
+ * ic:[ Op_arrayfor_incr | ib ]
+ * [ Op_var_assign if any ]
+ *
+ * body
+ *
+ * [Op_jmp | ic ]
+ * ib:[Op_arrayfor_final ]
+ */
regular_loop:
ip = $5;
ip->nexti->opcode = Op_push_array;
@@ -886,8 +886,7 @@ simple_stmt
|| ($3->lasti->opcode == Op_field_spec
&& $3->nexti->nexti->nexti == $3->lasti
&& $3->nexti->nexti->opcode == Op_push_i
- && $3->nexti->nexti->memory->type == Node_val
- && $3->nexti->nexti->memory->numbr == 0.0)
+ && $3->nexti->nexti->memory->type == Node_val)
)
) {
static short warned = FALSE;
@@ -901,11 +900,16 @@ simple_stmt
*/
if ($3 != NULL) {
- bcfree($3->lasti); /* Op_field_spec */
- unref($3->nexti->nexti->memory); /* Node_val */
+ NODE *n = $3->nexti->nexti->memory;
+
+ if (! iszero(n))
+ goto regular_print;
+
+ bcfree($3->lasti); /* Op_field_spec */
+ unref(n); /* Node_val */
bcfree($3->nexti->nexti); /* Op_push_i */
- bcfree($3->nexti); /* Op_list */
- bcfree($3); /* Op_list */
+ bcfree($3->nexti); /* Op_list */
+ bcfree($3); /* Op_list */
} else {
if (do_lint && (rule == BEGIN || rule == END) && ! warned) {
warned = TRUE;
@@ -917,7 +921,7 @@ simple_stmt
$1->expr_count = 0;
$1->opcode = Op_K_print_rec;
if ($4 == NULL) { /* no redircetion */
- $1->redir_type = 0;
+ $1->redir_type = redirect_none;
$$ = list_create($1);
} else {
INSTRUCTION *ip;
@@ -937,16 +941,16 @@ simple_stmt
* [$1 | NULL | redir_type | expr_count]
*
*/
-
+regular_print:
if ($4 == NULL) { /* no redirection */
if ($3 == NULL) { /* printf without arg */
$1->expr_count = 0;
- $1->redir_type = 0;
+ $1->redir_type = redirect_none;
$$ = list_create($1);
} else {
INSTRUCTION *t = $3;
$1->expr_count = count_expressions(&t, FALSE);
- $1->redir_type = 0;
+ $1->redir_type = redirect_none;
$$ = list_append(t, $1);
}
} else {
@@ -1071,7 +1075,9 @@ case_value
{ $$ = $1; }
| '-' YNUMBER %prec UNARY
{
- $2->memory->numbr = -(force_number($2->memory));
+ NODE *n = $2->memory;
+ (void) force_number(n);
+ negate_num(n);
bcfree($1);
$$ = $2;
}
@@ -1458,6 +1464,7 @@ non_post_simp_exp
} else {
if (do_optimize > 1 && $2->nexti == $2->lasti
&& $2->nexti->opcode == Op_push_i
+ && ($2->nexti->memory->flags & (MPFN|MPZN)) == 0
) {
NODE *n = $2->nexti->memory;
if ((n->flags & (STRCUR|STRING)) != 0) {
@@ -1530,7 +1537,9 @@ non_post_simp_exp
if ($2->lasti->opcode == Op_push_i
&& ($2->lasti->memory->flags & (STRCUR|STRING)) == 0
) {
- $2->lasti->memory->numbr = -(force_number($2->lasti->memory));
+ NODE *n = $2->lasti->memory;
+ (void) force_number(n);
+ negate_num(n);
$$ = $2;
bcfree($1);
} else {
@@ -1776,6 +1785,7 @@ struct token {
# define CONTINUE 0x2000 /* continue allowed inside */
NODE *(*ptr)(int); /* function that implements this keyword */
+ NODE *(*ptr2)(int); /* alternate arbitrary-precision function */
};
#if 'a' == 0x81 /* it's EBCDIC */
@@ -1799,82 +1809,85 @@ tokcompare(const void *l, const void *r)
* Function pointers come from declarations in awk.h.
*/
-static const struct token tokentab[] = {
-{"BEGIN", Op_rule, LEX_BEGIN, 0, 0},
-{"BEGINFILE", Op_rule, LEX_BEGINFILE, GAWKX, 0},
-{"END", Op_rule, LEX_END, 0, 0},
-{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0},
-#ifdef ARRAYDEBUG
-{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_adump},
+#ifdef HAVE_MPFR
+#define MPF(F) do_mpfr_##F
+#else
+#define MPF(F) 0
#endif
-{"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and},
+
+static const struct token tokentab[] = {
+{"BEGIN", Op_rule, LEX_BEGIN, 0, 0, 0},
+{"BEGINFILE", Op_rule, LEX_BEGINFILE, GAWKX, 0, 0},
+{"END", Op_rule, LEX_END, 0, 0, 0},
+{"ENDFILE", Op_rule, LEX_ENDFILE, GAWKX, 0, 0},
#ifdef ARRAYDEBUG
-{"aoption", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_aoption},
+{"adump", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_adump, 0},
#endif
-{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort},
-{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti},
-{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2},
-{"bindtextdomain", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain},
-{"break", Op_K_break, LEX_BREAK, 0, 0},
-{"case", Op_K_case, LEX_CASE, GAWKX, 0},
-{"close", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close},
-{"compl", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl},
-{"continue", Op_K_continue, LEX_CONTINUE, 0, 0},
-{"cos", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos},
-{"dcgettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext},
-{"dcngettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext},
-{"default", Op_K_default, LEX_DEFAULT, GAWKX, 0},
-{"delete", Op_K_delete, LEX_DELETE, NOT_OLD, 0},
-{"do", Op_K_do, LEX_DO, NOT_OLD|BREAK|CONTINUE, 0},
-{"else", Op_K_else, LEX_ELSE, 0, 0},
-{"eval", Op_symbol, LEX_EVAL, 0, 0},
-{"exit", Op_K_exit, LEX_EXIT, 0, 0},
-{"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp},
-{"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext},
-{"fflush", Op_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush},
-{"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0},
-{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0},
-{"function",Op_func, LEX_FUNCTION, NOT_OLD, 0},
-{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0},
-{"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0},
-{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
-{"if", Op_K_if, LEX_IF, 0, 0},
-{"in", Op_symbol, LEX_IN, 0, 0},
-{"include", Op_symbol, LEX_INCLUDE, GAWKX, 0},
-{"index", Op_builtin, LEX_BUILTIN, A(2), do_index},
-{"int", Op_builtin, LEX_BUILTIN, A(1), do_int},
-{"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray},
-{"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length},
-{"load", Op_symbol, LEX_LOAD, GAWKX, 0},
-{"log", Op_builtin, LEX_BUILTIN, A(1), do_log},
-{"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
-{"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
-{"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime},
-{"next", Op_K_next, LEX_NEXT, 0, 0},
-{"nextfile", Op_K_nextfile, LEX_NEXTFILE, GAWKX, 0},
-{"or", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_or},
-{"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit},
-{"print", Op_K_print, LEX_PRINT, 0, 0},
-{"printf", Op_K_printf, LEX_PRINTF, 0, 0},
-{"rand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand},
-{"return", Op_K_return, LEX_RETURN, NOT_OLD, 0},
-{"rshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift},
-{"sin", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin},
-{"split", Op_builtin, LEX_BUILTIN, A(2)|A(3)|A(4), do_split},
-{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf},
-{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt},
-{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand},
-{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime},
-{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum},
-{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0},
-{"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr},
-{"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0},
-{"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system},
-{"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime},
-{"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower},
-{"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper},
-{"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0},
-{"xor", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor},
+{"and", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_and, MPF(and)},
+{"asort", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asort, 0},
+{"asorti", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_asorti, 0},
+{"atan2", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2), do_atan2, MPF(atan2)},
+{"bindtextdomain", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2), do_bindtextdomain, 0},
+{"break", Op_K_break, LEX_BREAK, 0, 0, 0},
+{"case", Op_K_case, LEX_CASE, GAWKX, 0, 0},
+{"close", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1)|A(2), do_close, 0},
+{"compl", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_compl, MPF(compl)},
+{"continue", Op_K_continue, LEX_CONTINUE, 0, 0, 0},
+{"cos", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_cos, MPF(cos)},
+{"dcgettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3), do_dcgettext, 0},
+{"dcngettext", Op_builtin, LEX_BUILTIN, GAWKX|A(1)|A(2)|A(3)|A(4)|A(5), do_dcngettext, 0},
+{"default", Op_K_default, LEX_DEFAULT, GAWKX, 0, 0},
+{"delete", Op_K_delete, LEX_DELETE, NOT_OLD, 0, 0},
+{"do", Op_K_do, LEX_DO, NOT_OLD|BREAK|CONTINUE, 0, 0},
+{"else", Op_K_else, LEX_ELSE, 0, 0, 0},
+{"eval", Op_symbol, LEX_EVAL, 0, 0, 0},
+{"exit", Op_K_exit, LEX_EXIT, 0, 0, 0},
+{"exp", Op_builtin, LEX_BUILTIN, A(1), do_exp, MPF(exp)},
+{"extension", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_ext, 0},
+{"fflush", Op_builtin, LEX_BUILTIN, RESX|A(0)|A(1), do_fflush, 0},
+{"for", Op_K_for, LEX_FOR, BREAK|CONTINUE, 0, 0},
+{"func", Op_func, LEX_FUNCTION, NOT_POSIX|NOT_OLD, 0, 0},
+{"function",Op_func, LEX_FUNCTION, NOT_OLD, 0, 0},
+{"gensub", Op_sub_builtin, LEX_BUILTIN, GAWKX|A(3)|A(4), 0, 0},
+{"getline", Op_K_getline_redir, LEX_GETLINE, NOT_OLD, 0, 0},
+{"gsub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0},
+{"if", Op_K_if, LEX_IF, 0, 0, 0},
+{"in", Op_symbol, LEX_IN, 0, 0, 0},
+{"include", Op_symbol, LEX_INCLUDE, GAWKX, 0, 0},
+{"index", Op_builtin, LEX_BUILTIN, A(2), do_index, 0},
+{"int", Op_builtin, LEX_BUILTIN, A(1), do_int, MPF(int)},
+{"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray, 0},
+{"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length, 0},
+{"load", Op_symbol, LEX_LOAD, GAWKX, 0, 0},
+{"log", Op_builtin, LEX_BUILTIN, A(1), do_log, MPF(log)},
+{"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift, MPF(lshift)},
+{"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match, 0},
+{"mktime", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_mktime, 0},
+{"next", Op_K_next, LEX_NEXT, 0, 0, 0},
+{"nextfile", Op_K_nextfile, LEX_NEXTFILE, GAWKX, 0, 0},
+{"or", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_or, MPF(or)},
+{"patsplit", Op_builtin, LEX_BUILTIN, GAWKX|A(2)|A(3)|A(4), do_patsplit, 0},
+{"print", Op_K_print, LEX_PRINT, 0, 0, 0},
+{"printf", Op_K_printf, LEX_PRINTF, 0, 0, 0},
+{"rand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0), do_rand, MPF(rand)},
+{"return", Op_K_return, LEX_RETURN, NOT_OLD, 0, 0},
+{"rshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_rshift, MPF(rhift)},
+{"sin", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_sin, MPF(sin)},
+{"split", Op_builtin, LEX_BUILTIN, A(2)|A(3)|A(4), do_split, 0},
+{"sprintf", Op_builtin, LEX_BUILTIN, 0, do_sprintf, 0},
+{"sqrt", Op_builtin, LEX_BUILTIN, A(1), do_sqrt, MPF(sqrt)},
+{"srand", Op_builtin, LEX_BUILTIN, NOT_OLD|A(0)|A(1), do_srand, MPF(srand)},
+{"strftime", Op_builtin, LEX_BUILTIN, GAWKX|A(0)|A(1)|A(2)|A(3), do_strftime, 0},
+{"strtonum", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_strtonum, MPF(strtonum)},
+{"sub", Op_sub_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), 0, 0},
+{"substr", Op_builtin, LEX_BUILTIN, A(2)|A(3), do_substr, 0},
+{"switch", Op_K_switch, LEX_SWITCH, GAWKX|BREAK, 0, 0},
+{"system", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_system, 0},
+{"systime", Op_builtin, LEX_BUILTIN, GAWKX|A(0), do_systime, 0},
+{"tolower", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_tolower, 0},
+{"toupper", Op_builtin, LEX_BUILTIN, NOT_OLD|A(1), do_toupper, 0},
+{"while", Op_K_while, LEX_WHILE, BREAK|CONTINUE, 0, 0},
+{"xor", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_xor, MPF(xor)},
};
#if MBS_SUPPORT
@@ -1910,6 +1923,23 @@ getfname(NODE *(*fptr)(int))
return NULL;
}
+/* negate_num --- negate a number in NODE */
+
+void
+negate_num(NODE *n)
+{
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n)) {
+ int tval;
+ tval = mpfr_neg(n->mpg_numbr, n->mpg_numbr, ROUND_MODE);
+ IEEE_FMT(n->mpg_numbr, tval);
+ } else if (is_mpg_integer(n)) {
+ mpz_neg(n->mpg_i, n->mpg_i);
+ } else
+#endif
+ n->numbr = -n->numbr;
+}
+
/* print_included_from --- print `Included from ..' file names and locations */
static void
@@ -2814,6 +2844,32 @@ allow_newline(void)
}
}
+/* newline_eof --- return newline or EOF as needed and adjust variables */
+
+/*
+ * This routine used to be a macro, however GCC 4.6.2 warned about
+ * the result of a computation not being used. Converting to a function
+ * removes the warnings.
+ */
+
+static int newline_eof()
+{
+ /* NB: a newline at end does not start a source line. */
+ if (lasttok != NEWLINE) {
+ pushback();
+ if (do_lint && ! eof_warned) {
+ lintwarn(_("source file does not end in newline"));
+ eof_warned = TRUE;
+ }
+ sourceline++;
+ return NEWLINE;
+ }
+
+ sourceline--;
+ eof_warned = FALSE;
+ return LEX_EOF;
+}
+
/* yylex --- Read the input and turn it into tokens. */
static int
@@ -2824,6 +2880,7 @@ yylex(void)
int seen_point = FALSE;
int esc_seen; /* for literal strings */
int mid;
+ int base;
static int did_newline = FALSE;
char *tokkey;
int inhex = FALSE;
@@ -2832,15 +2889,7 @@ yylex(void)
#define GET_INSTRUCTION(op) bcalloc(op, 1, sourceline)
- /* NB: a newline at end does not start a source line. */
-
-#define NEWLINE_EOF \
- (lasttok != NEWLINE ? \
- (pushback(), do_lint && ! eof_warned && \
- (lintwarn(_("source file does not end in newline")), \
- eof_warned = TRUE), sourceline++, NEWLINE) : \
- (sourceline--, eof_warned = FALSE, LEX_EOF))
-
+#define NEWLINE_EOF newline_eof()
yylval = (INSTRUCTION *) NULL;
if (lasttok == SUBSCRIPT) {
@@ -3400,17 +3449,42 @@ retry:
tokadd('\0');
yylval = GET_INSTRUCTION(Op_push_i);
- if (! do_traditional && isnondecimal(tokstart, FALSE)) {
+
+ base = 10;
+ if (! do_traditional) {
+ base = get_numbase(tokstart, FALSE);
if (do_lint) {
- if (isdigit((unsigned char) tokstart[1])) /* not an 'x' or 'X' */
+ if (base == 8)
lintwarn("numeric constant `%.*s' treated as octal",
(int) strlen(tokstart)-1, tokstart);
- else if (tokstart[1] == 'x' || tokstart[1] == 'X')
+ else if (base == 16)
lintwarn("numeric constant `%.*s' treated as hexadecimal",
(int) strlen(tokstart)-1, tokstart);
}
+ }
+
+#ifdef HAVE_MPFR
+ if (do_mpfr) {
+ NODE *r;
+
+ if (! seen_point && ! seen_e) {
+ r = mpg_integer();
+ mpg_strtoui(r->mpg_i, tokstart, strlen(tokstart), NULL, base);
+ errno = 0;
+ } else {
+ int tval;
+ r = mpg_float();
+ tval = mpfr_strtofr(r->mpg_numbr, tokstart, NULL, base, ROUND_MODE);
+ errno = 0;
+ IEEE_FMT(r->mpg_numbr, tval);
+ }
+ yylval->memory = r;
+ return lasttok = YNUMBER;
+ }
+#endif
+ if (base != 10)
d = nondec2awknum(tokstart, strlen(tokstart));
- } else
+ else
d = atof(tokstart);
yylval->memory = make_number(d);
if (d <= INT32_MAX && d >= INT32_MIN && d == (int32_t) d)
@@ -3697,7 +3771,13 @@ snode(INSTRUCTION *subn, INSTRUCTION *r)
}
}
- r->builtin = tokentab[idx].ptr;
+#ifdef HAVE_MPFR
+ /* N.B.: There isn't any special processing for an alternate function below */
+ if (do_mpfr && tokentab[idx].ptr2)
+ r->builtin = tokentab[idx].ptr2;
+ else
+#endif
+ r->builtin = tokentab[idx].ptr;
/* special case processing for a few builtins */
@@ -3903,14 +3983,28 @@ valinfo(NODE *n, Func_print print_func, FILE *fp)
else if (n->flags & STRING) {
pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
print_func(fp, "\n");
- } else if (n->flags & NUMBER)
+ } else if (n->flags & NUMBER) {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ print_func(fp, "%s\n", mpg_fmt("%.17R*g", ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ print_func(fp, "%s\n", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
print_func(fp, "%.17g\n", n->numbr);
- else if (n->flags & STRCUR) {
+ } else if (n->flags & STRCUR) {
pp_string_fp(print_func, fp, n->stptr, n->stlen, '"', FALSE);
print_func(fp, "\n");
- } else if (n->flags & NUMCUR)
+ } else if (n->flags & NUMCUR) {
+#ifdef HAVE_MPFR
+ if (is_mpg_float(n))
+ print_func(fp, "%s\n", mpg_fmt("%.17R*g", ROUND_MODE, n->mpg_numbr));
+ else if (is_mpg_integer(n))
+ print_func(fp, "%s\n", mpg_fmt("%Zd", n->mpg_i));
+ else
+#endif
print_func(fp, "%.17g\n", n->numbr);
- else
+ } else
print_func(fp, "?? flags %s\n", flags2str(n->flags));
}
@@ -4457,11 +4551,11 @@ mk_binary(INSTRUCTION *s1, INSTRUCTION *s2, INSTRUCTION *op)
ip1 = s1->nexti;
if (do_optimize > 1
&& ip1 == s1->lasti && ip1->opcode == Op_push_i
- && (ip1->memory->flags & (STRCUR|STRING)) == 0
- && (ip2->memory->flags & (STRCUR|STRING)) == 0
+ && (ip1->memory->flags & (MPFN|MPZN|STRCUR|STRING)) == 0
+ && (ip2->memory->flags & (MPFN|MPZN|STRCUR|STRING)) == 0
) {
NODE *n1 = ip1->memory, *n2 = ip2->memory;
- res = force_number(n1);
+ res = force_number(n1)->numbr;
(void) force_number(n2);
switch (op->opcode) {
case Op_times:
@@ -5044,7 +5138,7 @@ mk_getline(INSTRUCTION *op, INSTRUCTION *var, INSTRUCTION *redir, int redirtype)
else
ip = list_create(op);
op->into_var = (var != NULL);
- op->redir_type = (redir != NULL) ? redirtype : 0;
+ op->redir_type = (redir != NULL) ? redirtype : redirect_none;
return (asgn == NULL ? ip : list_append(ip, asgn));
}
@@ -5412,3 +5506,4 @@ one_line_close(int fd)
return ret;
}
+