fix a bug of neg number

Update compiler.h
This commit is contained in:
blueloveTH 2022-11-09 16:05:03 +08:00
parent 299370a225
commit f8df138b94
4 changed files with 25 additions and 38 deletions

View File

@ -1,13 +0,0 @@
import os
import re
with open("src/opcodes.h", "rt", encoding='utf-8') as f:
text = f.read()
# opcodes = re.findall(r"OP_(\w+)", text)
# print('\n'.join([f"OPCODE({o})" + o for o in opcodes]))
text = re.sub(r"OP_(\w+)", lambda m: f"OPCODE({m.group(1)})", text)
print(text.replace(',', ''))

View File

@ -154,29 +154,26 @@ public:
} }
void eatNumber() { void eatNumber() {
char c = *(parser->token_start); static const std::regex pattern("^[+-]?([0-9]+)(\\.[0-9]+)?");
bool is_float = false; std::smatch m;
while (isdigit(parser->peekChar())) parser->eatChar();
if (parser->peekChar() == '.' && isdigit(parser->peekNextChar())) { const char* i = parser->token_start;
parser->matchChar('.'); while(*i != '\n' && *i != '\0') i++;
is_float = true; std::string s = std::string(parser->token_start, i);
while (isdigit(parser->peekChar())) parser->eatChar();
}
errno = 0; try{
PyVar value = vm->None; if (std::regex_search(s, m, pattern)) {
if(is_float){ // here is m.length()-1, since the first char is eaten by lexToken()
value = vm->PyFloat(atof(parser->token_start)); for(int j=0; j<m.length()-1; j++) parser->eatChar();
if (m[2].matched) {
parser->setNextToken(TK("@num"), vm->PyFloat(std::stof(m[0])));
} else { } else {
value = vm->PyInt(atoi(parser->token_start)); parser->setNextToken(TK("@num"), vm->PyInt(std::stoi(m[0])));
} }
if (errno == ERANGE) {
const char* start = parser->token_start;
int len = (int)(parser->current_char - start);
throw SyntaxError(path, parser->makeErrToken(), "number literal too large: %.*s", len, start);
} }
parser->setNextToken(TK("@num"), value); }catch(std::exception& e){
throw SyntaxError(path, parser->makeErrToken(), "invalid number (%s)", e.what());
}
} }
// Lex the next token and set it as the next token. // Lex the next token and set it as the next token.
@ -206,7 +203,11 @@ public:
case '>': parser->setNextTwoCharToken('=', TK(">"), TK(">=")); return; case '>': parser->setNextTwoCharToken('=', TK(">"), TK(">=")); return;
case '<': parser->setNextTwoCharToken('=', TK("<"), TK("<=")); return; case '<': parser->setNextTwoCharToken('=', TK("<"), TK("<=")); return;
case '+': parser->setNextTwoCharToken('=', TK("+"), TK("+=")); return; case '+': parser->setNextTwoCharToken('=', TK("+"), TK("+=")); return;
case '-': parser->setNextTwoCharToken('=', TK("-"), TK("-=")); return; case '-': {
if(isdigit(parser->peekChar())) eatNumber();
else parser->setNextTwoCharToken('=', TK("-"), TK("-="));
return;
}
case '!': case '!':
if(parser->matchChar('=')) parser->setNextToken(TK("!=")); if(parser->matchChar('=')) parser->setNextToken(TK("!="));
else SyntaxError(path, parser->makeErrToken(), "expected '=' after '!'"); else SyntaxError(path, parser->makeErrToken(), "expected '=' after '!'");
@ -308,9 +309,9 @@ public:
} }
void exprFString() { void exprFString() {
static const std::regex pattern(R"(\{(.*?)\})");
PyVar value = parser->previous.value; PyVar value = parser->previous.value;
std::string s = vm->PyStr_AS_C(value).str(); std::string s = vm->PyStr_AS_C(value).str();
std::regex pattern(R"(\{(.*?)\})");
std::sregex_iterator begin(s.begin(), s.end(), pattern); std::sregex_iterator begin(s.begin(), s.end(), pattern);
std::sregex_iterator end; std::sregex_iterator end;
int size = 0; int size = 0;

View File

@ -238,7 +238,6 @@ struct Parser {
this->line_start = source; this->line_start = source;
this->nexts.push(Token{TK("@sof"), token_start, 0, current_line}); this->nexts.push(Token{TK("@sof"), token_start, 0, current_line});
this->indents.push(0); this->indents.push(0);
} }
}; };

View File

@ -165,7 +165,7 @@ public:
callstack.push(frame); callstack.push(frame);
while(!frame->isEnd()){ while(!frame->isEnd()){
const ByteCode& byte = frame->readCode(); const ByteCode& byte = frame->readCode();
//printf("%s (%d) stack_size: %d\n", OP_NAMES[byte.op], byte.arg, frame->stackSize()); printf("%s (%d) stack_size: %d\n", OP_NAMES[byte.op], byte.arg, frame->stackSize());
switch (byte.op) switch (byte.op)
{ {