This commit is contained in:
blueloveTH 2024-06-29 11:21:52 +08:00
parent c7597dfcdf
commit 62420dade1
5 changed files with 251 additions and 58 deletions

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

@ -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();
}