|
|
@@ -284,9 +284,15 @@ static bool is_unicode_Lo_char(uint32_t c) {
|
|
|
}
|
|
|
// try integer
|
|
|
i64 int_out;
|
|
|
- if(parse_int(text, &int_out, -1)){
|
|
|
- add_token(TK("@num"), int_out);
|
|
|
- return;
|
|
|
+ switch(parse_int(text, &int_out, -1)){
|
|
|
+ case IntParsingResult::Success:
|
|
|
+ add_token(TK("@num"), int_out);
|
|
|
+ return;
|
|
|
+ case IntParsingResult::Overflow:
|
|
|
+ SyntaxError("integer literal too large");
|
|
|
+ return;
|
|
|
+ case IntParsingResult::Failure:
|
|
|
+ break; // do nothing
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -476,7 +482,7 @@ static bool is_unicode_Lo_char(uint32_t c) {
|
|
|
return std::move(nexts);
|
|
|
}
|
|
|
|
|
|
-bool parse_int(std::string_view text, i64* out, int base){
|
|
|
+IntParsingResult parse_int(std::string_view text, i64* out, int base){
|
|
|
*out = 0;
|
|
|
|
|
|
const auto f_startswith_2 = [](std::string_view t, const char* prefix) -> bool{
|
|
|
@@ -493,63 +499,63 @@ bool parse_int(std::string_view text, i64* out, int base){
|
|
|
|
|
|
if(base == 10){
|
|
|
// 10-base 12334
|
|
|
- if(text.length() == 0) return false;
|
|
|
+ if(text.length() == 0) return IntParsingResult::Failure;
|
|
|
for(char c : text){
|
|
|
if(c >= '0' && c <= '9'){
|
|
|
*out = (*out * 10) + (c - '0');
|
|
|
- if(*out < 0) return false; // overflow
|
|
|
+ if(*out < 0) return IntParsingResult::Overflow;
|
|
|
}else{
|
|
|
- return false;
|
|
|
+ return IntParsingResult::Failure;
|
|
|
}
|
|
|
}
|
|
|
- return true;
|
|
|
+ return IntParsingResult::Success;
|
|
|
}else if(base == 2){
|
|
|
// 2-base 0b101010
|
|
|
if(f_startswith_2(text, "0b")) text.remove_prefix(2);
|
|
|
- if(text.length() == 0) return false;
|
|
|
+ if(text.length() == 0) return IntParsingResult::Failure;
|
|
|
for(char c : text){
|
|
|
if(c == '0' || c == '1'){
|
|
|
*out = (*out << 1) | (c - '0');
|
|
|
- if(*out < 0) return false; // overflow
|
|
|
+ if(*out < 0) return IntParsingResult::Overflow;
|
|
|
}else{
|
|
|
- return false;
|
|
|
+ return IntParsingResult::Failure;
|
|
|
}
|
|
|
}
|
|
|
- return true;
|
|
|
+ return IntParsingResult::Success;
|
|
|
}else if(base == 8){
|
|
|
// 8-base 0o123
|
|
|
if(f_startswith_2(text, "0o")) text.remove_prefix(2);
|
|
|
- if(text.length() == 0) return false;
|
|
|
+ if(text.length() == 0) return IntParsingResult::Failure;
|
|
|
for(char c : text){
|
|
|
if(c >= '0' && c <= '7'){
|
|
|
*out = (*out << 3) | (c - '0');
|
|
|
- if(*out < 0) return false; // overflow
|
|
|
+ if(*out < 0) return IntParsingResult::Overflow;
|
|
|
}else{
|
|
|
- return false;
|
|
|
+ return IntParsingResult::Failure;
|
|
|
}
|
|
|
}
|
|
|
- return true;
|
|
|
+ return IntParsingResult::Success;
|
|
|
}else if(base == 16){
|
|
|
// 16-base 0x123
|
|
|
if(f_startswith_2(text, "0x")) text.remove_prefix(2);
|
|
|
- if(text.length() == 0) return false;
|
|
|
+ if(text.length() == 0) return IntParsingResult::Failure;
|
|
|
for(char c : text){
|
|
|
if(c >= '0' && c <= '9'){
|
|
|
*out = (*out << 4) | (c - '0');
|
|
|
- if(*out < 0) return false; // overflow
|
|
|
+ if(*out < 0) return IntParsingResult::Overflow;
|
|
|
}else if(c >= 'a' && c <= 'f'){
|
|
|
*out = (*out << 4) | (c - 'a' + 10);
|
|
|
- if(*out < 0) return false; // overflow
|
|
|
+ if(*out < 0) return IntParsingResult::Overflow;
|
|
|
}else if(c >= 'A' && c <= 'F'){
|
|
|
*out = (*out << 4) | (c - 'A' + 10);
|
|
|
- if(*out < 0) return false; // overflow
|
|
|
+ if(*out < 0) return IntParsingResult::Overflow;
|
|
|
}else{
|
|
|
- return false;
|
|
|
+ return IntParsingResult::Failure;
|
|
|
}
|
|
|
}
|
|
|
- return true;
|
|
|
+ return IntParsingResult::Success;
|
|
|
}
|
|
|
- return false;
|
|
|
+ return IntParsingResult::Failure;
|
|
|
}
|
|
|
|
|
|
} // namespace pkpy
|