Support 64-bit integer constants in parser. Partial fix to issue #21.
This commit is contained in:
59
lex.ll
59
lex.ll
@@ -39,8 +39,9 @@
|
|||||||
#include "sym.h"
|
#include "sym.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
static uint32_t lParseBinary(const char *ptr, SourcePos pos);
|
static uint64_t lParseBinary(const char *ptr, SourcePos pos);
|
||||||
static void lCComment(SourcePos *);
|
static void lCComment(SourcePos *);
|
||||||
static void lCppComment(SourcePos *);
|
static void lCppComment(SourcePos *);
|
||||||
static void lHandleCppHash(SourcePos *);
|
static void lHandleCppHash(SourcePos *);
|
||||||
@@ -136,51 +137,54 @@ L?\"(\\.|[^\\"])*\" { lStringConst(yylval, yylloc); return TOKEN_STRING_LITERAL;
|
|||||||
|
|
||||||
{INT_NUMBER} {
|
{INT_NUMBER} {
|
||||||
char *endPtr = NULL;
|
char *endPtr = NULL;
|
||||||
#ifdef ISPC_IS_WINDOWS
|
int64_t val;
|
||||||
unsigned long val;
|
|
||||||
#else
|
|
||||||
unsigned long long val;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (yytext[0] == '0' && yytext[1] == 'b')
|
if (yytext[0] == '0' && yytext[1] == 'b')
|
||||||
val = lParseBinary(yytext+2, *yylloc);
|
val = lParseBinary(yytext+2, *yylloc);
|
||||||
else {
|
else {
|
||||||
#ifdef ISPC_IS_WINDOWS
|
#ifdef ISPC_IS_WINDOWS
|
||||||
val = strtoul(yytext, &endPtr, 0);
|
val = _strtoi64(yytext, &endPtr, 0);
|
||||||
#else
|
#else
|
||||||
|
// FIXME: should use strtouq and then issue an error if we can't
|
||||||
|
// fit into 64 bits...
|
||||||
val = strtoull(yytext, &endPtr, 0);
|
val = strtoull(yytext, &endPtr, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
yylval->int32Val = (int32_t)val;
|
|
||||||
if (val != (unsigned int)yylval->int32Val)
|
// See if we can fit this into a 32-bit integer...
|
||||||
Warning(*yylloc, "32-bit integer has insufficient bits to represent value %s (%x %llx)",
|
if ((val & 0xffffffff) == val) {
|
||||||
yytext, yylval->int32Val, (unsigned long long)val);
|
yylval->int32Val = (int32_t)val;
|
||||||
return TOKEN_INT_CONSTANT;
|
return TOKEN_INT32_CONSTANT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
yylval->int64Val = val;
|
||||||
|
return TOKEN_INT64_CONSTANT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{INT_NUMBER}[uU] {
|
{INT_NUMBER}[uU] {
|
||||||
char *endPtr = NULL;
|
char *endPtr = NULL;
|
||||||
#ifdef ISPC_IS_WINDOWS
|
uint64_t val;
|
||||||
unsigned long val;
|
|
||||||
#else
|
|
||||||
unsigned long long val;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (yytext[0] == '0' && yytext[1] == 'b')
|
if (yytext[0] == '0' && yytext[1] == 'b')
|
||||||
val = lParseBinary(yytext+2, *yylloc);
|
val = lParseBinary(yytext+2, *yylloc);
|
||||||
else {
|
else {
|
||||||
#ifdef ISPC_IS_WINDOWS
|
#ifdef ISPC_IS_WINDOWS
|
||||||
val = strtoul(yytext, &endPtr, 0);
|
val = _strtoui64(yytext, &endPtr, 0);
|
||||||
#else
|
#else
|
||||||
val = strtoull(yytext, &endPtr, 0);
|
val = strtoull(yytext, &endPtr, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
yylval->int32Val = (int32_t)val;
|
if ((val & 0xffffffff) == val) {
|
||||||
if (val != (unsigned int)yylval->int32Val)
|
// we can represent it in a 32-bit value
|
||||||
Warning(*yylloc, "32-bit integer has insufficient bits to represent value %s (%x %llx)",
|
yylval->int32Val = (int32_t)val;
|
||||||
yytext, yylval->int32Val, (unsigned long long)val);
|
return TOKEN_UINT32_CONSTANT;
|
||||||
return TOKEN_UINT_CONSTANT;
|
}
|
||||||
|
else {
|
||||||
|
yylval->int64Val = val;
|
||||||
|
return TOKEN_UINT64_CONSTANT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{FLOAT_NUMBER} {
|
{FLOAT_NUMBER} {
|
||||||
@@ -268,19 +272,18 @@ L?\"(\\.|[^\\"])*\" { lStringConst(yylval, yylloc); return TOKEN_STRING_LITERAL;
|
|||||||
|
|
||||||
/** Return the integer version of a binary constant from a string.
|
/** Return the integer version of a binary constant from a string.
|
||||||
*/
|
*/
|
||||||
static uint32_t
|
static uint64_t
|
||||||
lParseBinary(const char *ptr, SourcePos pos) {
|
lParseBinary(const char *ptr, SourcePos pos) {
|
||||||
uint32_t val = 0;
|
uint64_t val = 0;
|
||||||
bool warned = false;
|
bool warned = false;
|
||||||
|
|
||||||
while (*ptr != '\0') {
|
while (*ptr != '\0') {
|
||||||
/* if this hits, the regexp for 0b... constants is broken */
|
/* if this hits, the regexp for 0b... constants is broken */
|
||||||
assert(*ptr == '0' || *ptr == '1');
|
assert(*ptr == '0' || *ptr == '1');
|
||||||
|
|
||||||
if ((val & (1<<31)) && warned == false) {
|
if ((val & (((int64_t)1)<<63)) && warned == false) {
|
||||||
// We're about to shift out a set bit
|
// We're about to shift out a set bit
|
||||||
// FIXME: 64-bit int constants...
|
Warning(pos, "Can't represent binary constant with a 64-bit integer type");
|
||||||
Warning(pos, "Can't represent binary constant with 32-bit integer type");
|
|
||||||
warned = true;
|
warned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
22
parse.yy
22
parse.yy
@@ -129,17 +129,16 @@ static const char *lParamListTokens[] = {
|
|||||||
StructDeclaration *structDeclaration;
|
StructDeclaration *structDeclaration;
|
||||||
std::vector<StructDeclaration *> *structDeclarationList;
|
std::vector<StructDeclaration *> *structDeclarationList;
|
||||||
int32_t int32Val;
|
int32_t int32Val;
|
||||||
uint32_t uint32Val;
|
|
||||||
double floatVal;
|
double floatVal;
|
||||||
int64_t int64Val;
|
int64_t int64Val;
|
||||||
uint64_t uint64Val;
|
|
||||||
std::string *stringVal;
|
std::string *stringVal;
|
||||||
const char *constCharPtr;
|
const char *constCharPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
%token TOKEN_IDENTIFIER TOKEN_INT_CONSTANT TOKEN_UINT_CONSTANT TOKEN_FLOAT_CONSTANT
|
%token TOKEN_INT32_CONSTANT TOKEN_UINT32_CONSTANT TOKEN_INT64_CONSTANT
|
||||||
%token TOKEN_STRING_LITERAL TOKEN_TYPE_NAME
|
%token TOKEN_UINT64_CONSTANT TOKEN_FLOAT_CONSTANT
|
||||||
|
%token TOKEN_IDENTIFIER TOKEN_STRING_LITERAL TOKEN_TYPE_NAME
|
||||||
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
|
%token TOKEN_PTR_OP TOKEN_INC_OP TOKEN_DEC_OP TOKEN_LEFT_OP TOKEN_RIGHT_OP
|
||||||
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
|
%token TOKEN_LE_OP TOKEN_GE_OP TOKEN_EQ_OP TOKEN_NE_OP
|
||||||
%token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN
|
%token TOKEN_AND_OP TOKEN_OR_OP TOKEN_MUL_ASSIGN TOKEN_DIV_ASSIGN TOKEN_MOD_ASSIGN
|
||||||
@@ -220,12 +219,17 @@ primary_expression
|
|||||||
Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
|
Error(@1, "Undeclared symbol \"%s\".%s", name, alts.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| TOKEN_INT_CONSTANT {
|
| TOKEN_INT32_CONSTANT {
|
||||||
/* FIXME: should support 64 bit constants (and doubles...) */
|
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstInt32, yylval.int32Val, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstInt32, yylval.int32Val, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_UINT_CONSTANT {
|
| TOKEN_UINT32_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstUInt32, yylval.uint32Val, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstUInt32, (uint32_t)yylval.int32Val, @1);
|
||||||
|
}
|
||||||
|
| TOKEN_INT64_CONSTANT {
|
||||||
|
$$ = new ConstExpr(AtomicType::UniformConstInt64, yylval.int64Val, @1);
|
||||||
|
}
|
||||||
|
| TOKEN_UINT64_CONSTANT {
|
||||||
|
$$ = new ConstExpr(AtomicType::UniformConstUInt64, (uint64_t)yylval.int64Val, @1);
|
||||||
}
|
}
|
||||||
| TOKEN_FLOAT_CONSTANT {
|
| TOKEN_FLOAT_CONSTANT {
|
||||||
$$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1);
|
$$ = new ConstExpr(AtomicType::UniformConstFloat, (float)yylval.floatVal, @1);
|
||||||
@@ -740,7 +744,7 @@ declarator
|
|||||||
;
|
;
|
||||||
|
|
||||||
int_constant
|
int_constant
|
||||||
: TOKEN_INT_CONSTANT { $$ = yylval.int32Val; }
|
: TOKEN_INT32_CONSTANT { $$ = yylval.int32Val; }
|
||||||
;
|
;
|
||||||
|
|
||||||
direct_declarator
|
direct_declarator
|
||||||
|
|||||||
Reference in New Issue
Block a user