source: branches/xpascal/Optimizer.pas

Last change on this file was 232, checked in by chronos, 17 months ago
  • Fixed: Generation of var function parameters.
File size: 4.1 KB
Line 
1unit Optimizer;
2
3interface
4
5uses
6 Classes, SysUtils, Source, SourceNode;
7
8type
9 TOptimizeFeature = (ofReplaceRepeatUntilByWhileDo, ofReplaceResultByReturn);
10 TOptimizeFeatures = set of TOptimizeFeature;
11
12 { TOptimizer }
13
14 TOptimizer = class
15 private
16 procedure OptimizeNodes(SourceNodes: TSourceNodeList<TSourceNode>; out NewNode: TSourceNode);
17 procedure OptimizeNode(SourceNode: TSourceNode; out NewNode: TSourceNode);
18 public
19 Prog: TProgram;
20 Features: TOptimizeFeatures;
21 procedure Optimize;
22 end;
23
24implementation
25
26resourcestring
27 SUnsupportedNodeType = 'Unsupported node type';
28
29{ TOptimizer }
30
31procedure TOptimizer.OptimizeNodes(SourceNodes: TSourceNodeList<TSourceNode>; out
32 NewNode: TSourceNode);
33var
34 I: Integer;
35 TempNewNode: TSourceNode;
36begin
37 for I := 0 to SourceNodes.Count - 1 do begin
38 if SourceNodes[I] is TSourceNode then begin
39 OptimizeNode(TSourceNode(SourceNodes[I]), TempNewNode);
40 if Assigned(TempNewNode) and (TempNewNode <> TSourceNode(SourceNodes[I])) then begin
41 SourceNodes[I] := TempNewNode;
42 end;
43 end else raise Exception.Create(SUnsupportedNodeType);
44 end;
45end;
46
47procedure TOptimizer.OptimizeNode(SourceNode: TSourceNode; out
48 NewNode: TSourceNode);
49var
50 I: Integer;
51 WhileDo: TWhileDo;
52 Condition: TIfThenElse;
53 Return: TReturn;
54 Field: TField;
55 Obj: TObject;
56 TempNewNode: TSourceNode;
57 ListValue: TSourceNodeList<TSourceNode>;
58begin
59 NewNode := nil;
60 if (ofReplaceRepeatUntilByWhileDo in Features) and (SourceNode is TRepeatUntil) then begin
61 WhileDo := TWhileDo.Create;
62 WhileDo.Command := TBeginEnd.Create;
63 WhileDo.Parent := TRepeatUntil(SourceNode).Parent;
64 TBeginEnd(WhileDo.Command).Commands := TRepeatUntil(SourceNode).Commands;
65 TBeginEnd(WhileDo.Command).Parent := WhileDo;
66 TRepeatUntil(SourceNode).Commands := TCommands.Create;
67 WhileDo.Expression := TExpressionOperand.Create;
68 WhileDo.Expression.Parent := WhileDo;
69 TExpressionOperand(WhileDo.Expression).OperandType := otConstantDirect;
70 TExpressionOperand(WhileDo.Expression).ConstantDirect := TConstant.Create;
71 TConstant(TExpressionOperand(WhileDo.Expression).ConstantDirect).Value := TValueBoolean.Create;
72 TValueBoolean(TConstant(TExpressionOperand(WhileDo.Expression).ConstantDirect).Value).Value := True;
73
74 // Add final if
75 Condition := TIfThenElse.Create;
76 Condition.Parent := WhileDo;
77 Condition.Expression := TRepeatUntil(SourceNode).Expression;
78 Condition.CommandThen := TBreak.Create;
79 Condition.CommandThen.Parent := Condition;
80 TRepeatUntil(SourceNode).Expression := TExpression.Create;
81 TBeginEnd(WhileDo.Command).Commands.Add(Condition);
82 NewNode := WhileDo;
83 end else
84 if (ofReplaceResultByReturn in Features) and (SourceNode is TAssignment) then begin
85 if TAssignment(SourceNode).Variable.Name = 'Result' then begin
86 Return := TReturn.Create;
87 Return.Parent := TAssignment(SourceNode).Parent;
88 Return.Expression.Free;
89 Return.Expression := TAssignment(SourceNode).Expression;
90 Return.Expression.Parent := Return;
91 TAssignment(SourceNode).Expression := TExpression.Create;
92 NewNode := Return;
93 end;
94 end else
95 if SourceNode is TSourceNode then begin
96 for I := 0 to SourceNode.FieldsCount - 1 do begin
97 Field := SourceNode.GetField(I);
98 if Field.DataType = dtObject then begin
99 SourceNode.GetValue(I, Obj);
100 if Obj is TSourceNode then begin
101 OptimizeNode(TSourceNode(Obj), TempNewNode);
102 if Assigned(TempNewNode) and (TempNewNode <> TSourceNode(Obj)) then begin
103 SourceNode.SetValueObject(I, TempNewNode);
104 end;
105 end;
106 end;
107 Field.Free;
108 end;
109 end else
110 raise Exception.Create(SUnsupportedNodeType);
111
112 for I := 0 to SourceNode.FieldsCount - 1 do begin
113 Field := SourceNode.GetField(I);
114 if Field.DataType = dtList then begin
115 SourceNode.GetValue(I, ListValue);
116 OptimizeNodes(TSourceNodeList<TSourceNode>(ListValue), NewNode)
117 end;
118 end;
119end;
120
121procedure TOptimizer.Optimize;
122var
123 NewProg: TSourceNode;
124begin
125 OptimizeNode(Prog, NewProg);
126end;
127
128end.
129
Note: See TracBrowser for help on using the repository browser.