mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
add unique_ptr_64
This commit is contained in:
parent
4ac915e25c
commit
5983dd2ae6
@ -20,7 +20,8 @@ class Compiler {
|
|||||||
PK_ALWAYS_PASS_BY_POINTER(Compiler)
|
PK_ALWAYS_PASS_BY_POINTER(Compiler)
|
||||||
|
|
||||||
inline static PrattRule rules[kTokenCount];
|
inline static PrattRule rules[kTokenCount];
|
||||||
std::unique_ptr<Lexer> lexer;
|
|
||||||
|
Lexer lexer;
|
||||||
stack<CodeEmitContext> contexts;
|
stack<CodeEmitContext> contexts;
|
||||||
VM* vm;
|
VM* vm;
|
||||||
bool unknown_global_scope; // for eval/exec() call
|
bool unknown_global_scope; // for eval/exec() call
|
||||||
@ -39,7 +40,7 @@ class Compiler {
|
|||||||
void advance(int delta=1) { i += delta; }
|
void advance(int delta=1) { i += delta; }
|
||||||
|
|
||||||
CodeEmitContext* ctx() { return &contexts.top(); }
|
CodeEmitContext* ctx() { return &contexts.top(); }
|
||||||
CompileMode mode() const{ return lexer->src->mode; }
|
CompileMode mode() const{ return lexer.src->mode; }
|
||||||
NameScope name_scope() const;
|
NameScope name_scope() const;
|
||||||
CodeObject_ push_global_context();
|
CodeObject_ push_global_context();
|
||||||
FuncDecl_ push_f_context(Str name);
|
FuncDecl_ push_f_context(Str name);
|
||||||
@ -61,8 +62,9 @@ class Compiler {
|
|||||||
Expr_ EXPR_VARS(); // special case for `for loop` and `comp`
|
Expr_ EXPR_VARS(); // special case for `for loop` and `comp`
|
||||||
|
|
||||||
template <typename T, typename... Args>
|
template <typename T, typename... Args>
|
||||||
std::unique_ptr<T> make_expr(Args&&... args) {
|
unique_ptr_64<T> make_expr(Args&&... args) {
|
||||||
std::unique_ptr<T> expr = std::make_unique<T>(std::forward<Args>(args)...);
|
void* p = pool64_alloc(sizeof(T));
|
||||||
|
unique_ptr_64<T> expr(new (p) T(std::forward<Args>(args)...));
|
||||||
expr->line = prev().line;
|
expr->line = prev().line;
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
@ -70,7 +72,7 @@ class Compiler {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void _consume_comp(Expr_ expr){
|
void _consume_comp(Expr_ expr){
|
||||||
static_assert(std::is_base_of<CompExpr, T>::value);
|
static_assert(std::is_base_of<CompExpr, T>::value);
|
||||||
std::unique_ptr<CompExpr> ce = make_expr<T>();
|
unique_ptr_64<CompExpr> ce = make_expr<T>();
|
||||||
ce->expr = std::move(expr);
|
ce->expr = std::move(expr);
|
||||||
ce->vars = EXPR_VARS();
|
ce->vars = EXPR_VARS();
|
||||||
consume(TK("in"));
|
consume(TK("in"));
|
||||||
@ -130,9 +132,9 @@ class Compiler {
|
|||||||
PyObject* to_object(const TokenValue& value);
|
PyObject* to_object(const TokenValue& value);
|
||||||
PyObject* read_literal();
|
PyObject* read_literal();
|
||||||
|
|
||||||
void SyntaxError(Str msg){ lexer->throw_err("SyntaxError", msg, err().line, err().start); }
|
void SyntaxError(Str msg){ lexer.throw_err("SyntaxError", msg, err().line, err().start); }
|
||||||
void SyntaxError(){ lexer->throw_err("SyntaxError", "invalid syntax", err().line, err().start); }
|
void SyntaxError(){ lexer.throw_err("SyntaxError", "invalid syntax", err().line, err().start); }
|
||||||
void IndentationError(Str msg){ lexer->throw_err("IndentationError", msg, err().line, err().start); }
|
void IndentationError(Str msg){ lexer.throw_err("IndentationError", msg, err().line, err().start); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
|
Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope=false);
|
||||||
|
@ -10,7 +10,47 @@ namespace pkpy{
|
|||||||
|
|
||||||
struct CodeEmitContext;
|
struct CodeEmitContext;
|
||||||
struct Expr;
|
struct Expr;
|
||||||
typedef std::unique_ptr<Expr> Expr_;
|
|
||||||
|
#define PK_POOL64_DELETE(ptr) if(ptr != nullptr) { ptr->~T(); pool64_dealloc(ptr); ptr = nullptr; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class unique_ptr_64{
|
||||||
|
T* ptr;
|
||||||
|
public:
|
||||||
|
unique_ptr_64(): ptr(nullptr) {}
|
||||||
|
unique_ptr_64(T* ptr): ptr(ptr) {}
|
||||||
|
T* operator->() const { return ptr; }
|
||||||
|
T* get() const { return ptr; }
|
||||||
|
T* release() { T* p = ptr; ptr = nullptr; return p; }
|
||||||
|
|
||||||
|
unique_ptr_64(const unique_ptr_64&) = delete;
|
||||||
|
unique_ptr_64& operator=(const unique_ptr_64&) = delete;
|
||||||
|
|
||||||
|
bool operator==(std::nullptr_t) const { return ptr == nullptr; }
|
||||||
|
bool operator!=(std::nullptr_t) const { return ptr != nullptr; }
|
||||||
|
|
||||||
|
~unique_ptr_64(){ PK_POOL64_DELETE(ptr) }
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
unique_ptr_64(unique_ptr_64<U>&& other): ptr(other.release()) {}
|
||||||
|
|
||||||
|
operator bool() const { return ptr != nullptr; }
|
||||||
|
|
||||||
|
template<typename U>
|
||||||
|
unique_ptr_64& operator=(unique_ptr_64<U>&& other) {
|
||||||
|
PK_POOL64_DELETE(ptr)
|
||||||
|
ptr = other.release();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr_64& operator=(std::nullptr_t) {
|
||||||
|
PK_POOL64_DELETE(ptr)
|
||||||
|
ptr = nullptr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef unique_ptr_64<Expr> Expr_;
|
||||||
|
|
||||||
struct Expr{
|
struct Expr{
|
||||||
int line = 0;
|
int line = 0;
|
||||||
|
@ -9,7 +9,7 @@ namespace pkpy{
|
|||||||
}
|
}
|
||||||
|
|
||||||
CodeObject_ Compiler::push_global_context(){
|
CodeObject_ Compiler::push_global_context(){
|
||||||
CodeObject_ co = std::make_shared<CodeObject>(lexer->src, lexer->src->filename);
|
CodeObject_ co = std::make_shared<CodeObject>(lexer.src, lexer.src->filename);
|
||||||
co->start_line = i==0 ? 1 : prev().line;
|
co->start_line = i==0 ? 1 : prev().line;
|
||||||
contexts.push(CodeEmitContext(vm, co, contexts.size()));
|
contexts.push(CodeEmitContext(vm, co, contexts.size()));
|
||||||
return co;
|
return co;
|
||||||
@ -17,7 +17,7 @@ namespace pkpy{
|
|||||||
|
|
||||||
FuncDecl_ Compiler::push_f_context(Str name){
|
FuncDecl_ Compiler::push_f_context(Str name){
|
||||||
FuncDecl_ decl = std::make_shared<FuncDecl>();
|
FuncDecl_ decl = std::make_shared<FuncDecl>();
|
||||||
decl->code = std::make_shared<CodeObject>(lexer->src, name);
|
decl->code = std::make_shared<CodeObject>(lexer.src, name);
|
||||||
decl->code->start_line = i==0 ? 1 : prev().line;
|
decl->code->start_line = i==0 ? 1 : prev().line;
|
||||||
decl->nested = name_scope() == NAME_LOCAL;
|
decl->nested = name_scope() == NAME_LOCAL;
|
||||||
contexts.push(CodeEmitContext(vm, decl->code, contexts.size()));
|
contexts.push(CodeEmitContext(vm, decl->code, contexts.size()));
|
||||||
@ -912,7 +912,7 @@ __EAT_DOTS_END:
|
|||||||
}
|
}
|
||||||
ctx()->emit_(OP_WITH_ENTER, BC_NOARG, prev().line);
|
ctx()->emit_(OP_WITH_ENTER, BC_NOARG, prev().line);
|
||||||
// [ <expr> <expr>.__enter__() ]
|
// [ <expr> <expr>.__enter__() ]
|
||||||
if(as_name){
|
if(as_name != nullptr){
|
||||||
bool ok = as_name->emit_store(ctx());
|
bool ok = as_name->emit_store(ctx());
|
||||||
if(!ok) SyntaxError();
|
if(!ok) SyntaxError();
|
||||||
}else{
|
}else{
|
||||||
@ -1178,13 +1178,11 @@ __EAT_DOTS_END:
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiler::Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope){
|
Compiler::Compiler(VM* vm, std::string_view source, const Str& filename, CompileMode mode, bool unknown_global_scope)
|
||||||
|
:lexer(vm, std::make_shared<SourceData>(source, filename, mode)){
|
||||||
this->vm = vm;
|
this->vm = vm;
|
||||||
this->used = false;
|
this->used = false;
|
||||||
this->unknown_global_scope = unknown_global_scope;
|
this->unknown_global_scope = unknown_global_scope;
|
||||||
this->lexer = std::make_unique<Lexer>(
|
|
||||||
vm, std::make_shared<SourceData>(source, filename, mode)
|
|
||||||
);
|
|
||||||
init_pratt_rules();
|
init_pratt_rules();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1193,7 +1191,7 @@ __EAT_DOTS_END:
|
|||||||
PK_ASSERT(!used)
|
PK_ASSERT(!used)
|
||||||
used = true;
|
used = true;
|
||||||
|
|
||||||
tokens = lexer->run();
|
tokens = lexer.run();
|
||||||
CodeObject_ code = push_global_context();
|
CodeObject_ code = push_global_context();
|
||||||
|
|
||||||
advance(); // skip @sof, so prev() is always valid
|
advance(); // skip @sof, so prev() is always valid
|
||||||
|
Loading…
x
Reference in New Issue
Block a user