vlog95: Print double values correctly and clean up string emitting.
This patch adds code to make sure a double (Verilog real) constant is printed correctly. It also adds code to trim any leading escaped NULLs from an expression string.
This commit is contained in:
parent
085a5c8d02
commit
087f4794af
|
|
@ -558,7 +558,7 @@ void emit_expr(ivl_scope_t scope, ivl_expr_t expr, unsigned wid)
|
|||
emit_expr_signal(scope, expr, wid);
|
||||
break;
|
||||
case IVL_EX_STRING:
|
||||
fprintf(vlog_out, "\"%s\"", ivl_expr_string(expr));
|
||||
emit_string(ivl_expr_string(expr));
|
||||
break;
|
||||
case IVL_EX_TERNARY:
|
||||
emit_expr_ternary(scope, expr, wid);
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include "config.h"
|
||||
# include "vlog95_priv.h"
|
||||
|
||||
|
|
@ -175,11 +177,34 @@ void emit_real_number(double value)
|
|||
else fprintf(vlog_out, "(-1.0/0.0)");
|
||||
return;
|
||||
}
|
||||
// HERE: This needs to be reworked. We must have a trailing digit after the
|
||||
// decimal point and we want to print all the significant digits.
|
||||
// I think this will require our own printing routine.
|
||||
if (value == 0.0) fprintf(vlog_out, "0.0");
|
||||
else fprintf(vlog_out, "%#.16g", value);
|
||||
if (value == 0.0) {
|
||||
if (1.0/value < 0.0) fprintf(vlog_out, "-0.0");
|
||||
else fprintf(vlog_out, "0.0");
|
||||
} else {
|
||||
char buffer[32];
|
||||
char *cptr;
|
||||
unsigned len;
|
||||
/* Print the double to a temporary string using an extra digit. */
|
||||
buffer[sizeof(buffer)-1] = 0;
|
||||
snprintf(buffer, sizeof(buffer), "%#.17g", value);
|
||||
assert(buffer[sizeof(buffer)-1] == 0);
|
||||
/* Check to see if there is a digit after the decimal point and
|
||||
* add a digit if it is missing. */
|
||||
len = strlen(buffer);
|
||||
if (buffer[len-1] == '.') {
|
||||
assert((len + 1) < sizeof(buffer));
|
||||
buffer[len] = '0';
|
||||
len += 1;
|
||||
buffer[len] = 0;
|
||||
}
|
||||
/* Now trim any extra trailing zero digits. */
|
||||
cptr = buffer + len - 1;
|
||||
while ((*cptr == '0') && (*(cptr-1) != '.')) cptr -= 1;
|
||||
*(cptr+1) = 0;
|
||||
|
||||
/* Now print the processed output. */
|
||||
fprintf(vlog_out, "%s", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -289,3 +314,20 @@ int32_t get_int32_from_number(ivl_expr_t expr, int *result_type)
|
|||
return get_int32_from_bits(ivl_expr_bits(expr), ivl_expr_width(expr),
|
||||
ivl_expr_signed(expr), result_type);
|
||||
}
|
||||
|
||||
/*
|
||||
* Routine to print a string value as a string after removing any leading
|
||||
* escaped NULL bytes.
|
||||
*/
|
||||
void emit_string(const char* string)
|
||||
{
|
||||
char *buffer = strdup(string);
|
||||
char *cptr = buffer;
|
||||
fprintf(vlog_out, "\"");
|
||||
/* Prune any leading escaped NULL bytes. */
|
||||
while ((cptr[0] == '\\') && (cptr[1] == '0') &&
|
||||
(cptr[2] == '0') && (cptr[3] == '0')) cptr += 4;
|
||||
if (*cptr) fprintf(vlog_out, "%s", cptr);
|
||||
free(buffer);
|
||||
fprintf(vlog_out, "\"");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ extern void emit_id(const char *id);
|
|||
extern void emit_real_number(double value);
|
||||
extern void emit_number(const char *bits, unsigned nbits, unsigned is_signed,
|
||||
const char *file, unsigned lineno);
|
||||
extern void emit_string(const char *string);
|
||||
|
||||
/*
|
||||
* Find the enclosing module scope.
|
||||
|
|
|
|||
Loading…
Reference in New Issue