mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
Merge branch 'main' of https://github.com/blueloveTH/pocketpy
This commit is contained in:
commit
3e65101a0d
35
.github/workflows/website.yml
vendored
Normal file
35
.github/workflows/website.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: website
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
###################################################
|
||||
- uses: actions/setup-node@v3.1.1
|
||||
- name: Retype build
|
||||
run: |
|
||||
cd docs
|
||||
npm install retypeapp --global
|
||||
retype build
|
||||
###################################################
|
||||
- name: Setup emsdk
|
||||
uses: mymindstorm/setup-emsdk@v12
|
||||
with:
|
||||
version: 3.1.25
|
||||
actions-cache-folder: 'emsdk-cache'
|
||||
- name: Compile
|
||||
run: |
|
||||
bash build_web.sh
|
||||
mv web docs/.retype/static
|
||||
###################################################
|
||||
- uses: crazy-max/ghaction-github-pages@v3
|
||||
with:
|
||||
target_branch: gh-pages
|
||||
build_dir: docs/.retype
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
@ -20,12 +20,14 @@ endif()
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR- /EHsc /utf-8 /O2")
|
||||
else()
|
||||
if (NOT EMSCRIPTEN)
|
||||
find_program(CLANGPP clang++)
|
||||
if(CLANGPP)
|
||||
message(STATUS "Using clang with libc++")
|
||||
set(CMAKE_CXX_COMPILER ${CLANGPP})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fexceptions -O2")
|
||||
endif()
|
||||
|
7
build_web.sh
Normal file
7
build_web.sh
Normal file
@ -0,0 +1,7 @@
|
||||
python3 prebuild.py
|
||||
|
||||
rm -rf web/lib
|
||||
mkdir web/lib
|
||||
|
||||
SRC=$(find src/ -name "*.cpp")
|
||||
em++ $SRC -Iinclude/ -fno-rtti -fexceptions -O3 -sEXPORTED_FUNCTIONS=_pkpy_new_repl,_pkpy_repl_input,_pkpy_new_vm -sEXPORTED_RUNTIME_METHODS=ccall -o web/lib/pocketpy.js
|
@ -20,7 +20,7 @@
|
||||
#include <variant>
|
||||
#include <type_traits>
|
||||
|
||||
#define PK_VERSION "1.0.8"
|
||||
#define PK_VERSION "1.0.9"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
@ -22,10 +22,7 @@ struct FastLocals{
|
||||
FastLocals(const CodeObject* co, PyObject** a): varnames_inv(&co->varnames_inv), a(a) {}
|
||||
FastLocals(const FastLocals& other): varnames_inv(other.varnames_inv), a(other.a) {}
|
||||
|
||||
PyObject* try_get(StrName name);
|
||||
bool contains(StrName name);
|
||||
void erase(StrName name);
|
||||
bool try_set(StrName name, PyObject* value);
|
||||
PyObject** try_get_name(StrName name);
|
||||
NameDict_ to_namedict();
|
||||
};
|
||||
|
||||
|
@ -351,6 +351,7 @@ public:
|
||||
void IndexError(const Str& msg){ _error("IndexError", msg); }
|
||||
void ValueError(const Str& msg){ _error("ValueError", msg); }
|
||||
void NameError(StrName name){ _error("NameError", fmt("name ", name.escape() + " is not defined")); }
|
||||
void UnboundLocalError(StrName name){ _error("UnboundLocalError", fmt("local variable ", name.escape() + " referenced before assignment")); }
|
||||
void KeyError(PyObject* obj){ _error("KeyError", PK_OBJ_GET(Str, py_repr(obj))); }
|
||||
void BinaryOptError(const char* op) { TypeError(fmt("unsupported operand type(s) for ", op)); }
|
||||
|
||||
|
@ -111,11 +111,15 @@ __NEXT_STEP:;
|
||||
if(_0 == PY_NULL) vm->NameError(co->varnames[byte.arg]);
|
||||
PUSH(_0);
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_NAME)
|
||||
TARGET(LOAD_NAME) {
|
||||
heap._auto_collect();
|
||||
_name = StrName(byte.arg);
|
||||
_0 = frame->_locals.try_get(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
PyObject** slot = frame->_locals.try_get_name(_name);
|
||||
if(slot != nullptr) {
|
||||
if(*slot == PY_NULL) vm->UnboundLocalError(_name);
|
||||
PUSH(*slot);
|
||||
DISPATCH();
|
||||
}
|
||||
_0 = frame->f_closure_try_get(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
_0 = frame->f_globals().try_get(_name);
|
||||
@ -123,7 +127,7 @@ __NEXT_STEP:;
|
||||
_0 = vm->builtins->attr().try_get(_name);
|
||||
if(_0 != nullptr) { PUSH(_0); DISPATCH(); }
|
||||
vm->NameError(_name);
|
||||
DISPATCH();
|
||||
} DISPATCH();
|
||||
TARGET(LOAD_NONLOCAL) {
|
||||
heap._auto_collect();
|
||||
_name = StrName(byte.arg);
|
||||
@ -164,16 +168,17 @@ __NEXT_STEP:;
|
||||
TARGET(STORE_FAST)
|
||||
frame->_locals[byte.arg] = POPX();
|
||||
DISPATCH();
|
||||
TARGET(STORE_NAME)
|
||||
TARGET(STORE_NAME){
|
||||
_name = StrName(byte.arg);
|
||||
_0 = POPX();
|
||||
if(frame->_callable != nullptr){
|
||||
bool ok = frame->_locals.try_set(_name, _0);
|
||||
if(!ok) vm->NameError(_name);
|
||||
PyObject** slot = frame->_locals.try_get_name(_name);
|
||||
if(slot == nullptr) vm->UnboundLocalError(_name);
|
||||
*slot = _0;
|
||||
}else{
|
||||
frame->f_globals().set(_name, _0);
|
||||
}
|
||||
DISPATCH();
|
||||
} DISPATCH();
|
||||
TARGET(STORE_GLOBAL)
|
||||
frame->f_globals().set(StrName(byte.arg), POPX());
|
||||
DISPATCH();
|
||||
@ -202,8 +207,9 @@ __NEXT_STEP:;
|
||||
TARGET(DELETE_NAME)
|
||||
_name = StrName(byte.arg);
|
||||
if(frame->_callable != nullptr){
|
||||
if(!frame->_locals.contains(_name)) vm->NameError(_name);
|
||||
frame->_locals.erase(_name);
|
||||
PyObject** slot = frame->_locals.try_get_name(_name);
|
||||
if(slot == nullptr) vm->UnboundLocalError(_name);
|
||||
*slot = PY_NULL;
|
||||
}else{
|
||||
if(!frame->f_globals().contains(_name)) vm->NameError(_name);
|
||||
frame->f_globals().erase(_name);
|
||||
|
@ -1,28 +1,10 @@
|
||||
#include "pocketpy/frame.h"
|
||||
|
||||
namespace pkpy{
|
||||
|
||||
PyObject* FastLocals::try_get(StrName name){
|
||||
PyObject** FastLocals::try_get_name(StrName name){
|
||||
int index = varnames_inv->try_get(name);
|
||||
if(index == -1) return nullptr;
|
||||
return a[index];
|
||||
}
|
||||
|
||||
bool FastLocals::contains(StrName name){
|
||||
return varnames_inv->contains(name);
|
||||
}
|
||||
|
||||
void FastLocals::erase(StrName name){
|
||||
int index = varnames_inv->try_get(name);
|
||||
if(index == -1) FATAL_ERROR();
|
||||
a[index] = nullptr;
|
||||
}
|
||||
|
||||
bool FastLocals::try_set(StrName name, PyObject* value){
|
||||
int index = varnames_inv->try_get(name);
|
||||
if(index == -1) return false;
|
||||
a[index] = value;
|
||||
return true;
|
||||
return &a[index];
|
||||
}
|
||||
|
||||
NameDict_ FastLocals::to_namedict(){
|
||||
|
@ -398,7 +398,11 @@ PyObject* VM::format(Str spec, PyObject* obj){
|
||||
int width, precision;
|
||||
try{
|
||||
if(dot >= 0){
|
||||
if(dot == 0){
|
||||
width = -1;
|
||||
}else{
|
||||
width = Number::stoi(spec.substr(0, dot).str());
|
||||
}
|
||||
precision = Number::stoi(spec.substr(dot+1).str());
|
||||
}else{
|
||||
width = Number::stoi(spec.str());
|
||||
@ -424,7 +428,7 @@ PyObject* VM::format(Str spec, PyObject* obj){
|
||||
}else{
|
||||
ret = CAST(Str&, py_str(obj));
|
||||
}
|
||||
if(width > ret.length()){
|
||||
if(width != -1 && width > ret.length()){
|
||||
int pad = width - ret.length();
|
||||
std::string padding(pad, pad_c);
|
||||
if(align == '>') ret = padding.c_str() + ret;
|
||||
@ -446,7 +450,7 @@ PyObject* VM::new_module(StrName name) {
|
||||
static std::string _opcode_argstr(VM* vm, Bytecode byte, const CodeObject* co){
|
||||
std::string argStr = byte.arg == -1 ? "" : std::to_string(byte.arg);
|
||||
switch(byte.op){
|
||||
case OP_LOAD_CONST:
|
||||
case OP_LOAD_CONST: case OP_FORMAT_STRING:
|
||||
if(vm != nullptr){
|
||||
argStr += fmt(" (", CAST(Str, vm->py_repr(co->consts[byte.arg])), ")");
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ assert f'{a:010}' == '0000000010'
|
||||
assert f'{a:010d}' == '0000000010'
|
||||
assert f'{a:010f}' == '010.000000'
|
||||
assert f'{a:010.2f}' == '0000010.00'
|
||||
assert f'{a:.2f}' == '10.00'
|
||||
assert f'{a:.5f}' == '10.00000'
|
||||
|
||||
b = '123'
|
||||
assert f'{b:10}' == '123 '
|
||||
|
@ -57,3 +57,18 @@ f()
|
||||
|
||||
# class A: a=b=1
|
||||
# class A: a, b = 1, 2
|
||||
|
||||
bmi = 0.0
|
||||
|
||||
def test(a):
|
||||
if a:
|
||||
bmi = 1.4
|
||||
return f'{bmi:.2f}'
|
||||
|
||||
assert test(1) == '1.40'
|
||||
|
||||
try:
|
||||
assert test(0) == '0.00'
|
||||
exit(1)
|
||||
except UnboundLocalError:
|
||||
pass
|
Loading…
x
Reference in New Issue
Block a user