This commit is contained in:
blueloveTH 2022-11-19 21:17:46 +08:00
parent 5057e333cd
commit 43f99dde5d
23 changed files with 132 additions and 193 deletions

View File

@ -31,4 +31,12 @@ jobs:
target_branch: gh-pages
build_dir: web
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build_test_linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Compiling
run: |
bash build_cpp.sh
python3 scripts/run_tests.py

View File

@ -30,7 +30,7 @@ It will generate `pocketpy.h` and `main.cpp` in `amalgamated/` directory. You ca
**If you want to do development:**
```bash
g++ -o pocketpy src/main.cpp --std=c++17 -O1
g++ -o pocketpy src/main.cpp --std=c++17 -O1 -pthread
```
## Flutter Plugin

View File

@ -1,23 +1,23 @@
import os
singletypepath = 'tests/singletype'
mixedtypepath = 'tests/mixedtype'
def test_file(filepath):
return os.system("./pocketpy " + filepath) == 0
#return os.system("python3 " + filepath) == 0
def test_dir(path):
print("=" * 50)
has_error = False
for filename in os.listdir(path):
if filename.endswith('.py'):
filepath = os.path.join(path, filename)
code = test_file(filepath)
if not code:
print("[x] " + filepath)
has_error = True
else:
print("[√] " + filepath)
return not has_error
if __name__ == '__main__':
test_dir(singletypepath)
test_dir(mixedtypepath)
ok = test_dir('./tests')
if not ok:
exit(1)

View File

@ -42,6 +42,23 @@ def __list4extend(self, other):
list.extend = __list4extend
del __list4extend
def __list4remove(self, value):
for i in range(len(self)):
if self[i] == value:
del self[i]
return True
return False
list.remove = __list4remove
del __list4remove
def __list4index(self, value):
for i in range(len(self)):
if self[i] == value:
return i
return -1
list.index = __list4index
del __list4index
def __list4__mul__(self, n):
a = []
for i in range(n):
@ -61,6 +78,16 @@ list.__eq__ = __iterable4__eq__
tuple.__eq__ = __iterable4__eq__
del __iterable4__eq__
def __iterable4count(self, x):
res = 0
for i in self:
if i == x:
res += 1
return res
list.count = __iterable4count
tuple.count = __iterable4count
del __iterable4count
def __iterable4__contains__(self, item):
for i in self:
if i == item:
@ -135,6 +162,14 @@ class dict:
def items(self):
return [kv for kv in self._a if kv is not None]
def clear(self):
self._a = [None] * self._capacity
self._len = 0
def update(self, other):
for k, v in other.items():
self[k] = v
def copy(self):
d = dict()
for kv in self._a:
@ -181,6 +216,18 @@ def map(f, iterable):
def zip(a, b):
return [(a[i], b[i]) for i in range(min(len(a), len(b)))]
def sorted(iterable, key=None, reverse=False):
if key is None:
key = lambda x: x
a = [key(i) for i in iterable]
b = list(iterable)
for i in range(len(a)):
for j in range(i+1, len(a)):
if (a[i] > a[j]) ^ reverse:
a[i], a[j] = a[j], a[i]
b[i], b[j] = b[j], b[i]
return b
)";
const char* __RANDOM_CODE = R"(

View File

@ -833,7 +833,11 @@ __LISTCOMP:
{
case 0: func->args.push_back(name); break;
case 1: func->starredArg = name; state+=1; break;
case 2: consume(TK("=")); func->kwArgs[name] = consumeLiteral(); break;
case 2:
consume(TK("="));
func->kwArgs[name] = consumeLiteral();
func->kwArgsOrder.push_back(name);
break;
case 3: syntaxError("**kwargs is not supported yet"); break;
}
} while (match(TK(",")));

View File

@ -2,7 +2,7 @@
#include "pocketpy.h"
#define PK_DEBUG_TIME
//#define PK_DEBUG_TIME
struct Timer{
const char* title;

View File

@ -10,7 +10,7 @@ const _Int _Int_MAX_NEG = -9223372036854775807LL;
const _Float _FLOAT_INF_POS = INFINITY;
const _Float _FLOAT_INF_NEG = -INFINITY;
#define PK_VERSION "0.2.6"
#define PK_VERSION "0.2.9"
class CodeObject;
class BasePointer;
@ -27,6 +27,7 @@ struct Function {
std::vector<_Str> args;
_Str starredArg; // empty if no *arg
PyVarDict kwArgs; // empty if no k=v
std::vector<_Str> kwArgsOrder;
bool hasName(const _Str& val) const {
bool _0 = std::find(args.begin(), args.end(), val) != args.end();

View File

@ -424,7 +424,9 @@ void __initializeBuiltinFunctions(VM* _vm) {
vm->__checkArgSize(args, 3, true);
PyVarList& _self = vm->PyList_AS_C(args[0]);
int _index = vm->PyInt_AS_C(args[1]);
_index = vm->normalizedIndex(_index, _self.size());
if(_index < 0) _index += _self.size();
if(_index < 0) _index = 0;
if(_index > _self.size()) _index = _self.size();
_self.insert(_self.begin() + _index, args[2]);
return vm->None;
});
@ -534,6 +536,12 @@ void __initializeBuiltinFunctions(VM* _vm) {
_vm->bindMethod("bool", "__eq__", [](VM* vm, PyVarList args) {
return vm->PyBool(args[0] == args[1]);
});
_vm->bindMethod("bool", "__xor__", [](VM* vm, PyVarList args) {
bool _self = vm->PyBool_AS_C(args[0]);
bool _obj = vm->PyBool_AS_C(args[1]);
return vm->PyBool(_self ^ _obj);
});
}
#include "builtins.h"

View File

@ -439,11 +439,11 @@ public:
locals[fn->starredArg] = PyTuple(vargs);
}
// handle keyword arguments
for(const auto& [name, value] : fn->kwArgs){
for(const _Str& name : fn->kwArgsOrder){
if(i < args.size()) {
locals[name] = args[i++];
}else{
locals[name] = value;
locals[name] = fn->kwArgs[name];
}
}

View File

@ -1,15 +0,0 @@
def test(n):
k = 0
for x in range(n):
if x<2:
continue
flag = True
for i in range(2,x):
if x%i == 0:
flag = False
break
if flag:
k += 1
return k
print(test(10000))

View File

@ -1,7 +0,0 @@
for i in range(100):
for j in range(100):
print(i, j)
goto .end
label .end
print("END")

View File

@ -1,9 +0,0 @@
for i in range(10):
for j in range(10):
goto .test
print(2)
label .test
print(i)
# 15, 23
# 5, 28

View File

@ -1,16 +0,0 @@
[
1,2,3
]
import ink
print('Once upon a time...')
index, val = ink.choice(
'There were two choices.',
'There were four lines of content.'
)
print(f'You selected {index}')
print('They lived happily ever after.')

View File

@ -89,6 +89,4 @@ 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")
assert [1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3]

View File

@ -67,7 +67,7 @@ assert l[-1:-3] == []
assert l[-3:-1] == [2,3]
l1 = [1];l2 = l1;l1 += [2];l3 = [1,1,2]
l1 = [1];l2 = l1;l1.append(2);l3 = [1,1,2]
assert l2[1] == 2
assert l1 == l2
assert l1*3 == [1,2,1,2,1,2]
@ -104,19 +104,20 @@ l.insert(0, 'h')
l.insert(3, 'o')
l.insert(1, 'e')
assert l == ['h', 'e', 'l', 'l', 'o']
assert l.pop(-2) == 'l'
assert l[-2] == 'l'
##############################################
##tuple
##############################################
# tup = ('Google', 'Runoob', 'Taobao', 'Wiki', 'Weibo','Weixin')
# assert tup[1] == 'Runoob';assert tup[-2] == 'Weibo'
# assert tup[1:] == ('Runoob', 'Taobao', 'Wiki', 'Weibo', 'Weixin')
# assert tup[2:4] == ('Taobao', 'Wiki')
# assert len(tup) == 6
tup = ('Google', 'Runoob', 'Taobao', 'Wiki', 'Weibo','Weixin')
a,b = 1,2
assert a == 1
assert b == 2
a,b = b,a
assert a == 2
assert b == 1
assert len(tup) == 6
##############################################
##dict
@ -134,19 +135,21 @@ assert len(tinydict) == 0
dict1 = {'user':'circle','num':[1,2,3]}
dict2 = dict1.copy()
assert dict2 == {'user':'circle','num':[1,2,3]}
dict1['user'] = 'root'
assert dict1 == {'user': 'root', 'num': [1, 2, 3]};assert dict2 == {'user':'circle','num':[1,2,3]}
for k,v in dict1.items():
assert dict2[k] == v
tinydict = {'Name': 'circle', 'Age': 7}
tinydict2 = {'Sex': 'female' }
tinydict.update(tinydict2)
assert tinydict == {'Name': 'circle', 'Age': 7, 'Sex': 'female'}
updated_dict = {'Name': 'circle', 'Age': 7, 'Sex': 'female'}
for k,v in tinydict.items():
assert updated_dict[k] == v
dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
keys = dishes.keys()
values = dishes.values()
assert list(keys) == ['eggs', 'sausage', 'bacon', 'spam'];assert list(values) == [2, 1, 1, 500]
assert sorted(keys) == sorted(['eggs', 'sausage', 'bacon', 'spam'])
assert sorted(values) == sorted([2, 1, 1, 500])
d={1:"a",2:"b",3:"c"}
result=[]
@ -156,3 +159,7 @@ for kv in d.items():
result.append(v)
assert result == [1, 'a', 2, 'b', 3, 'c']
a = [1,2,3,-1]
assert sorted(a) == [-1,1,2,3]
assert sorted(a, lambda x:-x) == [3,2,1,-1]
assert sorted(a, None, True) == [3,2,1,-1]

19
tests/goto.py Normal file
View File

@ -0,0 +1,19 @@
a = []
for i in range(10):
for j in range(10):
goto .test
print(2)
label .test
a.append(i)
assert a == list(range(10))
b = False
for i in range(10):
for j in range(10):
goto .out
b = True
label .out
assert not b

8
tests/listcomp.py Normal file
View File

@ -0,0 +1,8 @@
a = [i for i in range(10)]
assert a == list(range(10))
a = [i for i in range(10) if i % 2 == 0]
assert a == [0, 2, 4, 6, 8]
a = [i**3 for i in range(10) if i % 2 == 0]
assert a == [0, 8, 64, 216, 512]

View File

@ -1,39 +0,0 @@
def compare(a,b):
d = a-b
if d > -0.0001 and d < 0.0001:
return 1
return 0
assert compare(32 + 32.0,64) == 1
assert compare(8855 / 3.2,2767.1875) == 1
#assert 6412//6.5 == 986.0 #TypeError: unsupported operand type(s) for //
assert compare(1054.5*7985,8420182.5) == 1
#assert 4 % 2.0 == 0.0 #TypeError: unsupported operand type(s) for %
l = [3.2,5,10,8.9]
assert 2.3 + l[0] == 5.5
assert 3 + l[1] == 8
assert compare(3/l[2],0.3) == 1
assert 3 // l[1] == 0
assert l[2] % 3 == 1
assert compare(3*l[3],26.7) == 1
assert 'a' * l[1] == 'aaaaa'
assert compare(2.9**2,8.41) == 1
assert compare(2.5**(-1),0.4) == 1
assert 2.5 > 2
assert 1.6 < 100
assert 1.0 == 1
x = 2.6
y = 5
l = [5.4,8,'40',3.14]
assert x <= y
assert y >= x
assert x != y
assert y < l[0]
str = ['s','bb']
s = 'jack' + str[0]
assert s == 'jacks'
assert str[1] * 3 == 'bbbbbb'

View File

@ -13,4 +13,4 @@ def test(n):
k += 1
return k
print(test(10000))
assert test(100) == 25

View File

@ -1,75 +0,0 @@
def compare(a,b):
d = a-b
if d > -0.0001 and d < 0.0001:
return 1
return 0
s = 'foo'; s += 'bar'
assert s == 'foobar'
assert 1 + 2 * 3 == 7
assert (1 + 2)* 3 == 9
assert compare(1.2*3.5 , 4.2) == 1
assert compare(9.8*(2.5 - 3),-4.9) == 1
assert compare(2.4*8.6,20.64) == 1
assert compare(1.5 + 3,4.5) == 1
assert compare(1.5 + 3.9,5.4) == 1
assert 2 - 1 == 1
assert compare(5.3 - 2.5,2.8) == 1
assert 42 % 40 == 2
assert -15 % 6 == -3 # in python -15 % 6 == 3
assert 2/1 == 2
assert 3//2 == 1
assert 1 - 9 == -8
a = 1
assert -a == -1
assert 'testing'== 'test' + 'ing'
x = 42
assert x%3 == 0
x = 27
assert x%8 == 3
assert 2**3 == 8
assert -2**2 == 4
assert (-2)**2 == 4
assert compare(0.2**2,0.04) == 1
x = 4
assert x**4 == 256
assert compare(x**0.5,2) == 1
assert compare(4**(-1.0),0.25) == 1
assert 'abc' * 3 == 'abcabcabc'
assert '' * 1000 == ''
assert 'foo' * 0 == ''
assert 1 < 2
assert 3 > 1
x = 1
y = 8
assert x <= y
assert y >= x
assert x != y
assert 42 in [12, 42, 3.14]
assert 'key' in {'key':'value'}
assert 'a' in 'abc'
assert 'd' not in 'abc'
x = 1
y = 0
assert not x == False
assert not y == True
a = 1
b = 1
c = 0.1
assert (a==b) and (a is not b) # small int cache
assert a is not c