mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
fix initial demo
This commit is contained in:
parent
f53ae5e459
commit
5be3300554
@ -5,8 +5,8 @@ python prebuild.py
|
|||||||
SRC=$(find src/ -name "*.c")
|
SRC=$(find src/ -name "*.c")
|
||||||
|
|
||||||
FLAGS="-std=c11 -lm -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1"
|
FLAGS="-std=c11 -lm -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1"
|
||||||
# SANITIZE_FLAGS="-fsanitize=address,leak,undefined"
|
SANITIZE_FLAGS="-fsanitize=address,leak,undefined"
|
||||||
SANITIZE_FLAGS=""
|
# SANITIZE_FLAGS=""
|
||||||
|
|
||||||
echo "Compiling C files..."
|
echo "Compiling C files..."
|
||||||
clang $FLAGS $SANITIZE_FLAGS $SRC src2/main.c -o main
|
clang $FLAGS $SANITIZE_FLAGS $SRC src2/main.c -o main
|
||||||
|
@ -89,18 +89,3 @@ void Frame__set_unwind_target(Frame* self, py_TValue* sp);
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// some patch here
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#include "pocketpy/objects/codeobject.hpp"
|
|
||||||
|
|
||||||
extern "C"{
|
|
||||||
inline py_TValue* Frame__f_closure_try_get(Frame* self, StrName name){
|
|
||||||
if(self->function == NULL) return NULL;
|
|
||||||
pkpy::Function* fn = PyObject__as(pkpy::Function, self->function);
|
|
||||||
if(fn->_closure == nullptr) return nullptr;
|
|
||||||
return pk_NameDict__try_get(fn->_closure, name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -58,8 +58,10 @@ typedef struct pk_VM {
|
|||||||
|
|
||||||
// singleton objects
|
// singleton objects
|
||||||
py_TValue True, False, None, NotImplemented, Ellipsis;
|
py_TValue True, False, None, NotImplemented, Ellipsis;
|
||||||
// last error
|
|
||||||
py_Error* last_error;
|
py_Error* last_error;
|
||||||
|
py_TValue last_retval;
|
||||||
|
py_TValue reg[8]; // users' registers
|
||||||
|
|
||||||
PyObject* __curr_class;
|
PyObject* __curr_class;
|
||||||
PyObject* __cached_object_new;
|
PyObject* __cached_object_new;
|
||||||
|
@ -31,7 +31,7 @@ void py_finalize();
|
|||||||
/// Run a simple source string. Do not change the stack.
|
/// Run a simple source string. Do not change the stack.
|
||||||
int py_exec(const char*);
|
int py_exec(const char*);
|
||||||
/// Eval a simple expression. The result is pushed to the stack.
|
/// Eval a simple expression. The result is pushed to the stack.
|
||||||
int py_eval(const char*);
|
int py_eval(const char*, py_Ref out);
|
||||||
|
|
||||||
/************* Values Creation *************/
|
/************* Values Creation *************/
|
||||||
void py_newint(py_Ref, int64_t);
|
void py_newint(py_Ref, int64_t);
|
||||||
@ -101,6 +101,9 @@ bool py_istype(const py_Ref, py_Type);
|
|||||||
// bool py_issubclass(py_Type derived, py_Type base);
|
// bool py_issubclass(py_Type derived, py_Type base);
|
||||||
|
|
||||||
/************* References *************/
|
/************* References *************/
|
||||||
|
py_Ref py_getreg(int i);
|
||||||
|
void py_setreg(int i, const py_Ref val);
|
||||||
|
|
||||||
py_Ref py_getdict(const py_Ref self, py_Name name);
|
py_Ref py_getdict(const py_Ref self, py_Name name);
|
||||||
void py_setdict(py_Ref self, py_Name name, const py_Ref val);
|
void py_setdict(py_Ref self, py_Name name, const py_Ref val);
|
||||||
|
|
||||||
@ -171,14 +174,12 @@ int py_callmethod(py_Ref self, py_Name name, ...);
|
|||||||
py_Ref py_tuple__getitem(const py_Ref self, int i);
|
py_Ref py_tuple__getitem(const py_Ref self, int i);
|
||||||
void py_tuple__setitem(py_Ref self, int i, const py_Ref val);
|
void py_tuple__setitem(py_Ref self, int i, const py_Ref val);
|
||||||
int py_tuple__len(const py_Ref self);
|
int py_tuple__len(const py_Ref self);
|
||||||
bool py_tuple__contains(const py_Ref self, const py_Ref val);
|
|
||||||
|
|
||||||
// unchecked functions, if self is not a list, the behavior is undefined
|
// unchecked functions, if self is not a list, the behavior is undefined
|
||||||
py_Ref py_list__getitem(const py_Ref self, int i);
|
py_Ref py_list__getitem(const py_Ref self, int i);
|
||||||
void py_list__setitem(py_Ref self, int i, const py_Ref val);
|
void py_list__setitem(py_Ref self, int i, const py_Ref val);
|
||||||
void py_list__delitem(py_Ref self, int i);
|
void py_list__delitem(py_Ref self, int i);
|
||||||
int py_list__len(const py_Ref self);
|
int py_list__len(const py_Ref self);
|
||||||
bool py_list__contains(const py_Ref self, const py_Ref val);
|
|
||||||
void py_list__append(py_Ref self, const py_Ref val);
|
void py_list__append(py_Ref self, const py_Ref val);
|
||||||
void py_list__extend(py_Ref self, const py_Ref begin, const py_Ref end);
|
void py_list__extend(py_Ref self, const py_Ref begin, const py_Ref end);
|
||||||
void py_list__clear(py_Ref self);
|
void py_list__clear(py_Ref self);
|
||||||
|
@ -79,6 +79,10 @@ void pk_StrName__initialize(){
|
|||||||
|
|
||||||
void pk_StrName__finalize(){
|
void pk_StrName__finalize(){
|
||||||
if(!_initialized) return;
|
if(!_initialized) return;
|
||||||
|
// free all char*
|
||||||
|
for(int i=0; i<_r_interned.count; i++){
|
||||||
|
free(c11__getitem(char*, &_r_interned, i));
|
||||||
|
}
|
||||||
c11_smallmap_s2n__dtor(&_interned);
|
c11_smallmap_s2n__dtor(&_interned);
|
||||||
c11_vector__dtor(&_r_interned);
|
c11_vector__dtor(&_r_interned);
|
||||||
}
|
}
|
||||||
|
@ -468,7 +468,7 @@ static SequenceExpr* SequenceExpr__new(int line, const ExprVt* vt, int count, Op
|
|||||||
self->vt = vt;
|
self->vt = vt;
|
||||||
self->line = line;
|
self->line = line;
|
||||||
self->opcode = opcode;
|
self->opcode = opcode;
|
||||||
c11_array__ctor(&self->items, count, sizeof(Expr*));
|
c11_array__ctor(&self->items, sizeof(Expr*), count);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1395,7 +1395,7 @@ void Ctx__emit_store_name(Ctx* self, NameScope scope, StrName name, int line) {
|
|||||||
// emit top -> pop -> delete
|
// emit top -> pop -> delete
|
||||||
void Ctx__s_emit_top(Ctx* self) {
|
void Ctx__s_emit_top(Ctx* self) {
|
||||||
Expr* top = c11_vector__back(Expr*, &self->s_expr);
|
Expr* top = c11_vector__back(Expr*, &self->s_expr);
|
||||||
top->vt->emit_(top, self);
|
vtemit_(top, self);
|
||||||
c11_vector__pop(&self->s_expr);
|
c11_vector__pop(&self->s_expr);
|
||||||
vtdelete(top);
|
vtdelete(top);
|
||||||
}
|
}
|
||||||
@ -1670,7 +1670,8 @@ static Error* pop_context(Compiler* self) {
|
|||||||
|
|
||||||
/* Expression Callbacks */
|
/* Expression Callbacks */
|
||||||
static Error* exprLiteral(Compiler* self) {
|
static Error* exprLiteral(Compiler* self) {
|
||||||
Ctx__s_push(ctx(), (Expr*)LiteralExpr__new(prev()->line, &prev()->value));
|
LiteralExpr* e = LiteralExpr__new(prev()->line, &prev()->value);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2064,15 +2065,15 @@ Error* pk_compile(pk_SourceData_ src, CodeObject* out) {
|
|||||||
Error* err = pk_Lexer__process(src, &tokens);
|
Error* err = pk_Lexer__process(src, &tokens);
|
||||||
if(err) return err;
|
if(err) return err;
|
||||||
|
|
||||||
// Token* data = (Token*)tokens.data;
|
Token* data = (Token*)tokens.data;
|
||||||
// printf("%s\n", py_Str__data(&src->filename));
|
printf("%s\n", py_Str__data(&src->filename));
|
||||||
// for(int i = 0; i < tokens.count; i++) {
|
for(int i = 0; i < tokens.count; i++) {
|
||||||
// Token* t = data + i;
|
Token* t = data + i;
|
||||||
// py_Str tmp;
|
py_Str tmp;
|
||||||
// py_Str__ctor2(&tmp, t->start, t->length);
|
py_Str__ctor2(&tmp, t->start, t->length);
|
||||||
// printf("[%d] %s: %s\n", t->line, pk_TokenSymbols[t->type], py_Str__data(&tmp));
|
printf("[%d] %s: %s\n", t->line, pk_TokenSymbols[t->type], py_Str__data(&tmp));
|
||||||
// py_Str__dtor(&tmp);
|
py_Str__dtor(&tmp);
|
||||||
// }
|
}
|
||||||
|
|
||||||
Compiler compiler;
|
Compiler compiler;
|
||||||
Compiler__ctor(&compiler, src, tokens);
|
Compiler__ctor(&compiler, src, tokens);
|
||||||
|
@ -376,7 +376,7 @@ static Error* eat_number(pk_Lexer* self){
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// try integer
|
// try integer
|
||||||
TokenValue value = {.index = TokenValue_EMPTY};
|
TokenValue value = {.index = TokenValue_I64};
|
||||||
switch(parse_uint(text, &value._i64, -1)) {
|
switch(parse_uint(text, &value._i64, -1)) {
|
||||||
case IntParsing_SUCCESS:
|
case IntParsing_SUCCESS:
|
||||||
add_token_with_value(self, TK_NUM, value);
|
add_token_with_value(self, TK_NUM, value);
|
||||||
|
@ -203,7 +203,36 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
if(err) goto __ERROR;
|
if(err) goto __ERROR;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
/*******************/
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
/*******************/
|
||||||
|
case OP_BUILD_TUPLE: {
|
||||||
|
py_TValue tmp;
|
||||||
|
py_newtuple(&tmp, byte.arg);
|
||||||
|
py_TValue* begin = SP() - byte.arg;
|
||||||
|
for(int i = 0; i < byte.arg; i++) {
|
||||||
|
py_tuple__setitem(&tmp, i, begin + i);
|
||||||
|
}
|
||||||
|
SP() = begin;
|
||||||
|
PUSH(tmp);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
/**************************** */
|
||||||
|
case OP_RETURN_VALUE: {
|
||||||
|
py_TValue tmp = byte.arg == BC_NOARG ? POPX() : self->None;
|
||||||
|
pk_VM__pop_frame(self);
|
||||||
|
if(frame == base_frame) { // [ frameBase<- ]
|
||||||
|
self->last_retval = tmp;
|
||||||
|
return RES_RETURN;
|
||||||
|
} else {
|
||||||
|
frame = self->top_frame;
|
||||||
|
PUSH(tmp);
|
||||||
|
goto __NEXT_FRAME;
|
||||||
|
}
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
default: PK_UNREACHABLE();
|
default: PK_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ Frame* Frame__new(const CodeObject* co, const py_TValue* module, const py_TValue
|
|||||||
self->ip = (Bytecode*)co->codes.data - 1;
|
self->ip = (Bytecode*)co->codes.data - 1;
|
||||||
self->co = co;
|
self->co = co;
|
||||||
self->module = module->_obj;
|
self->module = module->_obj;
|
||||||
self->function = function->_obj;
|
self->function = function ? function->_obj : NULL;
|
||||||
self->p0 = p0;
|
self->p0 = p0;
|
||||||
self->locals = locals;
|
self->locals = locals;
|
||||||
self->locals_co = locals_co;
|
self->locals_co = locals_co;
|
||||||
@ -131,3 +131,11 @@ void Frame__set_unwind_target(Frame* self, py_TValue* sp) {
|
|||||||
self->uw_list = UnwindTarget__new(prev, iblock, sp - self->locals);
|
self->uw_list = UnwindTarget__new(prev, iblock, sp - self->locals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
py_TValue* Frame__f_closure_try_get(Frame* self, StrName name){
|
||||||
|
// if(self->function == NULL) return NULL;
|
||||||
|
// pkpy::Function* fn = PyObject__as(pkpy::Function, self->function);
|
||||||
|
// if(fn->_closure == nullptr) return nullptr;
|
||||||
|
// return pk_NameDict__try_get(fn->_closure, name);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -56,6 +56,7 @@ void pk_VM__ctor(pk_VM* self){
|
|||||||
self->_stderr = pk_default_stderr;
|
self->_stderr = pk_default_stderr;
|
||||||
|
|
||||||
self->last_error = NULL;
|
self->last_error = NULL;
|
||||||
|
self->last_retval = PY_NULL;
|
||||||
|
|
||||||
self->__curr_class = NULL;
|
self->__curr_class = NULL;
|
||||||
self->__cached_object_new = NULL;
|
self->__cached_object_new = NULL;
|
||||||
@ -153,7 +154,9 @@ void pk_VM__ctor(pk_VM* self){
|
|||||||
}
|
}
|
||||||
|
|
||||||
void pk_VM__dtor(pk_VM* self){
|
void pk_VM__dtor(pk_VM* self){
|
||||||
|
if(self->__dynamic_func_decl){
|
||||||
PK_DECREF(self->__dynamic_func_decl);
|
PK_DECREF(self->__dynamic_func_decl);
|
||||||
|
}
|
||||||
// destroy all objects
|
// destroy all objects
|
||||||
pk_ManagedHeap__dtor(&self->heap);
|
pk_ManagedHeap__dtor(&self->heap);
|
||||||
// clear frames
|
// clear frames
|
||||||
@ -171,6 +174,9 @@ 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){
|
||||||
assert(self->top_frame);
|
assert(self->top_frame);
|
||||||
Frame* frame = self->top_frame;
|
Frame* frame = self->top_frame;
|
||||||
|
// reset stack pointer
|
||||||
|
self->stack.sp = frame->p0;
|
||||||
|
// pop frame and delete
|
||||||
self->top_frame = frame->f_back;
|
self->top_frame = frame->f_back;
|
||||||
Frame__delete(frame);
|
Frame__delete(frame);
|
||||||
}
|
}
|
||||||
@ -187,7 +193,7 @@ py_Type pk_VM__new_type(pk_VM* self, const char* name, py_Type base, const py_TV
|
|||||||
|
|
||||||
/****************************************/
|
/****************************************/
|
||||||
void PyObject__delete(PyObject *self){
|
void PyObject__delete(PyObject *self){
|
||||||
pk_TypeInfo* ti = c11__getitem(pk_TypeInfo*, &pk_current_vm->types, self->type);
|
pk_TypeInfo* ti = c11__at(pk_TypeInfo, &pk_current_vm->types, self->type);
|
||||||
if(ti->dtor) ti->dtor(PyObject__value(self));
|
if(ti->dtor) ti->dtor(PyObject__value(self));
|
||||||
if(self->slots == -1) pk_NameDict__dtor(PyObject__dict(self));
|
if(self->slots == -1) pk_NameDict__dtor(PyObject__dict(self));
|
||||||
if(self->gc_is_large){
|
if(self->gc_is_large){
|
||||||
|
@ -14,3 +14,15 @@ int py_repr(const py_Ref val) {
|
|||||||
if(ti->m__repr__) return ti->m__repr__(1, val);
|
if(ti->m__repr__) return ti->m__repr__(1, val);
|
||||||
return py_callmethod(val, __repr__);
|
return py_callmethod(val, __repr__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int py_getattr(const py_Ref self, py_Name name, py_Ref out){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int py_setattr(py_Ref self, py_Name name, const py_Ref val){
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int py_callmethod(py_Ref self, py_Name name, ...){
|
||||||
|
return -1;
|
||||||
|
}
|
25
src/public/py_tuple.c
Normal file
25
src/public/py_tuple.c
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "pocketpy/pocketpy.h"
|
||||||
|
|
||||||
|
#include "pocketpy/common/utils.h"
|
||||||
|
#include "pocketpy/objects/object.h"
|
||||||
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
|
||||||
|
void py_newtuple(py_Ref out, int n) {
|
||||||
|
pk_VM* vm = pk_current_vm;
|
||||||
|
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0);
|
||||||
|
out->type = tp_tuple;
|
||||||
|
out->is_ptr = true;
|
||||||
|
out->_obj = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
py_Ref py_tuple__getitem(const py_Ref self, int i){
|
||||||
|
return py_getslot(self, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void py_tuple__setitem(py_Ref self, int i, const py_Ref val){
|
||||||
|
py_setslot(self, i, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int py_tuple__len(const py_Ref self){
|
||||||
|
return self->_obj->slots;
|
||||||
|
}
|
@ -4,6 +4,13 @@
|
|||||||
#include "pocketpy/objects/object.h"
|
#include "pocketpy/objects/object.h"
|
||||||
#include "pocketpy/interpreter/vm.h"
|
#include "pocketpy/interpreter/vm.h"
|
||||||
|
|
||||||
|
py_Ref py_getreg(int i){
|
||||||
|
return pk_current_vm->reg + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void py_setreg(int i, const py_Ref val){
|
||||||
|
pk_current_vm->reg[i] = *val;
|
||||||
|
}
|
||||||
|
|
||||||
py_Ref py_getdict(const py_Ref self, py_Name name){
|
py_Ref py_getdict(const py_Ref self, py_Name name){
|
||||||
assert(self && self->is_ptr);
|
assert(self && self->is_ptr);
|
||||||
|
@ -46,14 +46,6 @@ void py_newnone(py_Ref out) {
|
|||||||
|
|
||||||
void py_newnull(py_Ref out) { out->type = 0; }
|
void py_newnull(py_Ref out) { out->type = 0; }
|
||||||
|
|
||||||
void py_newtuple(py_Ref out, int n) {
|
|
||||||
pk_VM* vm = pk_current_vm;
|
|
||||||
PyObject* obj = pk_ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0);
|
|
||||||
out->type = tp_tuple;
|
|
||||||
out->is_ptr = true;
|
|
||||||
out->_obj = obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
void py_newfunction(py_Ref out, py_CFunction f, const char* sig) {
|
void py_newfunction(py_Ref out, py_CFunction f, const char* sig) {
|
||||||
py_newfunction2(out, f, sig, BindType_FUNCTION, NULL, NULL);
|
py_newfunction2(out, f, sig, BindType_FUNCTION, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ void py_finalize() {
|
|||||||
|
|
||||||
int py_exec(const char* source) { PK_UNREACHABLE(); }
|
int py_exec(const char* source) { PK_UNREACHABLE(); }
|
||||||
|
|
||||||
int py_eval(const char* source) {
|
int py_eval(const char* source, py_Ref out) {
|
||||||
CodeObject co;
|
CodeObject co;
|
||||||
pk_SourceData_ src = pk_SourceData__rcnew(source, "main.py", EVAL_MODE, false);
|
pk_SourceData_ src = pk_SourceData__rcnew(source, "main.py", EVAL_MODE, false);
|
||||||
Error* err = pk_compile(src, &co);
|
Error* err = pk_compile(src, &co);
|
||||||
@ -40,6 +40,9 @@ int py_eval(const char* source) {
|
|||||||
CodeObject__dtor(&co);
|
CodeObject__dtor(&co);
|
||||||
PK_DECREF(src);
|
PK_DECREF(src);
|
||||||
if(res == RES_ERROR) return vm->last_error->type;
|
if(res == RES_ERROR) return vm->last_error->type;
|
||||||
if(res == RES_RETURN) return 0;
|
if(res == RES_RETURN){
|
||||||
|
*out = vm->last_retval;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
PK_UNREACHABLE();
|
PK_UNREACHABLE();
|
||||||
}
|
}
|
10
src2/main.c
10
src2/main.c
@ -25,19 +25,19 @@ int main(int argc, char** argv) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
py_initialize();
|
py_initialize();
|
||||||
const char* source = "[1, 'a']";
|
const char* source = "1, 'a'";
|
||||||
|
|
||||||
if(py_eval(source)){
|
py_Ref r0 = py_getreg(0);
|
||||||
|
if(py_eval(source, r0)){
|
||||||
py_Error* err = py_getlasterror();
|
py_Error* err = py_getlasterror();
|
||||||
py_Error__print(err);
|
py_Error__print(err);
|
||||||
}else{
|
}else{
|
||||||
// handle the result
|
// handle the result
|
||||||
py_Ref _0 = py_list__getitem(py_gettop(), 0);
|
py_Ref _0 = py_tuple__getitem(r0, 0);
|
||||||
py_Ref _1 = py_list__getitem(py_gettop(), 1);
|
py_Ref _1 = py_tuple__getitem(r0, 1);
|
||||||
int _L0 = py_toint(_0);
|
int _L0 = py_toint(_0);
|
||||||
const char* _L1 = py_tostr(_1);
|
const char* _L1 = py_tostr(_1);
|
||||||
printf("%d, %s\n", _L0, _L1);
|
printf("%d, %s\n", _L0, _L1);
|
||||||
py_pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
py_finalize();
|
py_finalize();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user