fix error pos

This commit is contained in:
blueloveTH 2022-11-09 21:47:52 +08:00
parent 21a0314b1a
commit 94bda0c947
7 changed files with 114 additions and 26 deletions

View File

@ -118,7 +118,7 @@ public:
_Str errorSnapshot(){ _Str errorSnapshot(){
int line = -1; int line = -1;
if(!isEnd()) line = code->co_code[ip].line; if(!isEnd()) line = code->co_code[ip-1].line;
return code->src->snapshot(line); return code->src->snapshot(line);
} }

View File

@ -120,9 +120,9 @@ public:
_Str eatStringUntil(char quote) { _Str eatStringUntil(char quote) {
std::vector<char> buff; std::vector<char> buff;
while (true) { while (true) {
char c = parser->eatChar(); char c = parser->eatCharIncludeNewLine();
if (c == quote) break; if (c == quote) break;
if (c == '\0') syntaxError("EOL while scanning string literal"); if (c == '\0' || c == '\n') syntaxError("EOL while scanning string literal");
if (c == '\\') { if (c == '\\') {
switch (parser->eatCharIncludeNewLine()) { switch (parser->eatCharIncludeNewLine()) {
case '"': buff.push_back('"'); break; case '"': buff.push_back('"'); break;
@ -177,7 +177,8 @@ public:
void lexToken() { void lexToken() {
parser->previous = parser->current; parser->previous = parser->current;
parser->current = parser->nextToken(); parser->current = parser->nextToken();
//printf("<%s> ", TK_STR(peek()));
//_Str _info = parser->current.info(); printf("%s\n", (const char*)_info);
while (parser->peekChar() != '\0') { while (parser->peekChar() != '\0') {
parser->token_start = parser->current_char; parser->token_start = parser->current_char;
@ -871,7 +872,8 @@ __LITERAL_EXIT:
/***** Error Reporter *****/ /***** Error Reporter *****/
_Str getLineSnapshot(){ _Str getLineSnapshot(){
int lineno = parser->previous.line; int lineno = parser->current_line;
if(parser->peekChar() == '\n') lineno--;
return parser->src->snapshot(lineno); return parser->src->snapshot(lineno);
} }

View File

@ -33,13 +33,16 @@ VM* newVM(){
std::cout << str; std::cout << str;
std::cout.flush(); std::cout.flush();
}); });
registerModule(vm, "math", "pi = 3.141593");
return vm; return vm;
} }
void REPL(){ void REPL(){
std::cout << "pocketpy 0.1.0" << std::endl; std::cout << "pocketpy 0.1.0" << std::endl;
std::cout << "https://github.com/blueloveTH/pocketpy" << std::endl; std::cout << "https://github.com/blueloveTH/pocketpy" << std::endl;
#ifdef PK_DEBUG
std::cout << "[ DEBUG MODE ENABLED ]" << std::endl;
#endif
int need_more_lines = 0; int need_more_lines = 0;

View File

@ -61,6 +61,14 @@ struct Token{
const _Str str() const { const _Str str() const {
return _Str(start, length); return _Str(start, length);
} }
const _Str info() const {
_StrStream ss;
_Str raw = str();
if (raw == _Str("\n")) raw = "\\n";
ss << line << ": " << TK_STR(type) << " '" << raw << "'";
return ss.str();
}
}; };
enum Precedence { enum Precedence {
@ -146,7 +154,7 @@ struct Parser {
char eatChar() { char eatChar() {
char c = peekChar(); char c = peekChar();
if(c == '\n') throw std::runtime_error("eatChar() cannot consume a newline"); if(c == '\n') throw UnexpectedError("eatChar() cannot consume a newline");
current_char++; current_char++;
return c; return c;
} }

View File

@ -404,18 +404,6 @@ void __runCodeBuiltins(VM* vm, const char* src){
vm->exec(code, {}, vm->builtins); vm->exec(code, {}, vm->builtins);
} }
#include <cstdlib>
void __addModuleRandom(VM* vm){
srand(time(NULL));
PyVar random = vm->newModule("random");
vm->bindFunc(random, "randint", [](VM* vm, PyVarList args) {
int _min = vm->PyInt_AS_C(args[0]);
int _max = vm->PyInt_AS_C(args[1]);
return vm->PyInt(rand() % (_max - _min + 1) + _min);
});
vm->_modules["random"] = random;
}
#include "builtins.h" #include "builtins.h"
#ifdef _WIN32 #ifdef _WIN32
@ -432,7 +420,6 @@ extern "C" {
VM* vm = new VM(); VM* vm = new VM();
__initializeBuiltinFunctions(vm); __initializeBuiltinFunctions(vm);
__runCodeBuiltins(vm, __BUILTINS_CODE); __runCodeBuiltins(vm, __BUILTINS_CODE);
__addModuleRandom(vm);
vm->_stdout = _stdout; vm->_stdout = _stdout;
return vm; return vm;
} }

94
tests/basic.py Normal file
View File

@ -0,0 +1,94 @@
# generate assert test for int
# test == != >= <= < >
# generate 2 cases for each operator
assert -1 == -1
assert -1 != 1
assert -1 >= -1
assert -1 <= -1
assert -1 < 1
assert -1 > -2
# test + - * % ** //
assert -1 + 1 == 0
assert -1 - 1 == -2
assert 4 * -1 == -4
assert 5 % 2 == 1
assert 2 ** 3 == 8
assert 4 // 2 == 2
assert 5 // 2 == 2
# test += -= *= //=
x = 3
x += 1
assert x == 4
x -= 1
assert x == 3
x *= 2
assert x == 6
x //= 2
assert x == 3
# generate assert test for float
def eq(a, b):
dt = a - b
return dt > -0.001 and dt < 0.001
# test + - * / **
assert eq(1.5 + 3, 4.5)
assert eq(1.5 + 3.9, 5.4)
assert eq(5.3 - 2.5, 2.8)
assert eq(0.2**2, 0.04)
assert eq(4**(-1.0), 0.25)
assert eq(2/1, 2)
assert eq(3/2.0, 1.5)
assert eq(1/9, 0.11111)
# test += -= *= /=
x = 3.0
x += 1
assert eq(x, 4.0)
x -= 1
assert eq(x, 3.0)
x *= 2
assert eq(x, 6.0)
x /= 1.8
assert eq(x, 3.3333)
# generate assert test for bool
assert True == True
assert True != False
assert False == False
assert False != True
# test and/or/not
assert True and True
assert not (True and False)
assert True or True
assert True or False
assert not False
assert not (not True)
# generate assert test for str
assert 'testing' == 'test' + 'ing'
assert 'testing' != 'test' + 'ing2'
assert 'testing' < 'test' + 'ing2'
assert 'testing5' > 'test' + 'ing1'
# test + *=
assert 'abc' + 'def' == 'abcdef'
assert 'abc' * 3 == 'abcabcabc'
# generate assert test for list
assert [1, 2, 3] == [1, 2, 3]
assert [1, 2, 3] != [1, 2, 4]
# test + *=
assert [1, 2, 3] + [4, 5, 6] == [1, 2, 3, 4, 5, 6]
assert [1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3]
print("ALL TESTS PASSED")

View File

@ -1,6 +0,0 @@
class Complex:
def __init__(self, realpart, imagpart):
self.r = realpart
self.i = imagpart
x = Complex(3.0, -4.5)
assert x.r == 3.0