add hex support

This commit is contained in:
blueloveTH 2022-11-13 18:48:30 +08:00
parent dcc899a884
commit 80c8c837c4

View File

@ -140,24 +140,33 @@ public:
} }
void eatNumber() { void eatNumber() {
static const std::regex pattern("^([0-9]+)(\\.[0-9]+)?"); static const std::regex pattern("^(0x)?[0-9a-f]+(\\.[0-9]+)?");
std::smatch m; std::smatch m;
const char* i = parser->token_start; const char* i = parser->token_start;
while(*i != '\n' && *i != '\0') i++; while(*i != '\n' && *i != '\0') i++;
std::string s = std::string(parser->token_start, i); std::string s = std::string(parser->token_start, i);
size_t* size = new size_t;
try{ try{
if (std::regex_search(s, m, pattern)) { if (std::regex_search(s, m, pattern)) {
// here is m.length()-1, since the first char is eaten by lexToken() // here is m.length()-1, since the first char is eaten by lexToken()
for(int j=0; j<m.length()-1; j++) parser->eatChar(); for(int j=0; j<m.length()-1; j++) parser->eatChar();
int base = 10;
if (m[1].matched) base = 16;
if (m[2].matched) { if (m[2].matched) {
parser->setNextToken(TK("@num"), vm->PyFloat(std::stod(m[0]))); if(base == 16) syntaxError("hex literal should not contain a dot");
parser->setNextToken(TK("@num"), vm->PyFloat(std::stod(m[0], size)));
} else { } else {
parser->setNextToken(TK("@num"), vm->PyInt(std::stoll(m[0]))); parser->setNextToken(TK("@num"), vm->PyInt(std::stoll(m[0], size, base)));
} }
if (*size != m.length()) throw std::runtime_error("length mismatch");
delete size;
} }
}catch(std::exception& e){ }catch(std::exception& e){
delete size;
syntaxError("invalid number literal"); syntaxError("invalid number literal");
} }
} }