デコレータはPythonの最も珍しい機能の1つです。これは、動的に型付けされ、解釈される言語でのみ完全に存在できるツールです。では記事の最初の部分で、私の友人ウィッチャー136 C ++で、最も近いリファレンス(Python)バージョンのデコレータを実装する方法を示しました。
LLVMに基づくHaskellに基づく独自の小さなコンパイラーを作成するために、コンパイルされたプログラミング言語にデコレーターを実装しようと決心した方法について説明します。
目次
Pythonでのデコレーターの仕組み
デコレーターのコンパイルアルゴリズムに入る前に、Pythonでのデコレーターの実装について、そしてそれをコンパイルされた言語で同じ形式で再現できない理由について説明しましょう。この記事では、PythonがCPythonとして理解されていることをすぐに指摘します。すべてのエンジンルームパーツはそれのみを参照します。
, , , , — , .
Python, - , :
decorator, func, old. new — old
def decorator(func):
def new(*args, **kwargs):
print('Hey!')
return func(*args, **kwargs)
return new
@decorator
def old():
pass
# old() "Hey!" - old new
— , -, — , .
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 — 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 flatten
— flatten
@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"
. DecoratorTarget
— incr
.
, — . , , , "" — , .
, :
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 , , , , . , ( , ), - .
PSそれは私にとって非常に興味深く、珍しい経験でした-私もあなたがこの話から何か役に立つものを学ぶことができたことを願っています。LLVMに基づくHaskellコンパイラーの作成に関する別の記事が必要な場合は、コメントに書き込んでください。
コメントや電報で質問に答えようと思います-@ nu11_pointer_exception