我想修改我的編譯器的代碼生成器以使用訪問者模式,因爲當前的方法必須使用多個條件語句在生成相應的代碼之前檢查孩子的實際類型。但是,在訪問後我有問題要獲得孩子的屬性。例如,在雙元表達我用這個:訪問者模式和編譯器代碼生成,如何獲取子代屬性?
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 2011-01-14 12:30:00
@ssmir:如果我理解正確,則顯示的代碼是非訪客實現的片段。 – 2011-01-14 12:58:55