source: tags/1.2.0/UBFTarget.pas

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