mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
some fix
This commit is contained in:
parent
14a01c0e6d
commit
23b523b788
@ -103,6 +103,8 @@ Error* pk_Lexer__process(pk_SourceData_ src, pk_TokenArray* out_tokens);
|
|||||||
Error* pk_Lexer__process_and_dump(pk_SourceData_ src, py_Str* out_string);
|
Error* pk_Lexer__process_and_dump(pk_SourceData_ src, py_Str* out_string);
|
||||||
void pk_TokenArray__dtor(pk_TokenArray* self);
|
void pk_TokenArray__dtor(pk_TokenArray* self);
|
||||||
|
|
||||||
|
#define Token__sv(self) (c11_string){(self)->start, (self)->length}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -243,7 +243,7 @@ PK_THREAD_LOCAL FixedMemoryPool PoolFrame;
|
|||||||
PK_THREAD_LOCAL MemoryPool PoolObject;
|
PK_THREAD_LOCAL MemoryPool PoolObject;
|
||||||
PK_THREAD_LOCAL bool _Pools_initialized = false;
|
PK_THREAD_LOCAL bool _Pools_initialized = false;
|
||||||
|
|
||||||
void Pools_initialize(){
|
void pk_MemoryPools__initialize(){
|
||||||
if(_Pools_initialized) return;
|
if(_Pools_initialized) return;
|
||||||
FixedMemoryPool__ctor(&PoolExpr, kPoolExprBlockSize, 64);
|
FixedMemoryPool__ctor(&PoolExpr, kPoolExprBlockSize, 64);
|
||||||
FixedMemoryPool__ctor(&PoolFrame, kPoolFrameBlockSize, 128);
|
FixedMemoryPool__ctor(&PoolFrame, kPoolFrameBlockSize, 128);
|
||||||
@ -251,7 +251,7 @@ void Pools_initialize(){
|
|||||||
_Pools_initialized = true;
|
_Pools_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pools_finalize(){
|
void pk_MemoryPools__finalize(){
|
||||||
if(!_Pools_initialized) return;
|
if(!_Pools_initialized) return;
|
||||||
FixedMemoryPool__dtor(&PoolExpr);
|
FixedMemoryPool__dtor(&PoolExpr);
|
||||||
FixedMemoryPool__dtor(&PoolFrame);
|
FixedMemoryPool__dtor(&PoolFrame);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "pocketpy/compiler/lexer.h"
|
#include "pocketpy/compiler/lexer.h"
|
||||||
#include "pocketpy/objects/sourcedata.h"
|
#include "pocketpy/objects/sourcedata.h"
|
||||||
#include "pocketpy/common/strname.h"
|
#include "pocketpy/common/strname.h"
|
||||||
|
#include "pocketpy/common/config.h"
|
||||||
#include "pocketpy/common/memorypool.h"
|
#include "pocketpy/common/memorypool.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
@ -70,7 +71,6 @@ typedef struct Expr Expr;
|
|||||||
|
|
||||||
void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level);
|
void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level);
|
||||||
void Ctx__dtor(Ctx* self);
|
void Ctx__dtor(Ctx* self);
|
||||||
|
|
||||||
int Ctx__get_loop(Ctx* self);
|
int Ctx__get_loop(Ctx* self);
|
||||||
CodeBlock* Ctx__enter_block(Ctx* self, CodeBlockType type);
|
CodeBlock* Ctx__enter_block(Ctx* self, CodeBlockType type);
|
||||||
void Ctx__exit_block(Ctx* self);
|
void Ctx__exit_block(Ctx* self);
|
||||||
@ -85,21 +85,12 @@ int Ctx__add_const(Ctx* self, py_Ref);
|
|||||||
int Ctx__add_const_string(Ctx* self, c11_string);
|
int Ctx__add_const_string(Ctx* self, c11_string);
|
||||||
void Ctx__emit_store_name(Ctx* self, NameScope scope, StrName name, int line);
|
void Ctx__emit_store_name(Ctx* self, NameScope scope, StrName name, int line);
|
||||||
void Ctx__try_merge_for_iter_store(Ctx* self, int);
|
void Ctx__try_merge_for_iter_store(Ctx* self, int);
|
||||||
// emit top -> pop -> delete
|
void Ctx__s_emit_top(Ctx*); // emit top -> pop -> delete
|
||||||
void Ctx__s_emit_top(Ctx*);
|
void Ctx__s_push(Ctx*, Expr*); // push
|
||||||
// push
|
Expr* Ctx__s_top(Ctx*); // top
|
||||||
void Ctx__s_push(Ctx*, Expr*);
|
int Ctx__s_size(Ctx*); // size
|
||||||
// top
|
void Ctx__s_pop(Ctx*); // pop -> delete
|
||||||
Expr* Ctx__s_top(Ctx*);
|
Expr* Ctx__s_popx(Ctx*); // pop move
|
||||||
// size
|
|
||||||
int Ctx__s_size(Ctx*);
|
|
||||||
// pop -> delete
|
|
||||||
void Ctx__s_pop(Ctx*);
|
|
||||||
// pop move
|
|
||||||
Expr* Ctx__s_popx(Ctx*);
|
|
||||||
// clean
|
|
||||||
void Ctx__s_clean(Ctx*);
|
|
||||||
// emit decorators
|
|
||||||
void Ctx__s_emit_decorators(Ctx*, int count);
|
void Ctx__s_emit_decorators(Ctx*, int count);
|
||||||
|
|
||||||
/* expr.c */
|
/* expr.c */
|
||||||
@ -152,7 +143,7 @@ bool NameExpr__emit_store(Expr* self_, Ctx* ctx) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NameExpr* NameExpr__new(StrName name, NameScope scope) {
|
NameExpr* NameExpr__new(int line, StrName name, NameScope scope) {
|
||||||
const static ExprVt Vt = {.emit_ = NameExpr__emit_,
|
const static ExprVt Vt = {.emit_ = NameExpr__emit_,
|
||||||
.emit_del = NameExpr__emit_del,
|
.emit_del = NameExpr__emit_del,
|
||||||
.emit_store = NameExpr__emit_store,
|
.emit_store = NameExpr__emit_store,
|
||||||
@ -160,7 +151,7 @@ NameExpr* NameExpr__new(StrName name, NameScope scope) {
|
|||||||
static_assert_expr_size(NameExpr);
|
static_assert_expr_size(NameExpr);
|
||||||
NameExpr* self = PoolExpr_alloc();
|
NameExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->name = name;
|
self->name = name;
|
||||||
self->scope = scope;
|
self->scope = scope;
|
||||||
return self;
|
return self;
|
||||||
@ -185,14 +176,14 @@ bool StarredExpr__emit_store(Expr* self_, Ctx* ctx) {
|
|||||||
return vtemit_store(self->child, ctx);
|
return vtemit_store(self->child, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
StarredExpr* StarredExpr__new(Expr* child, int level) {
|
StarredExpr* StarredExpr__new(int line, Expr* child, int level) {
|
||||||
const static ExprVt Vt = {.emit_ = StarredExpr__emit_,
|
const static ExprVt Vt = {.emit_ = StarredExpr__emit_,
|
||||||
.emit_store = StarredExpr__emit_store,
|
.emit_store = StarredExpr__emit_store,
|
||||||
.is_starred = true};
|
.is_starred = true};
|
||||||
static_assert_expr_size(StarredExpr);
|
static_assert_expr_size(StarredExpr);
|
||||||
StarredExpr* self = PoolExpr_alloc();
|
StarredExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->child = child;
|
self->child = child;
|
||||||
self->level = level;
|
self->level = level;
|
||||||
return self;
|
return self;
|
||||||
@ -217,18 +208,17 @@ static void UnaryExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line);
|
Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnaryExpr* UnaryExpr__new(Expr* child, Opcode opcode) {
|
UnaryExpr* UnaryExpr__new(int line, Expr* child, Opcode opcode) {
|
||||||
const static ExprVt Vt = {.emit_ = UnaryExpr__emit_, .dtor = UnaryExpr__dtor};
|
const static ExprVt Vt = {.emit_ = UnaryExpr__emit_, .dtor = UnaryExpr__dtor};
|
||||||
static_assert_expr_size(UnaryExpr);
|
static_assert_expr_size(UnaryExpr);
|
||||||
UnaryExpr* self = PoolExpr_alloc();
|
UnaryExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->child = child;
|
self->child = child;
|
||||||
self->opcode = opcode;
|
self->opcode = opcode;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// LongExpr, BytesExpr
|
|
||||||
typedef struct RawStringExpr {
|
typedef struct RawStringExpr {
|
||||||
EXPR_COMMON_HEADER
|
EXPR_COMMON_HEADER
|
||||||
c11_string value;
|
c11_string value;
|
||||||
@ -242,12 +232,12 @@ void RawStringExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line);
|
Ctx__emit_(ctx, self->opcode, BC_NOARG, self->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
RawStringExpr* RawStringExpr__new(c11_string value, Opcode opcode) {
|
RawStringExpr* RawStringExpr__new(int line, c11_string value, Opcode opcode) {
|
||||||
const static ExprVt Vt = {.emit_ = RawStringExpr__emit_};
|
const static ExprVt Vt = {.emit_ = RawStringExpr__emit_};
|
||||||
static_assert_expr_size(RawStringExpr);
|
static_assert_expr_size(RawStringExpr);
|
||||||
RawStringExpr* self = PoolExpr_alloc();
|
RawStringExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->value = value;
|
self->value = value;
|
||||||
self->opcode = opcode;
|
self->opcode = opcode;
|
||||||
return self;
|
return self;
|
||||||
@ -267,12 +257,12 @@ void ImagExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__emit_(ctx, OP_BUILD_IMAG, BC_NOARG, self->line);
|
Ctx__emit_(ctx, OP_BUILD_IMAG, BC_NOARG, self->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagExpr* ImagExpr__new(double value) {
|
ImagExpr* ImagExpr__new(int line, double value) {
|
||||||
const static ExprVt Vt = {.emit_ = ImagExpr__emit_};
|
const static ExprVt Vt = {.emit_ = ImagExpr__emit_};
|
||||||
static_assert_expr_size(ImagExpr);
|
static_assert_expr_size(ImagExpr);
|
||||||
ImagExpr* self = PoolExpr_alloc();
|
ImagExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->value = value;
|
self->value = value;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -307,18 +297,48 @@ void LiteralExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LiteralExpr* LiteralExpr__new(const TokenValue* value) {
|
LiteralExpr* LiteralExpr__new(int line, const TokenValue* value) {
|
||||||
const static ExprVt Vt = {.emit_ = LiteralExpr__emit_,
|
const static ExprVt Vt = {.emit_ = LiteralExpr__emit_,
|
||||||
.is_literal = true,
|
.is_literal = true,
|
||||||
.is_json_object = true};
|
.is_json_object = true};
|
||||||
static_assert_expr_size(LiteralExpr);
|
static_assert_expr_size(LiteralExpr);
|
||||||
LiteralExpr* self = PoolExpr_alloc();
|
LiteralExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->value = value;
|
self->value = value;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct Literal0Expr {
|
||||||
|
EXPR_COMMON_HEADER
|
||||||
|
TokenIndex token;
|
||||||
|
} Literal0Expr;
|
||||||
|
|
||||||
|
void Literal0Expr__emit_(Expr* self_, Ctx* ctx) {
|
||||||
|
Literal0Expr* self = (Literal0Expr*)self_;
|
||||||
|
Opcode opcode;
|
||||||
|
switch(self->token) {
|
||||||
|
case TK_NONE: opcode = OP_LOAD_NONE; break;
|
||||||
|
case TK_TRUE: opcode = OP_LOAD_TRUE; break;
|
||||||
|
case TK_FALSE: opcode = OP_LOAD_FALSE; break;
|
||||||
|
case TK_DOTDOTDOT: opcode = OP_LOAD_ELLIPSIS; break;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
Ctx__emit_(ctx, opcode, BC_NOARG, self->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
Literal0Expr* Literal0Expr__new(int line, TokenIndex token) {
|
||||||
|
const static ExprVt Vt = {.emit_ = Literal0Expr__emit_,
|
||||||
|
.is_literal = true,
|
||||||
|
.is_json_object = true};
|
||||||
|
static_assert_expr_size(Literal0Expr);
|
||||||
|
Literal0Expr* self = PoolExpr_alloc();
|
||||||
|
self->vt = &Vt;
|
||||||
|
self->line = line;
|
||||||
|
self->token = token;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct SliceExpr {
|
typedef struct SliceExpr {
|
||||||
EXPR_COMMON_HEADER
|
EXPR_COMMON_HEADER
|
||||||
Expr* start;
|
Expr* start;
|
||||||
@ -350,12 +370,12 @@ void SliceExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__emit_(ctx, OP_BUILD_SLICE, BC_NOARG, self->line);
|
Ctx__emit_(ctx, OP_BUILD_SLICE, BC_NOARG, self->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
SliceExpr* SliceExpr__new() {
|
SliceExpr* SliceExpr__new(int line) {
|
||||||
const static ExprVt Vt = {.dtor = SliceExpr__dtor, .emit_ = SliceExpr__emit_};
|
const static ExprVt Vt = {.dtor = SliceExpr__dtor, .emit_ = SliceExpr__emit_};
|
||||||
static_assert_expr_size(SliceExpr);
|
static_assert_expr_size(SliceExpr);
|
||||||
SliceExpr* self = PoolExpr_alloc();
|
SliceExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->start = NULL;
|
self->start = NULL;
|
||||||
self->stop = NULL;
|
self->stop = NULL;
|
||||||
self->step = NULL;
|
self->step = NULL;
|
||||||
@ -441,45 +461,45 @@ bool TupleExpr__emit_del(Expr* self_, Ctx* ctx) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SequenceExpr* SequenceExpr__new(const ExprVt* vt, int count, Opcode opcode) {
|
static SequenceExpr* SequenceExpr__new(int line, const ExprVt* vt, int count, Opcode opcode) {
|
||||||
static_assert_expr_size(SequenceExpr);
|
static_assert_expr_size(SequenceExpr);
|
||||||
SequenceExpr* self = PoolExpr_alloc();
|
SequenceExpr* self = PoolExpr_alloc();
|
||||||
self->vt = vt;
|
self->vt = vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->opcode = opcode;
|
self->opcode = opcode;
|
||||||
c11_array__ctor(&self->items, count, sizeof(Expr*));
|
c11_array__ctor(&self->items, count, sizeof(Expr*));
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
SequenceExpr* ListExpr__new(int count) {
|
SequenceExpr* ListExpr__new(int line, int count) {
|
||||||
const static ExprVt ListExprVt = {.dtor = SequenceExpr__dtor,
|
const static ExprVt ListExprVt = {.dtor = SequenceExpr__dtor,
|
||||||
.emit_ = SequenceExpr__emit_,
|
.emit_ = SequenceExpr__emit_,
|
||||||
.is_json_object = true};
|
.is_json_object = true};
|
||||||
return SequenceExpr__new(&ListExprVt, count, OP_BUILD_LIST);
|
return SequenceExpr__new(line, &ListExprVt, count, OP_BUILD_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
SequenceExpr* DictExpr__new(int count) {
|
SequenceExpr* DictExpr__new(int line, int count) {
|
||||||
const static ExprVt DictExprVt = {.dtor = SequenceExpr__dtor,
|
const static ExprVt DictExprVt = {.dtor = SequenceExpr__dtor,
|
||||||
.emit_ = SequenceExpr__emit_,
|
.emit_ = SequenceExpr__emit_,
|
||||||
.is_json_object = true};
|
.is_json_object = true};
|
||||||
return SequenceExpr__new(&DictExprVt, count, OP_BUILD_DICT);
|
return SequenceExpr__new(line, &DictExprVt, count, OP_BUILD_DICT);
|
||||||
}
|
}
|
||||||
|
|
||||||
SequenceExpr* SetExpr__new(int count) {
|
SequenceExpr* SetExpr__new(int line, int count) {
|
||||||
const static ExprVt SetExprVt = {
|
const static ExprVt SetExprVt = {
|
||||||
.dtor = SequenceExpr__dtor,
|
.dtor = SequenceExpr__dtor,
|
||||||
.emit_ = SequenceExpr__emit_,
|
.emit_ = SequenceExpr__emit_,
|
||||||
};
|
};
|
||||||
return SequenceExpr__new(&SetExprVt, count, OP_BUILD_SET);
|
return SequenceExpr__new(line, &SetExprVt, count, OP_BUILD_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
SequenceExpr* TupleExpr__new(int count) {
|
SequenceExpr* TupleExpr__new(int line, int count) {
|
||||||
const static ExprVt TupleExprVt = {.dtor = SequenceExpr__dtor,
|
const static ExprVt TupleExprVt = {.dtor = SequenceExpr__dtor,
|
||||||
.emit_ = SequenceExpr__emit_,
|
.emit_ = SequenceExpr__emit_,
|
||||||
.is_tuple = true,
|
.is_tuple = true,
|
||||||
.emit_store = TupleExpr__emit_store,
|
.emit_store = TupleExpr__emit_store,
|
||||||
.emit_del = TupleExpr__emit_del};
|
.emit_del = TupleExpr__emit_del};
|
||||||
return SequenceExpr__new(&TupleExprVt, count, OP_BUILD_TUPLE);
|
return SequenceExpr__new(line, &TupleExprVt, count, OP_BUILD_TUPLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct CompExpr {
|
typedef struct CompExpr {
|
||||||
@ -527,12 +547,12 @@ void CompExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__exit_block(ctx);
|
Ctx__exit_block(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
CompExpr* CompExpr__new(Opcode op0, Opcode op1) {
|
CompExpr* CompExpr__new(int line, Opcode op0, Opcode op1) {
|
||||||
const static ExprVt Vt = {.dtor = CompExpr__dtor, .emit_ = CompExpr__emit_};
|
const static ExprVt Vt = {.dtor = CompExpr__dtor, .emit_ = CompExpr__emit_};
|
||||||
static_assert_expr_size(CompExpr);
|
static_assert_expr_size(CompExpr);
|
||||||
CompExpr* self = PoolExpr_alloc();
|
CompExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->op0 = op0;
|
self->op0 = op0;
|
||||||
self->op1 = op1;
|
self->op1 = op1;
|
||||||
self->expr = NULL;
|
self->expr = NULL;
|
||||||
@ -552,12 +572,12 @@ static void LambdaExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__emit_(ctx, OP_LOAD_FUNCTION, self->index, self->line);
|
Ctx__emit_(ctx, OP_LOAD_FUNCTION, self->index, self->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
LambdaExpr* LambdaExpr__new(int index) {
|
LambdaExpr* LambdaExpr__new(int line, int index) {
|
||||||
const static ExprVt Vt = {.emit_ = LambdaExpr__emit_};
|
const static ExprVt Vt = {.emit_ = LambdaExpr__emit_};
|
||||||
static_assert_expr_size(LambdaExpr);
|
static_assert_expr_size(LambdaExpr);
|
||||||
LambdaExpr* self = PoolExpr_alloc();
|
LambdaExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->index = index;
|
self->index = index;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -732,12 +752,12 @@ static void FStringExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__emit_(ctx, OP_BUILD_STRING, count, self->line);
|
Ctx__emit_(ctx, OP_BUILD_STRING, count, self->line);
|
||||||
}
|
}
|
||||||
|
|
||||||
FStringExpr* FStringExpr__new(c11_string src) {
|
FStringExpr* FStringExpr__new(int line, c11_string src) {
|
||||||
const static ExprVt Vt = {.emit_ = FStringExpr__emit_};
|
const static ExprVt Vt = {.emit_ = FStringExpr__emit_};
|
||||||
static_assert_expr_size(FStringExpr);
|
static_assert_expr_size(FStringExpr);
|
||||||
FStringExpr* self = PoolExpr_alloc();
|
FStringExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->src = src;
|
self->src = src;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -764,14 +784,14 @@ void LogicBinaryExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__patch_jump(ctx, patch);
|
Ctx__patch_jump(ctx, patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicBinaryExpr* LogicBinaryExpr__new(Expr* lhs, Expr* rhs, Opcode opcode) {
|
LogicBinaryExpr* LogicBinaryExpr__new(int line, Opcode opcode) {
|
||||||
const static ExprVt Vt = {.emit_ = LogicBinaryExpr__emit_, .dtor = LogicBinaryExpr__dtor};
|
const static ExprVt Vt = {.emit_ = LogicBinaryExpr__emit_, .dtor = LogicBinaryExpr__dtor};
|
||||||
static_assert_expr_size(LogicBinaryExpr);
|
static_assert_expr_size(LogicBinaryExpr);
|
||||||
LogicBinaryExpr* self = PoolExpr_alloc();
|
LogicBinaryExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->lhs = lhs;
|
self->lhs = NULL;
|
||||||
self->rhs = rhs;
|
self->rhs = NULL;
|
||||||
self->opcode = opcode;
|
self->opcode = opcode;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -801,7 +821,7 @@ bool GroupedExpr__emit_store(Expr* self_, Ctx* ctx) {
|
|||||||
return vtemit_store(self->child, ctx);
|
return vtemit_store(self->child, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
GroupedExpr* GroupedExpr__new(Expr* child) {
|
GroupedExpr* GroupedExpr__new(int line, Expr* child) {
|
||||||
const static ExprVt Vt = {.dtor = GroupedExpr__dtor,
|
const static ExprVt Vt = {.dtor = GroupedExpr__dtor,
|
||||||
.emit_ = GroupedExpr__emit_,
|
.emit_ = GroupedExpr__emit_,
|
||||||
.emit_del = GroupedExpr__emit_del,
|
.emit_del = GroupedExpr__emit_del,
|
||||||
@ -809,7 +829,7 @@ GroupedExpr* GroupedExpr__new(Expr* child) {
|
|||||||
static_assert_expr_size(GroupedExpr);
|
static_assert_expr_size(GroupedExpr);
|
||||||
GroupedExpr* self = PoolExpr_alloc();
|
GroupedExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->child = child;
|
self->child = child;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -914,6 +934,19 @@ static void BinaryExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
c11__foreach(int, &jmps, i) { Ctx__patch_jump(ctx, *i); }
|
c11__foreach(int, &jmps, i) { Ctx__patch_jump(ctx, *i); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BinaryExpr* BinaryExpr__new(int line, TokenIndex op, bool inplace) {
|
||||||
|
const static ExprVt Vt = {.emit_ = BinaryExpr__emit_, .dtor = BinaryExpr__dtor};
|
||||||
|
static_assert_expr_size(BinaryExpr);
|
||||||
|
BinaryExpr* self = PoolExpr_alloc();
|
||||||
|
self->vt = &Vt;
|
||||||
|
self->line = line;
|
||||||
|
self->lhs = NULL;
|
||||||
|
self->rhs = NULL;
|
||||||
|
self->op = op;
|
||||||
|
self->inplace = inplace;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct TernaryExpr {
|
typedef struct TernaryExpr {
|
||||||
EXPR_COMMON_HEADER
|
EXPR_COMMON_HEADER
|
||||||
Expr* cond;
|
Expr* cond;
|
||||||
@ -939,12 +972,12 @@ void TernaryExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
Ctx__patch_jump(ctx, patch_2);
|
Ctx__patch_jump(ctx, patch_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
TernaryExpr* TernaryExpr__new() {
|
TernaryExpr* TernaryExpr__new(int line) {
|
||||||
const static ExprVt Vt = {.dtor = TernaryExpr__dtor, .emit_ = TernaryExpr__emit_};
|
const static ExprVt Vt = {.dtor = TernaryExpr__dtor, .emit_ = TernaryExpr__emit_};
|
||||||
static_assert_expr_size(TernaryExpr);
|
static_assert_expr_size(TernaryExpr);
|
||||||
TernaryExpr* self = PoolExpr_alloc();
|
TernaryExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->cond = NULL;
|
self->cond = NULL;
|
||||||
self->true_expr = NULL;
|
self->true_expr = NULL;
|
||||||
self->false_expr = NULL;
|
self->false_expr = NULL;
|
||||||
@ -1014,7 +1047,7 @@ bool SubscrExpr__emit_del(Expr* self_, Ctx* ctx) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubscrExpr* SubscrExpr__new(Expr* lhs, Expr* rhs) {
|
SubscrExpr* SubscrExpr__new(int line, Expr* lhs, Expr* rhs) {
|
||||||
const static ExprVt Vt = {
|
const static ExprVt Vt = {
|
||||||
.dtor = SubscrExpr__dtor,
|
.dtor = SubscrExpr__dtor,
|
||||||
.emit_ = SubscrExpr__emit_,
|
.emit_ = SubscrExpr__emit_,
|
||||||
@ -1027,7 +1060,7 @@ SubscrExpr* SubscrExpr__new(Expr* lhs, Expr* rhs) {
|
|||||||
static_assert_expr_size(SubscrExpr);
|
static_assert_expr_size(SubscrExpr);
|
||||||
SubscrExpr* self = PoolExpr_alloc();
|
SubscrExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->lhs = lhs;
|
self->lhs = lhs;
|
||||||
self->rhs = rhs;
|
self->rhs = rhs;
|
||||||
return self;
|
return self;
|
||||||
@ -1074,7 +1107,7 @@ bool AttribExpr__emit_istore(Expr* self_, Ctx* ctx) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttribExpr* AttribExpr__new(Expr* child, StrName name) {
|
AttribExpr* AttribExpr__new(int line, Expr* child, StrName name) {
|
||||||
const static ExprVt Vt = {.emit_ = AttribExpr__emit_,
|
const static ExprVt Vt = {.emit_ = AttribExpr__emit_,
|
||||||
.emit_del = AttribExpr__emit_del,
|
.emit_del = AttribExpr__emit_del,
|
||||||
.emit_store = AttribExpr__emit_store,
|
.emit_store = AttribExpr__emit_store,
|
||||||
@ -1084,7 +1117,7 @@ AttribExpr* AttribExpr__new(Expr* child, StrName name) {
|
|||||||
static_assert_expr_size(AttribExpr);
|
static_assert_expr_size(AttribExpr);
|
||||||
AttribExpr* self = PoolExpr_alloc();
|
AttribExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->child = child;
|
self->child = child;
|
||||||
self->name = name;
|
self->name = name;
|
||||||
return self;
|
return self;
|
||||||
@ -1172,12 +1205,12 @@ void CallExpr__emit_(Expr* self_, Ctx* ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CallExpr* CallExpr__new(Expr* callable) {
|
CallExpr* CallExpr__new(int line, Expr* callable) {
|
||||||
const static ExprVt Vt = {.dtor = CallExpr__dtor, .emit_ = CallExpr__emit_};
|
const static ExprVt Vt = {.dtor = CallExpr__dtor, .emit_ = CallExpr__emit_};
|
||||||
static_assert_expr_size(CallExpr);
|
static_assert_expr_size(CallExpr);
|
||||||
CallExpr* self = PoolExpr_alloc();
|
CallExpr* self = PoolExpr_alloc();
|
||||||
self->vt = &Vt;
|
self->vt = &Vt;
|
||||||
self->line = -1;
|
self->line = line;
|
||||||
self->callable = callable;
|
self->callable = callable;
|
||||||
c11_vector__ctor(&self->args, sizeof(Expr*));
|
c11_vector__ctor(&self->args, sizeof(Expr*));
|
||||||
c11_vector__ctor(&self->kwargs, sizeof(CallExprKwArg));
|
c11_vector__ctor(&self->kwargs, sizeof(CallExprKwArg));
|
||||||
@ -1197,6 +1230,11 @@ void Ctx__ctor(Ctx* self, CodeObject* co, FuncDecl* func, int level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Ctx__dtor(Ctx* self) {
|
void Ctx__dtor(Ctx* self) {
|
||||||
|
// clean the expr stack
|
||||||
|
for(int i = 0; i < self->s_expr.count; i++) {
|
||||||
|
vtdelete(c11__getitem(Expr*, &self->s_expr, i));
|
||||||
|
}
|
||||||
|
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_vector__dtor(&self->global_names);
|
||||||
c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map);
|
c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map);
|
||||||
@ -1232,15 +1270,6 @@ Expr* Ctx__s_popx(Ctx* self) {
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clean
|
|
||||||
void Ctx__s_clean(Ctx* self) {
|
|
||||||
c11_smallmap_s2n__dtor(&self->co_consts_string_dedup_map); // ??
|
|
||||||
for(int i = 0; i < self->s_expr.count; i++) {
|
|
||||||
vtdelete(c11__getitem(Expr*, &self->s_expr, i));
|
|
||||||
}
|
|
||||||
c11_vector__clear(&self->s_expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compiler.c */
|
/* compiler.c */
|
||||||
typedef struct Compiler Compiler;
|
typedef struct Compiler Compiler;
|
||||||
typedef Error* (*PrattCallback)(Compiler* self);
|
typedef Error* (*PrattCallback)(Compiler* self);
|
||||||
@ -1273,7 +1302,7 @@ static void Compiler__dtor(Compiler* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**************************************/
|
/**************************************/
|
||||||
#define tk(i) c11__getitem(Token, &self->tokens, i)
|
#define tk(i) c11__at(Token, &self->tokens, i)
|
||||||
#define prev() tk(self->i - 1)
|
#define prev() tk(self->i - 1)
|
||||||
#define curr() tk(self->i)
|
#define curr() tk(self->i)
|
||||||
#define next() tk(self->i + 1)
|
#define next() tk(self->i + 1)
|
||||||
@ -1281,23 +1310,23 @@ static void Compiler__dtor(Compiler* self) {
|
|||||||
|
|
||||||
#define advance() self->i++
|
#define advance() self->i++
|
||||||
#define mode() self->src->mode
|
#define mode() self->src->mode
|
||||||
#define ctx() c11_vector__back(Ctx, &self->contexts)
|
#define ctx() (&c11_vector__back(Ctx, &self->contexts))
|
||||||
|
|
||||||
#define match_newlines() match_newlines_repl(self, NULL)
|
#define match_newlines() match_newlines_repl(self, NULL)
|
||||||
|
|
||||||
#define consume(expected) \
|
#define consume(expected) \
|
||||||
if(!match(expected)) \
|
if(!match(expected)) \
|
||||||
return SyntaxError("expected '%s', got '%s'", \
|
return SyntaxError("expected '%s', got '%s'", \
|
||||||
TokenSymbols[expected], \
|
pk_TokenSymbols[expected], \
|
||||||
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()) return SyntaxError("expected statement end")
|
||||||
#define check_newlines_repl() \
|
#define check_newlines_repl() \
|
||||||
{ \
|
do { \
|
||||||
bool __nml; \
|
bool __nml; \
|
||||||
match_newlines_repl(self, &__nml); \
|
match_newlines_repl(self, &__nml); \
|
||||||
if(__nml) return NeedMoreLines(); \
|
if(__nml) return NeedMoreLines(); \
|
||||||
}
|
} while(0)
|
||||||
#define check(B) \
|
#define check(B) \
|
||||||
if((err = B)) return err
|
if((err = B)) return err
|
||||||
|
|
||||||
@ -1313,20 +1342,20 @@ static Error* NeedMoreLines() { return NULL; }
|
|||||||
|
|
||||||
/* Matchers */
|
/* Matchers */
|
||||||
static bool is_expression(Compiler* self, bool allow_slice) {
|
static bool is_expression(Compiler* self, bool allow_slice) {
|
||||||
PrattCallback prefix = rules[curr().type].prefix;
|
PrattCallback prefix = rules[curr()->type].prefix;
|
||||||
return prefix && (allow_slice || curr().type != TK_COLON);
|
return prefix && (allow_slice || curr()->type != TK_COLON);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define match(expected) (curr().type == expected ? (++self->i) : 0)
|
#define match(expected) (curr()->type == expected ? (++self->i) : 0)
|
||||||
|
|
||||||
static bool match_newlines_repl(Compiler* self, bool* need_more_lines) {
|
static bool match_newlines_repl(Compiler* self, bool* need_more_lines) {
|
||||||
bool consumed = false;
|
bool consumed = false;
|
||||||
if(curr().type == TK_EOL) {
|
if(curr()->type == TK_EOL) {
|
||||||
while(curr().type == TK_EOL)
|
while(curr()->type == TK_EOL)
|
||||||
advance();
|
advance();
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
if(need_more_lines) { *need_more_lines = (mode() == REPL_MODE && curr().type == TK_EOF); }
|
if(need_more_lines) { *need_more_lines = (mode() == REPL_MODE && curr()->type == TK_EOF); }
|
||||||
return consumed;
|
return consumed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1335,46 +1364,25 @@ static bool match_end_stmt(Compiler* self) {
|
|||||||
match_newlines();
|
match_newlines();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if(match_newlines() || curr().type == TK_EOF) return true;
|
if(match_newlines() || curr()->type == TK_EOF) return true;
|
||||||
if(curr().type == TK_DEDENT) return true;
|
if(curr()->type == TK_DEDENT) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Expression Callbacks */
|
|
||||||
static Error* exprLiteral(Compiler* self);
|
|
||||||
static Error* exprLong(Compiler* self);
|
|
||||||
static Error* exprImag(Compiler* self);
|
|
||||||
static Error* exprBytes(Compiler* self);
|
|
||||||
static Error* exprFString(Compiler* self);
|
|
||||||
static Error* exprLambda(Compiler* self);
|
|
||||||
static Error* exprOr(Compiler* self);
|
|
||||||
static Error* exprAnd(Compiler* self);
|
|
||||||
static Error* exprTernary(Compiler* self);
|
|
||||||
static Error* exprBinaryOp(Compiler* self);
|
|
||||||
static Error* exprNot(Compiler* self);
|
|
||||||
static Error* exprUnaryOp(Compiler* self);
|
|
||||||
static Error* exprGroup(Compiler* self);
|
|
||||||
static Error* exprList(Compiler* self);
|
|
||||||
static Error* exprMap(Compiler* self);
|
|
||||||
static Error* exprCall(Compiler* self);
|
|
||||||
static Error* exprName(Compiler* self);
|
|
||||||
static Error* exprAttrib(Compiler* self);
|
|
||||||
static Error* exprSlice0(Compiler* self);
|
|
||||||
static Error* exprSlice1(Compiler* self);
|
|
||||||
static Error* exprSubscr(Compiler* self);
|
|
||||||
static Error* exprLiteral0(Compiler* self);
|
|
||||||
|
|
||||||
/* Expression */
|
/* Expression */
|
||||||
|
|
||||||
|
/// Parse an expression and push it onto the stack.
|
||||||
static Error* parse_expression(Compiler* self, int precedence, bool allow_slice) {
|
static Error* parse_expression(Compiler* self, int precedence, bool allow_slice) {
|
||||||
PrattCallback prefix = rules[curr().type].prefix;
|
PrattCallback prefix = rules[curr()->type].prefix;
|
||||||
if(!prefix || (curr().type == TK_COLON && !allow_slice)) {
|
if(!prefix || (curr()->type == TK_COLON && !allow_slice)) {
|
||||||
return SyntaxError("expected an expression, got %s", pk_TokenSymbols[curr().type]);
|
return SyntaxError("expected an expression, got %s", pk_TokenSymbols[curr()->type]);
|
||||||
}
|
}
|
||||||
advance();
|
advance();
|
||||||
Error* err;
|
Error* err;
|
||||||
check(prefix(self));
|
check(prefix(self));
|
||||||
while(rules[curr().type].precedence >= precedence && (allow_slice || curr().type != TK_COLON)) {
|
while(rules[curr()->type].precedence >= precedence &&
|
||||||
TokenIndex op = curr().type;
|
(allow_slice || curr()->type != TK_COLON)) {
|
||||||
|
TokenIndex op = curr()->type;
|
||||||
advance();
|
advance();
|
||||||
PrattCallback infix = rules[op].infix;
|
PrattCallback infix = rules[op].infix;
|
||||||
assert(infix != NULL);
|
assert(infix != NULL);
|
||||||
@ -1383,27 +1391,35 @@ static Error* parse_expression(Compiler* self, int precedence, bool allow_slice)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Error* EXPR(Compiler* self) { return parse_expression(self, PREC_LOWEST + 1, false); }
|
static Error* EXPR_TUPLE_ALLOW_SLICE(Compiler* self, bool allow_slice) {
|
||||||
|
|
||||||
static Error* EXPR_TUPLE(Compiler* self, bool allow_slice) {
|
|
||||||
Error* err;
|
Error* err;
|
||||||
check(parse_expression(self, PREC_LOWEST + 1, allow_slice));
|
check(parse_expression(self, PREC_LOWEST + 1, allow_slice));
|
||||||
if(!match(TK_COMMA)) return NULL;
|
if(!match(TK_COMMA)) return NULL;
|
||||||
// tuple expression
|
// tuple expression // (a, )
|
||||||
int count = 1;
|
int count = 1;
|
||||||
do {
|
do {
|
||||||
if(curr().brackets_level) check_newlines_repl() if(!is_expression(self, allow_slice)) break;
|
if(curr()->brackets_level) check_newlines_repl();
|
||||||
|
if(!is_expression(self, allow_slice)) break;
|
||||||
check(parse_expression(self, PREC_LOWEST + 1, allow_slice));
|
check(parse_expression(self, PREC_LOWEST + 1, allow_slice));
|
||||||
count += 1;
|
count += 1;
|
||||||
if(curr().brackets_level) check_newlines_repl();
|
if(curr()->brackets_level) check_newlines_repl();
|
||||||
} while(match(TK_COMMA));
|
} while(match(TK_COMMA));
|
||||||
// TupleExpr* e = make_expr<TupleExpr>(count);
|
// pop `count` expressions from the stack and merge them into a TupleExpr
|
||||||
// for(int i=count-1; i>=0; i--)
|
SequenceExpr* e = TupleExpr__new(prev()->line, count);
|
||||||
// e->items[i] = ctx()->s_popx();
|
for(int i = count - 1; i >= 0; i--) {
|
||||||
// ctx()->s_push(e);
|
Expr* item = Ctx__s_popx(ctx());
|
||||||
|
c11__setitem(Expr*, &e->items, i, item);
|
||||||
|
}
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Parse a simple expression.
|
||||||
|
static Error* EXPR(Compiler* self) { return parse_expression(self, PREC_LOWEST + 1, false); }
|
||||||
|
|
||||||
|
/// Parse a simple expression or a tuple of expressions.
|
||||||
|
static Error* EXPR_TUPLE(Compiler* self) { return EXPR_TUPLE_ALLOW_SLICE(self, false); }
|
||||||
|
|
||||||
// special case for `for loop` and `comp`
|
// special case for `for loop` and `comp`
|
||||||
static Error* EXPR_VARS(Compiler* self) {
|
static Error* EXPR_VARS(Compiler* self) {
|
||||||
// int count = 0;
|
// int count = 0;
|
||||||
@ -1421,31 +1437,278 @@ static Error* EXPR_VARS(Compiler* self) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_global_context(Compiler* self, CodeObject* co) {
|
/* Misc */
|
||||||
co->start_line = self->i == 0 ? 1 : prev().line;
|
static void push_global_context(Compiler* self, CodeObject* co) {
|
||||||
|
co->start_line = self->i == 0 ? 1 : prev()->line;
|
||||||
Ctx* ctx = c11_vector__emplace(&self->contexts);
|
Ctx* ctx = c11_vector__emplace(&self->contexts);
|
||||||
Ctx__ctor(ctx, co, NULL, self->contexts.count);
|
Ctx__ctor(ctx, co, NULL, self->contexts.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Error* pop_context(Compiler* self) {
|
||||||
|
// add a `return None` in the end as a guard
|
||||||
|
// previously, we only do this if the last opcode is not a return
|
||||||
|
// however, this is buggy...since there may be a jump to the end (out of bound) even if the last
|
||||||
|
// opcode is a return
|
||||||
|
Ctx__emit_virtual(ctx(), OP_RETURN_VALUE, 1, BC_KEEPLINE);
|
||||||
|
|
||||||
|
CodeObject* co = ctx()->co;
|
||||||
|
// find the last valid token
|
||||||
|
int j = self->i - 1;
|
||||||
|
while(tk(j)->type == TK_EOL || tk(j)->type == TK_DEDENT || tk(j)->type == TK_EOF)
|
||||||
|
j--;
|
||||||
|
co->end_line = tk(j)->line;
|
||||||
|
|
||||||
|
// some check here
|
||||||
|
c11_vector* codes = &co->codes;
|
||||||
|
if(co->nlocals > PK_MAX_CO_VARNAMES) {
|
||||||
|
return SyntaxError("maximum number of local variables exceeded");
|
||||||
|
}
|
||||||
|
if(co->consts.count > 65530) { return SyntaxError("maximum number of constants exceeded"); }
|
||||||
|
// pre-compute LOOP_BREAK and LOOP_CONTINUE
|
||||||
|
for(int i = 0; i < codes->count; i++) {
|
||||||
|
Bytecode* bc = c11__at(Bytecode, codes, i);
|
||||||
|
if(bc->op == OP_LOOP_CONTINUE) {
|
||||||
|
CodeBlock* block = c11__at(CodeBlock, &ctx()->co->blocks, bc->arg);
|
||||||
|
Bytecode__set_signed_arg(bc, block->start - i);
|
||||||
|
} else if(bc->op == OP_LOOP_BREAK) {
|
||||||
|
CodeBlock* block = c11__at(CodeBlock, &ctx()->co->blocks, bc->arg);
|
||||||
|
Bytecode__set_signed_arg(bc, (block->end2 != -1 ? block->end2 : block->end) - i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// pre-compute func->is_simple
|
||||||
|
FuncDecl* func = ctx()->func;
|
||||||
|
if(func) {
|
||||||
|
// check generator
|
||||||
|
c11__foreach(Bytecode, &func->code.codes, bc) {
|
||||||
|
if(bc->op == OP_YIELD_VALUE || bc->op == OP_FOR_ITER_YIELD_VALUE) {
|
||||||
|
func->type = FuncType_GENERATOR;
|
||||||
|
c11__foreach(Bytecode, &func->code.codes, bc) {
|
||||||
|
if(bc->op == OP_RETURN_VALUE && bc->arg == BC_NOARG) {
|
||||||
|
return SyntaxError("'return' with argument inside generator function");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(func->type == FuncType_UNSET) {
|
||||||
|
bool is_simple = true;
|
||||||
|
if(func->kwargs.count > 0) is_simple = false;
|
||||||
|
if(func->starred_arg >= 0) is_simple = false;
|
||||||
|
if(func->starred_kwarg >= 0) is_simple = false;
|
||||||
|
|
||||||
|
if(is_simple) {
|
||||||
|
func->type = FuncType_SIMPLE;
|
||||||
|
|
||||||
|
bool is_empty = false;
|
||||||
|
if(func->code.codes.count == 1) {
|
||||||
|
Bytecode bc = c11__getitem(Bytecode, &func->code.codes, 0);
|
||||||
|
if(bc.op == OP_RETURN_VALUE && bc.arg == 1) { is_empty = true; }
|
||||||
|
}
|
||||||
|
if(is_empty) func->type = FuncType_EMPTY;
|
||||||
|
} else
|
||||||
|
func->type = FuncType_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(func->type != FuncType_UNSET);
|
||||||
|
}
|
||||||
|
Ctx__dtor(ctx());
|
||||||
|
c11_vector__pop(&self->contexts);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expression Callbacks */
|
||||||
|
static Error* exprLiteral(Compiler* self) {
|
||||||
|
Ctx__s_push(ctx(), (Expr*)LiteralExpr__new(prev()->line, &prev()->value));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprLong(Compiler* self) {
|
||||||
|
c11_string sv = Token__sv(prev());
|
||||||
|
Ctx__s_push(ctx(), (Expr*)RawStringExpr__new(prev()->line, sv, OP_BUILD_LONG));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprBytes(Compiler* self) {
|
||||||
|
c11_string sv = py_Str__sv(&prev()->value._str);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)RawStringExpr__new(prev()->line, sv, OP_BUILD_BYTES));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprFString(Compiler* self) {
|
||||||
|
c11_string sv = py_Str__sv(&prev()->value._str);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)FStringExpr__new(prev()->line, sv));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprImag(Compiler* self) {
|
||||||
|
Ctx__s_push(ctx(), (Expr*)ImagExpr__new(prev()->line, prev()->value._f64));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprLambda(Compiler* self) {
|
||||||
|
assert(false);
|
||||||
|
return NULL;
|
||||||
|
// Error* err;
|
||||||
|
// int line = prev()->line;
|
||||||
|
// int decl_index;
|
||||||
|
// FuncDecl_ decl = push_f_context({"<lambda>", 8}, &decl_index);
|
||||||
|
// if(!match(TK_COLON)) {
|
||||||
|
// check(_compile_f_args(decl, false));
|
||||||
|
// consume(TK_COLON);
|
||||||
|
// }
|
||||||
|
// // https://github.com/pocketpy/pocketpy/issues/37
|
||||||
|
// check(parse_expression(self, PREC_LAMBDA + 1, false));
|
||||||
|
// Ctx__s_emit_top(ctx());
|
||||||
|
// Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
||||||
|
// check(pop_context(self));
|
||||||
|
// LambdaExpr* e = LambdaExpr__new(line, decl_index);
|
||||||
|
// Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
// return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprOr(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
check(parse_expression(self, PREC_LOGICAL_OR + 1, false));
|
||||||
|
LogicBinaryExpr* e = LogicBinaryExpr__new(line, OP_JUMP_IF_TRUE_OR_POP);
|
||||||
|
e->rhs = Ctx__s_popx(ctx());
|
||||||
|
e->lhs = Ctx__s_popx(ctx());
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprAnd(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
check(parse_expression(self, PREC_LOGICAL_AND + 1, false));
|
||||||
|
LogicBinaryExpr* e = LogicBinaryExpr__new(line, OP_JUMP_IF_FALSE_OR_POP);
|
||||||
|
e->rhs = Ctx__s_popx(ctx());
|
||||||
|
e->lhs = Ctx__s_popx(ctx());
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprTernary(Compiler* self) {
|
||||||
|
// [true_expr]
|
||||||
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
check(parse_expression(self, PREC_TERNARY + 1, false)); // [true_expr, cond]
|
||||||
|
consume(TK_ELSE);
|
||||||
|
check(parse_expression(self, PREC_TERNARY + 1, false)); // [true_expr, cond, false_expr]
|
||||||
|
TernaryExpr* e = TernaryExpr__new(line);
|
||||||
|
e->false_expr = Ctx__s_popx(ctx());
|
||||||
|
e->cond = Ctx__s_popx(ctx());
|
||||||
|
e->true_expr = Ctx__s_popx(ctx());
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprBinaryOp(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
TokenIndex op = prev()->type;
|
||||||
|
check(parse_expression(self, rules[op].precedence + 1, false));
|
||||||
|
BinaryExpr* e = BinaryExpr__new(line, op, false);
|
||||||
|
e->rhs = Ctx__s_popx(ctx());
|
||||||
|
e->lhs = Ctx__s_popx(ctx());
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprNot(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
check(parse_expression(self, PREC_LOGICAL_NOT + 1, false));
|
||||||
|
UnaryExpr* e = UnaryExpr__new(line, Ctx__s_popx(ctx()), OP_UNARY_NOT);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprUnaryOp(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
TokenIndex op = prev()->type;
|
||||||
|
check(parse_expression(self, PREC_UNARY + 1, false));
|
||||||
|
Expr* e = Ctx__s_popx(ctx());
|
||||||
|
switch(op) {
|
||||||
|
case TK_SUB: Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_NEGATIVE)); break;
|
||||||
|
case TK_INVERT: Ctx__s_push(ctx(), (Expr*)UnaryExpr__new(line, e, OP_UNARY_INVERT)); break;
|
||||||
|
case TK_MUL: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 1)); break;
|
||||||
|
case TK_POW: Ctx__s_push(ctx(), (Expr*)StarredExpr__new(line, e, 2)); break;
|
||||||
|
default: assert(false);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprGroup(Compiler* self) {
|
||||||
|
Error* err;
|
||||||
|
int line = prev()->line;
|
||||||
|
check_newlines_repl();
|
||||||
|
check(EXPR_TUPLE(self)); // () is just for change precedence
|
||||||
|
check_newlines_repl();
|
||||||
|
consume(TK_RPAREN);
|
||||||
|
if(Ctx__s_top(ctx())->vt->is_tuple) return NULL;
|
||||||
|
GroupedExpr* g = GroupedExpr__new(line, Ctx__s_popx(ctx()));
|
||||||
|
Ctx__s_push(ctx(), (Expr*)g);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprName(Compiler* self) {
|
||||||
|
StrName name = pk_StrName__map2(Token__sv(prev()));
|
||||||
|
NameScope scope = name_scope(self);
|
||||||
|
// promote this name to global scope if needed
|
||||||
|
c11_vector* global_names = &ctx()->global_names;
|
||||||
|
c11__foreach(StrName, global_names, it) {
|
||||||
|
if(*it == name) scope = NAME_GLOBAL;
|
||||||
|
}
|
||||||
|
NameExpr* e = NameExpr__new(prev()->line, name, scope);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprAttrib(Compiler* self) {
|
||||||
|
consume(TK_ID);
|
||||||
|
StrName name = pk_StrName__map2(Token__sv(prev()));
|
||||||
|
AttribExpr* e = AttribExpr__new(prev()->line, Ctx__s_popx(ctx()), name);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprLiteral0(Compiler* self) {
|
||||||
|
Literal0Expr* e = Literal0Expr__new(prev()->line, prev()->type);
|
||||||
|
Ctx__s_push(ctx(), (Expr*)e);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Error* exprList(Compiler* self);
|
||||||
|
static Error* exprMap(Compiler* self);
|
||||||
|
static Error* exprCall(Compiler* self);
|
||||||
|
static Error* exprSlice0(Compiler* self);
|
||||||
|
static Error* exprSlice1(Compiler* self);
|
||||||
|
static Error* exprSubscr(Compiler* self);
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
Error* Compiler__compile(Compiler* self, CodeObject* out) {
|
Error* Compiler__compile(Compiler* self, CodeObject* out) {
|
||||||
// make sure it is the first time to compile
|
// make sure it is the first time to compile
|
||||||
assert(self->i == 0);
|
assert(self->i == 0);
|
||||||
// make sure the first token is @sof
|
// make sure the first token is @sof
|
||||||
assert(tk(0).type == TK_SOF);
|
assert(tk(0)->type == TK_SOF);
|
||||||
|
|
||||||
setup_global_context(self, out);
|
push_global_context(self, out);
|
||||||
|
|
||||||
advance(); // skip @sof, so prev() is always valid
|
advance(); // skip @sof, so prev() is always valid
|
||||||
match_newlines(); // skip possible leading '\n'
|
match_newlines(); // skip possible leading '\n'
|
||||||
|
|
||||||
Error* err;
|
Error* err;
|
||||||
// if(mode() == EVAL_MODE) {
|
if(mode() == EVAL_MODE) {
|
||||||
// check(EXPR_TUPLE());
|
check(EXPR_TUPLE(self));
|
||||||
// ctx()->s_emit_top();
|
Ctx__s_emit_top(ctx());
|
||||||
// consume(TK_EOF);
|
consume(TK_EOF);
|
||||||
// ctx()->emit_(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
Ctx__emit_(ctx(), OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
|
||||||
// check(pop_context());
|
check(pop_context(self));
|
||||||
// return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
// } else if(mode() == JSON_MODE) {
|
// } else if(mode() == JSON_MODE) {
|
||||||
// check(EXPR());
|
// check(EXPR());
|
||||||
// Expr* e = ctx()->s_popx();
|
// Expr* e = ctx()->s_popx();
|
||||||
@ -1486,7 +1749,10 @@ Error* pk_compile(pk_SourceData_ src, CodeObject* out) {
|
|||||||
Compiler__ctor(&compiler, src, tokens);
|
Compiler__ctor(&compiler, src, tokens);
|
||||||
CodeObject__ctor(out, src, py_Str__sv(&src->filename));
|
CodeObject__ctor(out, src, py_Str__sv(&src->filename));
|
||||||
err = Compiler__compile(&compiler, out);
|
err = Compiler__compile(&compiler, out);
|
||||||
if(err) CodeObject__dtor(out);
|
if(err) {
|
||||||
|
// if error occurs, dispose the code object
|
||||||
|
CodeObject__dtor(out);
|
||||||
|
}
|
||||||
Compiler__dtor(&compiler);
|
Compiler__dtor(&compiler);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
33
src2/main.c
33
src2/main.c
@ -24,19 +24,38 @@ int main(int argc, char** argv) {
|
|||||||
SetConsoleOutputCP(CP_UTF8);
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(argc != 2) goto __HELP;
|
|
||||||
char* source = read_file(argv[1]);
|
|
||||||
py_initialize();
|
py_initialize();
|
||||||
|
const char* source = "[1, 'a']";
|
||||||
|
|
||||||
if(py_exec(source)){
|
if(py_eval(source)){
|
||||||
py_Error* err = py_getlasterror();
|
py_Error* err = py_getlasterror();
|
||||||
py_Error__print(err);
|
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);
|
||||||
|
int _L0 = py_toint(_0);
|
||||||
|
const char* _L1 = py_tostr(_1);
|
||||||
|
printf("%d, %s\n", _L0, _L1);
|
||||||
|
py_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
py_finalize();
|
py_finalize();
|
||||||
free(source);
|
|
||||||
|
|
||||||
__HELP:
|
|
||||||
printf("Usage: pocketpy [filename]\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// if(argc != 2) goto __HELP;
|
||||||
|
// char* source = read_file(argv[1]);
|
||||||
|
// py_initialize();
|
||||||
|
|
||||||
|
// if(py_exec(source)){
|
||||||
|
// py_Error* err = py_getlasterror();
|
||||||
|
// py_Error__print(err);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// py_finalize();
|
||||||
|
// free(source);
|
||||||
|
|
||||||
|
// __HELP:
|
||||||
|
// printf("Usage: pocketpy [filename]\n");
|
||||||
|
// return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user