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... "
|
||||
|
||||
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
|
||||
LIB_EXTENSION=".dylib"
|
||||
@ -46,7 +46,7 @@ clang++ $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared
|
||||
# compile main.cpp and link to libpocketpy.so
|
||||
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
|
||||
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 int pkpy_CName;
|
||||
typedef int pkpy_CType;
|
||||
|
||||
typedef struct{
|
||||
const char* data;
|
||||
int size;
|
||||
}pkpy_CString;
|
||||
typedef const char* pkpy_CString;
|
||||
|
||||
/* Basic Functions */
|
||||
PK_EXPORT pkpy_vm* pkpy_new_vm(bool enable_os);
|
||||
|
@ -13,25 +13,20 @@ struct Str{
|
||||
int size;
|
||||
bool is_ascii;
|
||||
char* data;
|
||||
char _inlined[16];
|
||||
|
||||
mutable const char* _cached_c_str = nullptr;
|
||||
char _inlined[24];
|
||||
|
||||
bool is_inlined() const { return data == _inlined; }
|
||||
|
||||
Str(): size(0), is_ascii(true), data(_inlined) {}
|
||||
Str();
|
||||
Str(int size, bool is_ascii);
|
||||
Str(const std::string& s);
|
||||
Str(std::string_view s);
|
||||
Str(std::nullptr_t) { PK_FATAL_ERROR(); }
|
||||
Str(const char* s);
|
||||
Str(const char* s, int len);
|
||||
Str(std::pair<char *, int>);
|
||||
Str(const Str& other);
|
||||
Str(Str&& other);
|
||||
|
||||
void _alloc();
|
||||
|
||||
const char* begin() const { return data; }
|
||||
const char* end() const { return data + size; }
|
||||
char operator[](int idx) const { return data[idx]; }
|
||||
@ -41,29 +36,30 @@ struct Str{
|
||||
|
||||
Str& operator=(const Str& other);
|
||||
Str operator+(const Str& other) const;
|
||||
friend Str operator+(const char* p, const Str& str);
|
||||
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 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 std::string_view other) const;
|
||||
|
||||
~Str();
|
||||
|
||||
friend Str operator+(const char* p, 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) const;
|
||||
char* c_str_dup() const;
|
||||
const char* c_str() const;
|
||||
std::string_view sv() const;
|
||||
std::string str() const;
|
||||
@ -95,6 +91,7 @@ struct StrName {
|
||||
StrName(const char* s);
|
||||
StrName(const Str& s);
|
||||
std::string_view sv() const;
|
||||
const char* c_str() const;
|
||||
bool empty() const { return index == 0; }
|
||||
|
||||
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) {
|
||||
VM* vm = (VM*) vm_handle;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
@ -251,8 +251,7 @@ bool pkpy_to_string(pkpy_vm* vm_handle, int i, pkpy_CString* out){
|
||||
PK_PROTECTED(
|
||||
PyObject* item = stack_item(vm, i);
|
||||
const Str& s = py_cast<Str&>(vm, item);
|
||||
out->data = s.data;
|
||||
out->size = s.size;
|
||||
*out = s.c_str();
|
||||
)
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -518,7 +517,7 @@ bool pkpy_clear_error(pkpy_vm* vm_handle, char** message) {
|
||||
if (vm->_c.error == nullptr) return false;
|
||||
Exception& e = PK_OBJ_GET(Exception, vm->_c.error);
|
||||
if (message != nullptr)
|
||||
*message = e.summary().c_str_dup();
|
||||
*message = strdup(e.summary().c_str());
|
||||
else
|
||||
std::cout << e.summary() << std::endl;
|
||||
vm->_c.error = nullptr;
|
||||
@ -548,10 +547,7 @@ void pkpy_free(void* p){
|
||||
}
|
||||
|
||||
pkpy_CString pkpy_string(const char* value){
|
||||
pkpy_CString s;
|
||||
s.data = value;
|
||||
s.size = strlen(value);
|
||||
return s;
|
||||
return value;
|
||||
}
|
||||
|
||||
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){
|
||||
std::string_view sv = StrName(name).sv();
|
||||
pkpy_CString s;
|
||||
s.data = sv.data();
|
||||
s.size = sv.size();
|
||||
return s;
|
||||
return StrName(name).c_str();
|
||||
}
|
||||
|
||||
void pkpy_set_output_handler(pkpy_vm* vm_handle, pkpy_COutputHandler handler){
|
||||
|
85
src/str.cpp
85
src/str.cpp
@ -13,51 +13,58 @@ int utf8len(unsigned char c, bool suppress){
|
||||
return 0;
|
||||
}
|
||||
|
||||
Str::Str(int size, bool is_ascii): size(size), is_ascii(is_ascii) {
|
||||
_alloc();
|
||||
#define PK_STR_ALLOCATE() \
|
||||
if(this->size < sizeof(this->_inlined)){ \
|
||||
this->data = this->_inlined; \
|
||||
}else{ \
|
||||
this->data = (char*)pool64_alloc(this->size); \
|
||||
}
|
||||
|
||||
#define STR_INIT() \
|
||||
_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_INIT()
|
||||
PK_STR_ALLOCATE()
|
||||
PK_STR_COPY_INIT(s)
|
||||
}
|
||||
|
||||
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_INIT()
|
||||
PK_STR_ALLOCATE()
|
||||
PK_STR_COPY_INIT(s)
|
||||
}
|
||||
|
||||
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) {
|
||||
this->size = detached.second;
|
||||
Str::Str(std::pair<char *, int> detached): size(detached.second), is_ascii(true) {
|
||||
this->data = detached.first;
|
||||
this->is_ascii = true;
|
||||
// check is_ascii
|
||||
for(int i=0; i<size; i++){
|
||||
if(!isascii(data[i])){
|
||||
is_ascii = false;
|
||||
break;
|
||||
}
|
||||
if(!isascii(data[i])){ is_ascii = false; break; }
|
||||
}
|
||||
}
|
||||
|
||||
Str::Str(const Str& other): size(other.size), is_ascii(other.is_ascii) {
|
||||
_alloc();
|
||||
PK_STR_ALLOCATE()
|
||||
memcpy(data, other.data, size);
|
||||
data[size] = '\0';
|
||||
}
|
||||
|
||||
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];
|
||||
}else{
|
||||
data = other.data;
|
||||
// zero out `other`
|
||||
other.data = other._inlined;
|
||||
other.data[0] = '\0';
|
||||
other.size = 0;
|
||||
}
|
||||
}
|
||||
@ -84,20 +93,11 @@ int utf8len(unsigned char c, bool suppress){
|
||||
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){
|
||||
if(!is_inlined()) pool64_dealloc(data);
|
||||
size = other.size;
|
||||
is_ascii = other.is_ascii;
|
||||
_cached_c_str = nullptr;
|
||||
_alloc();
|
||||
PK_STR_ALLOCATE()
|
||||
memcpy(data, other.data, size);
|
||||
return *this;
|
||||
}
|
||||
@ -164,7 +164,6 @@ int utf8len(unsigned char c, bool suppress){
|
||||
|
||||
Str::~Str(){
|
||||
if(!is_inlined()) pool64_dealloc(data);
|
||||
if(_cached_c_str != nullptr) free((void*)_cached_c_str);
|
||||
}
|
||||
|
||||
Str Str::substr(int start, int len) const {
|
||||
@ -177,18 +176,8 @@ int utf8len(unsigned char c, bool suppress){
|
||||
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{
|
||||
if(_cached_c_str == nullptr){
|
||||
_cached_c_str = c_str_dup();
|
||||
}
|
||||
return _cached_c_str;
|
||||
return data;
|
||||
}
|
||||
|
||||
std::string_view Str::sv() const {
|
||||
@ -435,6 +424,11 @@ int utf8len(unsigned char c, bool suppress){
|
||||
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(){
|
||||
// after this call, the buffer is no longer valid
|
||||
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
|
@ -53,7 +53,7 @@ static int f_input(pkpy_vm* vm){
|
||||
pkpy_CString prompt;
|
||||
bool ok = pkpy_to_string(vm, -1, &prompt);
|
||||
if(!ok) return 0;
|
||||
std::cout << std::string_view(prompt.data, prompt.size) << std::flush;
|
||||
std::cout << prompt << std::flush;
|
||||
}
|
||||
bool eof;
|
||||
std::string output = pkpy_platform_getline(&eof);
|
||||
|
Loading…
x
Reference in New Issue
Block a user