This commit is contained in:
blueloveTH 2024-06-26 02:36:14 +08:00
parent 6f99ebed88
commit 2ac2ff807f
7 changed files with 414 additions and 81 deletions

View File

@ -4,7 +4,7 @@ python prebuild.py
SRC=$(find src/ -name "*.c") SRC=$(find src/ -name "*.c")
FLAGS="-std=c11 -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" # -fsanitize=address,leak,undefined" FLAGS="-std=c11 -lm -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" # -fsanitize=address,leak,undefined"
echo "Compiling C files..." echo "Compiling C files..."
clang $FLAGS $SRC src2/main.c -o main clang $FLAGS $SRC src2/main.c -o main

View File

@ -82,6 +82,8 @@ void pk_VM__dtor(pk_VM* self);
void pk_VM__push_frame(pk_VM* self, Frame* frame); void pk_VM__push_frame(pk_VM* self, Frame* frame);
void pk_VM__pop_frame(pk_VM* self); void pk_VM__pop_frame(pk_VM* self);
void pk_VM__init_builtins(pk_VM* self);
typedef enum pk_FrameResult{ typedef enum pk_FrameResult{
RES_RETURN, RES_RETURN,
RES_CALL, RES_CALL,

View File

@ -10,7 +10,7 @@ typedef struct pk_VM pk_VM;
typedef uint16_t py_Name; typedef uint16_t py_Name;
typedef int16_t py_Type; typedef int16_t py_Type;
typedef PyVar* py_Ref; typedef PyVar* py_Ref;
typedef int (*py_CFunction)(const py_Ref, int); typedef int (*py_CFunction)(int argc, py_Ref argv);
typedef struct py_Str py_Str; typedef struct py_Str py_Str;
@ -48,11 +48,37 @@ void py_newtuple(py_Ref, int);
// void py_newlist(py_Ref); // void py_newlist(py_Ref);
// new style decl-based function // new style decl-based function
void py_newfunction(py_Ref, py_CFunction, const char* sig, BindType bt); void py_newfunction(py_Ref self, py_CFunction, const char* sig);
void py_newfunction2(py_Ref, py_CFunction, const char* sig, BindType bt, const char* docstring, const py_Ref userdata); void py_newfunction2(py_Ref self, py_CFunction, const char* sig, BindType bt, const char* docstring, const py_Ref userdata);
// old style argc-based function // old style argc-based function
void py_newnativefunc(py_Ref, py_CFunction, int argc, BindType bt); void py_newnativefunc(py_Ref self, py_CFunction, int argc);
void py_newnativefunc2(py_Ref, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata); void py_newnativefunc2(py_Ref self, py_CFunction, int argc, BindType bt, const char* docstring, const py_Ref userdata);
/************* Stack Values Creation *************/
void py_pushint(int64_t);
void py_pushfloat(double);
void py_pushbool(bool);
void py_pushstr(const py_Str*);
void py_pushcstr(const char*);
void py_pushcstrn(const char*, int);
void py_push_notimplemented();
/************* Type Cast *************/
int64_t py_toint(py_Ref);
double py_tofloat(py_Ref);
bool py_castfloat(py_Ref, double* out);
bool py_tobool(py_Ref);
const py_Str* py_tostr(py_Ref);
const char* py_tocstr(py_Ref);
#define py_isint(self) py_istype(self, tp_int)
#define py_isfloat(self) py_istype(self, tp_float)
#define py_isbool(self) py_istype(self, tp_bool)
#define py_isstr(self) py_istype(self, tp_str)
bool py_istype(const py_Ref, py_Type);
// bool py_isinstance(const py_Ref obj, py_Type type);
// bool py_issubclass(py_Type derived, py_Type base);
/************* References *************/ /************* References *************/
py_Ref py_getdict(const py_Ref self, py_Name name); py_Ref py_getdict(const py_Ref self, py_Name name);
@ -134,15 +160,6 @@ void py_dict__clear(py_Ref self);
int py_str(const py_Ref, py_Str* out); int py_str(const py_Ref, py_Str* out);
int py_repr(const py_Ref, py_Str* out); int py_repr(const py_Ref, py_Str* out);
int py_toint(py_Ref, int64_t* out);
int py_tofloat(py_Ref, double* out);
int py_tostr(py_Ref, py_Str** out);
int py_tobool(py_Ref, bool* out);
bool py_istype(const py_Ref, py_Type);
bool py_isinstance(const py_Ref obj, py_Type type);
bool py_issubclass(py_Type derived, py_Type base);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

293
src/interpreter/py_number.c Normal file
View File

@ -0,0 +1,293 @@
#include "pocketpy/interpreter/vm.h"
#include <math.h>
// static int _py_print(const py_Ref args, int argc){
// int length = py_tuple__len(args+0);
// py_Str* sep;
// py_Str* end;
// int err;
// err = py_tostr(args+1, &sep);
// if(err) return err;
// err = py_tostr(args+2, &end);
// if(err) return err;
// pk_SStream ss;
// pk_SStream__ctor(&ss);
// for(int i=0; i<length; i++){
// const py_Ref item = py_tuple__getitem(args+0, i);
// py_Str tmp;
// int err = py_str(item, &tmp);
// if(!err){
// pk_SStream__write_Str(&ss, &tmp);
// py_Str__dtor(&tmp);
// if(i != length-1){
// pk_SStream__write_Str(&ss, sep);
// }
// }else{
// py_Str__dtor(&tmp);
// pk_SStream__dtor(&ss);
// return err;
// }
// }
// pk_SStream__write_Str(&ss, end);
// py_Str out = pk_SStream__submit(&ss);
// pk_current_vm->_stdout(py_Str__data(&out));
// py_Str__dtor(&out);
// return 0;
// }
#define DEF_NUM_BINARY_OP(name, op) \
static int _py_int##name(int argc, py_Ref argv) { \
if(py_isint(&argv[1])) { \
int64_t lhs = py_toint(&argv[0]); \
int64_t rhs = py_toint(&argv[1]); \
py_pushint(lhs op rhs); \
} else if(py_isfloat(&argv[1])) { \
int64_t lhs = py_toint(&argv[0]); \
double rhs = py_tofloat(&argv[1]); \
py_pushfloat(lhs op rhs); \
} else { \
py_push_notimplemented(); \
} \
return 1; \
} \
static int _py_float##name(int argc, py_Ref argv) { \
double lhs = py_tofloat(&argv[0]); \
double rhs; \
if(py_castfloat(&argv[1], &rhs)) { \
py_pushfloat(lhs op rhs); \
} else { \
py_push_notimplemented(); \
} \
return 1; \
}
DEF_NUM_BINARY_OP(__add__, +)
DEF_NUM_BINARY_OP(__sub__, -)
DEF_NUM_BINARY_OP(__mul__, *)
DEF_NUM_BINARY_OP(__eq__, ==)
DEF_NUM_BINARY_OP(__lt__, <)
DEF_NUM_BINARY_OP(__le__, <=)
DEF_NUM_BINARY_OP(__gt__, >)
DEF_NUM_BINARY_OP(__ge__, >=)
#undef DEF_NUM_BINARY_OP
static int _py_int__neg__(int argc, py_Ref argv) {
int64_t val = py_toint(&argv[0]);
py_pushint(-val);
return 1;
}
static int _py_float__neg__(int argc, py_Ref argv) {
double val = py_tofloat(&argv[0]);
py_pushfloat(-val);
return 1;
}
static int _py_int__truediv__(int argc, py_Ref argv) {
int64_t lhs = py_toint(&argv[0]);
double rhs;
if(py_castfloat(&argv[1], &rhs)) {
py_pushfloat(lhs / rhs);
} else {
py_push_notimplemented();
}
return 1;
}
static int _py_float__truediv__(int argc, py_Ref argv) {
double lhs = py_tofloat(&argv[0]);
double rhs;
if(py_castfloat(&argv[1], &rhs)) {
py_pushfloat(lhs / rhs);
} else {
py_push_notimplemented();
}
return 1;
}
static int _py_number__pow__(int argc, py_Ref argv) {
if(py_isint(&argv[0]) && py_isint(&argv[1])) {
int64_t lhs = py_toint(&argv[0]);
int64_t rhs = py_toint(&argv[1]);
if(rhs < 0) {
if(lhs == 0) {
// py_pusherror("0.0 cannot be raised to a negative power");
// TODO: ZeroDivisionError
return -1;
} else {
py_pushfloat(pow(lhs, rhs));
}
} else {
int64_t ret = 1;
while(rhs) {
if(rhs & 1) ret *= lhs;
lhs *= lhs;
rhs >>= 1;
}
py_pushint(ret);
}
} else {
double lhs, rhs;
py_castfloat(&argv[0], &lhs);
if(py_castfloat(&argv[1], &rhs)) {
py_pushfloat(pow(lhs, rhs));
} else {
py_push_notimplemented();
}
}
return 1;
}
static int _py_int__floordiv__(int argc, py_Ref argv) {
int64_t lhs = py_toint(&argv[0]);
if(py_isint(&argv[1])) {
int64_t rhs = py_toint(&argv[1]);
if(rhs == 0) return -1;
py_pushint(lhs / rhs);
} else {
py_push_notimplemented();
}
return 1;
}
static int _py_int__mod__(int argc, py_Ref argv) {
int64_t lhs = py_toint(&argv[0]);
if(py_isint(&argv[1])) {
int64_t rhs = py_toint(&argv[1]);
if(rhs == 0) return -1;
py_pushint(lhs % rhs);
} else {
py_push_notimplemented();
}
return 1;
}
static int _py_int__invert__(int argc, py_Ref argv) {
int64_t val = py_toint(&argv[0]);
py_pushint(~val);
return 1;
}
static int _py_int__bit_length(int argc, py_Ref argv) {
int64_t x = py_toint(&argv[0]);
if(x < 0) x = -x;
int bits = 0;
while(x) {
x >>= 1;
bits++;
}
py_pushint(bits);
return 1;
}
#define DEF_INT_BITWISE_OP(name, op) \
static int _py_int##name(int argc, py_Ref argv) { \
int64_t lhs = py_toint(&argv[0]); \
if(py_isint(&argv[1])) { \
int64_t rhs = py_toint(&argv[1]); \
py_pushint(lhs op rhs); \
} else { \
py_push_notimplemented(); \
} \
return 1; \
}
DEF_INT_BITWISE_OP(__and__, &)
DEF_INT_BITWISE_OP(__or__, |)
DEF_INT_BITWISE_OP(__xor__, ^)
DEF_INT_BITWISE_OP(__lshift__, <<)
DEF_INT_BITWISE_OP(__rshift__, >>)
#undef DEF_INT_BITWISE_OP
void pk_VM__init_builtins(pk_VM* self) {
/****** tp_int & tp_float ******/
py_Ref tmp = py_pushtmp();
py_Ref int_type = py_pushtmp();
*int_type = *py_getdict(&self->builtins, py_name("int"));
py_Ref float_type = py_pushtmp();
*float_type = *py_getdict(&self->builtins, py_name("float"));
#define BIND_INT_BINARY_OP(name) \
py_newnativefunc(tmp, _py_int##name, 2); \
py_setdict(int_type, name, tmp);
#define BIND_FLOAT_BINARY_OP(name) \
py_newnativefunc(tmp, _py_float##name, 2); \
py_setdict(float_type, name, tmp);
BIND_INT_BINARY_OP(__add__);
BIND_FLOAT_BINARY_OP(__add__);
BIND_INT_BINARY_OP(__sub__);
BIND_FLOAT_BINARY_OP(__sub__);
BIND_INT_BINARY_OP(__mul__);
BIND_FLOAT_BINARY_OP(__mul__);
BIND_INT_BINARY_OP(__eq__);
BIND_FLOAT_BINARY_OP(__eq__);
BIND_INT_BINARY_OP(__lt__);
BIND_FLOAT_BINARY_OP(__lt__);
BIND_INT_BINARY_OP(__le__);
BIND_FLOAT_BINARY_OP(__le__);
BIND_INT_BINARY_OP(__gt__);
BIND_FLOAT_BINARY_OP(__gt__);
BIND_INT_BINARY_OP(__ge__);
BIND_FLOAT_BINARY_OP(__ge__);
// __neg__
py_newnativefunc(tmp, _py_int__neg__, 1);
py_setdict(int_type, __neg__, tmp);
py_newnativefunc(tmp, _py_float__neg__, 1);
py_setdict(float_type, __neg__, tmp);
// TODO: __repr__, __new__, __hash__
// __truediv__
py_newnativefunc(tmp, _py_int__truediv__, 2);
py_setdict(int_type, __truediv__, tmp);
py_newnativefunc(tmp, _py_float__truediv__, 2);
py_setdict(float_type, __truediv__, tmp);
// __pow__
py_newnativefunc(tmp, _py_number__pow__, 2);
py_setdict(int_type, __pow__, tmp);
py_setdict(float_type, __pow__, tmp);
// __floordiv__ & __mod__
py_newnativefunc(tmp, _py_int__floordiv__, 2);
py_setdict(int_type, __floordiv__, tmp);
py_newnativefunc(tmp, _py_int__mod__, 2);
py_setdict(int_type, __mod__, tmp);
// int.__invert__ & int.<BITWISE OP>
py_newnativefunc(tmp, _py_int__invert__, 1);
py_setdict(int_type, __invert__, tmp);
BIND_INT_BINARY_OP(__and__);
BIND_INT_BINARY_OP(__or__);
BIND_INT_BINARY_OP(__xor__);
BIND_INT_BINARY_OP(__lshift__);
BIND_INT_BINARY_OP(__rshift__);
// int.bit_length
py_newnativefunc(tmp, _py_int__bit_length, 1);
py_setdict(int_type, py_name("bit_length"), tmp);
#undef BIND_INT_BINARY_OP
#undef BIND_FLOAT_BINARY_OP
py_poptmp(3);
// py_Ref builtins = py_getmodule("builtins");
// py_newfunction(py_reg(0), _py_print,
// "print(*args, sep=' ', end='\\n')",
// BindType_FUNCTION
// );
// py_setdict(builtins, py_name("hello"), py_reg(0));
}

View File

@ -34,52 +34,6 @@ void pk_TypeInfo__dtor(pk_TypeInfo *self){
c11_vector__dtor(&self->annotated_fields); c11_vector__dtor(&self->annotated_fields);
} }
// static int _py_print(const py_Ref args, int argc){
// int length = py_tuple__len(args+0);
// py_Str* sep;
// py_Str* end;
// int err;
// err = py_tostr(args+1, &sep);
// if(err) return err;
// err = py_tostr(args+2, &end);
// if(err) return err;
// pk_SStream ss;
// pk_SStream__ctor(&ss);
// for(int i=0; i<length; i++){
// const py_Ref item = py_tuple__getitem(args+0, i);
// py_Str tmp;
// int err = py_str(item, &tmp);
// if(!err){
// pk_SStream__write_Str(&ss, &tmp);
// py_Str__dtor(&tmp);
// if(i != length-1){
// pk_SStream__write_Str(&ss, sep);
// }
// }else{
// py_Str__dtor(&tmp);
// pk_SStream__dtor(&ss);
// return err;
// }
// }
// pk_SStream__write_Str(&ss, end);
// py_Str out = pk_SStream__submit(&ss);
// pk_current_vm->_stdout(py_Str__data(&out));
// py_Str__dtor(&out);
// return 0;
// }
static void do_builtin_bindings(){
// py_Ref builtins = py_getmodule("builtins");
// py_newfunction(py_reg(0), _py_print,
// "print(*args, sep=' ', end='\\n')",
// BindType_FUNCTION
// );
// py_setdict(builtins, py_name("hello"), py_reg(0));
}
void pk_VM__ctor(pk_VM* self){ void pk_VM__ctor(pk_VM* self){
self->top_frame = NULL; self->top_frame = NULL;
@ -189,7 +143,7 @@ void pk_VM__ctor(pk_VM* self){
py_setdict(&self->builtins, py_name("NotImplemented"), &self->NotImplemented); py_setdict(&self->builtins, py_name("NotImplemented"), &self->NotImplemented);
/* Do Buildin Bindings*/ /* Do Buildin Bindings*/
do_builtin_bindings(); pk_VM__init_builtins(self);
self->main = *py_newmodule("__main__", NULL); self->main = *py_newmodule("__main__", NULL);
} }

46
src/public/cast.c Normal file
View File

@ -0,0 +1,46 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
int64_t py_toint(py_Ref self){
return self->_i64;
}
double py_tofloat(py_Ref self){
return self->_f64;
}
bool py_castfloat(py_Ref self, double* out){
switch(self->type){
case tp_int:
*out = (double)self->_i64;
return true;
case tp_float:
*out = self->_f64;
return true;
case tp_bool:
*out = self->extra;
return true;
default:
return false;
}
}
bool py_tobool(py_Ref self){
return self->extra;
}
const py_Str* py_tostr(py_Ref self){
return PyObject__value(self->_obj);
}
const char* py_tocstr(py_Ref self){
const py_Str* s = PyObject__value(self->_obj);
return py_Str__data(s);
}
bool py_istype(const py_Ref self, py_Type type){
return self->type == type;
}

View File

@ -4,24 +4,24 @@
#include "pocketpy/objects/object.h" #include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h" #include "pocketpy/interpreter/vm.h"
void py_newint(py_Ref self, int64_t val){ void py_newint(py_Ref self, int64_t val) {
self->type = tp_int; self->type = tp_int;
self->is_ptr = false; self->is_ptr = false;
self->_i64 = val; self->_i64 = val;
} }
void py_newfloat(py_Ref self, double val){ void py_newfloat(py_Ref self, double val) {
self->type = tp_float; self->type = tp_float;
self->is_ptr = false; self->is_ptr = false;
self->_f64 = val; self->_f64 = val;
} }
void py_newbool(py_Ref self, bool val){ void py_newbool(py_Ref self, bool val) {
pk_VM* vm = pk_current_vm; pk_VM* vm = pk_current_vm;
*self = val ? vm->True : vm->False; *self = val ? vm->True : vm->False;
} }
void py_newstr(py_Ref self, const char* data){ void py_newstr(py_Ref self, const char* data) {
pk_ManagedHeap* heap = &pk_current_vm->heap; pk_ManagedHeap* heap = &pk_current_vm->heap;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str)); PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str));
py_Str__ctor((py_Str*)PyObject__value(obj), data); py_Str__ctor((py_Str*)PyObject__value(obj), data);
@ -30,7 +30,7 @@ void py_newstr(py_Ref self, const char* data){
self->_obj = obj; self->_obj = obj;
} }
void py_newstrn(py_Ref self, const char* data, int size){ void py_newstrn(py_Ref self, const char* data, int size) {
pk_ManagedHeap* heap = &pk_current_vm->heap; pk_ManagedHeap* heap = &pk_current_vm->heap;
PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str)); PyObject* obj = pk_ManagedHeap__gcnew(heap, tp_str, 0, sizeof(py_Str));
py_Str__ctor2((py_Str*)PyObject__value(obj), data, size); py_Str__ctor2((py_Str*)PyObject__value(obj), data, size);
@ -39,16 +39,14 @@ void py_newstrn(py_Ref self, const char* data, int size){
self->_obj = obj; self->_obj = obj;
} }
void py_newnone(py_Ref self){ void py_newnone(py_Ref self) {
pk_VM* vm = pk_current_vm; pk_VM* vm = pk_current_vm;
*self = vm->None; *self = vm->None;
} }
void py_newnull(py_Ref self){ void py_newnull(py_Ref self) { self->type = 0; }
self->type = 0;
}
void py_newtuple(py_Ref self, int n){ void py_newtuple(py_Ref self, int n) {
pk_VM* vm = pk_current_vm; pk_VM* vm = pk_current_vm;
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0); PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0);
self->type = tp_tuple; self->type = tp_tuple;
@ -56,18 +54,41 @@ void py_newtuple(py_Ref self, int n){
self->_obj = obj; self->_obj = obj;
} }
void py_newfunction(py_Ref self, py_CFunction f, const char* sig, BindType bt){ void py_newfunction(py_Ref self, py_CFunction f, const char* sig) {
py_newfunction2(self, f, sig, bt, NULL, NULL); py_newfunction2(self, f, sig, BindType_FUNCTION, NULL, NULL);
} }
void py_newfunction2(py_Ref self, py_CFunction f, const char *sig, BindType bt, const char *docstring, const py_Ref userdata){ void py_newfunction2(py_Ref self,
py_CFunction f,
const char* sig,
BindType bt,
const char* docstring,
const py_Ref userdata) {}
void py_newnativefunc(py_Ref self, py_CFunction f, int argc) {
py_newnativefunc2(self, f, argc, BindType_FUNCTION, NULL, NULL);
} }
void py_newnativefunc(py_Ref self, py_CFunction f, int argc, BindType bt){ void py_newnativefunc2(py_Ref self,
py_newnativefunc2(self, f, argc, bt, NULL, NULL); py_CFunction f,
int argc,
BindType bt,
const char* docstring,
const py_Ref userdata) {}
void py_pushint(int64_t val) { py_newint(pk_current_vm->stack.sp++, val); }
void py_pushfloat(double val) { py_newfloat(pk_current_vm->stack.sp++, val); }
void py_pushbool(bool val) { py_newbool(pk_current_vm->stack.sp++, val); }
void py_pushstr(const py_Str* val) { py_newstr(pk_current_vm->stack.sp++, py_Str__data(val)); }
void py_pushcstr(const char* val) { py_newstr(pk_current_vm->stack.sp++, val); }
void py_pushcstrn(const char* val, int size) { py_newstrn(pk_current_vm->stack.sp++, val, size); }
void py_push_notimplemented() {
pk_VM* vm = pk_current_vm;
*vm->stack.sp++ = vm->NotImplemented;
} }
void py_newnativefunc2(py_Ref self, py_CFunction f, int argc, BindType bt, const char *docstring, const py_Ref userdata){
}