mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
up
This commit is contained in:
parent
8bc04389c8
commit
26b065c1fb
@ -8,4 +8,11 @@ The initial version. Hello, world!
|
||||
+ Support hex integer literal `0xFFFF`
|
||||
+ Fix some bugs
|
||||
+ Add `list.pop` and `reversed` builtin function
|
||||
+ Optimize `dict` performance
|
||||
+ Optimize `dict` performance
|
||||
|
||||
## 0.4.8+2
|
||||
|
||||
+ Fix a bug of `bool`
|
||||
+ Support type hints
|
||||
+ Fix a bug about comment and indentation
|
||||
+ Fix a bug about compile error line number
|
@ -1,6 +1,6 @@
|
||||
name: pocketpy
|
||||
description: A lightweight Python interpreter for game engines.
|
||||
version: 0.4.8+1
|
||||
version: 0.4.8+2
|
||||
homepage: https://pocketpy.dev
|
||||
repository: https://github.com/blueloveth/pocketpy
|
||||
|
||||
|
@ -3255,7 +3255,7 @@ struct Parser {
|
||||
int count = 0;
|
||||
while (true) {
|
||||
switch (peekChar()) {
|
||||
case ' ': count++; break;
|
||||
case ' ' : count+=1; break;
|
||||
case '\t': count+=4; break;
|
||||
default: return count;
|
||||
}
|
||||
@ -3266,6 +3266,8 @@ struct Parser {
|
||||
bool eatIndentation(){
|
||||
if(brackets_level_0 > 0 || brackets_level_1 > 0 || brackets_level_2 > 0) return true;
|
||||
int spaces = eatSpaces();
|
||||
if(peekChar() == '#') skipLineComment();
|
||||
if(peekChar() == '\0' || peekChar() == '\n') return true;
|
||||
// https://docs.python.org/3/reference/lexical_analysis.html#indentation
|
||||
if(spaces > indents.top()){
|
||||
indents.push(spaces);
|
||||
@ -5236,7 +5238,7 @@ public:
|
||||
parser->previous = parser->current;
|
||||
parser->current = parser->nextToken();
|
||||
|
||||
//_Str _info = parser->current.info(); printf("%s\n", (const char*)_info);
|
||||
//_Str _info = parser->current.info(); std::cout << _info << '[' << parser->current_line << ']' << std::endl;
|
||||
|
||||
while (parser->peekChar() != '\0') {
|
||||
parser->token_start = parser->current_char;
|
||||
@ -5311,7 +5313,7 @@ public:
|
||||
case '\r': break; // just ignore '\r'
|
||||
case ' ': case '\t': parser->eatSpaces(); break;
|
||||
case '\n': {
|
||||
parser->setNextToken(TK("@eol")); while(parser->matchChar('\n'));
|
||||
parser->setNextToken(TK("@eol"));
|
||||
if(!parser->eatIndentation()) indentationError("unindent does not match any outer indentation level");
|
||||
return;
|
||||
}
|
||||
@ -5324,7 +5326,7 @@ public:
|
||||
eatNumber();
|
||||
} else if (parser->isNameStart(c)) {
|
||||
int ret = parser->eatName();
|
||||
if(ret!=0) syntaxError("identifier is illegal, err " + std::to_string(ret));
|
||||
if(ret!=0) syntaxError("@id is illegal, err " + std::to_string(ret));
|
||||
} else {
|
||||
syntaxError("unknown character: " + std::string(1, c));
|
||||
}
|
||||
@ -5427,7 +5429,7 @@ public:
|
||||
_Func func = pkpy::make_shared<Function>();
|
||||
func->name = "<lambda>";
|
||||
if(!match(TK(":"))){
|
||||
__compileFunctionArgs(func);
|
||||
__compileFunctionArgs(func, false);
|
||||
consume(TK(":"));
|
||||
}
|
||||
func->code = pkpy::make_shared<CodeObject>(parser->src, func->name);
|
||||
@ -5962,7 +5964,7 @@ __LISTCOMP:
|
||||
emitCode(OP_BUILD_CLASS, clsNameIdx);
|
||||
}
|
||||
|
||||
void __compileFunctionArgs(_Func func){
|
||||
void __compileFunctionArgs(_Func func, bool enableTypeHints){
|
||||
int state = 0; // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
|
||||
do {
|
||||
if(state == 3) syntaxError("**kwargs should be the last argument");
|
||||
@ -5979,6 +5981,9 @@ __LISTCOMP:
|
||||
const _Str& name = parser->previous.str();
|
||||
if(func->hasName(name)) syntaxError("duplicate argument name");
|
||||
|
||||
// eat type hints
|
||||
if(enableTypeHints && match(TK(":"))) consume(TK("@id"));
|
||||
|
||||
if(state == 0 && peek() == TK("=")) state = 2;
|
||||
|
||||
switch (state)
|
||||
@ -6009,10 +6014,13 @@ __LISTCOMP:
|
||||
func->name = parser->previous.str();
|
||||
|
||||
if (match(TK("(")) && !match(TK(")"))) {
|
||||
__compileFunctionArgs(func);
|
||||
__compileFunctionArgs(func, true);
|
||||
consume(TK(")"));
|
||||
}
|
||||
|
||||
// eat type hints
|
||||
if(match(TK("->"))) consume(TK("@id"));
|
||||
|
||||
func->code = pkpy::make_shared<CodeObject>(parser->src, func->name);
|
||||
this->codes.push(func->code);
|
||||
compileBlockBody();
|
||||
@ -6082,7 +6090,7 @@ __LISTCOMP:
|
||||
|
||||
/***** Error Reporter *****/
|
||||
_Str getLineSnapshot(){
|
||||
int lineno = parser->current_line;
|
||||
int lineno = parser->current.line;
|
||||
if(parser->peekChar() == '\n') lineno--;
|
||||
return parser->src->snapshot(lineno);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit f0c35d535dca99b31b15100f82f48bc1becbca45
|
||||
Subproject commit 81b5fc7f112d83abc6fd93824397017e3d837921
|
@ -3255,7 +3255,7 @@ struct Parser {
|
||||
int count = 0;
|
||||
while (true) {
|
||||
switch (peekChar()) {
|
||||
case ' ': count++; break;
|
||||
case ' ' : count+=1; break;
|
||||
case '\t': count+=4; break;
|
||||
default: return count;
|
||||
}
|
||||
@ -3266,6 +3266,8 @@ struct Parser {
|
||||
bool eatIndentation(){
|
||||
if(brackets_level_0 > 0 || brackets_level_1 > 0 || brackets_level_2 > 0) return true;
|
||||
int spaces = eatSpaces();
|
||||
if(peekChar() == '#') skipLineComment();
|
||||
if(peekChar() == '\0' || peekChar() == '\n') return true;
|
||||
// https://docs.python.org/3/reference/lexical_analysis.html#indentation
|
||||
if(spaces > indents.top()){
|
||||
indents.push(spaces);
|
||||
@ -5236,7 +5238,7 @@ public:
|
||||
parser->previous = parser->current;
|
||||
parser->current = parser->nextToken();
|
||||
|
||||
//_Str _info = parser->current.info(); printf("%s\n", (const char*)_info);
|
||||
//_Str _info = parser->current.info(); std::cout << _info << '[' << parser->current_line << ']' << std::endl;
|
||||
|
||||
while (parser->peekChar() != '\0') {
|
||||
parser->token_start = parser->current_char;
|
||||
@ -5311,7 +5313,7 @@ public:
|
||||
case '\r': break; // just ignore '\r'
|
||||
case ' ': case '\t': parser->eatSpaces(); break;
|
||||
case '\n': {
|
||||
parser->setNextToken(TK("@eol")); while(parser->matchChar('\n'));
|
||||
parser->setNextToken(TK("@eol"));
|
||||
if(!parser->eatIndentation()) indentationError("unindent does not match any outer indentation level");
|
||||
return;
|
||||
}
|
||||
@ -5324,7 +5326,7 @@ public:
|
||||
eatNumber();
|
||||
} else if (parser->isNameStart(c)) {
|
||||
int ret = parser->eatName();
|
||||
if(ret!=0) syntaxError("identifier is illegal, err " + std::to_string(ret));
|
||||
if(ret!=0) syntaxError("@id is illegal, err " + std::to_string(ret));
|
||||
} else {
|
||||
syntaxError("unknown character: " + std::string(1, c));
|
||||
}
|
||||
@ -5427,7 +5429,7 @@ public:
|
||||
_Func func = pkpy::make_shared<Function>();
|
||||
func->name = "<lambda>";
|
||||
if(!match(TK(":"))){
|
||||
__compileFunctionArgs(func);
|
||||
__compileFunctionArgs(func, false);
|
||||
consume(TK(":"));
|
||||
}
|
||||
func->code = pkpy::make_shared<CodeObject>(parser->src, func->name);
|
||||
@ -5962,7 +5964,7 @@ __LISTCOMP:
|
||||
emitCode(OP_BUILD_CLASS, clsNameIdx);
|
||||
}
|
||||
|
||||
void __compileFunctionArgs(_Func func){
|
||||
void __compileFunctionArgs(_Func func, bool enableTypeHints){
|
||||
int state = 0; // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
|
||||
do {
|
||||
if(state == 3) syntaxError("**kwargs should be the last argument");
|
||||
@ -5979,6 +5981,9 @@ __LISTCOMP:
|
||||
const _Str& name = parser->previous.str();
|
||||
if(func->hasName(name)) syntaxError("duplicate argument name");
|
||||
|
||||
// eat type hints
|
||||
if(enableTypeHints && match(TK(":"))) consume(TK("@id"));
|
||||
|
||||
if(state == 0 && peek() == TK("=")) state = 2;
|
||||
|
||||
switch (state)
|
||||
@ -6009,10 +6014,13 @@ __LISTCOMP:
|
||||
func->name = parser->previous.str();
|
||||
|
||||
if (match(TK("(")) && !match(TK(")"))) {
|
||||
__compileFunctionArgs(func);
|
||||
__compileFunctionArgs(func, true);
|
||||
consume(TK(")"));
|
||||
}
|
||||
|
||||
// eat type hints
|
||||
if(match(TK("->"))) consume(TK("@id"));
|
||||
|
||||
func->code = pkpy::make_shared<CodeObject>(parser->src, func->name);
|
||||
this->codes.push(func->code);
|
||||
compileBlockBody();
|
||||
@ -6082,7 +6090,7 @@ __LISTCOMP:
|
||||
|
||||
/***** Error Reporter *****/
|
||||
_Str getLineSnapshot(){
|
||||
int lineno = parser->current_line;
|
||||
int lineno = parser->current.line;
|
||||
if(parser->peekChar() == '\n') lineno--;
|
||||
return parser->src->snapshot(lineno);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "com.bl.pocketpy",
|
||||
"displayName": "PocketPy",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"unity": "2020.3",
|
||||
"description": "A lightweight Python interpreter for game engines.",
|
||||
"dependencies": {}
|
||||
|
@ -175,7 +175,7 @@ public:
|
||||
parser->previous = parser->current;
|
||||
parser->current = parser->nextToken();
|
||||
|
||||
//_Str _info = parser->current.info(); printf("%s\n", (const char*)_info);
|
||||
//_Str _info = parser->current.info(); std::cout << _info << '[' << parser->current_line << ']' << std::endl;
|
||||
|
||||
while (parser->peekChar() != '\0') {
|
||||
parser->token_start = parser->current_char;
|
||||
@ -250,7 +250,7 @@ public:
|
||||
case '\r': break; // just ignore '\r'
|
||||
case ' ': case '\t': parser->eatSpaces(); break;
|
||||
case '\n': {
|
||||
parser->setNextToken(TK("@eol")); while(parser->matchChar('\n'));
|
||||
parser->setNextToken(TK("@eol"));
|
||||
if(!parser->eatIndentation()) indentationError("unindent does not match any outer indentation level");
|
||||
return;
|
||||
}
|
||||
@ -263,7 +263,7 @@ public:
|
||||
eatNumber();
|
||||
} else if (parser->isNameStart(c)) {
|
||||
int ret = parser->eatName();
|
||||
if(ret!=0) syntaxError("identifier is illegal, err " + std::to_string(ret));
|
||||
if(ret!=0) syntaxError("@id is illegal, err " + std::to_string(ret));
|
||||
} else {
|
||||
syntaxError("unknown character: " + std::string(1, c));
|
||||
}
|
||||
@ -366,7 +366,7 @@ public:
|
||||
_Func func = pkpy::make_shared<Function>();
|
||||
func->name = "<lambda>";
|
||||
if(!match(TK(":"))){
|
||||
__compileFunctionArgs(func);
|
||||
__compileFunctionArgs(func, false);
|
||||
consume(TK(":"));
|
||||
}
|
||||
func->code = pkpy::make_shared<CodeObject>(parser->src, func->name);
|
||||
@ -901,7 +901,7 @@ __LISTCOMP:
|
||||
emitCode(OP_BUILD_CLASS, clsNameIdx);
|
||||
}
|
||||
|
||||
void __compileFunctionArgs(_Func func){
|
||||
void __compileFunctionArgs(_Func func, bool enableTypeHints){
|
||||
int state = 0; // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
|
||||
do {
|
||||
if(state == 3) syntaxError("**kwargs should be the last argument");
|
||||
@ -918,6 +918,9 @@ __LISTCOMP:
|
||||
const _Str& name = parser->previous.str();
|
||||
if(func->hasName(name)) syntaxError("duplicate argument name");
|
||||
|
||||
// eat type hints
|
||||
if(enableTypeHints && match(TK(":"))) consume(TK("@id"));
|
||||
|
||||
if(state == 0 && peek() == TK("=")) state = 2;
|
||||
|
||||
switch (state)
|
||||
@ -948,10 +951,13 @@ __LISTCOMP:
|
||||
func->name = parser->previous.str();
|
||||
|
||||
if (match(TK("(")) && !match(TK(")"))) {
|
||||
__compileFunctionArgs(func);
|
||||
__compileFunctionArgs(func, true);
|
||||
consume(TK(")"));
|
||||
}
|
||||
|
||||
// eat type hints
|
||||
if(match(TK("->"))) consume(TK("@id"));
|
||||
|
||||
func->code = pkpy::make_shared<CodeObject>(parser->src, func->name);
|
||||
this->codes.push(func->code);
|
||||
compileBlockBody();
|
||||
@ -1021,7 +1027,7 @@ __LISTCOMP:
|
||||
|
||||
/***** Error Reporter *****/
|
||||
_Str getLineSnapshot(){
|
||||
int lineno = parser->current_line;
|
||||
int lineno = parser->current.line;
|
||||
if(parser->peekChar() == '\n') lineno--;
|
||||
return parser->src->snapshot(lineno);
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ struct Parser {
|
||||
int count = 0;
|
||||
while (true) {
|
||||
switch (peekChar()) {
|
||||
case ' ': count++; break;
|
||||
case ' ' : count+=1; break;
|
||||
case '\t': count+=4; break;
|
||||
default: return count;
|
||||
}
|
||||
@ -144,6 +144,8 @@ struct Parser {
|
||||
bool eatIndentation(){
|
||||
if(brackets_level_0 > 0 || brackets_level_1 > 0 || brackets_level_2 > 0) return true;
|
||||
int spaces = eatSpaces();
|
||||
if(peekChar() == '#') skipLineComment();
|
||||
if(peekChar() == '\0' || peekChar() == '\n') return true;
|
||||
// https://docs.python.org/3/reference/lexical_analysis.html#indentation
|
||||
if(spaces > indents.top()){
|
||||
indents.push(spaces);
|
||||
|
44
tests/_typehints.py
Normal file
44
tests/_typehints.py
Normal file
@ -0,0 +1,44 @@
|
||||
# test type hints
|
||||
|
||||
def f(x: int) -> int:
|
||||
return x + 1
|
||||
|
||||
def g(x: int, y: int) -> int:
|
||||
return x + y
|
||||
|
||||
def h(x: int, y):
|
||||
return x + y
|
||||
|
||||
def i(x, y: int):
|
||||
return x + y
|
||||
|
||||
# test type hints with default values
|
||||
|
||||
def f(x: int = 1) -> int:
|
||||
return x + 1
|
||||
|
||||
def g(x: int = 1, y: int = 2) -> int:
|
||||
return x + y
|
||||
|
||||
def h(x: int = 1, y = 2):
|
||||
return x + y
|
||||
|
||||
def i(x = 1, y: int = 2):
|
||||
return x + y
|
||||
|
||||
# test type hints with *args
|
||||
|
||||
def f(x: int, *args) -> int:
|
||||
return x + len(args)
|
||||
|
||||
def g(x: int, y: int, *args) -> int:
|
||||
return x + y + len(args)
|
||||
|
||||
def h(x: int, y, *args):
|
||||
return x + y + len(args)
|
||||
|
||||
def i(x, y: int, *args):
|
||||
return x + y + len(args)
|
||||
|
||||
def j(x, y: int, *args: str) -> int:
|
||||
return x + y + len(args)
|
120
tests/dna.py
Normal file
120
tests/dna.py
Normal file
@ -0,0 +1,120 @@
|
||||
import random
|
||||
import builtins
|
||||
|
||||
builtins.print = lambda *x: None
|
||||
|
||||
def f(x):
|
||||
return -x**2+10
|
||||
|
||||
def create_init_DNA():
|
||||
# out: DNA
|
||||
ret = random.randint(-100,100)
|
||||
return int_to_bin(ret)
|
||||
|
||||
def int_to_bin(x):
|
||||
# in: int_DNA
|
||||
# out: DNA
|
||||
ret = []
|
||||
if x >= 0:
|
||||
ret.append(0)
|
||||
else:
|
||||
ret.append(1)
|
||||
x = -x
|
||||
for i in [4096,2048,1024,512,256,128,64,32,16,8,4,2,1] :
|
||||
if x>=i :
|
||||
ret.append(1)
|
||||
x -= i
|
||||
else :
|
||||
ret.append(0)
|
||||
return ret
|
||||
|
||||
def bin_to_int(x):
|
||||
# in: DNA
|
||||
# out: int_DNA
|
||||
ret = 0
|
||||
new_x = x[:]
|
||||
flag = -(new_x[0]*2-1)
|
||||
mul = 1
|
||||
new_x = reversed(new_x)
|
||||
new_x.pop()
|
||||
for i in new_x :
|
||||
ret += flag * i * mul
|
||||
mul *= 2
|
||||
return ret
|
||||
|
||||
def reversed(x):
|
||||
ret = []
|
||||
for i in range(0,len(x)):
|
||||
ret.append(x[-i-1])
|
||||
return ret
|
||||
|
||||
def create_DNAs(num):
|
||||
# in: int
|
||||
# out: DNAs
|
||||
ret = []
|
||||
for i in range(num):
|
||||
ret.append(create_init_DNA())
|
||||
return ret
|
||||
|
||||
def bins_to_ints(x):
|
||||
# in: DNAs
|
||||
# out: int_DNAs
|
||||
ret = []
|
||||
for i in x:
|
||||
ret.append(bin_to_int(i))
|
||||
return ret
|
||||
|
||||
def create_probabilitys(x):
|
||||
# in: DNAs
|
||||
# out: probabilitys
|
||||
scores = survival_scores(x)
|
||||
mid = []
|
||||
ret = []
|
||||
sum = 0
|
||||
for i in scores:
|
||||
sum+=i
|
||||
for i in scores:
|
||||
mid.append(1/(i/sum))
|
||||
sum = 0
|
||||
for i in mid:
|
||||
sum+=i
|
||||
for i in mid:
|
||||
ret.append(i/sum)
|
||||
return ret
|
||||
|
||||
def survival_scores(x):
|
||||
# in: DNAs
|
||||
# out: survival_scores
|
||||
ret = []
|
||||
for i in x:
|
||||
ret.append(f(bin_to_int(i)))
|
||||
return ret
|
||||
|
||||
def choose_DNA(DNAs,probabilitys):
|
||||
# in: DNAs,probabilitys
|
||||
# out: DNA
|
||||
# probabilitys是由若干(0,1)之间的浮点数组成的数组,这些浮点数的和为1
|
||||
i = 0 # i记录取出元素的位置
|
||||
ran = random.random()
|
||||
# a=0
|
||||
for max in probabilitys :
|
||||
if i != 0 :
|
||||
min = probabilitys[i-1]
|
||||
else :
|
||||
min = 0
|
||||
if ran < max and ran >= min :
|
||||
return DNAs[i]
|
||||
|
||||
|
||||
def next_gen_DNAs(DNAs,num=None):
|
||||
num = num or len(DNAs)
|
||||
ret = []
|
||||
for i in range(num) :
|
||||
ret.append(choose_DNA(DNAs,create_probabilitys(DNAs)))
|
||||
|
||||
|
||||
a = create_DNAs(10)
|
||||
print(a)
|
||||
print(bins_to_ints(a))
|
||||
print(survival_scores(a))
|
||||
print(create_probabilitys(a))
|
Loading…
x
Reference in New Issue
Block a user