كيفية تجميع الديكور - C ++ و Python وتنفيذها الخاص. الجزء 2

يعتبر الديكور أحد أكثر الميزات غير المعتادة في Python. إنها أداة لا يمكن أن توجد إلا بشكل كامل بلغة مترجمة بشكل ديناميكي. في الجزء الأول من المقال يا صديقيعوض محمد عطيه 136 أوضحت كيف في C ++ لتنفيذ النسخة الأقرب من النسخة المرجعية (Python) من الديكور.



سأخبرك كيف قررت أن أحاول تنفيذ الديكور في لغة برمجة مُجمَّعة ، والتي كتبتُ مُجمِّعًا صغيرًا خاصًا بي يعتمد على Haskell بناءً على LLVM .





جدول المحتويات



  1. كيف يعمل الديكور في بيثون
  2. هاسكل و LLVM - مترجم أصلي
  3. فكيف يمكنك تجميع الديكور؟




كيف يعمل الديكور في بيثون



قبل الغوص في خوارزمية تجميع الديكور ، دعنا نتحدث عن تنفيذ الديكور في الثعبان ، ولماذا لا يمكن استنساخه بنفس الشكل في اللغة المترجمة. ألاحظ على الفور أنه في هذه المقالة ، يُفهم الثعبان على أنه CPython. جميع أجزاء حجرة المحرك تشير إليها فقط.



, , , , — , .



Python, - , :



decorator, func, old. newold


def decorator(func):
    def new(*args, **kwargs):
        print('Hey!')
        return func(*args, **kwargs)
    return new

@decorator
def old():
    pass

# old()  "Hey!" -   old    new


— , -, — , .



CPython

Python-. , - — , , , . , , , — - "" .



, , , — - "" . : BINARY_SUBSTRACT () TypeError, 1 'a'. , STORE_FAST ( ), , , TypeError, .. STORE_FAST — .



, new — . -, , , decorator old.



1. —



. decorator , :



name = input('  ')

def first(func):
    ...  #  

def second (func):
    ...  #  

if name == 'first':
    decorator = first
elif name == 'second':
    decorator = second
else:
    decorator = lambda f: f   #    

@decorator 
def old():
    pass


, old . (, C++) , (- ), . Python — , , , " ", .



, , old void-, , — , , , .



, Python, : .



2. Python



def decorator(func):
    def two_args(x, y):
        ...
    return two_args

@decorator
def one_arg(x):
    ...


, . one_arg , ( ) — , , , (, "" ). , ? " " . , , decorator -, .



, , , — . , .



— — func? , , — , . func A, A. void* func, , .



func , — Witcher136 . , (. C++ ).






. :



  • — ?
  • — ?
  • , , ( )


, Python — . , — Python — .

— " ", , , . , .



.





Haskell LLVM —



Haskell, , LLVM . Haskell llvm-hs, LLVM. Parsec, , - ( , , Parsec — parser combinators).



, Grit, ( , , ) — . .



Grit — expression-oriented ()



Grit, , if-else, , — , .



int main() = {
    int i = 0;
    i = i + if(someFunction() > 0) {
        1;
    }
    else {
        0;
    };
};


, i 1, someFunction , , 0 .



return



, ( ) .



, — , Grit, — , . returns, — , ; .



, , "" — "", — , .



int simple(int x) = {
    /* 
          
        x   y
    */
    int y = someOtherFunction();
    x + y;
};

/*
   ,    ,    .
      ,   
*/
int incr(int x) = x + 1;

int main() returns statusCode {
    /*
             returns
         ,  
           .
         "" 
         ,     
    */
    int statusCode = 0;
    int result = someFunction();
    if (someFunction < 0) {
        statusCode = 1;
    };
};


Auto — Grit



Grit auto, , ( ) .



— , . — — , — ..

, , returns.



auto half (int x) = x / 2;   //   incr    float





(expression-oriented), return () — Grit. , .

, , .



— ?





?



, , — runtime compile-time, .



, , , — , .



-, Grit — , ( AST, abstract syntax tree), . -, , .



, :



@auto flatten = {
    auto result = @target;
    if (result < 0) {
        0;
    }
    else {
         result;
    };
};


, , 0, 0, .



@auto flattenflatten @auto — , (@ — , , ).



. , — , , , .



@target. , . ( ), , , , ( ).

, AST @target, . , , — . , .



, Grit, — , Python.



, :



@auto lockFunction = {
    mutex.lock();
    @target
};


, - :



@auto optional = if (checkCondition()) {
    @target;
}
else {
    someDefaultValue;
};




Grit :



@auto flatten = {
    auto result = @target;
    if (result < 0) {
        0;
    }
    else {
         result;
    };
};

@flatten
int incr(int x) = x+1;


flatten , .



"" , - :



Decorator "flatten" auto {
  BinaryOp = (Def auto "result") (DecoratorTarget)
  If (BinaryOp < (Var "result") (Int 0)) {
    Int 0
  }
  else {
    Var "result"
  }
}
Function "incr" int ; args [Def int "x"] ; modifiers [Decorator "flatten"] ; returns Nothing {
  BinaryOp + (Var "x") (Int 1)
}


, — Decorator, incr , Decorator "flatten". DecoratorTargetincr.



, — . , , , "" — , .



, :



Function (int -> int) incr ["x"] {
  BinaryOp i= (Def int "result") (
    Block int {
      BinaryOp i+ (Var int "x") (int 1)
    }
  )
  If int (BinaryOp b< (Var int "result") (int 0)) {
    int 0
  }
  else {
    Var int "result"
  }
}


:



  • — AST, .
  • incr — , flatten, DecoratorTarget Block {...} — " ", . , , — int "result". BinaryOp i= int-, result auto — , , .


, , , . Python, , , Grit.



, — , , :



@auto lockF(mutex M) {
    M.lock();
    @target;
};

@lockF()
int someFunction(...)


mutex M, "", (, , Python — ).



, @args, , " " . , @args.length — , @args.1 — . - , - — .



, Haskell , , , , . , ( , ), - .



, stack



ملاحظة: لقد كانت تجربة مثيرة للاهتمام وغير عادية بالنسبة لي - آمل أن تكون أنت أيضًا قادرًا على تعلم شيء مفيد من هذه القصة. إذا كنت بحاجة إلى مقال منفصل حول كتابة مترجم هاسكل القائم على LLVM - اكتب في التعليقات.

سأحاول الإجابة على أي أسئلة في التعليقات ، أو في برقية - @ nu11_pointer_exception




All Articles