mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some up
This commit is contained in:
parent
1696bb6d66
commit
e365124af3
@ -27,6 +27,7 @@ static void pk_SourceData__ctor(struct pk_SourceData* self,
|
|||||||
}
|
}
|
||||||
self->source = c11_sbuf__submit(&ss);
|
self->source = c11_sbuf__submit(&ss);
|
||||||
self->is_precompiled = (strncmp(source, "pkpy:", 5) == 0);
|
self->is_precompiled = (strncmp(source, "pkpy:", 5) == 0);
|
||||||
|
self->is_dynamic = is_dynamic;
|
||||||
c11_vector__push(const char*, &self->line_starts, self->source->data);
|
c11_vector__push(const char*, &self->line_starts, self->source->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,12 +10,10 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
const static int C11_STRING_HEADER_SIZE = sizeof(c11_string);
|
|
||||||
|
|
||||||
void c11_sbuf__ctor(c11_sbuf* self) {
|
void c11_sbuf__ctor(c11_sbuf* self) {
|
||||||
c11_vector__ctor(&self->data, sizeof(char));
|
c11_vector__ctor(&self->data, sizeof(char));
|
||||||
c11_vector__reserve(&self->data, 100 + C11_STRING_HEADER_SIZE);
|
c11_vector__reserve(&self->data, 100 + sizeof(c11_string));
|
||||||
self->data.count = C11_STRING_HEADER_SIZE;
|
self->data.count = sizeof(c11_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
void c11_sbuf__dtor(c11_sbuf* self) { c11_vector__dtor(&self->data); }
|
void c11_sbuf__dtor(c11_sbuf* self) { c11_vector__dtor(&self->data); }
|
||||||
@ -137,7 +135,7 @@ c11_string* c11_sbuf__submit(c11_sbuf* self) {
|
|||||||
c11_vector__push(char, &self->data, '\0');
|
c11_vector__push(char, &self->data, '\0');
|
||||||
c11_array arr = c11_vector__submit(&self->data);
|
c11_array arr = c11_vector__submit(&self->data);
|
||||||
c11_string* retval = (c11_string*)arr.data;
|
c11_string* retval = (c11_string*)arr.data;
|
||||||
retval->size = arr.count - C11_STRING_HEADER_SIZE - 1;
|
retval->size = arr.count - sizeof(c11_string) - 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ typedef struct Ctx {
|
|||||||
int curr_iblock;
|
int curr_iblock;
|
||||||
bool is_compiling_class;
|
bool is_compiling_class;
|
||||||
c11_vector /*T=Expr* */ s_expr;
|
c11_vector /*T=Expr* */ s_expr;
|
||||||
c11_vector /*T=py_Name*/ global_names;
|
c11_smallmap_n2i global_names;
|
||||||
c11_smallmap_s2n co_consts_string_dedup_map;
|
c11_smallmap_s2n co_consts_string_dedup_map;
|
||||||
} Ctx;
|
} Ctx;
|
||||||
|
|
||||||
@ -1209,7 +1209,7 @@ void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level) {
|
|||||||
self->curr_iblock = 0;
|
self->curr_iblock = 0;
|
||||||
self->is_compiling_class = false;
|
self->is_compiling_class = false;
|
||||||
c11_vector__ctor(&self->s_expr, sizeof(Expr*));
|
c11_vector__ctor(&self->s_expr, sizeof(Expr*));
|
||||||
c11_vector__ctor(&self->global_names, sizeof(py_Name));
|
c11_smallmap_n2i__ctor(&self->global_names);
|
||||||
c11_smallmap_s2n__ctor(&self->co_consts_string_dedup_map);
|
c11_smallmap_s2n__ctor(&self->co_consts_string_dedup_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1220,7 +1220,7 @@ void Ctx__dtor(Ctx* self) {
|
|||||||
}
|
}
|
||||||
c11_vector__clear(&self->s_expr);
|
c11_vector__clear(&self->s_expr);
|
||||||
c11_vector__dtor(&self->s_expr);
|
c11_vector__dtor(&self->s_expr);
|
||||||
c11_vector__dtor(&self->global_names);
|
c11_smallmap_n2i__dtor(&self->global_names);
|
||||||
c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map);
|
c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1455,7 +1455,7 @@ static void Compiler__dtor(Compiler* self) {
|
|||||||
pk_TokenSymbols[expected], \
|
pk_TokenSymbols[expected], \
|
||||||
pk_TokenSymbols[curr()->type]);
|
pk_TokenSymbols[curr()->type]);
|
||||||
#define consume_end_stmt() \
|
#define consume_end_stmt() \
|
||||||
if(!match_end_stmt()) return SyntaxError("expected statement end")
|
if(!match_end_stmt(self)) return SyntaxError("expected statement end")
|
||||||
#define check_newlines_repl() \
|
#define check_newlines_repl() \
|
||||||
do { \
|
do { \
|
||||||
bool __nml; \
|
bool __nml; \
|
||||||
@ -1471,7 +1471,7 @@ static NameScope name_scope(Compiler* self) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Error* SyntaxError(const char* fmt, ...) { return NULL; }
|
#define SyntaxError(...) NULL
|
||||||
|
|
||||||
static Error* NeedMoreLines() { return NULL; }
|
static Error* NeedMoreLines() { return NULL; }
|
||||||
|
|
||||||
@ -1798,10 +1798,7 @@ static Error* exprName(Compiler* self) {
|
|||||||
py_Name name = py_name2(Token__sv(prev()));
|
py_Name name = py_name2(Token__sv(prev()));
|
||||||
NameScope scope = name_scope(self);
|
NameScope scope = name_scope(self);
|
||||||
// promote this name to global scope if needed
|
// promote this name to global scope if needed
|
||||||
c11_vector* global_names = &ctx()->global_names;
|
if(c11_smallmap_n2i__contains(&ctx()->global_names, name)) { scope = NAME_GLOBAL; }
|
||||||
c11__foreach(py_Name, global_names, it) {
|
|
||||||
if(*it == name) scope = NAME_GLOBAL;
|
|
||||||
}
|
|
||||||
NameExpr* e = NameExpr__new(prev()->line, name, scope);
|
NameExpr* e = NameExpr__new(prev()->line, name, scope);
|
||||||
Ctx__s_push(ctx(), (Expr*)e);
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -2005,6 +2002,258 @@ static Error* exprSubscr(Compiler* self) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
static Error* consume_type_hints(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
check(EXPR(self));
|
||||||
|
Ctx__s_pop(ctx());
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error* try_compile_assignment(Compiler* self, bool* is_assign) {
|
||||||
|
Error* err;
|
||||||
|
switch(curr()->type) {
|
||||||
|
case TK_IADD:
|
||||||
|
case TK_ISUB:
|
||||||
|
case TK_IMUL:
|
||||||
|
case TK_IDIV:
|
||||||
|
case TK_IFLOORDIV:
|
||||||
|
case TK_IMOD:
|
||||||
|
case TK_ILSHIFT:
|
||||||
|
case TK_IRSHIFT:
|
||||||
|
case TK_IAND:
|
||||||
|
case TK_IOR:
|
||||||
|
case TK_IXOR: {
|
||||||
|
if(Ctx__s_top(ctx())->vt->is_starred) return SyntaxError();
|
||||||
|
if(ctx()->is_compiling_class) {
|
||||||
|
return SyntaxError("can't use inplace operator in class definition");
|
||||||
|
}
|
||||||
|
advance();
|
||||||
|
// a[x] += 1; a and x should be evaluated only once
|
||||||
|
// a.x += 1; a should be evaluated only once
|
||||||
|
// -1 to remove =; inplace=true
|
||||||
|
int line = prev()->line;
|
||||||
|
TokenIndex op = (TokenIndex)(prev()->type - 1);
|
||||||
|
// [lhs]
|
||||||
|
check(EXPR_TUPLE(self)); // [lhs, rhs]
|
||||||
|
if(Ctx__s_top(ctx())->vt->is_starred) return SyntaxError();
|
||||||
|
BinaryExpr* e = BinaryExpr__new(line, op, true);
|
||||||
|
e->rhs = Ctx__s_popx(ctx()); // [lhs]
|
||||||
|
e->lhs = Ctx__s_popx(ctx()); // []
|
||||||
|
vtemit_((Expr*)e, ctx());
|
||||||
|
bool ok = vtemit_istore(e->lhs, ctx());
|
||||||
|
vtdelete((Expr*)e);
|
||||||
|
if(!ok) return SyntaxError();
|
||||||
|
*is_assign = true;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
case TK_ASSIGN: {
|
||||||
|
int n = 0;
|
||||||
|
while(match(TK_ASSIGN)) {
|
||||||
|
check(EXPR_TUPLE(self));
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
// stack size is n+1
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
for(int j = 1; j < n; j++)
|
||||||
|
Ctx__emit_(ctx(), OP_DUP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||||
|
for(int j = 0; j < n; j++) {
|
||||||
|
if(Ctx__s_top(ctx())->vt->is_starred) return SyntaxError();
|
||||||
|
Expr* e = Ctx__s_top(ctx());
|
||||||
|
bool ok = vtemit_store(e, ctx());
|
||||||
|
Ctx__s_pop(ctx());
|
||||||
|
if(!ok) return SyntaxError();
|
||||||
|
}
|
||||||
|
*is_assign = true;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
default: *is_assign = false;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* compile_stmt(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
if(match(TK_CLASS)) {
|
||||||
|
// check(compile_class());
|
||||||
|
assert(false);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
advance();
|
||||||
|
int kw_line = prev()->line; // backup line number
|
||||||
|
int curr_loop_block = Ctx__get_loop(ctx());
|
||||||
|
switch(prev()->type) {
|
||||||
|
case TK_BREAK:
|
||||||
|
if(curr_loop_block < 0) return SyntaxError("'break' outside loop");
|
||||||
|
Ctx__emit_(ctx(), OP_LOOP_BREAK, curr_loop_block, kw_line);
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
case TK_CONTINUE:
|
||||||
|
if(curr_loop_block < 0) return SyntaxError("'continue' not properly in loop");
|
||||||
|
Ctx__emit_(ctx(), OP_LOOP_CONTINUE, curr_loop_block, kw_line);
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
case TK_YIELD:
|
||||||
|
if(self->contexts.count <= 1) return SyntaxError("'yield' outside function");
|
||||||
|
check(EXPR_TUPLE(self));
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
Ctx__emit_(ctx(), OP_YIELD_VALUE, BC_NOARG, kw_line);
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
case TK_YIELD_FROM:
|
||||||
|
if(self->contexts.count <= 1) return SyntaxError("'yield from' outside function");
|
||||||
|
check(EXPR_TUPLE(self));
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
Ctx__emit_(ctx(), OP_GET_ITER_NEW, BC_NOARG, kw_line);
|
||||||
|
Ctx__enter_block(ctx(), CodeBlockType_FOR_LOOP);
|
||||||
|
Ctx__emit_(ctx(), OP_FOR_ITER_YIELD_VALUE, BC_NOARG, kw_line);
|
||||||
|
Ctx__emit_(ctx(), OP_LOOP_CONTINUE, Ctx__get_loop(ctx()), kw_line);
|
||||||
|
Ctx__exit_block(ctx());
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
case TK_RETURN:
|
||||||
|
if(self->contexts.count <= 1) return SyntaxError("'return' outside function");
|
||||||
|
if(match_end_stmt(self)) {
|
||||||
|
Ctx__emit_(ctx(), OP_RETURN_VALUE, 1, kw_line);
|
||||||
|
} else {
|
||||||
|
check(EXPR_TUPLE(self));
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
consume_end_stmt();
|
||||||
|
Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, kw_line);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/*************************************************/
|
||||||
|
// case TK_IF: check(compile_if_stmt()); break;
|
||||||
|
// case TK_WHILE: check(compile_while_loop()); break;
|
||||||
|
// case TK_FOR: check(compile_for_loop()); break;
|
||||||
|
// case TK_IMPORT: check(compile_normal_import()); break;
|
||||||
|
// case TK_FROM: check(compile_from_import()); break;
|
||||||
|
// case TK_DEF: check(compile_function()); break;
|
||||||
|
// case TK_DECORATOR: check(compile_decorated()); break;
|
||||||
|
// case TK_TRY: check(compile_try_except()); break;
|
||||||
|
case TK_PASS: consume_end_stmt(); break;
|
||||||
|
/*************************************************/
|
||||||
|
case TK_ASSERT: {
|
||||||
|
check(EXPR(self)); // condition
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
int index = Ctx__emit_(ctx(), OP_POP_JUMP_IF_TRUE, BC_NOARG, kw_line);
|
||||||
|
int has_msg = 0;
|
||||||
|
if(match(TK_COMMA)) {
|
||||||
|
check(EXPR(self)); // message
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
has_msg = 1;
|
||||||
|
}
|
||||||
|
Ctx__emit_(ctx(), OP_RAISE_ASSERT, has_msg, kw_line);
|
||||||
|
Ctx__patch_jump(ctx(), index);
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TK_GLOBAL:
|
||||||
|
do {
|
||||||
|
consume(TK_ID);
|
||||||
|
py_Name name = py_name2(Token__sv(prev()));
|
||||||
|
c11_smallmap_n2i__set(&ctx()->global_names, name, 0);
|
||||||
|
} while(match(TK_COMMA));
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
case TK_RAISE: {
|
||||||
|
check(EXPR(self));
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
Ctx__emit_(ctx(), OP_RAISE, BC_NOARG, kw_line);
|
||||||
|
consume_end_stmt();
|
||||||
|
} break;
|
||||||
|
case TK_DEL: {
|
||||||
|
check(EXPR_TUPLE(self));
|
||||||
|
Expr* e = Ctx__s_top(ctx());
|
||||||
|
if(!vtemit_del(e, ctx())) return SyntaxError();
|
||||||
|
Ctx__s_pop(ctx());
|
||||||
|
consume_end_stmt();
|
||||||
|
} break;
|
||||||
|
// case TK_WITH: {
|
||||||
|
// check(EXPR(self)); // [ <expr> ]
|
||||||
|
// Ctx__s_emit_top(ctx());
|
||||||
|
// Ctx__enter_block(ctx(), CodeBlockType_CONTEXT_MANAGER);
|
||||||
|
// Expr* as_name = nullptr;
|
||||||
|
// if(match(TK_AS)) {
|
||||||
|
// consume(TK_ID);
|
||||||
|
// as_name = make_expr<NameExpr>(prev().str(), name_scope());
|
||||||
|
// }
|
||||||
|
// Ctx__emit_(ctx(), OP_WITH_ENTER, BC_NOARG, prev().line);
|
||||||
|
// // [ <expr> <expr>.__enter__() ]
|
||||||
|
// if(as_name) {
|
||||||
|
// bool ok = as_name->emit_store(ctx());
|
||||||
|
// delete_expr(as_name);
|
||||||
|
// if(!ok) return SyntaxError();
|
||||||
|
// } else {
|
||||||
|
// Ctx__emit_(ctx(), OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||||
|
// }
|
||||||
|
// check(compile_block_body());
|
||||||
|
// Ctx__emit_(ctx(), OP_WITH_EXIT, BC_NOARG, prev().line);
|
||||||
|
// Ctx__exit_block(ctx());
|
||||||
|
// } break;
|
||||||
|
/*************************************************/
|
||||||
|
case TK_EQ: {
|
||||||
|
consume(TK_ID);
|
||||||
|
if(mode() != EXEC_MODE) return SyntaxError("'label' is only available in EXEC_MODE");
|
||||||
|
c11_sv name = Token__sv(prev());
|
||||||
|
bool ok = Ctx__add_label(ctx(), py_name2(name));
|
||||||
|
if(!ok) return SyntaxError("label %q already exists", name);
|
||||||
|
consume(TK_EQ);
|
||||||
|
consume_end_stmt();
|
||||||
|
} break;
|
||||||
|
case TK_ARROW:
|
||||||
|
consume(TK_ID);
|
||||||
|
if(mode() != EXEC_MODE) return SyntaxError("'goto' is only available in EXEC_MODE");
|
||||||
|
py_Name name = py_name2(Token__sv(prev()));
|
||||||
|
Ctx__emit_(ctx(), OP_GOTO, name, prev()->line);
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
/*************************************************/
|
||||||
|
// handle dangling expression or assignment
|
||||||
|
default: {
|
||||||
|
// do revert since we have pre-called advance() at the beginning
|
||||||
|
--self->i;
|
||||||
|
|
||||||
|
check(EXPR_TUPLE(self));
|
||||||
|
|
||||||
|
bool is_typed_name = false; // e.g. x: int
|
||||||
|
// eat variable's type hint if it is a single name
|
||||||
|
if(Ctx__s_top(ctx())->vt->is_name) {
|
||||||
|
if(match(TK_COLON)) {
|
||||||
|
check(consume_type_hints(self));
|
||||||
|
is_typed_name = true;
|
||||||
|
|
||||||
|
if(ctx()->is_compiling_class) {
|
||||||
|
NameExpr* ne = (NameExpr*)Ctx__s_top(ctx());
|
||||||
|
Ctx__emit_(ctx(), OP_ADD_CLASS_ANNOTATION, ne->name, BC_KEEPLINE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool is_assign = false;
|
||||||
|
check(try_compile_assignment(self, &is_assign));
|
||||||
|
if(!is_assign) {
|
||||||
|
if(Ctx__s_size(ctx()) > 0 && Ctx__s_top(ctx())->vt->is_starred) {
|
||||||
|
return SyntaxError();
|
||||||
|
}
|
||||||
|
if(!is_typed_name) {
|
||||||
|
Ctx__s_emit_top(ctx());
|
||||||
|
if((mode() == CELL_MODE || mode() == REPL_MODE) &&
|
||||||
|
name_scope(self) == NAME_GLOBAL) {
|
||||||
|
Ctx__emit_(ctx(), OP_PRINT_EXPR, BC_NOARG, BC_KEEPLINE);
|
||||||
|
} else {
|
||||||
|
Ctx__emit_(ctx(), OP_POP_TOP, BC_NOARG, BC_KEEPLINE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ctx__s_pop(ctx());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
consume_end_stmt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Error* Compiler__compile(Compiler* self, CodeObject* out) {
|
Error* Compiler__compile(Compiler* self, CodeObject* out) {
|
||||||
@ -2026,25 +2275,22 @@ Error* Compiler__compile(Compiler* self, CodeObject* out) {
|
|||||||
Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
||||||
check(pop_context(self));
|
check(pop_context(self));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
} else if(mode() == JSON_MODE) {
|
||||||
|
check(EXPR(self));
|
||||||
|
Expr* e = Ctx__s_popx(ctx());
|
||||||
|
if(!e->vt->is_json_object) { return SyntaxError("expect a JSON object, literal or array"); }
|
||||||
|
consume(TK_EOF);
|
||||||
|
vtemit_(e, ctx());
|
||||||
|
Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
||||||
|
check(pop_context(self));
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
// } else if(mode() == JSON_MODE) {
|
|
||||||
// check(EXPR(self));
|
|
||||||
// Expr* e = Ctx__s_popx(ctx());
|
|
||||||
// if(!e->is_json_object()){
|
|
||||||
// return SyntaxError("expect a JSON object, literal or array");
|
|
||||||
// }
|
|
||||||
// consume(TK_EOF);
|
|
||||||
// e->emit_(ctx());
|
|
||||||
// ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
|
||||||
// check(pop_context());
|
|
||||||
// return NULL;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// while(!match(TK_EOF)) {
|
while(!match(TK_EOF)) {
|
||||||
// check(compile_stmt());
|
check(compile_stmt(self));
|
||||||
// match_newlines();
|
match_newlines();
|
||||||
// }
|
}
|
||||||
// check(pop_context());
|
check(pop_context(self));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2069,6 +2315,8 @@ Error* pk_compile(pk_SourceData_ src, CodeObject* out) {
|
|||||||
if(err) {
|
if(err) {
|
||||||
// if error occurs, dispose the code object
|
// if error occurs, dispose the code object
|
||||||
CodeObject__dtor(out);
|
CodeObject__dtor(out);
|
||||||
|
} else {
|
||||||
|
assert(out->codes.count);
|
||||||
}
|
}
|
||||||
Compiler__dtor(&compiler);
|
Compiler__dtor(&compiler);
|
||||||
return err;
|
return err;
|
||||||
|
@ -620,6 +620,31 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
|
|||||||
}
|
}
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////
|
||||||
|
case OP_UNARY_NEGATIVE: {
|
||||||
|
if(!py_callmagic(__neg__, 1, TOP())) goto __ERROR;
|
||||||
|
*TOP() = self->last_retval;
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
case OP_UNARY_NOT: {
|
||||||
|
int res = py_bool(TOP());
|
||||||
|
if(res < 0) goto __ERROR;
|
||||||
|
py_newbool(TOP(), !res);
|
||||||
|
DISPATCH();
|
||||||
|
}
|
||||||
|
// case OP_UNARY_STAR: TOP() = VAR(StarWrapper(byte.arg, TOP())); DISPATCH();
|
||||||
|
// case OP_UNARY_INVERT: {
|
||||||
|
// PyVar _0;
|
||||||
|
// auto _ti = _tp_info(TOP());
|
||||||
|
// if(_ti->m__invert__)
|
||||||
|
// _0 = _ti->m__invert__(this, TOP());
|
||||||
|
// else
|
||||||
|
// _0 = call_method(TOP(), __invert__);
|
||||||
|
// TOP() = _0;
|
||||||
|
// DISPATCH();
|
||||||
|
// }
|
||||||
|
|
||||||
default: PK_UNREACHABLE();
|
default: PK_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,10 +89,12 @@ static void disassemble(CodeObject* co) {
|
|||||||
case OP_LOAD_CONST:
|
case OP_LOAD_CONST:
|
||||||
case OP_FORMAT_STRING:
|
case OP_FORMAT_STRING:
|
||||||
case OP_IMPORT_PATH: {
|
case OP_IMPORT_PATH: {
|
||||||
c11_string* ud = py_touserdata(c11__at(py_TValue, &co->consts, byte.arg));
|
py_Ref tmp = c11__at(py_TValue, &co->consts, byte.arg);
|
||||||
c11_sbuf__write_cstr(&ss, " (");
|
c11_sbuf__write_cstr(&ss, " (");
|
||||||
c11_sbuf__write_cstr(&ss, ud->data);
|
// here we need to use py_repr, however this function is not ready yet
|
||||||
c11_sbuf__write_char(&ss, ')');
|
c11_sbuf__write_cstr(&ss, "<class '");
|
||||||
|
c11_sbuf__write_cstr(&ss, py_tpname(tmp->type));
|
||||||
|
c11_sbuf__write_cstr(&ss, "'>)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_LOAD_NAME:
|
case OP_LOAD_NAME:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user