-
Notifications
You must be signed in to change notification settings - Fork 5
/
Loops.pas
150 lines (129 loc) · 3.4 KB
/
Loops.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
unit Loops;
interface
uses
Classes, Types, Generics.Collections, CodeElement, WriterIntf;
type
TLoop = class(TCodeElement)
private
FRelation: TObjectList<TCodeElement>;
public
constructor Create();
destructor Destroy(); override;
property Relation: TObjectList<TCodeElement> read FRelation;
end;
TWhileLoop = class(TLoop)
public
procedure GetDCPUSource(AWriter: IWriter); override;
end;
TRepeatLoop = class(TLoop)
public
procedure GetDCPUSource(AWriter: IWriter); override;
end;
TForLoop = class(TLoop)
private
FAssignment: TObjectList<TCodeElement>;
public
constructor Create();
destructor Destroy(); override;
procedure GetDCPUSource(AWriter: IWriter); override;
property Assignment: TObjectList<TCodeElement> read FAssignment;
end;
implementation
uses
Optimizer, Assignment;
{ TLoop }
constructor TLoop.Create;
begin
inherited Create('');
FRelation := TObjectList<TCodeElement>.Create();
end;
destructor TLoop.Destroy;
begin
FRelation.Free;
inherited;
end;
{ TWhileLoop }
procedure TWhileLoop.GetDCPUSOurce;
var
LID: string;
LEnd: string;
LWhile: string;
begin
AWriter.AddMapping(Self);
LID := GetUniqueID();
LWhile := 'While' + LID;
LEnd := 'End' + LID;
Self.Write(':' + LWhile);
FRelation.Items[0].GetDCPUSource(Self);
Self.Write('set x, pop');
Self.Write('ife x, 0');
Self.Write('set pc, ' + LEnd);
OptimizeDCPUCode(Self.FSource, Self.FSource);
AWriter.WriteList(Self.FSource);
inherited;
AWriter.Write('set pc, ' + LWhile);
AWriter.Write(':' + LEnd);
end;
{ TRepeatLoop }
procedure TRepeatLoop.GetDCPUSOurce;
var
LID: string;
LRepeat: string;
begin
AWriter.AddMapping(Self);
LID := GetUniqueID();
LRepeat := 'Repeat' + LID;
AWriter.Write(':' + LRepeat);
inherited;
FRelation.Items[0].GetDCPUSource(Self);
Self.Write('set x, pop');
Self.Write('ifn x, 0');
Self.Write('set pc, ' + LRepeat);
OptimizeDCPUCode(Self.FSource, Self.FSource);
AWriter.WriteList(Self.FSource);
end;
{ TForLoop }
constructor TForLoop.Create;
begin
inherited;
FAssignment := TObjectList<TCodeElement>.Create();
end;
destructor TForLoop.Destroy;
begin
FAssignment.Free;
inherited;
end;
procedure TForLoop.GetDCPUSource;
var
LID: string;
LFor: string;
LEnd: string;
LVar: string;
begin
AWriter.AddMapping(Self);
LID := GetUniqueID('');
LVar := TAssignment(Assignment.Items[0]).TargetVar.GetAccessIdentifier();
if (TAssignment(Assignment.Items[0]).TargetVar.ParamIndex > 3) or (TAssignment(Assignment.Items[0]).TargetVar.ParamIndex < 1) then
begin
LVar := '[' + LVar + ']';
end;
LFor := 'for' + LID;
LEnd := 'end' + LID;
Assignment.Items[0].GetDCPUSource(Self);
OptimizeDCPUCode(Self.FSource, Self.FSource);
AWriter.WriteList(Self.FSource);
Self.FSource.Clear; //clear it, because we are going to write a new statement to it
Relation.Items[0].GetDCPUSource(Self);
OptimizeDCPUCode(Self.FSource, Self.FSource);
AWriter.WriteList(Self.FSource);
AWriter.Write(':' + LFor);
AWriter.Write('set x, pop');
AWriter.Write('ifg ' + LVar + ', x');
AWriter.Write('set pc, ' + LEnd);
AWriter.Write('set push, x');
inherited;
AWriter.Write('add ' + LVar + ', 1');
AWriter.Write('set pc, ' + LFor);
AWriter.Write(':' + LEnd);
end;
end.