Explorar o código

add `unique_ptr_64`

blueloveTH %!s(int64=2) %!d(string=hai) anos
pai
achega
5983dd2ae6
Modificáronse 3 ficheiros con 57 adicións e 17 borrados
  1. 10 8
      include/pocketpy/compiler.h
  2. 41 1
      include/pocketpy/expr.h
  3. 6 8
      src/compiler.cpp

+ 10 - 8
include/pocketpy/compiler.h

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

+ 41 - 1
include/pocketpy/expr.h

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

+ 6 - 8
src/compiler.cpp

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