mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-23 13:00:17 +00:00
up
This commit is contained in:
parent
af9f2ba6c4
commit
051560279d
@ -3,7 +3,7 @@ with open("src/opcodes.h", "rt", encoding='utf-8') as f:
|
||||
|
||||
pipeline = [
|
||||
["hash_table8.hpp", "common.h", "memory.h", "str.h", "safestl.h", "builtins.h", "error.h"],
|
||||
["obj.h", "parser.h", "ref.h", "codeobject.h"],
|
||||
["obj.h", "parser.h", "ref.h", "codeobject.h", "frame.h"],
|
||||
["vm.h", "compiler.h", "repl.h"],
|
||||
["iter.h", "pocketpy.h"]
|
||||
]
|
||||
|
@ -51,10 +51,12 @@ def sum(iterable):
|
||||
return res
|
||||
|
||||
def map(f, iterable):
|
||||
return [f(i) for i in iterable]
|
||||
for i in iterable:
|
||||
yield f(i)
|
||||
|
||||
def zip(a, b):
|
||||
return [(a[i], b[i]) for i in range(min(len(a), len(b)))]
|
||||
for i in range(min(len(a), len(b))):
|
||||
yield (a[i], b[i])
|
||||
|
||||
def reversed(iterable):
|
||||
a = list(iterable)
|
||||
@ -136,15 +138,6 @@ def __qsort(a: list, i: int, j: int):
|
||||
__qsort(a, d1, i-1)
|
||||
__qsort(a, i+1, d2)
|
||||
|
||||
def __list4reverse(self):
|
||||
i, j = 0, len(self)-1
|
||||
while i < j:
|
||||
self[i], self[j] = self[j], self[i]
|
||||
i += 1
|
||||
j -= 1
|
||||
list.reverse = __list4reverse
|
||||
del __list4reverse
|
||||
|
||||
def __list4sort(self, reverse=False):
|
||||
__qsort(self, 0, len(self)-1)
|
||||
if reverse:
|
||||
|
143
src/codeobject.h
143
src/codeobject.h
@ -107,146 +107,3 @@ struct CodeObject {
|
||||
}
|
||||
/************************************************/
|
||||
};
|
||||
|
||||
static THREAD_LOCAL i64 kFrameGlobalId = 0;
|
||||
|
||||
struct Frame {
|
||||
std::vector<PyVar> _data;
|
||||
int _ip = -1;
|
||||
int _next_ip = 0;
|
||||
|
||||
const CodeObject_ co;
|
||||
PyVar _module;
|
||||
pkpy::shared_ptr<pkpy::NameDict> _locals;
|
||||
const i64 id;
|
||||
std::stack<std::pair<int, std::vector<PyVar>>> s_try_block;
|
||||
|
||||
inline pkpy::NameDict& f_locals() noexcept { return *_locals; }
|
||||
inline pkpy::NameDict& f_globals() noexcept { return _module->attr(); }
|
||||
|
||||
Frame(const CodeObject_ co, PyVar _module, pkpy::shared_ptr<pkpy::NameDict> _locals)
|
||||
: co(co), _module(_module), _locals(_locals), id(kFrameGlobalId++) { }
|
||||
|
||||
inline const Bytecode& next_bytecode() {
|
||||
_ip = _next_ip++;
|
||||
return co->codes[_ip];
|
||||
}
|
||||
|
||||
Str snapshot(){
|
||||
int line = co->codes[_ip].line;
|
||||
return co->src->snapshot(line);
|
||||
}
|
||||
|
||||
// Str stack_info(){
|
||||
// StrStream ss;
|
||||
// ss << "[";
|
||||
// for(int i=0; i<_data.size(); i++){
|
||||
// ss << OBJ_TP_NAME(_data[i]);
|
||||
// if(i != _data.size()-1) ss << ", ";
|
||||
// }
|
||||
// ss << "]";
|
||||
// return ss.str();
|
||||
// }
|
||||
|
||||
inline bool has_next_bytecode() const {
|
||||
return _next_ip < co->codes.size();
|
||||
}
|
||||
|
||||
inline PyVar pop(){
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
PyVar v = std::move(_data.back());
|
||||
_data.pop_back();
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void _pop(){
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
inline void try_deref(VM*, PyVar&);
|
||||
|
||||
inline PyVar pop_value(VM* vm){
|
||||
PyVar value = pop();
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline PyVar top_value(VM* vm){
|
||||
PyVar value = top();
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline PyVar& top(){
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
return _data.back();
|
||||
}
|
||||
|
||||
inline PyVar top_value_offset(VM* vm, int n){
|
||||
PyVar value = _data[_data.size() + n];
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void push(T&& obj){ _data.push_back(std::forward<T>(obj)); }
|
||||
|
||||
inline void jump_abs(int i){ _next_ip = i; }
|
||||
inline void jump_rel(int i){ _next_ip += i; }
|
||||
|
||||
inline void on_try_block_enter(){
|
||||
s_try_block.push(std::make_pair(co->codes[_ip].block, _data));
|
||||
}
|
||||
|
||||
inline void on_try_block_exit(){
|
||||
s_try_block.pop();
|
||||
}
|
||||
|
||||
bool jump_to_exception_handler(){
|
||||
if(s_try_block.empty()) return false;
|
||||
PyVar obj = pop();
|
||||
auto& p = s_try_block.top();
|
||||
_data = std::move(p.second);
|
||||
_data.push_back(obj);
|
||||
_next_ip = co->blocks[p.first].end;
|
||||
on_try_block_exit();
|
||||
return true;
|
||||
}
|
||||
|
||||
void jump_abs_safe(int target){
|
||||
const Bytecode& prev = co->codes[_ip];
|
||||
int i = prev.block;
|
||||
_next_ip = target;
|
||||
if(_next_ip >= co->codes.size()){
|
||||
while(i>=0){
|
||||
if(co->blocks[i].type == FOR_LOOP) pop();
|
||||
else if(co->blocks[i].type == TRY_EXCEPT) on_try_block_exit();
|
||||
i = co->blocks[i].parent;
|
||||
}
|
||||
}else{
|
||||
const Bytecode& next = co->codes[target];
|
||||
while(i>=0 && i!=next.block){
|
||||
if(co->blocks[i].type == FOR_LOOP) pop();
|
||||
else if(co->blocks[i].type == TRY_EXCEPT) on_try_block_exit();
|
||||
i = co->blocks[i].parent;
|
||||
}
|
||||
if(i!=next.block) throw std::runtime_error("invalid jump");
|
||||
}
|
||||
}
|
||||
|
||||
pkpy::Args pop_n_values_reversed(VM* vm, int n){
|
||||
pkpy::Args v(n);
|
||||
for(int i=n-1; i>=0; i--){
|
||||
v[i] = pop();
|
||||
try_deref(vm, v[i]);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
pkpy::Args pop_n_reversed(int n){
|
||||
pkpy::Args v(n);
|
||||
for(int i=n-1; i>=0; i--) v[i] = pop();
|
||||
return v;
|
||||
}
|
||||
};
|
144
src/frame.h
Normal file
144
src/frame.h
Normal file
@ -0,0 +1,144 @@
|
||||
#pragma once
|
||||
|
||||
#include "codeobject.h"
|
||||
|
||||
static THREAD_LOCAL i64 kFrameGlobalId = 0;
|
||||
|
||||
struct Frame {
|
||||
std::vector<PyVar> _data;
|
||||
int _ip = -1;
|
||||
int _next_ip = 0;
|
||||
|
||||
const CodeObject_ co;
|
||||
PyVar _module;
|
||||
pkpy::shared_ptr<pkpy::NameDict> _locals;
|
||||
const i64 id;
|
||||
std::stack<std::pair<int, std::vector<PyVar>>> s_try_block;
|
||||
|
||||
inline pkpy::NameDict& f_locals() noexcept { return *_locals; }
|
||||
inline pkpy::NameDict& f_globals() noexcept { return _module->attr(); }
|
||||
|
||||
Frame(const CodeObject_ co, PyVar _module, pkpy::shared_ptr<pkpy::NameDict> _locals)
|
||||
: co(co), _module(_module), _locals(_locals), id(kFrameGlobalId++) { }
|
||||
|
||||
inline const Bytecode& next_bytecode() {
|
||||
_ip = _next_ip++;
|
||||
return co->codes[_ip];
|
||||
}
|
||||
|
||||
Str snapshot(){
|
||||
int line = co->codes[_ip].line;
|
||||
return co->src->snapshot(line);
|
||||
}
|
||||
|
||||
// Str stack_info(){
|
||||
// StrStream ss;
|
||||
// ss << "[";
|
||||
// for(int i=0; i<_data.size(); i++){
|
||||
// ss << OBJ_TP_NAME(_data[i]);
|
||||
// if(i != _data.size()-1) ss << ", ";
|
||||
// }
|
||||
// ss << "]";
|
||||
// return ss.str();
|
||||
// }
|
||||
|
||||
inline bool has_next_bytecode() const {
|
||||
return _next_ip < co->codes.size();
|
||||
}
|
||||
|
||||
inline PyVar pop(){
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
PyVar v = std::move(_data.back());
|
||||
_data.pop_back();
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void _pop(){
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
_data.pop_back();
|
||||
}
|
||||
|
||||
inline void try_deref(VM*, PyVar&);
|
||||
|
||||
inline PyVar pop_value(VM* vm){
|
||||
PyVar value = pop();
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline PyVar top_value(VM* vm){
|
||||
PyVar value = top();
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
inline PyVar& top(){
|
||||
if(_data.empty()) throw std::runtime_error("_data.empty() is true");
|
||||
return _data.back();
|
||||
}
|
||||
|
||||
inline PyVar top_value_offset(VM* vm, int n){
|
||||
PyVar value = _data[_data.size() + n];
|
||||
try_deref(vm, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void push(T&& obj){ _data.push_back(std::forward<T>(obj)); }
|
||||
|
||||
inline void jump_abs(int i){ _next_ip = i; }
|
||||
inline void jump_rel(int i){ _next_ip += i; }
|
||||
|
||||
inline void on_try_block_enter(){
|
||||
s_try_block.push(std::make_pair(co->codes[_ip].block, _data));
|
||||
}
|
||||
|
||||
inline void on_try_block_exit(){
|
||||
s_try_block.pop();
|
||||
}
|
||||
|
||||
bool jump_to_exception_handler(){
|
||||
if(s_try_block.empty()) return false;
|
||||
PyVar obj = pop();
|
||||
auto& p = s_try_block.top();
|
||||
_data = std::move(p.second);
|
||||
_data.push_back(obj);
|
||||
_next_ip = co->blocks[p.first].end;
|
||||
on_try_block_exit();
|
||||
return true;
|
||||
}
|
||||
|
||||
int _exit_block(int i){
|
||||
if(co->blocks[i].type == FOR_LOOP) pop();
|
||||
else if(co->blocks[i].type == TRY_EXCEPT) on_try_block_exit();
|
||||
return co->blocks[i].parent;
|
||||
}
|
||||
|
||||
void jump_abs_safe(int target){
|
||||
const Bytecode& prev = co->codes[_ip];
|
||||
int i = prev.block;
|
||||
_next_ip = target;
|
||||
if(_next_ip >= co->codes.size()){
|
||||
while(i>=0) i = _exit_block(i);
|
||||
}else{
|
||||
const Bytecode& next = co->codes[target];
|
||||
while(i>=0 && i!=next.block) i = _exit_block(i);
|
||||
if(i!=next.block) throw std::runtime_error("invalid jump");
|
||||
}
|
||||
}
|
||||
|
||||
pkpy::Args pop_n_values_reversed(VM* vm, int n){
|
||||
pkpy::Args v(n);
|
||||
for(int i=n-1; i>=0; i--){
|
||||
v[i] = pop();
|
||||
try_deref(vm, v[i]);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
pkpy::Args pop_n_reversed(int n){
|
||||
pkpy::Args v(n);
|
||||
for(int i=n-1; i>=0; i--) v[i] = pop();
|
||||
return v;
|
||||
}
|
||||
};
|
@ -394,6 +394,12 @@ void init_builtins(VM* _vm) {
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
_vm->bind_method<0>("list", "reverse", [](VM* vm, pkpy::Args& args) {
|
||||
pkpy::List& self = vm->PyList_AS_C(args[0]);
|
||||
std::reverse(self.begin(), self.end());
|
||||
return vm->None;
|
||||
});
|
||||
|
||||
_vm->bind_method<1>("list", "__mul__", [](VM* vm, pkpy::Args& args) {
|
||||
const pkpy::List& self = vm->PyList_AS_C(args[0]);
|
||||
int n = (int)vm->PyInt_AS_C(args[1]);
|
||||
|
Loading…
x
Reference in New Issue
Block a user