現在のアプローチでは、対応するコードを生成する前に、子の実際の型をチェックするために複数の条件文を使用する必要があるため、コンパイラのコードジェネレータをvisitorパターンを使用して変更したいと考えています。しかし、私は訪問した後に子供の属性を取得するのに問題があります。例えば、私はこれを使用したバイナリ表現で:ビジターパターンでビジターパターンとコンパイラコード生成、どのように子供の属性を取得するには?
LHSCode := GenerateExpressionCode(LHSNode);
RHSCode := GenerateExpressionCode(RHSNode);
CreateBinaryExpression(Self,LHS,RHS);
訪問の方法は、通常は無効となりますので、私はLHSとRHSからの発現コードを取得することはできません。式のコード生成は再帰的であるため、変数に保存されている以前の値を消去する可能性があるため、共有グローバル変数を保持することはオプションではありません。
これは(今のところ)最も複雑な部分であると私はバイナリ表現を単に紹介:
function TLLVMCodeGenerator.GenerateExpressionCode(
Expr: TASTExpression): TLLVMValue;
var
BinExpr: TASTBinaryExpression;
UnExpr: TASTUnaryExpression;
LHSCode, RHSCode, ExprCode: TLLVMValue;
VarExpr: TASTVariableExpression;
begin
if Expr is TASTBinaryExpression then begin
BinExpr := Expr as TASTBinaryExpression;
LHSCode := GenerateExpressionCode(BinExpr.LHS);
RHSCode := GenerateExpressionCode(BinExpr.RHS);
case BinExpr.Op of
'<': Result := FBuilder.CreateICmp(ccSLT, LHSCode, RHSCode);
'<=': Result := FBuilder.CreateICmp(ccSLE, LHSCode, RHSCode);
'>': Result := FBuilder.CreateICmp(ccSGT, LHSCode, RHSCode);
'>=': Result := FBuilder.CreateICmp(ccSGE, LHSCode, RHSCode);
'==': Result := FBuilder.CreateICmp(ccEQ, LHSCode, RHSCode);
'<>': Result := FBuilder.CreateICmp(ccNE, LHSCode, RHSCode);
'/\': Result := FBuilder.CreateAnd(LHSCode, RHSCode);
'\/': Result := FBuilder.CreateOr(LHSCode, RHSCode);
'+': Result := FBuilder.CreateAdd(LHSCode, RHSCode);
'-': Result := FBuilder.CreateSub(LHSCode, RHSCode);
'*': Result := FBuilder.CreateMul(LHSCode, RHSCode);
'/': Result := FBuilder.CreateSDiv(LHSCode, RHSCode);
end;
end else if Expr is TASTPrimaryExpression then
if Expr is TASTBooleanConstant then
with Expr as TASTBooleanConstant do
Result := FBuilder.CreateConstant(Ord(Value), ltI1)
else if Expr is TASTIntegerConstant then
with Expr as TASTIntegerConstant do
Result := FBuilder.CreateConstant(Value, ltI32)
else if Expr is TASTUnaryExpression then begin
UnExpr := Expr as TASTUnaryExpression;
ExprCode := GenerateExpressionCode(UnExpr.Expr);
case UnExpr.Op of
'~': Result := FBuilder.CreateXor(
FBuilder.CreateConstant(1, ltI1), ExprCode);
'-': Result := FBuilder.CreateSub(
FBuilder.CreateConstant(0, ltI32), ExprCode);
end;
end else if Expr is TASTVariableExpression then begin
VarExpr := Expr as TASTVariableExpression;
with VarExpr.VarDecl do
Result := FBuilder.CreateVar(Ident, BaseTypeLLVMTypeMap[BaseType]);
end;
end;
は、あなたがそれを理解してほしい:)ビジターパターンで
質問は不明です。どのような子供の属性が意味するのですか? GenerateExpressionCodeが訪問メソッドの役割を果たすことを意味しますか? – ssmir
@ssmir:正しく理解していれば、表示されているコードは訪問者以外の実装のスニペットです。 –
@ssmir:私が上に示したスニペットから、現在の(自己)ノードは左と右のオペランド(Selfの子である)から生成されたコードを必要とします。それは私が実際に "属性"を意味するものです。 – LeleDumbo