mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 11:30:18 +00:00
Merge branch 'main' into pr/208
This commit is contained in:
commit
ac284eee66
@ -20,7 +20,8 @@ class Compiler {
|
||||
PK_ALWAYS_PASS_BY_POINTER(Compiler)
|
||||
|
||||
inline static PrattRule rules[kTokenCount];
|
||||
std::unique_ptr<Lexer> lexer;
|
||||
|
||||
Lexer lexer;
|
||||
stack<CodeEmitContext> contexts;
|
||||
VM* vm;
|
||||
bool unknown_global_scope; // for eval/exec() call
|
||||
@ -39,7 +40,7 @@ class Compiler {
|
||||
void advance(int delta=1) { i += delta; }
|
||||
|
||||
CodeEmitContext* ctx() { return &contexts.top(); }
|
||||
CompileMode mode() const{ return lexer->src->mode; }
|
||||
CompileMode mode() const{ return lexer.src->mode; }
|
||||
NameScope name_scope() const;
|
||||
CodeObject_ push_global_context();
|
||||
FuncDecl_ push_f_context(Str name);
|
||||
@ -61,8 +62,9 @@ class Compiler {
|
||||
Expr_ EXPR_VARS(); // special case for `for loop` and `comp`
|
||||
|
||||
template <typename T, typename... Args>
|
||||
std::unique_ptr<T> make_expr(Args&&... args) {
|
||||
std::unique_ptr<T> expr = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
unique_ptr_64<T> make_expr(Args&&... args) {
|
||||
void* p = pool64_alloc(sizeof(T));
|
||||
unique_ptr_64<T> expr(new (p) T(std::forward<Args>(args)...));
|
||||
expr->line = prev().line;
|
||||
return expr;
|
||||
}
|
||||
@ -70,7 +72,7 @@ class Compiler {
|
||||
template<typename T>
|
||||
void _consume_comp(Expr_ expr){
|
||||
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->vars = EXPR_VARS();
|
||||
consume(TK("in"));
|
||||
@ -130,9 +132,9 @@ class Compiler {
|
||||
PyObject* to_object(const TokenValue& value);
|
||||
PyObject* read_literal();
|
||||
|
||||
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 IndentationError(Str msg){ lexer->throw_err("IndentationError", 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 IndentationError(Str msg){ lexer.throw_err("IndentationError", msg, err().line, err().start); }
|
||||
|
||||
public:
|
||||
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 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{
|
||||
int line = 0;
|
||||
|
@ -9,7 +9,7 @@ namespace pkpy{
|
||||
}
|
||||
|
||||
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;
|
||||
contexts.push(CodeEmitContext(vm, co, contexts.size()));
|
||||
return co;
|
||||
@ -17,7 +17,7 @@ namespace pkpy{
|
||||
|
||||
FuncDecl_ Compiler::push_f_context(Str name){
|
||||
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->nested = name_scope() == NAME_LOCAL;
|
||||
contexts.push(CodeEmitContext(vm, decl->code, contexts.size()));
|
||||
@ -912,7 +912,7 @@ __EAT_DOTS_END:
|
||||
}
|
||||
ctx()->emit_(OP_WITH_ENTER, BC_NOARG, prev().line);
|
||||
// [ <expr> <expr>.__enter__() ]
|
||||
if(as_name){
|
||||
if(as_name != nullptr){
|
||||
bool ok = as_name->emit_store(ctx());
|
||||
if(!ok) SyntaxError();
|
||||
}else{
|
||||
@ -1178,13 +1178,11 @@ __EAT_DOTS_END:
|
||||
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->used = false;
|
||||
this->unknown_global_scope = unknown_global_scope;
|
||||
this->lexer = std::make_unique<Lexer>(
|
||||
vm, std::make_shared<SourceData>(source, filename, mode)
|
||||
);
|
||||
init_pratt_rules();
|
||||
}
|
||||
|
||||
@ -1193,7 +1191,7 @@ __EAT_DOTS_END:
|
||||
PK_ASSERT(!used)
|
||||
used = true;
|
||||
|
||||
tokens = lexer->run();
|
||||
tokens = lexer.run();
|
||||
CodeObject_ code = push_global_context();
|
||||
|
||||
advance(); // skip @sof, so prev() is always valid
|
||||
|
Loading…
x
Reference in New Issue
Block a user