mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
This commit is contained in:
parent
5e55df9b97
commit
7a5ec84d14
4
build.sh
4
build.sh
@ -30,7 +30,7 @@ SRC=$(find src/ -name "*.cpp")
|
|||||||
|
|
||||||
echo "> Compiling and linking source files... "
|
echo "> Compiling and linking source files... "
|
||||||
|
|
||||||
FLAGS="-std=c++17 -s -O1 -stdlib=libc++ -Wfatal-errors -Iinclude"
|
FLAGS="-std=c++17 -O1 -stdlib=libc++ -Wfatal-errors -Iinclude"
|
||||||
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||||
LIB_EXTENSION=".dylib"
|
LIB_EXTENSION=".dylib"
|
||||||
@ -46,7 +46,7 @@ clang++ $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared
|
|||||||
# compile main.cpp and link to libpocketpy.so
|
# compile main.cpp and link to libpocketpy.so
|
||||||
echo "> Compiling main.cpp and linking to libpocketpy$LIB_EXTENSION..."
|
echo "> Compiling main.cpp and linking to libpocketpy$LIB_EXTENSION..."
|
||||||
|
|
||||||
clang++ $FLAGS -o main -s -O1 src2/main.cpp -L. -lpocketpy $LINK_FLAGS
|
clang++ $FLAGS -o main -O1 src2/main.cpp -L. -lpocketpy $LINK_FLAGS
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
echo "Build completed. Type \"./main\" to enter REPL."
|
echo "Build completed. Type \"./main\" to enter REPL."
|
||||||
|
@ -16,11 +16,7 @@ typedef void (*pkpy_COutputHandler)(const char*, int);
|
|||||||
typedef unsigned char* (*pkpy_CImportHandler)(const char*, int, int*);
|
typedef unsigned char* (*pkpy_CImportHandler)(const char*, int, int*);
|
||||||
typedef int pkpy_CName;
|
typedef int pkpy_CName;
|
||||||
typedef int pkpy_CType;
|
typedef int pkpy_CType;
|
||||||
|
typedef const char* pkpy_CString;
|
||||||
typedef struct{
|
|
||||||
const char* data;
|
|
||||||
int size;
|
|
||||||
}pkpy_CString;
|
|
||||||
|
|
||||||
/* Basic Functions */
|
/* Basic Functions */
|
||||||
PK_EXPORT pkpy_vm* pkpy_new_vm(bool enable_os);
|
PK_EXPORT pkpy_vm* pkpy_new_vm(bool enable_os);
|
||||||
|
@ -13,25 +13,20 @@ struct Str{
|
|||||||
int size;
|
int size;
|
||||||
bool is_ascii;
|
bool is_ascii;
|
||||||
char* data;
|
char* data;
|
||||||
char _inlined[16];
|
char _inlined[24];
|
||||||
|
|
||||||
mutable const char* _cached_c_str = nullptr;
|
|
||||||
|
|
||||||
bool is_inlined() const { return data == _inlined; }
|
bool is_inlined() const { return data == _inlined; }
|
||||||
|
|
||||||
Str(): size(0), is_ascii(true), data(_inlined) {}
|
Str();
|
||||||
Str(int size, bool is_ascii);
|
Str(int size, bool is_ascii);
|
||||||
Str(const std::string& s);
|
Str(const std::string& s);
|
||||||
Str(std::string_view s);
|
Str(std::string_view s);
|
||||||
Str(std::nullptr_t) { PK_FATAL_ERROR(); }
|
|
||||||
Str(const char* s);
|
Str(const char* s);
|
||||||
Str(const char* s, int len);
|
Str(const char* s, int len);
|
||||||
Str(std::pair<char *, int>);
|
Str(std::pair<char *, int>);
|
||||||
Str(const Str& other);
|
Str(const Str& other);
|
||||||
Str(Str&& other);
|
Str(Str&& other);
|
||||||
|
|
||||||
void _alloc();
|
|
||||||
|
|
||||||
const char* begin() const { return data; }
|
const char* begin() const { return data; }
|
||||||
const char* end() const { return data + size; }
|
const char* end() const { return data + size; }
|
||||||
char operator[](int idx) const { return data[idx]; }
|
char operator[](int idx) const { return data[idx]; }
|
||||||
@ -41,29 +36,30 @@ struct Str{
|
|||||||
|
|
||||||
Str& operator=(const Str& other);
|
Str& operator=(const Str& other);
|
||||||
Str operator+(const Str& other) const;
|
Str operator+(const Str& other) const;
|
||||||
|
friend Str operator+(const char* p, const Str& str);
|
||||||
Str operator+(const char* p) const;
|
Str operator+(const char* p) const;
|
||||||
|
|
||||||
|
bool operator==(const std::string_view other) const;
|
||||||
|
bool operator!=(const std::string_view other) const;
|
||||||
|
bool operator<(const std::string_view other) const;
|
||||||
|
friend bool operator<(const std::string_view other, const Str& str);
|
||||||
|
|
||||||
|
bool operator==(const char* p) const;
|
||||||
|
bool operator!=(const char* p) const;
|
||||||
|
|
||||||
bool operator==(const Str& other) const;
|
bool operator==(const Str& other) const;
|
||||||
bool operator!=(const Str& other) const;
|
bool operator!=(const Str& other) const;
|
||||||
bool operator==(const std::string_view other) const;
|
|
||||||
bool operator!=(const std::string_view other) const;
|
|
||||||
bool operator==(const char* p) const;
|
|
||||||
bool operator!=(const char* p) const;
|
|
||||||
bool operator<(const Str& other) const;
|
bool operator<(const Str& other) const;
|
||||||
bool operator>(const Str& other) const;
|
bool operator>(const Str& other) const;
|
||||||
bool operator<=(const Str& other) const;
|
bool operator<=(const Str& other) const;
|
||||||
bool operator>=(const Str& other) const;
|
bool operator>=(const Str& other) const;
|
||||||
bool operator<(const std::string_view other) const;
|
|
||||||
|
|
||||||
~Str();
|
~Str();
|
||||||
|
|
||||||
friend Str operator+(const char* p, const Str& str);
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const Str& str);
|
friend std::ostream& operator<<(std::ostream& os, const Str& str);
|
||||||
friend bool operator<(const std::string_view other, const Str& str);
|
|
||||||
|
|
||||||
Str substr(int start, int len) const;
|
Str substr(int start, int len) const;
|
||||||
Str substr(int start) const;
|
Str substr(int start) const;
|
||||||
char* c_str_dup() const;
|
|
||||||
const char* c_str() const;
|
const char* c_str() const;
|
||||||
std::string_view sv() const;
|
std::string_view sv() const;
|
||||||
std::string str() const;
|
std::string str() const;
|
||||||
@ -95,6 +91,7 @@ struct StrName {
|
|||||||
StrName(const char* s);
|
StrName(const char* s);
|
||||||
StrName(const Str& s);
|
StrName(const Str& s);
|
||||||
std::string_view sv() const;
|
std::string_view sv() const;
|
||||||
|
const char* c_str() const;
|
||||||
bool empty() const { return index == 0; }
|
bool empty() const { return index == 0; }
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const StrName& sn);
|
friend std::ostream& operator<<(std::ostream& os, const StrName& sn);
|
||||||
|
@ -231,7 +231,7 @@ bool pkpy_to_bool(pkpy_vm* vm_handle, int i, bool* out){
|
|||||||
bool pkpy_push_string(pkpy_vm* vm_handle, pkpy_CString value) {
|
bool pkpy_push_string(pkpy_vm* vm_handle, pkpy_CString value) {
|
||||||
VM* vm = (VM*) vm_handle;
|
VM* vm = (VM*) vm_handle;
|
||||||
PK_ASSERT_NO_ERROR()
|
PK_ASSERT_NO_ERROR()
|
||||||
PyObject* res = py_var(vm, std::string_view(value.data, value.size));
|
PyObject* res = py_var(vm, value);
|
||||||
vm->s_data.push(res);
|
vm->s_data.push(res);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -251,8 +251,7 @@ bool pkpy_to_string(pkpy_vm* vm_handle, int i, pkpy_CString* out){
|
|||||||
PK_PROTECTED(
|
PK_PROTECTED(
|
||||||
PyObject* item = stack_item(vm, i);
|
PyObject* item = stack_item(vm, i);
|
||||||
const Str& s = py_cast<Str&>(vm, item);
|
const Str& s = py_cast<Str&>(vm, item);
|
||||||
out->data = s.data;
|
*out = s.c_str();
|
||||||
out->size = s.size;
|
|
||||||
)
|
)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -503,7 +502,7 @@ bool pkpy_error(pkpy_vm* vm_handle, const char* name, pkpy_CString message) {
|
|||||||
std::cerr << "[warning] pkpy_error(): " << Str(name).escape() << " not found, fallback to 'Exception'" << std::endl;
|
std::cerr << "[warning] pkpy_error(): " << Str(name).escape() << " not found, fallback to 'Exception'" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vm->_c.error = vm->call(e_t, VAR(std::string_view(message.data, message.size)));
|
vm->_c.error = vm->call(e_t, VAR(message));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -518,7 +517,7 @@ bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) {
|
|||||||
if (vm->_c.error == nullptr) return false;
|
if (vm->_c.error == nullptr) return false;
|
||||||
Exception& e = PK_OBJ_GET(Exception, vm->_c.error);
|
Exception& e = PK_OBJ_GET(Exception, vm->_c.error);
|
||||||
if (message != nullptr)
|
if (message != nullptr)
|
||||||
*message = e.summary().c_str_dup();
|
*message = strdup(e.summary().c_str());
|
||||||
else
|
else
|
||||||
std::cout << e.summary() << std::endl;
|
std::cout << e.summary() << std::endl;
|
||||||
vm->_c.error = nullptr;
|
vm->_c.error = nullptr;
|
||||||
@ -548,10 +547,7 @@ void pkpy_free(void* p){
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkpy_CString pkpy_string(const char* value){
|
pkpy_CString pkpy_string(const char* value){
|
||||||
pkpy_CString s;
|
return value;
|
||||||
s.data = value;
|
|
||||||
s.size = strlen(value);
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pkpy_CName pkpy_name(const char* name){
|
pkpy_CName pkpy_name(const char* name){
|
||||||
@ -559,11 +555,7 @@ pkpy_CName pkpy_name(const char* name){
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkpy_CString pkpy_name_to_string(pkpy_CName name){
|
pkpy_CString pkpy_name_to_string(pkpy_CName name){
|
||||||
std::string_view sv = StrName(name).sv();
|
return StrName(name).c_str();
|
||||||
pkpy_CString s;
|
|
||||||
s.data = sv.data();
|
|
||||||
s.size = sv.size();
|
|
||||||
return s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler){
|
void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler){
|
||||||
|
89
src/str.cpp
89
src/str.cpp
@ -13,51 +13,58 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Str::Str(int size, bool is_ascii): size(size), is_ascii(is_ascii) {
|
#define PK_STR_ALLOCATE() \
|
||||||
_alloc();
|
if(this->size < sizeof(this->_inlined)){ \
|
||||||
}
|
this->data = this->_inlined; \
|
||||||
|
}else{ \
|
||||||
#define STR_INIT() \
|
this->data = (char*)pool64_alloc(this->size); \
|
||||||
_alloc(); \
|
|
||||||
for(int i=0; i<size; i++){ \
|
|
||||||
data[i] = s[i]; \
|
|
||||||
if(!isascii(s[i])) is_ascii = false; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PK_STR_COPY_INIT(__s) \
|
||||||
|
for(int i=0; i<this->size; i++){ \
|
||||||
|
this->data[i] = __s[i]; \
|
||||||
|
if(!isascii(__s[i])) is_ascii = false; \
|
||||||
|
}
|
||||||
|
|
||||||
|
Str::Str(): size(0), is_ascii(true), data(_inlined) {
|
||||||
|
_inlined[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
Str::Str(int size, bool is_ascii): size(size), is_ascii(is_ascii) {
|
||||||
|
PK_STR_ALLOCATE()
|
||||||
|
}
|
||||||
|
|
||||||
Str::Str(const std::string& s): size(s.size()), is_ascii(true) {
|
Str::Str(const std::string& s): size(s.size()), is_ascii(true) {
|
||||||
STR_INIT()
|
PK_STR_ALLOCATE()
|
||||||
|
PK_STR_COPY_INIT(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
Str::Str(std::string_view s): size(s.size()), is_ascii(true) {
|
Str::Str(std::string_view s): size(s.size()), is_ascii(true) {
|
||||||
STR_INIT()
|
PK_STR_ALLOCATE()
|
||||||
|
PK_STR_COPY_INIT(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
Str::Str(const char* s): size(strlen(s)), is_ascii(true) {
|
Str::Str(const char* s): size(strlen(s)), is_ascii(true) {
|
||||||
STR_INIT()
|
PK_STR_ALLOCATE()
|
||||||
|
PK_STR_COPY_INIT(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
Str::Str(const char* s, int len): size(len), is_ascii(true) {
|
Str::Str(const char* s, int len): size(len), is_ascii(true) {
|
||||||
STR_INIT()
|
PK_STR_ALLOCATE()
|
||||||
|
PK_STR_COPY_INIT(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef STR_INIT
|
Str::Str(std::pair<char *, int> detached): size(detached.second), is_ascii(true) {
|
||||||
|
|
||||||
Str::Str(std::pair<char *, int> detached) {
|
|
||||||
this->size = detached.second;
|
|
||||||
this->data = detached.first;
|
this->data = detached.first;
|
||||||
this->is_ascii = true;
|
|
||||||
// check is_ascii
|
|
||||||
for(int i=0; i<size; i++){
|
for(int i=0; i<size; i++){
|
||||||
if(!isascii(data[i])){
|
if(!isascii(data[i])){ is_ascii = false; break; }
|
||||||
is_ascii = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Str::Str(const Str& other): size(other.size), is_ascii(other.is_ascii) {
|
Str::Str(const Str& other): size(other.size), is_ascii(other.is_ascii) {
|
||||||
_alloc();
|
PK_STR_ALLOCATE()
|
||||||
memcpy(data, other.data, size);
|
memcpy(data, other.data, size);
|
||||||
|
data[size] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
Str::Str(Str&& other): size(other.size), is_ascii(other.is_ascii) {
|
Str::Str(Str&& other): size(other.size), is_ascii(other.is_ascii) {
|
||||||
@ -66,7 +73,9 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
for(int i=0; i<size; i++) _inlined[i] = other._inlined[i];
|
for(int i=0; i<size; i++) _inlined[i] = other._inlined[i];
|
||||||
}else{
|
}else{
|
||||||
data = other.data;
|
data = other.data;
|
||||||
|
// zero out `other`
|
||||||
other.data = other._inlined;
|
other.data = other._inlined;
|
||||||
|
other.data[0] = '\0';
|
||||||
other.size = 0;
|
other.size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,20 +93,11 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
return other < str.sv();
|
return other < str.sv();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Str::_alloc(){
|
|
||||||
if(size <= 16){
|
|
||||||
this->data = _inlined;
|
|
||||||
}else{
|
|
||||||
this->data = (char*)pool64_alloc(size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Str& Str::operator=(const Str& other){
|
Str& Str::operator=(const Str& other){
|
||||||
if(!is_inlined()) pool64_dealloc(data);
|
if(!is_inlined()) pool64_dealloc(data);
|
||||||
size = other.size;
|
size = other.size;
|
||||||
is_ascii = other.is_ascii;
|
is_ascii = other.is_ascii;
|
||||||
_cached_c_str = nullptr;
|
PK_STR_ALLOCATE()
|
||||||
_alloc();
|
|
||||||
memcpy(data, other.data, size);
|
memcpy(data, other.data, size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -164,7 +164,6 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
|
|
||||||
Str::~Str(){
|
Str::~Str(){
|
||||||
if(!is_inlined()) pool64_dealloc(data);
|
if(!is_inlined()) pool64_dealloc(data);
|
||||||
if(_cached_c_str != nullptr) free((void*)_cached_c_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Str Str::substr(int start, int len) const {
|
Str Str::substr(int start, int len) const {
|
||||||
@ -177,18 +176,8 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
return substr(start, size - start);
|
return substr(start, size - start);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* Str::c_str_dup() const {
|
|
||||||
char* p = (char*)malloc(size + 1);
|
|
||||||
memcpy(p, data, size);
|
|
||||||
p[size] = 0;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* Str::c_str() const{
|
const char* Str::c_str() const{
|
||||||
if(_cached_c_str == nullptr){
|
return data;
|
||||||
_cached_c_str = c_str_dup();
|
|
||||||
}
|
|
||||||
return _cached_c_str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string_view Str::sv() const {
|
std::string_view Str::sv() const {
|
||||||
@ -435,6 +424,11 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
return std::string_view(str);
|
return std::string_view(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* StrName::c_str() const{
|
||||||
|
const std::string& str = _r_interned()[index];
|
||||||
|
return str.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
Str SStream::str(){
|
Str SStream::str(){
|
||||||
// after this call, the buffer is no longer valid
|
// after this call, the buffer is no longer valid
|
||||||
return Str(buffer.detach());
|
return Str(buffer.detach());
|
||||||
@ -545,4 +539,7 @@ int utf8len(unsigned char c, bool suppress){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef PK_STR_ALLOCATE
|
||||||
|
#undef PK_STR_COPY_INIT
|
||||||
|
|
||||||
} // namespace pkpy
|
} // namespace pkpy
|
@ -53,7 +53,7 @@ static int f_input(pkpy_vm* vm){
|
|||||||
pkpy_CString prompt;
|
pkpy_CString prompt;
|
||||||
bool ok = pkpy_to_string(vm, -1, &prompt);
|
bool ok = pkpy_to_string(vm, -1, &prompt);
|
||||||
if(!ok) return 0;
|
if(!ok) return 0;
|
||||||
std::cout << std::string_view(prompt.data, prompt.size) << std::flush;
|
std::cout << prompt << std::flush;
|
||||||
}
|
}
|
||||||
bool eof;
|
bool eof;
|
||||||
std::string output = pkpy_platform_getline(&eof);
|
std::string output = pkpy_platform_getline(&eof);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user