static void AddObjSetNew(Obj set, Obj obj) { UInt size = CONST_ADDR_WORD(set)[OBJSET_SIZE]; UInt hash = ObjHash(set, obj); GAP_ASSERT(TNUM_OBJ(set) == T_OBJSET); GAP_ASSERT(hash < size); for (;;) { Obj current; current = CONST_ADDR_OBJ(set)[OBJSET_HDRSIZE+hash]; if (!current) { ADDR_OBJ(set)[OBJSET_HDRSIZE+hash] = obj; ADDR_WORD(set)[OBJSET_USED]++; CHANGED_BAG(set); return; } if (current == Undefined) { ADDR_OBJ(set)[OBJSET_HDRSIZE+hash] = obj; ADDR_WORD(set)[OBJSET_USED]++; GAP_ASSERT(ADDR_WORD(set)[OBJSET_DIRTY] >= 1); ADDR_WORD(set)[OBJSET_DIRTY]--; CHANGED_BAG(set); return; } hash++; if (hash >= size) hash = 0; } }
Int FindObjSet(Obj set, Obj obj) { UInt size = CONST_ADDR_WORD(set)[OBJSET_SIZE]; UInt hash = ObjHash(set, obj); GAP_ASSERT(hash < size); for (;;) { Obj current; current = CONST_ADDR_OBJ(set)[OBJSET_HDRSIZE+hash]; if (!current) return -1; if (current == obj) return (Int) hash; hash++; if (hash >= size) hash = 0; } }
static UInt GetNumber(Int readDecimalPoint) { UInt symbol = S_ILLEGAL; UInt i = 0; Char c; UInt seenADigit = 0; UInt seenExp = 0; UInt seenExpDigit = 0; STATE(ValueObj) = 0; c = PEEK_CURR_CHAR(); if (readDecimalPoint) { STATE(Value)[i++] = '.'; } else { // read initial sequence of digits into 'Value' while (IsDigit(c)) { i = AddCharToValue(i, c); seenADigit = 1; c = GET_NEXT_CHAR(); } // maybe we saw an identifier character and realised that this is an // identifier we are reading if (IsIdent(c) || c == '\\') { // if necessary, copy back from STATE(ValueObj) to STATE(Value) if (STATE(ValueObj)) { i = GET_LEN_STRING(STATE(ValueObj)); GAP_ASSERT(i >= MAX_VALUE_LEN - 1); memcpy(STATE(Value), CONST_CSTR_STRING(STATE(ValueObj)), MAX_VALUE_LEN); STATE(ValueObj) = 0; } // this looks like an identifier, scan the rest of it return GetIdent(i); } // 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 == '.') { GAP_ASSERT(i < MAX_VALUE_LEN - 1); // 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) { symbol = S_INT; goto finish; } // peek ahead to decide which if (PEEK_NEXT_CHAR() == '.') { // It was '.', so this looks like '..' and we are probably // inside a range expression. symbol = S_INT; goto finish; } // 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 symbol = S_INT; 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 // 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"); 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)) { 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)) { SyntaxError("Badly formed number"); } else { symbol = S_FLOAT; goto finish; } } // If the next thing is the start of the exponential notation, read it now. 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 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') { 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)) { 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 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 if (seenExpDigit) { if (IsAlpha(c)) { i = AddCharToValue(i, c); c = GET_NEXT_CHAR(); symbol = S_FLOAT; goto finish; } 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(); } symbol = S_FLOAT; goto finish; } } // Otherwise this is the end of the token if (!seenExpDigit) SyntaxError( "Badly formed number: need at least one digit in the exponent"); symbol = S_FLOAT; finish: i = AddCharToValue(i, '\0'); if (STATE(ValueObj)) { // flush buffer AppendBufToString(STATE(ValueObj), STATE(Value), i - 1); } return symbol; }