Hab das jetzt mal für dich gemacht.
Hier der interface-Teil:
Delphi-Quellcode:
type
TExpression = class
public
function eval:Extended; virtual; abstract;
end;
TZahl = class(TExpression)
private
Fzahl: Extended;
procedure Setzahl(const Value: Extended);
public
constructor Create(zahl:Extended);
function eval:Extended; override;
property zahl:Extended read Fzahl write Setzahl;
end;
TAdd = class(TExpression)
private
FExpr1: TExpression;
FExpr2: TExpression;
procedure SetExpr1(const Value: TExpression);
procedure SetExpr2(const Value: TExpression);
public
constructor Create(Expr1,Expr2:TExpression);
property Expr1:TExpression read FExpr1 write SetExpr1;
property Expr2:TExpression read FExpr2 write SetExpr2;
function eval:Extended; override;
end;
und hier die Implementation:
Delphi-Quellcode:
{ TZahl }
procedure TZahl.Setzahl(const Value: Extended);
begin
Fzahl := Value;
end;
constructor TZahl.Create(zahl: Extended);
begin
Fzahl := zahl
end;
function TZahl.eval: Extended;
begin
result := FZahl
end;
{ TAdd }
constructor TAdd.Create(Expr1, Expr2: TExpression);
begin
FExpr1 := Expr1;
FExpr2 := Expr2
end;
function TAdd.eval: Extended;
begin
result := FExpr1.eval + FExpr2.eval
end;
procedure TAdd.SetExpr1(const Value: TExpression);
begin
FExpr1 := Value;
end;
procedure TAdd.SetExpr2(const Value: TExpression);
begin
FExpr2 := Value;
end;
Was natürlich noch fehlt, aber ganz analog funktioniert, ist TSub, TDiv und TMul.
Um zu überprüfen, ob eine TExpression x eine TZahl ist, kannst du folgenden Code benutzen:
if x is TZahl then {.. ist eine Zahl ..}
Verwenden kannst du die Klasse ganz einfach so:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
num1, num2: TZahl;
add: TAdd;
begin
num1:=TZahl.Create(10);
num2:=TZahl.Create(20);
add:=TAdd.Create(num1,num2);
ShowMessage(FloatToStr(add.eval)); //gibt 30 aus
add.Free;
num1.Free;
num2.Free
end;
Wenn du deinen Stack erstellst, weisst du natürlich noch nicht, wie die einzelnen Operationen zusammengehören, deshalb kannst du bei jeder Nicht-Zahl einfach im Create 2 nil's übergeben.
Auf deinem Stack liegen dann lauter TExpressions, die du beim Auslesen des Stacks nur noch richtig "zusammenstopfen" musst, d.h. also, die entsprechenden Properties setzen musst.
Zu guter letzt genügt EIN einziger Aufruf von eval und du hast das Ergebnis ^^