mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
fix error pos
This commit is contained in:
parent
21a0314b1a
commit
94bda0c947
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
10
src/parser.h
10
src/parser.h
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
94
tests/basic.py
Normal 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")
|
@ -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
|
|
Loading…
x
Reference in New Issue
Block a user