mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some fix
This commit is contained in:
parent
c7597dfcdf
commit
62420dade1
@ -11,9 +11,6 @@ extern "C" {
|
||||
|
||||
Error* pk_compile(pk_SourceData_ src, CodeObject* out);
|
||||
|
||||
void pk_Compiler__initialize();
|
||||
#define pk_Compiler__finalize() // do nothing
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -58,7 +58,7 @@ typedef struct pk_StarredExpr{
|
||||
int level;
|
||||
} pk_StarredExpr;
|
||||
|
||||
// InvertExpr, NotExpr, AndExpr, OrExpr, NegatedExpr
|
||||
// InvertExpr, NotExpr, NegatedExpr
|
||||
// NOTE: NegatedExpr always contains a non-const child. Should not generate -1 or -0.1
|
||||
typedef struct pk_UnaryExpr{
|
||||
COMMON_HEADER
|
||||
@ -118,6 +118,34 @@ typedef struct pk_FStringExpr{
|
||||
c11_string src;
|
||||
} pk_FStringExpr;
|
||||
|
||||
// AndExpr, OrExpr
|
||||
typedef struct pk_LogicBinaryExpr{
|
||||
COMMON_HEADER
|
||||
pk_Expr* lhs;
|
||||
pk_Expr* rhs;
|
||||
Opcode opcode;
|
||||
} pk_LogicBinaryExpr;
|
||||
|
||||
typedef struct pk_GroupedExpr{
|
||||
COMMON_HEADER
|
||||
pk_Expr* child;
|
||||
} pk_GroupedExpr;
|
||||
|
||||
typedef struct pk_BinaryExpr{
|
||||
COMMON_HEADER
|
||||
pk_Expr* lhs;
|
||||
pk_Expr* rhs;
|
||||
TokenIndex op;
|
||||
bool inplace;
|
||||
} pk_BinaryExpr;
|
||||
|
||||
typedef struct pk_TernaryExpr{
|
||||
COMMON_HEADER
|
||||
pk_Expr* cond;
|
||||
pk_Expr* true_expr;
|
||||
pk_Expr* false_expr;
|
||||
} pk_TernaryExpr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -12,7 +12,7 @@ typedef struct PrattRule {
|
||||
enum Precedence precedence;
|
||||
} PrattRule;
|
||||
|
||||
static PrattRule rules[TK__COUNT__];
|
||||
const static PrattRule rules[TK__COUNT__];
|
||||
|
||||
typedef struct pk_Compiler {
|
||||
pk_SourceData_ src; // weakref
|
||||
@ -251,56 +251,52 @@ Error* pk_compile(pk_SourceData_ src, CodeObject* out){
|
||||
return err;
|
||||
}
|
||||
|
||||
void pk_Compiler__initialize(){
|
||||
const static PrattRule rules[TK__COUNT__] = {
|
||||
// clang-format off
|
||||
// http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
|
||||
rules[TK_DOT] = (PrattRule){ NULL, exprAttrib, PREC_PRIMARY };
|
||||
rules[TK_LPAREN] = (PrattRule){ exprGroup, exprCall, PREC_PRIMARY };
|
||||
rules[TK_LBRACKET] = (PrattRule){ exprList, exprSubscr, PREC_PRIMARY };
|
||||
rules[TK_MOD] = (PrattRule){ NULL, exprBinaryOp, PREC_FACTOR };
|
||||
rules[TK_ADD] = (PrattRule){ NULL, exprBinaryOp, PREC_TERM };
|
||||
rules[TK_SUB] = (PrattRule){ exprUnaryOp, exprBinaryOp, PREC_TERM };
|
||||
rules[TK_MUL] = (PrattRule){ exprUnaryOp, exprBinaryOp, PREC_FACTOR };
|
||||
rules[TK_INVERT] = (PrattRule){ exprUnaryOp, NULL, PREC_UNARY };
|
||||
rules[TK_DIV] = (PrattRule){ NULL, exprBinaryOp, PREC_FACTOR };
|
||||
rules[TK_FLOORDIV] = (PrattRule){ NULL, exprBinaryOp, PREC_FACTOR };
|
||||
rules[TK_POW] = (PrattRule){ exprUnaryOp, exprBinaryOp, PREC_EXPONENT };
|
||||
rules[TK_GT] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_LT] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_EQ] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_NE] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_GE] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_LE] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_IN] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_IS] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_LSHIFT] = (PrattRule){ NULL, exprBinaryOp, PREC_BITWISE_SHIFT };
|
||||
rules[TK_RSHIFT] = (PrattRule){ NULL, exprBinaryOp, PREC_BITWISE_SHIFT };
|
||||
rules[TK_AND] = (PrattRule){ NULL, exprBinaryOp, PREC_BITWISE_AND };
|
||||
rules[TK_OR] = (PrattRule){ NULL, exprBinaryOp, PREC_BITWISE_OR };
|
||||
rules[TK_XOR] = (PrattRule){ NULL, exprBinaryOp, PREC_BITWISE_XOR };
|
||||
rules[TK_DECORATOR] = (PrattRule){ NULL, exprBinaryOp, PREC_FACTOR };
|
||||
rules[TK_IF] = (PrattRule){ NULL, exprTernary, PREC_TERNARY };
|
||||
rules[TK_NOT_IN] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_IS_NOT] = (PrattRule){ NULL, exprBinaryOp, PREC_COMPARISION };
|
||||
rules[TK_AND_KW ] = (PrattRule){ NULL, exprAnd, PREC_LOGICAL_AND };
|
||||
rules[TK_OR_KW] = (PrattRule){ NULL, exprOr, PREC_LOGICAL_OR };
|
||||
rules[TK_NOT_KW] = (PrattRule){ exprNot, NULL, PREC_LOGICAL_NOT };
|
||||
rules[TK_TRUE] = (PrattRule){ exprLiteral0 };
|
||||
rules[TK_FALSE] = (PrattRule){ exprLiteral0 };
|
||||
rules[TK_NONE] = (PrattRule){ exprLiteral0 };
|
||||
rules[TK_DOTDOTDOT] = (PrattRule){ exprLiteral0 };
|
||||
rules[TK_LAMBDA] = (PrattRule){ exprLambda, };
|
||||
rules[TK_ID] = (PrattRule){ exprName, };
|
||||
rules[TK_NUM] = (PrattRule){ exprLiteral, };
|
||||
rules[TK_STR] = (PrattRule){ exprLiteral, };
|
||||
rules[TK_FSTR] = (PrattRule){ exprFString, };
|
||||
rules[TK_LONG] = (PrattRule){ exprLong, };
|
||||
rules[TK_IMAG] = (PrattRule){ exprImag, };
|
||||
rules[TK_BYTES] = (PrattRule){ exprBytes, };
|
||||
rules[TK_LBRACE] = (PrattRule){ exprMap };
|
||||
rules[TK_COLON] = (PrattRule){ exprSlice0, exprSlice1, PREC_PRIMARY };
|
||||
|
||||
#undef PK_METHOD
|
||||
#undef PK_NO_INFIX
|
||||
// clang-format on
|
||||
}
|
||||
[TK_DOT] = { NULL, exprAttrib, PREC_PRIMARY },
|
||||
[TK_LPAREN] = { exprGroup, exprCall, PREC_PRIMARY },
|
||||
[TK_LBRACKET] = { exprList, exprSubscr, PREC_PRIMARY },
|
||||
[TK_MOD] = { NULL, exprBinaryOp, PREC_FACTOR },
|
||||
[TK_ADD] = { NULL, exprBinaryOp, PREC_TERM },
|
||||
[TK_SUB] = { exprUnaryOp, exprBinaryOp, PREC_TERM },
|
||||
[TK_MUL] = { exprUnaryOp, exprBinaryOp, PREC_FACTOR },
|
||||
[TK_INVERT] = { exprUnaryOp, NULL, PREC_UNARY },
|
||||
[TK_DIV] = { NULL, exprBinaryOp, PREC_FACTOR },
|
||||
[TK_FLOORDIV] = { NULL, exprBinaryOp, PREC_FACTOR },
|
||||
[TK_POW] = { exprUnaryOp, exprBinaryOp, PREC_EXPONENT },
|
||||
[TK_GT] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_LT] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_EQ] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_NE] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_GE] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_LE] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_IN] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_IS] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_LSHIFT] = { NULL, exprBinaryOp, PREC_BITWISE_SHIFT },
|
||||
[TK_RSHIFT] = { NULL, exprBinaryOp, PREC_BITWISE_SHIFT },
|
||||
[TK_AND] = { NULL, exprBinaryOp, PREC_BITWISE_AND },
|
||||
[TK_OR] = { NULL, exprBinaryOp, PREC_BITWISE_OR },
|
||||
[TK_XOR] = { NULL, exprBinaryOp, PREC_BITWISE_XOR },
|
||||
[TK_DECORATOR] = { NULL, exprBinaryOp, PREC_FACTOR },
|
||||
[TK_IF] = { NULL, exprTernary, PREC_TERNARY },
|
||||
[TK_NOT_IN] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_IS_NOT] = { NULL, exprBinaryOp, PREC_COMPARISION },
|
||||
[TK_AND_KW ] = { NULL, exprAnd, PREC_LOGICAL_AND },
|
||||
[TK_OR_KW] = { NULL, exprOr, PREC_LOGICAL_OR },
|
||||
[TK_NOT_KW] = { exprNot, NULL, PREC_LOGICAL_NOT },
|
||||
[TK_TRUE] = { exprLiteral0 },
|
||||
[TK_FALSE] = { exprLiteral0 },
|
||||
[TK_NONE] = { exprLiteral0 },
|
||||
[TK_DOTDOTDOT] = { exprLiteral0 },
|
||||
[TK_LAMBDA] = { exprLambda, },
|
||||
[TK_ID] = { exprName, },
|
||||
[TK_NUM] = { exprLiteral, },
|
||||
[TK_STR] = { exprLiteral, },
|
||||
[TK_FSTR] = { exprFString, },
|
||||
[TK_LONG] = { exprLong, },
|
||||
[TK_IMAG] = { exprImag, },
|
||||
[TK_BYTES] = { exprBytes, },
|
||||
[TK_LBRACE] = { exprMap },
|
||||
[TK_COLON] = { exprSlice0, exprSlice1, PREC_PRIMARY }
|
||||
};
|
@ -594,6 +594,168 @@ pk_FStringExpr* pk_FStringExpr__new(c11_string src){
|
||||
return self;
|
||||
}
|
||||
|
||||
static pk_ExprVt LogicBinaryExpr;
|
||||
|
||||
pk_LogicBinaryExpr* pk_LogicBinaryExpr__new(pk_Expr* lhs, pk_Expr* rhs, Opcode opcode){
|
||||
static_assert_expr_size(pk_LogicBinaryExpr);
|
||||
pk_LogicBinaryExpr* self = PoolExpr_alloc();
|
||||
self->vt = &LogicBinaryExpr;
|
||||
self->line = -1;
|
||||
self->lhs = lhs;
|
||||
self->rhs = rhs;
|
||||
self->opcode = opcode;
|
||||
return self;
|
||||
}
|
||||
|
||||
void pk_LogicBinaryExpr__dtor(pk_Expr* self_){
|
||||
pk_LogicBinaryExpr* self = (pk_LogicBinaryExpr*)self_;
|
||||
pk_Expr__delete(self->lhs);
|
||||
pk_Expr__delete(self->rhs);
|
||||
}
|
||||
|
||||
void pk_LogicBinaryExpr__emit_(pk_Expr* self_, pk_CodeEmitContext* ctx) {
|
||||
pk_LogicBinaryExpr* self = (pk_LogicBinaryExpr*)self_;
|
||||
self->lhs->vt->emit_(self->lhs, ctx);
|
||||
int patch = pk_CodeEmitContext__emit_(ctx, self->opcode, BC_NOARG, self->line);
|
||||
self->rhs->vt->emit_(self->rhs, ctx);
|
||||
pk_CodeEmitContext__patch_jump(ctx, patch);
|
||||
}
|
||||
|
||||
static pk_ExprVt GroupedExprVt;
|
||||
|
||||
void pk_GroupedExpr__dtor(pk_Expr* self_){
|
||||
pk_GroupedExpr* self = (pk_GroupedExpr*)self_;
|
||||
pk_Expr__delete(self->child);
|
||||
}
|
||||
|
||||
void pk_GroupedExpr__emit_(pk_Expr* self_, pk_CodeEmitContext* ctx) {
|
||||
pk_GroupedExpr* self = (pk_GroupedExpr*)self_;
|
||||
self->child->vt->emit_(self->child, ctx);
|
||||
}
|
||||
|
||||
bool pk_GroupedExpr__emit_del(pk_Expr* self_, pk_CodeEmitContext* ctx) {
|
||||
pk_GroupedExpr* self = (pk_GroupedExpr*)self_;
|
||||
return self->child->vt->emit_del(self->child, ctx);
|
||||
}
|
||||
|
||||
bool pk_GroupedExpr__emit_store(pk_Expr* self_, pk_CodeEmitContext* ctx) {
|
||||
pk_GroupedExpr* self = (pk_GroupedExpr*)self_;
|
||||
return self->child->vt->emit_store(self->child, ctx);
|
||||
}
|
||||
|
||||
pk_GroupedExpr* pk_GroupedExpr__new(pk_Expr* child){
|
||||
static_assert_expr_size(pk_GroupedExpr);
|
||||
pk_GroupedExpr* self = PoolExpr_alloc();
|
||||
self->vt = &GroupedExprVt;
|
||||
self->line = -1;
|
||||
self->child = child;
|
||||
return self;
|
||||
}
|
||||
|
||||
static pk_ExprVt BinaryExprVt;
|
||||
|
||||
static void pk_BinaryExpr__dtor(pk_Expr* self_){
|
||||
pk_BinaryExpr* self = (pk_BinaryExpr*)self_;
|
||||
pk_Expr__delete(self->lhs);
|
||||
pk_Expr__delete(self->rhs);
|
||||
}
|
||||
|
||||
static pk_BinaryExpr__is_compare(pk_Expr* self_){
|
||||
pk_BinaryExpr* self = (pk_BinaryExpr*)self_;
|
||||
switch(self->op) {
|
||||
case TK_LT:
|
||||
case TK_LE:
|
||||
case TK_EQ:
|
||||
case TK_NE:
|
||||
case TK_GT:
|
||||
case TK_GE: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void _emit_compare(pk_BinaryExpr* self, pk_CodeEmitContext* ctx, c11_vector* jmps) {
|
||||
if(self->lhs->vt->is_compare(self->lhs)) {
|
||||
pk_BinaryExpr* lhs = (pk_BinaryExpr*)lhs;
|
||||
_emit_compare(lhs, ctx, jmps);
|
||||
} else {
|
||||
self->lhs->vt->emit_(self->lhs, ctx); // [a]
|
||||
}
|
||||
self->rhs->vt->emit_(self->rhs, ctx); // [a, b]
|
||||
pk_CodeEmitContext__emit_(ctx, OP_DUP_TOP, BC_NOARG, self->line); // [a, b, b]
|
||||
pk_CodeEmitContext__emit_(ctx, OP_ROT_THREE, BC_NOARG, self->line); // [b, a, b]
|
||||
Opcode opcode;
|
||||
switch(self->op) {
|
||||
case TK_LT: opcode = OP_COMPARE_LT; break;
|
||||
case TK_LE: opcode = OP_COMPARE_LE; break;
|
||||
case TK_EQ: opcode = OP_COMPARE_EQ; break;
|
||||
case TK_NE: opcode = OP_COMPARE_NE; break;
|
||||
case TK_GT: opcode = OP_COMPARE_GT; break;
|
||||
case TK_GE: opcode = OP_COMPARE_GE; break;
|
||||
default: PK_UNREACHABLE()
|
||||
}
|
||||
pk_CodeEmitContext__emit_(ctx, opcode, BC_NOARG, self->line);
|
||||
// [b, RES]
|
||||
int index = pk_CodeEmitContext__emit_(ctx, OP_JUMP_IF_FALSE_OR_POP, BC_NOARG, self->line);
|
||||
c11_vector__push(int, jmps, index);
|
||||
}
|
||||
|
||||
static void pk_BinaryExpr__emit_(pk_Expr* self_, pk_CodeEmitContext* ctx) {
|
||||
pk_BinaryExpr* self = (pk_BinaryExpr*)self_;
|
||||
c11_vector/*T=int*/ jmps;
|
||||
c11_vector__ctor(&jmps, sizeof(int));
|
||||
if(self->vt->is_compare(self_) && self->lhs->vt->is_compare(self->lhs)) {
|
||||
// (a < b) < c
|
||||
pk_BinaryExpr* e = (pk_BinaryExpr*)self->lhs;
|
||||
_emit_compare(e, ctx, &jmps);
|
||||
// [b, RES]
|
||||
} else {
|
||||
// (1 + 2) < c
|
||||
if(self->inplace) {
|
||||
self->lhs->vt->emit_inplace(self->lhs, ctx);
|
||||
} else {
|
||||
self->lhs->vt->emit_(self->lhs, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
self->rhs->vt->emit_(self->rhs, ctx);
|
||||
Opcode opcode;
|
||||
switch(self->op) {
|
||||
case TK_ADD: opcode = OP_BINARY_ADD; break;
|
||||
case TK_SUB: opcode = OP_BINARY_SUB; break;
|
||||
case TK_MUL: opcode = OP_BINARY_MUL; break;
|
||||
case TK_DIV: opcode = OP_BINARY_TRUEDIV; break;
|
||||
case TK_FLOORDIV: opcode = OP_BINARY_FLOORDIV; break;
|
||||
case TK_MOD: opcode = OP_BINARY_MOD; break;
|
||||
case TK_POW: opcode = OP_BINARY_POW; break;
|
||||
|
||||
case TK_LT: opcode = OP_COMPARE_LT; break;
|
||||
case TK_LE: opcode = OP_COMPARE_LE; break;
|
||||
case TK_EQ: opcode = OP_COMPARE_EQ; break;
|
||||
case TK_NE: opcode = OP_COMPARE_NE; break;
|
||||
case TK_GT: opcode = OP_COMPARE_GT; break;
|
||||
case TK_GE: opcode = OP_COMPARE_GE; break;
|
||||
|
||||
// case TK_IN: ctx->emit_(OP_CONTAINS_OP, 0, line); break;
|
||||
// case TK_NOT_IN: ctx->emit_(OP_CONTAINS_OP, 1, line); break;
|
||||
// case TK_IS: ctx->emit_(OP_IS_OP, BC_NOARG, line); break;
|
||||
// case TK_IS_NOT: ctx->emit_(OP_IS_NOT_OP, BC_NOARG, line); break;
|
||||
|
||||
case TK_LSHIFT: ctx->emit_(OP_BITWISE_LSHIFT, BC_NOARG, line); break;
|
||||
case TK_RSHIFT: ctx->emit_(OP_BITWISE_RSHIFT, BC_NOARG, line); break;
|
||||
case TK_AND: ctx->emit_(OP_BITWISE_AND, BC_NOARG, line); break;
|
||||
case TK_OR: ctx->emit_(OP_BITWISE_OR, BC_NOARG, line); break;
|
||||
case TK_XOR: ctx->emit_(OP_BITWISE_XOR, BC_NOARG, line); break;
|
||||
|
||||
case TK_DECORATOR: ctx->emit_(OP_BINARY_MATMUL, BC_NOARG, line); break;
|
||||
default: PK_FATAL_ERROR("unknown binary operator: %s\n", pk_TokenSymbols[op]);
|
||||
}
|
||||
|
||||
for(int i: jmps)
|
||||
ctx->patch_jump(i);
|
||||
}
|
||||
|
||||
static pk_ExprVt TernaryExprVt;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
void pk_Expr__initialize(){
|
||||
pk_ExprVt__ctor(&NameExprVt);
|
||||
@ -660,4 +822,16 @@ void pk_Expr__initialize(){
|
||||
pk_ExprVt__ctor(&FStringExprVt);
|
||||
vt = &FStringExprVt;
|
||||
vt->emit_ = pk_FStringExpr__emit_;
|
||||
|
||||
pk_ExprVt__ctor(&LogicBinaryExpr);
|
||||
vt = &LogicBinaryExpr;
|
||||
vt->dtor = pk_LogicBinaryExpr__dtor;
|
||||
vt->emit_ = pk_LogicBinaryExpr__emit_;
|
||||
|
||||
pk_ExprVt__ctor(&GroupedExprVt);
|
||||
vt = &GroupedExprVt;
|
||||
vt->dtor = pk_GroupedExpr__dtor;
|
||||
vt->emit_ = pk_GroupedExpr__emit_;
|
||||
vt->emit_del = pk_GroupedExpr__emit_del;
|
||||
vt->emit_store = pk_GroupedExpr__emit_store;
|
||||
}
|
||||
|
@ -12,7 +12,6 @@ static pk_VM pk_default_vm;
|
||||
void py_initialize() {
|
||||
pk_MemoryPools__initialize();
|
||||
pk_StrName__initialize();
|
||||
pk_Compiler__initialize();
|
||||
pk_current_vm = &pk_default_vm;
|
||||
pk_VM__ctor(&pk_default_vm);
|
||||
}
|
||||
@ -20,7 +19,6 @@ void py_initialize() {
|
||||
void py_finalize() {
|
||||
pk_VM__dtor(&pk_default_vm);
|
||||
pk_current_vm = NULL;
|
||||
pk_Compiler__finalize();
|
||||
pk_StrName__finalize();
|
||||
pk_MemoryPools__finalize();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user