diff --git a/src/gapstate.h b/src/gapstate.h index ce9f6bae13..6bf41bffb7 100644 --- a/src/gapstate.h +++ b/src/gapstate.h @@ -23,7 +23,7 @@ enum { MAX_OPEN_FILES = 16, - MAX_VALUE_LEN = 1030, + MAX_VALUE_LEN = 1024, }; typedef struct GAPState { diff --git a/src/intrprtr.c b/src/intrprtr.c index 1472e78339..a4739da02c 100644 --- a/src/intrprtr.c +++ b/src/intrprtr.c @@ -1730,13 +1730,13 @@ void IntrPow ( void ) ** 'IntrIntExpr' is the action to interpret a literal integer expression. ** is the integer as a (null terminated) C character string. */ -void IntrIntExpr(Char * str) +void IntrIntExpr(Obj string, Char * str) { /* ignore or code */ if ( STATE(IntrReturning) > 0 ) { return; } if ( STATE(IntrIgnoring) > 0 ) { return; } - Obj val = IntStringInternal(0, str); + Obj val = IntStringInternal(string, str); GAP_ASSERT(val != Fail); if (STATE(IntrCoding) > 0) { @@ -1749,30 +1749,6 @@ void IntrIntExpr(Char * str) } -/**************************************************************************** -** -*F IntrLongIntExpr() . . interpret literal long integer expression -** -** 'IntrLongIntExpr' is the action to interpret a long literal integer -** expression whose digits are stored in a string GAP object. -*/ -void IntrLongIntExpr(Obj string) -{ - if ( STATE(IntrReturning) > 0 ) { return; } - if ( STATE(IntrIgnoring) > 0 ) { return; } - - Obj val = IntStringInternal(string, 0); - GAP_ASSERT(val != Fail); - - if (STATE(IntrCoding) > 0) { - CodeIntExpr(val); - } - else { - // push the integer value - PushObj(val); - } -} - /**************************************************************************** ** *F IntrFloatExpr() . . . . . . . . interpret literal float expression @@ -1803,39 +1779,25 @@ static Obj ConvertFloatLiteralEager(Obj str) return res; } -void IntrFloatExpr ( - Char * str ) +void IntrFloatExpr(Obj string, Char * str) { - Obj val; - /* ignore or code */ if ( STATE(IntrReturning) > 0 ) { return; } if ( STATE(IntrIgnoring) > 0 ) { return; } - if ( STATE(IntrCoding) > 0 ) { CodeFloatExpr( str ); return; } - - val = MakeString(str); - PushObj(ConvertFloatLiteralEager(val)); -} - - -/**************************************************************************** -** -*F IntrLongFloatExpr() . . interpret literal long float expression -** -** 'IntrLongFloatExpr' is the action to interpret a long literal float -** expression whose digits are stored in a string GAP object. -*/ -void IntrLongFloatExpr ( - Obj string ) -{ - /* ignore or code */ - if ( STATE(IntrReturning) > 0 ) { return; } - if ( STATE(IntrIgnoring) > 0 ) { return; } - if ( STATE(IntrCoding) > 0 ) { CodeLongFloatExpr( string ); return; } + if ( STATE(IntrCoding) > 0 ) { + if (string) + CodeLongFloatExpr(string); + else + CodeFloatExpr( str ); + return; + } + if (string == 0) + string = MakeString(str); PushObj(ConvertFloatLiteralEager(string)); } + /**************************************************************************** ** *F IntrIntObjExpr() . . . . . . . 'interpret' a GAP small integer diff --git a/src/intrprtr.h b/src/intrprtr.h index fc910efb3d..dc7352d2e3 100644 --- a/src/intrprtr.h +++ b/src/intrprtr.h @@ -540,6 +540,13 @@ extern void IntrMod ( void ); extern void IntrPow ( void ); +/**************************************************************************** +** +*F IntrIntObjExpr() +*/ +extern void IntrIntObjExpr(Obj val); + + /**************************************************************************** ** *F IntrIntExpr() . . . . . . . . interpret literal integer expression @@ -547,12 +554,8 @@ extern void IntrPow ( void ); ** 'IntrIntExpr' is the action to interpret a literal integer expression. ** is the integer as a (null terminated) C character string. */ +extern void IntrIntExpr(Obj string, Char * str); -extern void IntrIntObjExpr(Obj val); -extern void IntrIntExpr ( - Char * str ); -extern void IntrLongIntExpr ( - Obj string ); /**************************************************************************** ** @@ -561,10 +564,8 @@ extern void IntrLongIntExpr ( ** 'IntrFloatExpr' is the action to interpret a literal float expression. ** is the float as a (null terminated) C character string. */ -extern void IntrFloatExpr ( - Char * str ); -extern void IntrLongFloatExpr ( - Obj string ); +extern void IntrFloatExpr(Obj string, Char * str); + /**************************************************************************** ** diff --git a/src/read.c b/src/read.c index 8ccbd66504..9335e245d4 100644 --- a/src/read.c +++ b/src/read.c @@ -924,194 +924,6 @@ static void ReadPerm ( TRY_READ { IntrPerm( nrc ); } } -/**************************************************************************** -** -*F ReadLongNumber( ) . . . . . . . . . . . . . . . read a long integer -** -** A `long integer' here means one whose digits don't fit into `STATE(Value)', -** see scanner.c. This function copies repeatedly digits from `STATE(Value)' -** into a GAP string until the full integer is read. -** -*/ - -static void appendToString(Obj string, const char * val) -{ - const UInt len = GET_LEN_STRING(string); - const UInt len1 = strlen(val); - - // ensure enough memory is allocated (GROW_STRING automatically - // reserves extra space for the terminating zero byte) - GROW_STRING(string, len + len1); - SET_LEN_STRING(string, len + len1); - - // copy the data, including the terminator byte - memcpy(CHARS_STRING(string) + len, val, len1 + 1); -} - -void ReadLongNumber( - TypSymbolSet follow ) -{ - Obj string; - UInt status; - UInt done; - - /* string in which to accumulate number */ - string = MakeString(STATE(Value)); - done = 0; - - while (!done) { - /* remember the current symbol and get the next one */ - status = STATE(Symbol); - Match(STATE(Symbol), "partial number", follow); - - /* Now there are just lots of cases */ - switch (status) { - case S_PARTIALINT: - switch (STATE(Symbol)) { - case S_INT: - appendToString(string, STATE(Value)); - Match(S_INT, "integer", follow); - TRY_READ { IntrLongIntExpr(string); } - done = 1; - break; - - case S_PARTIALINT: - appendToString(string, STATE(Value)); - /* Match(S_PARTIALINT, "integer", follow);*/ - break; - - case S_PARTIALFLOAT2: - case S_PARTIALFLOAT3: - case S_PARTIALFLOAT4: - status = STATE(Symbol); - appendToString(string, STATE(Value)); - /* Match(STATE(Symbol), "float", follow); */ - break; - - case S_FLOAT: - appendToString(string, STATE(Value)); - Match(S_FLOAT, "float", follow); - TRY_READ { IntrLongFloatExpr(string); } - done = 1; - break; - - case S_IDENT: - SyntaxError("Identifier over 1024 characters"); - - default: - appendToString(string, STATE(Value)); - TRY_READ { IntrLongIntExpr(string); } - done = 1; - } - break; - - case S_PARTIALFLOAT2: - switch (STATE(Symbol)) { - case S_INT: - case S_PARTIALINT: - assert(0); - Pr("Parsing error, this should never happen", 0L, 0L); - SyExit(2); - - - case S_PARTIALFLOAT2: - case S_PARTIALFLOAT3: - case S_PARTIALFLOAT4: - status = STATE(Symbol); - appendToString(string, STATE(Value)); - /* Match(STATE(Symbol), "float", follow); */ - break; - - case S_FLOAT: - appendToString(string, STATE(Value)); - Match(S_FLOAT, "float", follow); - TRY_READ { IntrLongFloatExpr(string); } - done = 1; - break; - - - case S_IDENT: - SyntaxError("Badly Formed Number"); - - default: - appendToString(string, STATE(Value)); - TRY_READ { IntrLongFloatExpr(string); } - done = 1; - } - break; - - case S_PARTIALFLOAT3: - switch (STATE(Symbol)) { - case S_INT: - case S_PARTIALINT: - case S_PARTIALFLOAT2: - case S_PARTIALFLOAT3: - assert(0); - Pr("Parsing error, this should never happen", 0L, 0L); - SyExit(2); - - - case S_PARTIALFLOAT4: - status = STATE(Symbol); - appendToString(string, STATE(Value)); - /* Match(STATE(Symbol), "float", follow); */ - break; - - case S_FLOAT: - appendToString(string, STATE(Value)); - Match(S_FLOAT, "float", follow); - TRY_READ { IntrLongFloatExpr(string); } - done = 1; - break; - - - default: - SyntaxError("Badly Formed Number"); - - } - break; - case S_PARTIALFLOAT4: - switch (STATE(Symbol)) { - case S_INT: - case S_PARTIALINT: - case S_PARTIALFLOAT2: - case S_PARTIALFLOAT3: - assert(0); - Pr("Parsing error, this should never happen", 0L, 0L); - SyExit(2); - - - case S_PARTIALFLOAT4: - status = STATE(Symbol); - appendToString(string, STATE(Value)); - /* Match(STATE(Symbol), "float", follow); */ - break; - - case S_FLOAT: - appendToString(string, STATE(Value)); - Match(S_FLOAT, "float", follow); - TRY_READ { IntrLongFloatExpr(string); } - done = 1; - break; - - case S_IDENT: - SyntaxError("Badly Formed Number"); - - default: - appendToString(string, STATE(Value)); - TRY_READ { IntrLongFloatExpr(string); } - done = 1; - - } - break; - default: - assert(0); - Pr("Parsing error, this should never happen", 0L, 0L); - SyExit(2); - } - } -} - /**************************************************************************** ** *F ReadListExpr( ) . . . . . . . . . . . . . . . . . . read a list @@ -1635,22 +1447,16 @@ static void ReadLiteral ( /* */ case S_INT: - TRY_READ { IntrIntExpr( STATE(Value) ); } + TRY_READ { IntrIntExpr(STATE(ValueObj), STATE(Value)); } Match( S_INT, "integer", follow ); break; /* */ case S_FLOAT: - TRY_READ { IntrFloatExpr( STATE(Value) ); } + TRY_READ { IntrFloatExpr(STATE(ValueObj), STATE(Value)); } Match( S_FLOAT, "float", follow ); break; - /* partial Int */ - case S_PARTIALINT: - case S_PARTIALFLOAT2: - ReadLongNumber( follow ); - break; - /* 'true' */ case S_TRUE: Match( S_TRUE, "true", follow ); @@ -1770,6 +1576,22 @@ static void ReadAtom ( ReadReferenceModifiers(follow); } +/**************************************************************************** +** +*F ReadSign( ) . . . . . . . . . . . . . . read a sign, or nothing +*/ +static Int ReadSign(TypSymbolSet follow) +{ + if (STATE(Symbol) == S_PLUS) { + Match(S_PLUS, "unary +", follow); + return +1; + } + if (STATE(Symbol) == S_MINUS) { + Match(S_MINUS, "unary -", follow); + return -1; + } + return 0; +} /**************************************************************************** ** @@ -1788,12 +1610,7 @@ static void ReadFactor ( volatile Int sign2; /* { '+'|'-' } leading sign */ - sign1 = 0; - if ( STATE(Symbol) == S_MINUS || STATE(Symbol) == S_PLUS ) { - if ( sign1 == 0 ) sign1 = 1; - if ( STATE(Symbol) == S_MINUS ) { sign1 = -sign1; } - Match( STATE(Symbol), "unary + or -", follow ); - } + sign1 = ReadSign(follow); /* */ ReadAtom( follow, (sign1 == 0 ? mode : 'r') ); @@ -1805,12 +1622,7 @@ static void ReadFactor ( Match( S_POW, "^", follow ); /* { '+'|'-' } leading sign */ - sign2 = 0; - if ( STATE(Symbol) == S_MINUS || STATE(Symbol) == S_PLUS ) { - if ( sign2 == 0 ) sign2 = 1; - if ( STATE(Symbol) == S_MINUS ) { sign2 = -sign2; } - Match( STATE(Symbol), "unary + or -", follow ); - } + sign2 = ReadSign(follow); /* ['^' ] */ ReadAtom( follow, 'r' ); diff --git a/src/records.c b/src/records.c index e6116598a3..e4861b8f61 100644 --- a/src/records.c +++ b/src/records.c @@ -96,9 +96,9 @@ UInt RNamName ( UInt i; /* loop variable */ UInt sizeRNam; - if (strlen(name) >= 1023) { + if (strlen(name) > 1023) { // Note: We can't pass 'name' here, as it might get moved by garbage collection - ErrorQuit("Record names must consist of less than 1023 characters", 0, 0); + ErrorQuit("Record names must consist of at most 1023 characters", 0, 0); return 0; } diff --git a/src/scanner.c b/src/scanner.c index f81f067a8f..219c89600f 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -256,8 +256,8 @@ static void GetIdent(Int i) } // terminate the identifier and lets assume that it is not a keyword - if (i >= SAFE_VALUE_SIZE-1) { - SyntaxError("Identifiers in GAP must consist of less than 1023 characters."); + if (i > SAFE_VALUE_SIZE-1) { + SyntaxError("Identifiers in GAP must consist of at most 1023 characters."); i = SAFE_VALUE_SIZE-1; } STATE(Value)[i] = '\0'; @@ -317,254 +317,242 @@ static void GetIdent(Int i) *F GetNumber() . . . . . . . . . . . . . . get an integer or float literal ** ** 'GetNumber' reads a number from the current input file into the variable -** 'STATE(Value)' and sets 'Symbol' to 'S_INT', 'S_PARTIALINT', 'S_FLOAT' or -** 'S_PARTIALFLOAT'. The first character of the number is the current -** character pointed to by 'In'. +** 'STATE(Value)' or 'STATE(ValueObj)' and sets 'STATE(Symbol)' to 'S_INT' or +** 'S_FLOAT'. The first character of the number is the current character +** pointed to by 'In'. ** ** If the sequence contains characters which do not match the regular ** expression [0-9]+.?[0-9]*([edqEDQ][+-]?[0-9]+)? 'GetNumber' will -** interpret the sequence as an identifier and set 'Symbol' to 'S_IDENT'. +** interpret the sequence as an identifier by delegating to 'GetIdent'. ** ** As we read, we keep track of whether we have seen a . or exponent -** notation and so whether we will return S_[PARTIAL]INT or -** S_[PARTIAL]FLOAT. +** notation and so whether we will return 'S_INT' or 'S_FLOAT'. ** -** When STATE(Value) is completely filled we have to check if the reading of -** the number is complete or not to decide whether to return a PARTIAL type. +** When 'STATE(Value)' is completely filled, then a GAP string object is +** created in 'STATE(ValueObj)' and all data is stored there. ** -** The argument reflects how far we are through reading a possibly very long -** number literal. 0 indicates that nothing has been read. 1 that at least -** one digit has been read, but no decimal point. 2 that a decimal point has -** been read with no digits before or after it. 3 a decimal point and at -** least one digit, but no exponential indicator 4 an exponential indicator -** but no exponent digits and 5 an exponential indicator and at least one -** exponent digit. +** The argument is used to signal if a decimal point was already read, +** or whether we are starting from scratch.. ** */ -static void GetNumber(const UInt StartingStatus) +static UInt AddCharToValue(UInt i, Char c) { - Int i=0; - Char c; - UInt seenADigit = (StartingStatus != 0 && StartingStatus != 2); + if (i >= SAFE_VALUE_SIZE - 1) { + STATE(ValueObj) = AppendBufToString(STATE(ValueObj), STATE(Value), i); + i = 0; + } + STATE(Value)[i++] = c; + return i; +} - if (StartingStatus == 2) { - STATE(Value)[i++] = '.'; - } +static void GetNumber(Int readDecimalPoint) +{ + UInt i = 0; + Char c; + UInt seenADigit = 0; + + STATE(ValueObj) = 0; c = PEEK_CURR_CHAR(); - if (StartingStatus < 2) { + if (readDecimalPoint) { + STATE(Value)[i++] = '.'; + } + else { // read initial sequence of digits into 'Value' - while (IsDigit(c) && i < SAFE_VALUE_SIZE-1) { - STATE(Value)[i++] = c; + while (IsDigit(c)) { + i = AddCharToValue(i, c); seenADigit = 1; c = GET_NEXT_CHAR(); } - /* So why did we run off the end of that loop */ - /* maybe we saw an identifier character and realised that this is an identifier we are reading */ + // maybe we saw an identifier character and realised that this is an + // identifier we are reading if (IsIdent(c) || c == '\\') { - // Now we know we have an identifier, read the rest of it + // if necessary, copy back from STATE(ValueObj) to STATE(Value) + if (STATE(ValueObj)) { + i = GET_LEN_STRING(STATE(ValueObj)); + GAP_ASSERT(i >= SAFE_VALUE_SIZE-1); + memcpy(STATE(Value), CSTR_STRING(STATE(ValueObj)), SAFE_VALUE_SIZE); + STATE(ValueObj) = 0; + } + // this looks like an identifier, scan the rest of it GetIdent(i); return; } - /* Or maybe we just ran out of space */ - if (IsDigit(c)) { - assert(i >= SAFE_VALUE_SIZE-1); - STATE(Symbol) = S_PARTIALINT; - STATE(Value)[SAFE_VALUE_SIZE-1] = '\0'; - return; - } - - /* Or maybe we saw a . which could indicate one of two things: - a float literal or .. */ + // Or maybe we saw a '.' which could indicate one of two things: a + // float literal or S_DOT, i.e., '.' used to access a record entry. if (c == '.') { - /* If the symbol before this integer was S_DOT then - we must be in a nested record element expression, so don't - look for a float. + GAP_ASSERT(i < SAFE_VALUE_SIZE - 1); - This is a bit fragile */ + // If the symbol before this integer was S_DOT then we must be in + // a nested record element expression, so don't look for a float. + // This is a bit fragile if (STATE(Symbol) == S_DOT || STATE(Symbol) == S_BDOT) { - STATE(Value)[i] = '\0'; STATE(Symbol) = S_INT; - return; + goto finish; } - - /* peek ahead to decide which */ + + // peek ahead to decide which if (PEEK_NEXT_CHAR() == '.') { - /* It was .. */ + // It was '.', so this looks like '..' and we are probably + // inside a range expression. STATE(Symbol) = S_INT; - STATE(Value)[i] = '\0'; - return; + goto finish; } - /* Now the . must be part of our number - store it and move on */ - STATE(Value)[i++] = '.'; + // Now the '.' must be part of our number; store it and move on + i = AddCharToValue(i, '.'); c = GET_NEXT_CHAR(); } else { - /* Anything else we see tells us that the token is done */ - STATE(Value)[i] = '\0'; + // Anything else we see tells us that the token is done STATE(Symbol) = S_INT; - return; + goto finish; } } + // When we get here we have read possibly some digits, a . and possibly + // some more digits, but not an e,E,d,D,q or Q - /* The only case in which we fall through to here is when - we have read zero or more digits, followed by . which is not part of a .. token - or we were called with StartingStatus >= 2 so we read at least that much in - a previous token */ - - - if (StartingStatus< 4) { - /* When we get here we have read (either in this token or a previous S_PARTIALFLOAT*) - possibly some digits, a . and possibly some more digits, but not an e,E,d,D,q or Q */ - - /* read digits */ - while (IsDigit(c) && i < SAFE_VALUE_SIZE-1) { - STATE(Value)[i++] = c; + // read digits + while (IsDigit(c)) { + i = AddCharToValue(i, c); seenADigit = 1; c = GET_NEXT_CHAR(); } if (!seenADigit) - SyntaxError("Badly formed number: need a digit before or after the decimal point"); + SyntaxError("Badly formed number: need a digit before or after the " + "decimal point"); if (c == '\\') - SyntaxError("Badly Formed Number"); - /* If we found an identifier type character in this context could be an error - or the start of one of the allowed trailing marker sequences */ - if (IsIdent(c) && c != 'e' && c != 'E' && c != 'd' && c != 'D' && c != 'q' && c != 'Q') { - - // Allow one letter on the end of the numbers -- could be an i, C99 style - if (IsAlpha(c)) { - STATE(Value)[i++] = c; - c = GET_NEXT_CHAR(); - } - /* independently of that, we allow an _ signalling immediate conversion */ - if (c == '_') { - STATE(Value)[i++] = c; - c = GET_NEXT_CHAR(); - /* After which there may be one character signifying the conversion style */ - if (IsAlpha(c)) { - STATE(Value)[i++] = c; - c = GET_NEXT_CHAR(); - } - } - /* Now if the next character is alphanumerical, or an identifier type symbol then we - really do have an error, otherwise we return a result */ - if (IsIdent(c) || IsDigit(c)) { - SyntaxError("Badly formed number"); - } - else { - STATE(Value)[i] = '\0'; - STATE(Symbol) = S_FLOAT; - return; - } - } + SyntaxError("Badly formed number"); - /* If the next thing is the start of the exponential notation, - read it now -- we have left enough space at the end of the buffer even if we - left the previous loop because of overflow */ - UInt seenExp = 0; - if (IsAlpha(c)) { - if (!seenADigit) - SyntaxError("Badly formed number: need a digit before or after the decimal point"); - seenExp = 1; - STATE(Value)[i++] = c; + // If we found an identifier type character in this context could be an + // error or the start of one of the allowed trailing marker sequences + if (IsIdent(c) && c != 'e' && c != 'E' && c != 'd' && c != 'D' && + c != 'q' && c != 'Q') { + + // Allow one letter on the end of the numbers -- could be an i, C99 + // style + if (IsAlpha(c)) { + i = AddCharToValue(i, c); c = GET_NEXT_CHAR(); - if (c == '+' || c == '-') { - STATE(Value)[i++] = c; - c = GET_NEXT_CHAR(); + } + // independently of that, we allow an _ signalling immediate conversion + if (c == '_') { + i = AddCharToValue(i, c); + c = GET_NEXT_CHAR(); + // After which there may be one character signifying the + // conversion style + if (IsAlpha(c)) { + i = AddCharToValue(i, c); + c = GET_NEXT_CHAR(); } + } + // Now if the next character is alphanumerical, or an identifier type + // symbol then we really do have an error, otherwise we return a result + if (IsIdent(c) || IsDigit(c)) { + SyntaxError("Badly formed number"); + } + else { + STATE(Symbol) = S_FLOAT; + goto finish; + } } - /* Now deal with full buffer case */ - if (i >= SAFE_VALUE_SIZE -1) { - STATE(Symbol) = seenExp ? S_PARTIALFLOAT3 : S_PARTIALFLOAT2; - STATE(Value)[i] = '\0'; - return; + // If the next thing is the start of the exponential notation, read it now. + UInt seenExp = 0; + if (IsAlpha(c)) { + if (!seenADigit) + SyntaxError("Badly formed number: need a digit before or after " + "the decimal point"); + seenExp = 1; + i = AddCharToValue(i, c); + c = GET_NEXT_CHAR(); + if (c == '+' || c == '-') { + i = AddCharToValue(i, c); + c = GET_NEXT_CHAR(); + } } - /* Either we saw an exponent indicator, or we hit end of token - deal with the end of token case */ + // Either we saw an exponent indicator, or we hit end of token deal with + // the end of token case if (!seenExp) { if (!seenADigit) - SyntaxError("Badly formed number: need a digit before or after the decimal point"); - /* Might be a conversion marker */ - if (IsAlpha(c) && c != 'e' && c != 'E' && c != 'd' && c != 'D' && c != 'q' && c != 'Q') { - STATE(Value)[i++] = c; - c = GET_NEXT_CHAR(); - } - /* independently of that, we allow an _ signalling immediate conversion */ - if (c == '_') { - STATE(Value)[i++] = c; - c = GET_NEXT_CHAR(); - /* After which there may be one character signifying the conversion style */ - if (IsAlpha(c)) - STATE(Value)[i++] = c; - c = GET_NEXT_CHAR(); - } - /* Now if the next character is alphanumerical, or an identifier type symbol then we - really do have an error, otherwise we return a result */ - if (!IsIdent(c) && !IsDigit(c)) { - STATE(Value)[i] = '\0'; - STATE(Symbol) = S_FLOAT; - return; - } - SyntaxError("Badly Formed Number"); + SyntaxError("Badly formed number: need a digit before or after " + "the decimal point"); + // Might be a conversion marker + if (IsAlpha(c) && c != 'e' && c != 'E' && c != 'd' && c != 'D' && + c != 'q' && c != 'Q') { + i = AddCharToValue(i, c); + c = GET_NEXT_CHAR(); + } + // independently of that, we allow an _ signalling immediate conversion + if (c == '_') { + i = AddCharToValue(i, c); + c = GET_NEXT_CHAR(); + // After which there may be one character signifying the + // conversion style + if (IsAlpha(c)) + i = AddCharToValue(i, c); + c = GET_NEXT_CHAR(); + } + // Now if the next character is alphanumerical, or an identifier type + // symbol then we really do have an error, otherwise we return a result + if (!IsIdent(c) && !IsDigit(c)) { + STATE(Symbol) = S_FLOAT; + goto finish; + } + SyntaxError("Badly formed number"); } - } - - /* Here we are into the unsigned exponent of a number - in scientific notation, so we just read digits */ - UInt seenExpDigit = (StartingStatus == 5); + // Here we are into the unsigned exponent of a number in scientific + // notation, so we just read digits + UInt seenExpDigit = 0; - while (IsDigit(c) && i < SAFE_VALUE_SIZE-1) { - STATE(Value)[i++] = c; + while (IsDigit(c)) { + i = AddCharToValue(i, c); seenExpDigit = 1; c = GET_NEXT_CHAR(); } - /* Look out for a single alphabetic character on the end - which could be a conversion marker */ + // Look out for a single alphabetic character on the end + // which could be a conversion marker if (seenExpDigit) { if (IsAlpha(c)) { - STATE(Value)[i] = c; + i = AddCharToValue(i, c); c = GET_NEXT_CHAR(); - STATE(Value)[i+1] = '\0'; STATE(Symbol) = S_FLOAT; - return; + goto finish; } if (c == '_') { - STATE(Value)[i++] = c; + i = AddCharToValue(i, c); c = GET_NEXT_CHAR(); - /* After which there may be one character signifying the conversion style */ + // After which there may be one character signifying the + // conversion style if (IsAlpha(c)) { - STATE(Value)[i++] = c; + i = AddCharToValue(i, c); c = GET_NEXT_CHAR(); } - STATE(Value)[i] = '\0'; STATE(Symbol) = S_FLOAT; - return; + goto finish; } } - /* If we ran off the end */ - if (i >= SAFE_VALUE_SIZE -1) { - STATE(Symbol) = seenExpDigit ? S_PARTIALFLOAT4 : S_PARTIALFLOAT3; - STATE(Value)[i] = '\0'; - return; - } - - /* Otherwise this is the end of the token */ + // Otherwise this is the end of the token if (!seenExpDigit) - SyntaxError("Badly Formed Number: need at least one digit in the exponent"); + SyntaxError( + "Badly formed number: need at least one digit in the exponent"); STATE(Symbol) = S_FLOAT; - STATE(Value)[i] = '\0'; + +finish: + i = AddCharToValue(i, '\0'); + if (STATE(ValueObj)) { + // flush buffer + AppendBufToString(STATE(ValueObj), STATE(Value), i - 1); + } } @@ -575,7 +563,7 @@ static void GetNumber(const UInt StartingStatus) */ void ScanForFloatAfterDotHACK(void) { - GetNumber(2); + GetNumber(1); } @@ -919,15 +907,6 @@ static void GetHelp(void) */ static void NextSymbol(void) { - /* special case if reading of a long token is not finished */ - switch (STATE(Symbol)) { - case S_PARTIALINT: GetNumber(STATE(Value)[0] == '\0' ? 0 : 1); return; - case S_PARTIALFLOAT2: GetNumber(3); return; - case S_PARTIALFLOAT3: GetNumber(4); return; - case S_PARTIALFLOAT4: GetNumber(5); return; - } - - Char c = PEEK_CURR_CHAR(); // if no character is available then get one diff --git a/src/scanner.h b/src/scanner.h index f193336043..951e5c90c3 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -55,20 +55,8 @@ enum SCANNER_SYMBOLS { S_READONLY = (1UL<< 9)+4, S_DOTDOTDOT = (1UL<< 9)+5, - S_PARTIALINT = (1UL<<10)+0, // Some digits - S_INT = (1UL<<10)+1, - S_FLOAT = (1UL<<10)+2, - - // Some digits and a decimal point - S_PARTIALFLOAT2 = (1UL<<10)+4, - - // Some digits and a decimal point and an exponent indicator and maybe a - // sign, but no digits - S_PARTIALFLOAT3 = (1UL<<10)+5, - - // Some digits and a decimal point and an exponent indicator and maybe a - // sign, and at least one digit - S_PARTIALFLOAT4 = (1UL<<10)+6, + S_INT = (1UL<<10)+0, + S_FLOAT = (1UL<<10)+1, S_TRUE = (1UL<<11)+0, S_FALSE = (1UL<<11)+1, diff --git a/tst/testinstall/kernel/read.tst b/tst/testinstall/kernel/read.tst index c8ed95b953..1f3e254e33 100644 --- a/tst/testinstall/kernel/read.tst +++ b/tst/testinstall/kernel/read.tst @@ -118,15 +118,15 @@ Syntax error: ; expected in stream:2 # errors in the middle of parsing a float literal gap> 12.34\56; -Syntax error: Badly Formed Number in stream:1 +Syntax error: Badly formed number in stream:1 12.34\56; ^ gap> 12.34\a56; -Syntax error: Badly Formed Number in stream:1 +Syntax error: Badly formed number in stream:1 12.34\a56; ^ gap> 12.34\56a; -Syntax error: Badly Formed Number in stream:1 +Syntax error: Badly formed number in stream:1 12.34\56a; ^ diff --git a/tst/testinstall/kernel/scanner.tst b/tst/testinstall/kernel/scanner.tst new file mode 100644 index 0000000000..8c37a96d9b --- /dev/null +++ b/tst/testinstall/kernel/scanner.tst @@ -0,0 +1,123 @@ +# +# Tests for functions defined in src/scanner.c +# +gap> START_TEST("kernel/scanner.tst"); + +# +# test long gvar names: at most 1023 chars are supported +# +gap> x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 := 1; +1 +gap> x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 := 1; +1 +gap> x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 := 1; +Syntax error: Identifiers in GAP must consist of at most 1023 characters. in s\ +tream:1 +x11111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +1111111111 := 1; + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + ^ + +# also test the case where the truncation to 1023 chars ia a number +gap> 1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111x := 1; +1 +gap> 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111x := 1; +1 +gap> 111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111x := 1; +Syntax error: Identifiers in GAP must consist of at most 1023 characters. in s\ +tream:1 +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111x := 1; + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + ^ + +# +# test long record names: at most 1023 chars are supported +# +gap> a:=rec();; +gap> a.x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 := 1; +1 +gap> a.x11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 := 1; +1 +gap> a.x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 := 1; +Syntax error: Identifiers in GAP must consist of at most 1023 characters. in s\ +tream:1 +a.x111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111111111111111111111111111111111111111111111111111111111111111111111\ +111111111111 := 1; + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + ^ + +# +gap> STOP_TEST("kernel/scanner.tst", 1); diff --git a/tst/testinstall/longnumber.tst b/tst/testinstall/longnumber.tst index 1849d49239..41d918b0dd 100644 --- a/tst/testinstall/longnumber.tst +++ b/tst/testinstall/longnumber.tst @@ -182,12 +182,12 @@ int in stream:1 gap> .0n; Error, failed to convert float literal gap> .0q; -Syntax error: Badly Formed Number: need at least one digit in the exponent in \ +Syntax error: Badly formed number: need at least one digit in the exponent in \ stream:1 .0q; ^ gap> .0qn; -Syntax error: Badly Formed Number: need at least one digit in the exponent in \ +Syntax error: Badly formed number: need at least one digit in the exponent in \ stream:1 .0qn; ^ diff --git a/tst/testinstall/recordname.tst b/tst/testinstall/recordname.tst index 0896aedf20..c51569c13f 100644 --- a/tst/testinstall/recordname.tst +++ b/tst/testinstall/recordname.tst @@ -33,11 +33,11 @@ gap> r.(str1022a) := 2; gap> r.(str1022b) := 3; 3 gap> r.(str1023) := 4; -Error, Record names must consist of less than 1023 characters +4 gap> r.(str1024) := 5; -Error, Record names must consist of less than 1023 characters +Error, Record names must consist of at most 1023 characters gap> names := RecNames(r);; -gap> SortedList(names) = [str1021, str1022a, str1022b, "x", "y"]; +gap> SortedList(names) = [str1021, str1022a, str1023, str1022b, "x", "y"]; true gap> RecNames( () ); Error, no method found! For debugging hints type ?Recovery from NoMethodFound @@ -62,14 +62,11 @@ gap> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 2 gap> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ > aaaxy := 1; # 1023 chars -Syntax error: Identifiers in GAP must consist of less than 1023 characters. in\ - stream:2 -aaaxy := 1; # 1023 chars - ^ +1 gap> aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\ > aaaxyz := 1; # 1024 chars -Syntax error: Identifiers in GAP must consist of less than 1023 characters. in\ - stream:2 +Syntax error: Identifiers in GAP must consist of at most 1023 characters. in s\ +tream:2 aaaxyz := 1; # 1024 chars ^ gap> STOP_TEST( "recordname.tst", 1);