Ver Fonte

fix initial demo

blueloveTH há 1 ano atrás
pai
commit
5be3300554

+ 2 - 2
build_g.sh

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

+ 0 - 15
include/pocketpy/interpreter/frame.h

@@ -89,18 +89,3 @@ void Frame__set_unwind_target(Frame* self, py_TValue* sp);
 #ifdef __cplusplus
 }
 #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

+ 3 - 1
include/pocketpy/interpreter/vm.h

@@ -58,8 +58,10 @@ typedef struct pk_VM {
     
     // singleton objects
     py_TValue True, False, None, NotImplemented, Ellipsis;
-    // last error
+
     py_Error* last_error;
+    py_TValue last_retval;
+    py_TValue reg[8];   // users' registers
 
     PyObject* __curr_class;
     PyObject* __cached_object_new;

+ 4 - 3
include/pocketpy/pocketpy.h

@@ -31,7 +31,7 @@ void py_finalize();
 /// Run a simple source string. Do not change the stack.
 int py_exec(const char*);
 /// 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 *************/
 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);
 
 /************* 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);
 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);
 void py_tuple__setitem(py_Ref self, int i, const py_Ref val);
 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
 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__delitem(py_Ref self, int i);
 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__extend(py_Ref self, const py_Ref begin, const py_Ref end);
 void py_list__clear(py_Ref self);

+ 4 - 0
src/common/strname.c

@@ -79,6 +79,10 @@ void pk_StrName__initialize(){
 
 void pk_StrName__finalize(){
     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_vector__dtor(&_r_interned);
 }

+ 13 - 12
src/compiler/compiler.c

@@ -468,7 +468,7 @@ static SequenceExpr* SequenceExpr__new(int line, const ExprVt* vt, int count, Op
     self->vt = vt;
     self->line = line;
     self->opcode = opcode;
-    c11_array__ctor(&self->items, count, sizeof(Expr*));
+    c11_array__ctor(&self->items, sizeof(Expr*), count);
     return self;
 }
 
@@ -1395,7 +1395,7 @@ void Ctx__emit_store_name(Ctx* self, NameScope scope, StrName name, int line) {
 // emit top -> pop -> delete
 void Ctx__s_emit_top(Ctx* self) {
     Expr* top = c11_vector__back(Expr*, &self->s_expr);
-    top->vt->emit_(top, self);
+    vtemit_(top, self);
     c11_vector__pop(&self->s_expr);
     vtdelete(top);
 }
@@ -1670,7 +1670,8 @@ static Error* pop_context(Compiler* self) {
 
 /* Expression Callbacks */
 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;
 }
 
@@ -2064,15 +2065,15 @@ Error* pk_compile(pk_SourceData_ src, CodeObject* out) {
     Error* err = pk_Lexer__process(src, &tokens);
     if(err) return err;
 
-    // Token* data = (Token*)tokens.data;
-    // printf("%s\n", py_Str__data(&src->filename));
-    // for(int i = 0; i < tokens.count; i++) {
-    //     Token* t = data + i;
-    //     py_Str tmp;
-    //     py_Str__ctor2(&tmp, t->start, t->length);
-    //     printf("[%d] %s: %s\n", t->line, pk_TokenSymbols[t->type], py_Str__data(&tmp));
-    //     py_Str__dtor(&tmp);
-    // }
+    Token* data = (Token*)tokens.data;
+    printf("%s\n", py_Str__data(&src->filename));
+    for(int i = 0; i < tokens.count; i++) {
+        Token* t = data + i;
+        py_Str tmp;
+        py_Str__ctor2(&tmp, t->start, t->length);
+        printf("[%d] %s: %s\n", t->line, pk_TokenSymbols[t->type], py_Str__data(&tmp));
+        py_Str__dtor(&tmp);
+    }
 
     Compiler compiler;
     Compiler__ctor(&compiler, src, tokens);

+ 1 - 1
src/compiler/lexer.c

@@ -376,7 +376,7 @@ static Error* eat_number(pk_Lexer* self){
             return NULL;
         }
         // try integer
-        TokenValue value = {.index = TokenValue_EMPTY};
+        TokenValue value = {.index = TokenValue_I64};
         switch(parse_uint(text, &value._i64, -1)) {
             case IntParsing_SUCCESS:
                 add_token_with_value(self, TK_NUM, value);

+ 29 - 0
src/interpreter/ceval.c

@@ -203,7 +203,36 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
                 if(err) goto __ERROR;
                 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();
         }
 

+ 9 - 1
src/interpreter/frame.c

@@ -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->co = co;
     self->module = module->_obj;
-    self->function = function->_obj;
+    self->function = function ? function->_obj : NULL;
     self->p0 = p0;
     self->locals = locals;
     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);
     }
 }
+
+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;
+}

+ 8 - 2
src/interpreter/vm.c

@@ -56,6 +56,7 @@ void pk_VM__ctor(pk_VM* self){
     self->_stderr = pk_default_stderr;
 
     self->last_error = NULL;
+    self->last_retval = PY_NULL;
 
     self->__curr_class = NULL;
     self->__cached_object_new = NULL;
@@ -153,7 +154,9 @@ void pk_VM__ctor(pk_VM* self){
 }
 
 void pk_VM__dtor(pk_VM* self){
-    PK_DECREF(self->__dynamic_func_decl);
+    if(self->__dynamic_func_decl){
+        PK_DECREF(self->__dynamic_func_decl);
+    }
     // destroy all objects
     pk_ManagedHeap__dtor(&self->heap);
     // clear frames
@@ -171,6 +174,9 @@ void pk_VM__push_frame(pk_VM* self, Frame* frame){
 void pk_VM__pop_frame(pk_VM* self){
     assert(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;
     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){
-    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(self->slots == -1) pk_NameDict__dtor(PyObject__dict(self));
     if(self->gc_is_large){

+ 12 - 0
src/public/py_ops.c

@@ -13,4 +13,16 @@ int py_repr(const py_Ref val) {
     const pk_TypeInfo* ti = c11__at(pk_TypeInfo, &pk_current_vm->types, val->type);
     if(ti->m__repr__) return ti->m__repr__(1, val);
     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 - 0
src/public/py_tuple.c

@@ -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;
+}

+ 7 - 0
src/public/stack_ops.c

@@ -4,6 +4,13 @@
 #include "pocketpy/objects/object.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){
     assert(self && self->is_ptr);

+ 0 - 8
src/public/values.c

@@ -46,14 +46,6 @@ void py_newnone(py_Ref out) {
 
 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) {
     py_newfunction2(out, f, sig, BindType_FUNCTION, NULL, NULL);
 }

+ 5 - 2
src/public/vm.c

@@ -25,7 +25,7 @@ void py_finalize() {
 
 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;
     pk_SourceData_ src = pk_SourceData__rcnew(source, "main.py", EVAL_MODE, false);
     Error* err = pk_compile(src, &co);
@@ -40,6 +40,9 @@ int py_eval(const char* source) {
     CodeObject__dtor(&co);
     PK_DECREF(src);
     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();
 }

+ 5 - 5
src2/main.c

@@ -25,19 +25,19 @@ int main(int argc, char** argv) {
 #endif
 
     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__print(err);
     }else{
         // handle the result
-        py_Ref _0 = py_list__getitem(py_gettop(), 0);
-        py_Ref _1 = py_list__getitem(py_gettop(), 1);
+        py_Ref _0 = py_tuple__getitem(r0, 0);
+        py_Ref _1 = py_tuple__getitem(r0, 1);
         int _L0 = py_toint(_0);
         const char* _L1 = py_tostr(_1);
         printf("%d, %s\n", _L0, _L1);
-        py_pop();
     }
 
     py_finalize();