source: tags/1.3.0/BFTarget.pas

Last change on this file was 147, checked in by chronos, 17 months ago
  • Modified: Code cleanup.
File size: 21.4 KB
Line 
1unit BFTarget;
2
3interface
4
5uses
6 Classes, SysUtils, Target;
7
8type
9
10 TMachineCommand = (cmNoOperation, cmInc, cmDec, cmPointerInc, cmPointerDec,
11 cmOutput, cmInput, cmLoopStart, cmLoopEnd, cmDebug, cmSet, cmMultiply);
12
13 { TMachineOperation }
14
15 TMachineOperation = record
16 Command: TMachineCommand;
17 Parameter: Integer;
18 RelIndex: Integer;
19 class function Create(Command: TMachineCommand; Parameter: Integer;
20 RelIndex: Integer = 0): TMachineOperation; static;
21 end;
22
23 TMachineOperations = array of TMachineOperation;
24
25 { TProgram }
26
27 TProgram = class
28 private
29 function GetCount: Integer;
30 function GetItem(Index: Integer): TMachineOperation;
31 procedure SetCount(AValue: Integer);
32 procedure SetItem(Index: Integer; AValue: TMachineOperation);
33 public
34 Operations: TMachineOperations;
35 Index: Integer;
36 procedure Assign(Source: TProgram);
37 procedure Write(Operation: TMachineOperation);
38 function Read: TMachineOperation;
39 property Count: Integer read GetCount write SetCount;
40 property Items[Index: Integer]: TMachineOperation read GetItem write SetItem; default;
41 end;
42
43 TOptimizations = record
44 AddSub: Boolean;
45 SetZero: Boolean;
46 Merge: Boolean;
47 RelativeIndexes: Boolean;
48 CopyMultiply: Boolean;
49 end;
50
51 { TBFTarget }
52
53 TBFTarget = class(TTarget)
54 private
55 function CheckLoopSetZero: Boolean;
56 function CheckOccurenceSumParam(C: TMachineCommand): Integer;
57 function CheckOccurence(C: TMachineCommand): Integer;
58 function CheckLoopDecrementCount: Integer;
59 procedure OptimizeAddSub;
60 procedure OptimizeSetZero;
61 procedure OptimizeMerge;
62 procedure OptimizeZeroInitMemory;
63 procedure OptimizeRelativeIndexes;
64 procedure OptimizeCopyMultiply;
65 protected
66 FProgram: TProgram;
67 FProgramIndex: Integer;
68 function GetOperationText(Operation: TMachineOperation): string; virtual;
69 procedure LoadProgram; override;
70 public
71 MemorySize: Integer;
72 MemoryMaxUsedAddr: Integer;
73 CellSize: Integer;
74 Optimizations: TOptimizations;
75 constructor Create; override;
76 destructor Destroy; override;
77 procedure OptimizeSource; override;
78 property ProgramIndex: Integer read FProgramIndex;
79 end;
80
81const
82 BrainFuckCommandText: array[TMachineCommand] of Char = (
83 ' ', '+', '-', '>', '<', '.', ',', '[', ']', '@', '=', '*');
84
85
86implementation
87
88resourcestring
89 SUnsupportedCommand = 'Unsupported command %d';
90
91{ TProgram }
92
93function TProgram.GetCount: Integer;
94begin
95 Result := Length(Operations);
96end;
97
98function TProgram.GetItem(Index: Integer): TMachineOperation;
99begin
100 Result := Operations[Index];
101end;
102
103procedure TProgram.SetCount(AValue: Integer);
104begin
105 SetLength(Operations, AValue);
106end;
107
108procedure TProgram.SetItem(Index: Integer; AValue: TMachineOperation);
109begin
110 Operations[Index] := AValue;
111end;
112
113procedure TProgram.Assign(Source: TProgram);
114begin
115 Count := Source.Count;
116 Move(Pointer(Source.Operations)^, Pointer(Operations)^, SizeOf(TMachineOperation) * Count);
117end;
118
119procedure TProgram.Write(Operation: TMachineOperation);
120begin
121 Operations[Index] := Operation;
122 Inc(Index);
123end;
124
125function TProgram.Read: TMachineOperation;
126begin
127 Result := Operations[Index];
128 Inc(Index);
129end;
130
131{ TMachineOperation }
132
133class function TMachineOperation.Create(Command: TMachineCommand;
134 Parameter: Integer; RelIndex: Integer = 0): TMachineOperation;
135begin
136 Result.Command := Command;
137 Result.Parameter := Parameter;
138 Result.RelIndex := RelIndex;
139end;
140
141function TBFTarget.CheckLoopSetZero: Boolean;
142begin
143 Result := (FProgram[FProgramIndex].Command = cmLoopStart) and (FProgram.Count >= FProgramIndex + 2) and
144 (((FProgram[FProgramIndex + 1].Command = cmDec) and (FProgram[FProgramIndex + 1].Parameter = 1)) or
145 ((FProgram[FProgramIndex + 1].Command = cmInc) and (FProgram[FProgramIndex + 1].Parameter = -1)))
146 and (FProgram[FProgramIndex + 2].Command = cmLoopEnd);
147end;
148
149function TBFTarget.CheckOccurence(C: TMachineCommand): Integer;
150begin
151 Result := 1;
152 while ((FProgramIndex + 1) < FProgram.Count) and (FProgram[FProgramIndex + 1].Command = C) do begin
153 Inc(Result);
154 Inc(FProgramIndex);
155 end;
156end;
157
158function TBFTarget.CheckOccurenceSumParam(C: TMachineCommand): Integer;
159begin
160 Result := FProgram[FProgramIndex].Parameter;
161 while ((FProgramIndex + 1) < FProgram.Count) and (FProgram[FProgramIndex + 1].Command = C) do begin
162 Inc(Result, FProgram[FProgramIndex + 1].Parameter);
163 Inc(FProgramIndex);
164 end;
165end;
166
167// Merge multiple sequential occurences of +/-/>/< operations into single fast
168// operation with parameter value set to number of occurences
169procedure TBFTarget.OptimizeAddSub;
170var
171 NewProgram: TProgram;
172 InitialProgramIndex: Integer;
173 InitialNewProgramIndex: Integer;
174begin
175 NewProgram := TProgram.Create;
176 NewProgram.Count := FProgram.Count;
177
178 FProgramIndex := 0;
179 while FProgramIndex < FProgram.Count do begin
180 InitialProgramIndex := FProgramIndex;
181 InitialNewProgramIndex := NewProgram.Index;
182 case FProgram[FProgramIndex].Command of
183 cmPointerInc: begin
184 NewProgram.Write(TMachineOperation.Create(cmPointerInc,
185 CheckOccurenceSumParam(cmPointerInc)));
186 end;
187 cmPointerDec: begin
188 NewProgram.Write(TMachineOperation.Create(cmPointerDec,
189 CheckOccurenceSumParam(cmPointerDec)));
190 end;
191 cmInc: begin
192 NewProgram.Write(TMachineOperation.Create(cmInc,
193 CheckOccurenceSumParam(cmInc)));
194 end;
195 cmDec: begin
196 NewProgram.Write(TMachineOperation.Create(cmDec,
197 CheckOccurenceSumParam(cmDec)));
198 end;
199 else NewProgram.Write(FProgram[FProgramIndex]);
200 end;
201 DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
202 NewProgram.Index);
203 Inc(FProgramIndex);
204 end;
205
206 NewProgram.Count := NewProgram.Index;
207 FProgram.Assign(NewProgram);
208 FreeAndNil(NewProgram);
209end;
210
211// Converts [-] into mSet,0 (=0) command
212procedure TBFTarget.OptimizeSetZero;
213var
214 NewProgram: TProgram;
215 InitialProgramIndex: Integer;
216 InitialNewProgramIndex: Integer;
217begin
218 NewProgram := TProgram.Create;
219 NewProgram.Count := FProgram.Count;
220
221 FProgramIndex := 0;
222 while FProgramIndex < FProgram.Count do begin
223 InitialProgramIndex := FProgramIndex;
224 InitialNewProgramIndex := NewProgram.Index;
225 case FProgram[FProgramIndex].Command of
226 cmLoopStart: begin
227 if CheckLoopSetZero then begin
228 NewProgram.Write(TMachineOperation.Create(cmSet, 0, 0));
229 Inc(FProgramIndex, 2);
230 end else begin
231 NewProgram.Write(FProgram[FProgramIndex]);
232 end;
233 end;
234 else NewProgram.Write(FProgram[FProgramIndex]);
235 end;
236 DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
237 NewProgram.Index);
238 Inc(FProgramIndex);
239 end;
240 NewProgram.Count := NewProgram.Index;
241 FProgram.Assign(NewProgram);
242 FreeAndNil(NewProgram);
243end;
244
245// Merge together cmInc, cmDec, cmSet
246// Merge together cmPointerInc, cmPointerDec
247procedure TBFTarget.OptimizeMerge;
248var
249 NewProgram: TProgram;
250 PreviousCommand: TMachineCommand;
251 InitialProgramIndex: Integer;
252 InitialNewProgramIndex: Integer;
253begin
254 NewProgram := TProgram.Create;
255 NewProgram.Count := FProgram.Count;
256
257 PreviousCommand := cmNoOperation;
258 FProgramIndex := 0;
259 while FProgramIndex < FProgram.Count do begin
260 InitialProgramIndex := FProgramIndex;
261 InitialNewProgramIndex := NewProgram.Index;
262 case FProgram[FProgramIndex].Command of
263 cmPointerInc: begin
264 if PreviousCommand in [cmPointerInc, cmPointerDec] then begin
265 if NewProgram[NewProgram.Index - 1].Command = cmPointerInc then
266 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter +
267 FProgram[FProgramIndex].Parameter
268 else
269 if NewProgram[NewProgram.Index - 1].Command = cmPointerDec then
270 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter -
271 FProgram[FProgramIndex].Parameter;
272 // If value negative then change command
273 if NewProgram[NewProgram.Index - 1].Parameter < 0 then begin
274 NewProgram.Operations[NewProgram.Index - 1].Parameter := -NewProgram[NewProgram.Index - 1].Parameter;
275 if NewProgram[NewProgram.Index - 1].Command = cmPointerInc then
276 NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerDec
277 else NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerInc;
278 end;
279 if NewProgram.Operations[NewProgram.Index - 1].Parameter = 0 then
280 Dec(NewProgram.Index);
281 end else begin
282 NewProgram.Write(TMachineOperation.Create(cmPointerInc,
283 FProgram[FProgramIndex].Parameter));
284 end;
285 end;
286 cmPointerDec: begin
287 if PreviousCommand in [cmPointerInc, cmPointerDec] then begin
288 if NewProgram[NewProgram.Index - 1].Command = cmPointerDec then
289 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter +
290 FProgram[FProgramIndex].Parameter
291 else if NewProgram[NewProgram.Index - 1].Command = cmPointerInc then
292 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter -
293 FProgram[FProgramIndex].Parameter;
294 // If value negative then change command
295 if NewProgram[NewProgram.Index - 1].Parameter < 0 then begin
296 NewProgram.Operations[NewProgram.Index - 1].Parameter := -NewProgram[NewProgram.Index - 1].Parameter;
297 if NewProgram[NewProgram.Index - 1].Command = cmPointerInc then
298 NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerDec
299 else NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerInc;
300 end;
301 if NewProgram[NewProgram.Index - 1].Parameter = 0 then
302 Dec(NewProgram.Index);
303 end else begin
304 NewProgram.Write(TMachineOperation.Create(cmPointerDec,
305 FProgram[FProgramIndex].Parameter));
306 end;
307 end;
308 cmInc: begin
309 if PreviousCommand in [cmInc, cmDec, cmSet] then begin
310 if NewProgram[NewProgram.Index - 1].Command in [cmInc, cmSet] then
311 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter +
312 FProgram[FProgramIndex].Parameter
313 else if NewProgram[NewProgram.Index - 1].Command = cmDec then
314 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter -
315 FProgram[FProgramIndex].Parameter;
316 // If value negative then change command
317 if (NewProgram[NewProgram.Index - 1].Parameter < 0) and (NewProgram[NewProgram.Index - 1].Command <> cmSet) then begin
318 NewProgram.Operations[NewProgram.Index - 1].Parameter := -NewProgram[NewProgram.Index - 1].Parameter;
319 if NewProgram[NewProgram.Index - 1].Command = cmInc then
320 NewProgram.Operations[NewProgram.Index - 1].Command := cmDec
321 else NewProgram.Operations[NewProgram.Index - 1].Command := cmInc;
322 end;
323 if NewProgram[NewProgram.Index - 1].Parameter = 0 then
324 Dec(NewProgram.Index);
325 end else begin
326 NewProgram.Write(TMachineOperation.Create(cmInc,
327 FProgram[FProgramIndex].Parameter));
328 end;
329 end;
330 cmDec: begin
331 if PreviousCommand in [cmInc, cmDec, cmSet] then begin
332 if NewProgram[NewProgram.Index - 1].Command = cmDec then
333 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter +
334 FProgram[FProgramIndex].Parameter
335 else if NewProgram[NewProgram.Index - 1].Command in [cmInc, cmSet] then
336 NewProgram.Operations[NewProgram.Index - 1].Parameter := NewProgram[NewProgram.Index - 1].Parameter -
337 FProgram[FProgramIndex].Parameter;
338 // If value negative then change command
339 if (NewProgram[NewProgram.Index - 1].Parameter < 0) and (NewProgram[NewProgram.Index - 1].Command <> cmSet) then begin
340 NewProgram.Operations[NewProgram.Index - 1].Parameter := -NewProgram[NewProgram.Index - 1].Parameter;
341 if NewProgram[NewProgram.Index - 1].Command = cmInc then
342 NewProgram.Operations[NewProgram.Index - 1].Command := cmDec
343 else NewProgram.Operations[NewProgram.Index - 1].Command := cmInc;
344 end;
345 if NewProgram[NewProgram.Index - 1].Parameter = 0 then
346 Dec(NewProgram.Index);
347 end else begin
348 NewProgram.Write(TMachineOperation.Create(cmDec,
349 FProgram[FProgramIndex].Parameter));
350 end;
351 end;
352 cmSet: begin
353 if PreviousCommand in [cmInc, cmDec, cmSet] then begin
354 // Set overrides value of previous commands
355 Dec(NewProgram.Index);
356 NewProgram.Write(TMachineOperation.Create(cmSet,
357 FProgram[FProgramIndex].Parameter));
358 end else begin
359 NewProgram.Write(FProgram[FProgramIndex]);
360 end;
361 end;
362 else NewProgram.Write(FProgram[FProgramIndex]);
363 end;
364 PreviousCommand := FProgram[FProgramIndex].Command;
365 DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
366 NewProgram.Index);
367 Inc(FProgramIndex);
368 end;
369
370 NewProgram.Count := NewProgram.Index;
371 FProgram.Assign(NewProgram);
372 FreeAndNil(NewProgram);
373end;
374
375procedure TBFTarget.OptimizeZeroInitMemory;
376begin
377 // Here Optimizations related to assumption that initial memory is filled with zeroes
378 // Then code for constants preparation can be translated to cmSet commands
379 // To eliminate also loops for building constants code need to be somehow interpretted partialy
380end;
381
382procedure TBFTarget.OptimizeRelativeIndexes;
383var
384 NewProgram: TProgram;
385 RelIndex: Integer;
386 InitialProgramIndex: Integer;
387 InitialNewProgramIndex: Integer;
388begin
389 NewProgram := TProgram.Create;
390 NewProgram.Count := FProgram.Count;
391
392 RelIndex := 0;
393 FProgramIndex := 0;
394 while FProgramIndex < FProgram.Count do begin
395 InitialProgramIndex := FProgramIndex;
396 InitialNewProgramIndex := NewProgram.Index;
397 case FProgram[FProgramIndex].Command of
398 cmPointerInc: begin
399 RelIndex := RelIndex + FProgram[FProgramIndex].Parameter;
400 end;
401 cmPointerDec: begin
402 RelIndex := RelIndex - FProgram[FProgramIndex].Parameter;
403 end;
404 cmInc, cmDec, cmInput, cmOutput, cmSet: begin
405 NewProgram.Write(FProgram[FProgramIndex]);
406 NewProgram.Operations[NewProgram.Index - 1].RelIndex :=
407 NewProgram[NewProgram.Index - 1].RelIndex + RelIndex;
408 end;
409 cmLoopStart, cmLoopEnd: begin
410 if RelIndex > 0 then begin
411 NewProgram.Write(TMachineOperation.Create(cmPointerInc,
412 RelIndex, 0));
413 RelIndex := 0;
414 end else
415 if RelIndex < 0 then begin
416 NewProgram.Write(TMachineOperation.Create(cmPointerDec,
417 Abs(RelIndex), 0));
418 RelIndex := 0;
419 end;
420 NewProgram.Write(FProgram[FProgramIndex]);
421 end;
422 else raise Exception.Create(Format(SUnsupportedCommand, [FProgram[FProgramIndex].Command]));
423 end;
424 DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
425 NewProgram.Index);
426 Inc(FProgramIndex);
427 end;
428
429 NewProgram.Count := NewProgram.Index;
430 FProgram.Assign(NewProgram);
431 FreeAndNil(NewProgram);
432end;
433
434function TBFTarget.CheckLoopDecrementCount: Integer;
435var
436 I: Integer;
437 PointerChange: Integer;
438begin
439 Result := 0;
440 PointerChange := 0;
441 I := FProgramIndex + 1;
442 while I < FProgram.Count do begin
443 case FProgram[I].Command of
444 cmPointerInc: begin
445 Inc(PointerChange, FProgram[I].Parameter);
446 end;
447 cmPointerDec: begin
448 Dec(PointerChange, FProgram[I].Parameter);
449 end;
450 cmInc: begin
451 end;
452 cmDec: begin
453 if (PointerChange = 0) and (FProgram[I].RelIndex = 0) and
454 (FProgram[I].Parameter = 1) then
455 Inc(Result);
456 end;
457 cmLoopEnd: begin
458 if (Result = 1) and (PointerChange = 0) then begin
459 Break;
460 end;
461 end;
462 else begin
463 // The loop can't be optimized as there are other operations inside
464 Result := 0;
465 Break;
466 end;
467 end;
468 Inc(I);
469 end;
470end;
471
472// Optimize copy and multiply loops like [>+<-] or [>++<-] or [>+>+<<-]
473procedure TBFTarget.OptimizeCopyMultiply;
474var
475 NewProgram: TProgram;
476 ProcessingLoop: Boolean;
477 PointerChange: Integer;
478 InitialProgramIndex: Integer;
479 InitialNewProgramIndex: Integer;
480begin
481 NewProgram := TProgram.Create;
482 NewProgram.Count := FProgram.Count;
483
484 ProcessingLoop := False;
485 FProgramIndex := 0;
486 PointerChange := 0;
487 while FProgramIndex < FProgram.Count do begin
488 InitialProgramIndex := FProgramIndex;
489 InitialNewProgramIndex := NewProgram.Index;
490 case FProgram[FProgramIndex].Command of
491 cmPointerInc: begin
492 Inc(PointerChange, FProgram[FProgramIndex].Parameter);
493 NewProgram.Write(FProgram[FProgramIndex]);
494 end;
495 cmPointerDec: begin
496 Dec(PointerChange, FProgram[FProgramIndex].Parameter);
497 NewProgram.Write(FProgram[FProgramIndex]);
498 end;
499 cmInc: begin
500 if not ProcessingLoop then begin
501 NewProgram.Write(FProgram[FProgramIndex]);
502 end else begin
503 if ((FProgram[FProgramIndex].RelIndex + PointerChange) <> 0) then begin
504 NewProgram.Write(FProgram[FProgramIndex]);
505 NewProgram.Operations[NewProgram.Index - 1].Command := cmMultiply;
506 end;
507 end;
508 end;
509 cmDec: begin
510 if not ProcessingLoop then begin
511 NewProgram.Write(FProgram[FProgramIndex]);
512 end else begin
513 if ((FProgram[FProgramIndex].RelIndex + PointerChange) <> 0) then begin
514 NewProgram.Write(FProgram[FProgramIndex]);
515 NewProgram.Operations[NewProgram.Index - 1].Command := cmMultiply;
516 NewProgram.Operations[NewProgram.Index - 1].Parameter := -FProgram[FProgramIndex].Parameter;
517 end;
518 end;
519 end;
520 cmInput, cmOutput, cmSet: begin
521 NewProgram.Write(FProgram[FProgramIndex]);
522 end;
523 cmLoopStart: begin
524 if not ProcessingLoop then begin
525 if CheckLoopDecrementCount = 1 then begin
526 PointerChange := 0;
527 ProcessingLoop := True;
528 end else
529 NewProgram.Write(FProgram[FProgramIndex]);
530 end else begin
531 raise Exception.Create('Another loop start not allowed inside loop');
532 end;
533 end;
534 cmLoopEnd: begin
535 if not ProcessingLoop then begin
536 NewProgram.Write(FProgram[FProgramIndex]);
537 end else begin
538 // Finally set decrementing cell to zero
539 NewProgram.Write(TMachineOperation.Create(cmSet, 0, 0));
540 ProcessingLoop := False;
541 end;
542 end;
543 else raise Exception.Create(Format(SUnsupportedCommand, [FProgram[FProgramIndex].Command]));
544 end;
545
546 DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex,
547 InitialNewProgramIndex, NewProgram.Index);
548 Inc(FProgramIndex);
549 end;
550
551 NewProgram.Count := NewProgram.Index;
552 FProgram.Assign(NewProgram);
553 FreeAndNil(NewProgram);
554end;
555
556function TBFTarget.GetOperationText(Operation: TMachineOperation): string;
557begin
558 Result := BrainFuckCommandText[Operation.Command];
559 if Operation.Command in [cmInc, cmDec, cmPointerInc, cmPointerDec,
560 cmSet, cmMultiply] then begin
561 if Operation.Parameter <> 1 then
562 Result := Result + IntToStr(Operation.Parameter);
563 end;
564 if Operation.RelIndex <> 0 then
565 Result := Result + 'R' + IntToStr(Operation.RelIndex);
566end;
567
568procedure TBFTarget.LoadProgram;
569var
570 I: Integer;
571 LastIndex: Integer;
572begin
573 inherited;
574 DebugSteps.Clear;
575 FProgram.Count := Length(FSourceCode);
576 FProgram.Index := 0;
577 LastIndex := 0;
578 for I := 1 to Length(FSourceCode) do begin
579 case FSourceCode[I] of
580 '+': FProgram.Write(TMachineOperation.Create(cmInc, 1));
581 '-': FProgram.Write(TMachineOperation.Create(cmDec, 1));
582 '>': FProgram.Write(TMachineOperation.Create(cmPointerInc, 1));
583 '<': FProgram.Write(TMachineOperation.Create(cmPointerDec, 1));
584 ',': FProgram.Write(TMachineOperation.Create(cmInput, 0));
585 '.': FProgram.Write(TMachineOperation.Create(cmOutput, 0));
586 '[': FProgram.Write(TMachineOperation.Create(cmLoopStart, 0));
587 ']': FProgram.Write(TMachineOperation.Create(cmLoopEnd, 0));
588 end;
589 if DebugEnabled and (FProgram.Index <> LastIndex) then begin
590 case FSourceCode[I] of
591 '[': DebugSteps.AddStep(I - 1, FProgram.Index - 1, soStepIn);
592 ']': DebugSteps.AddStep(I - 1, FProgram.Index - 1, soStepOut);
593 else DebugSteps.AddStep(I - 1, FProgram.Index - 1, soNormal);
594 end;
595 end;
596 LastIndex := FProgram.Index;
597 end;
598 FProgramIndex := FProgram.Index;
599 FProgram.Count := FProgram.Index;
600end;
601
602constructor TBFTarget.Create;
603begin
604 inherited;
605 MemorySize := 30000;
606 CellSize := 256;
607 FProgram := TProgram.Create;
608end;
609
610destructor TBFTarget.Destroy;
611begin
612 FreeAndNil(FProgram);
613 inherited;
614end;
615
616procedure TBFTarget.OptimizeSource;
617var
618 OldLength: Integer;
619begin
620 inherited;
621 if Optimizations.AddSub then OptimizeAddSub;
622 if Optimizations.SetZero then OptimizeSetZero;
623 if Optimizations.Merge then
624 repeat
625 OldLength := FProgram.Count;
626 OptimizeMerge;
627 until FProgram.Count = OldLength;
628 OptimizeZeroInitMemory;
629 if Optimizations.RelativeIndexes then OptimizeRelativeIndexes;
630 if Optimizations.CopyMultiply then OptimizeCopyMultiply;
631end;
632
633end.
634
Note: See TracBrowser for help on using the repository browser.