Merge branch 'main' into pr/208

This commit is contained in:
blueloveTH 2024-02-18 21:25:01 +08:00
commit ac284eee66
3 changed files with 57 additions and 17 deletions

View File

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

View File

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

View File

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