diff --git a/scripts/get_opcodes.py b/scripts/get_opcodes.py deleted file mode 100644 index bc407f19..00000000 --- a/scripts/get_opcodes.py +++ /dev/null @@ -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(',', '')) \ No newline at end of file diff --git a/src/compiler.h b/src/compiler.h index 8d57d153..a482270d 100644 --- a/src/compiler.h +++ b/src/compiler.h @@ -154,29 +154,26 @@ public: } void eatNumber() { - char c = *(parser->token_start); - bool is_float = false; - while (isdigit(parser->peekChar())) parser->eatChar(); - - if (parser->peekChar() == '.' && isdigit(parser->peekNextChar())) { - parser->matchChar('.'); - is_float = true; - while (isdigit(parser->peekChar())) parser->eatChar(); - } + static const std::regex pattern("^[+-]?([0-9]+)(\\.[0-9]+)?"); + std::smatch m; - errno = 0; - PyVar value = vm->None; - if(is_float){ - value = vm->PyFloat(atof(parser->token_start)); - } else { - value = vm->PyInt(atoi(parser->token_start)); + const char* i = parser->token_start; + while(*i != '\n' && *i != '\0') i++; + std::string s = std::string(parser->token_start, i); + + try{ + if (std::regex_search(s, m, pattern)) { + // here is m.length()-1, since the first char is eaten by lexToken() + for(int j=0; jeatChar(); + if (m[2].matched) { + parser->setNextToken(TK("@num"), vm->PyFloat(std::stof(m[0]))); + } else { + parser->setNextToken(TK("@num"), vm->PyInt(std::stoi(m[0]))); + } + } + }catch(std::exception& e){ + throw SyntaxError(path, parser->makeErrToken(), "invalid number (%s)", e.what()); } - 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); } // 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 '-': { + if(isdigit(parser->peekChar())) eatNumber(); + else parser->setNextTwoCharToken('=', TK("-"), TK("-=")); + return; + } case '!': if(parser->matchChar('=')) parser->setNextToken(TK("!=")); else SyntaxError(path, parser->makeErrToken(), "expected '=' after '!'"); @@ -308,9 +309,9 @@ public: } void exprFString() { + static const std::regex pattern(R"(\{(.*?)\})"); PyVar value = parser->previous.value; 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 end; int size = 0; diff --git a/src/parser.h b/src/parser.h index 857e345d..b6344441 100644 --- a/src/parser.h +++ b/src/parser.h @@ -238,7 +238,6 @@ struct Parser { this->line_start = source; this->nexts.push(Token{TK("@sof"), token_start, 0, current_line}); - this->indents.push(0); } }; \ No newline at end of file diff --git a/src/vm.h b/src/vm.h index 02905ea5..59630126 100644 --- a/src/vm.h +++ b/src/vm.h @@ -165,7 +165,7 @@ public: callstack.push(frame); while(!frame->isEnd()){ 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) {