Changeset 66 for trunk/UTarget.pas
- Timestamp:
- Jan 17, 2015, 12:23:38 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UTarget.pas
r65 r66 67 67 end; 68 68 69 TMachineCommand = (cmNoOperation, cmInc, cmDec, cmPointerInc, cmPointerDec,70 cmOutput, cmInput, cmLoopStart, cmLoopEnd, cmDebug, cmSet);71 72 TMachineOperation = record73 Command: TMachineCommand;74 Parameter: Integer;75 end;76 77 69 TLogEvent = procedure (Lines: TStrings) of object; 78 70 … … 85 77 FCompiled: Boolean; 86 78 function SourceReadNext: Char; 87 function CheckClear: Boolean;88 function CheckOccurenceSumParam(C: TMachineCommand): Integer;89 function CheckOccurence(C: TMachineCommand): Integer;90 procedure OptimizeAddSub;91 procedure OptimizeMerge;92 procedure OptimizeZeroInitMemory;93 79 protected 94 80 FSourceCode: string; 95 FProgram: array of TMachineOperation;96 FProgramIndex: Integer;97 81 FTargetCode: string; 98 82 FTargetIndex: Integer; … … 100 84 FState: TRunState; 101 85 FOnChangeState: TNotifyEvent; 102 procedure LoadProgram; 86 procedure LoadProgram; virtual; 103 87 procedure SetSourceCode(AValue: string); virtual; 104 88 function GetTargetCode: string; virtual; … … 143 127 property Compiled: Boolean read FCompiled write FCompiled; 144 128 property ExecutionPosition: Integer read GetExecutionPosition; 145 property ProgramIndex: Integer read FProgramIndex;146 129 property OnChangeState: TNotifyEvent read FOnChangeState write FOnChangeState; 147 130 property OnLog: TLogEvent read FOnLog write FOnLog; 131 end; 132 133 TBFTarget = class 134 148 135 end; 149 136 … … 409 396 410 397 procedure TTarget.OptimizeSource; 411 var 412 OldLength: Integer; 413 begin 414 OptimizeAddSub; 415 repeat 416 OldLength := Length(FProgram); 417 OptimizeMerge; 418 until Length(FProgram) = OldLength; 419 OptimizeZeroInitMemory; 398 begin 420 399 end; 421 400 … … 557 536 end; 558 537 559 function TTarget.CheckOccurence(C: TMachineCommand): Integer;560 begin561 Result := 1;562 while ((FProgramIndex + 1) < Length(FProgram)) and (FProgram[FProgramIndex + 1].Command = C) do begin563 Inc(Result);564 Inc(FProgramIndex);565 end;566 end;567 568 function TTarget.CheckOccurenceSumParam(C: TMachineCommand): Integer;569 begin570 Result := FProgram[FProgramIndex].Parameter;571 while ((FProgramIndex + 1) < Length(FProgram)) and (FProgram[FProgramIndex + 1].Command = C) do begin572 Inc(Result, FProgram[FProgramIndex + 1].Parameter);573 Inc(FProgramIndex);574 end;575 end;576 577 procedure TTarget.OptimizeAddSub;578 var579 NewProgram: array of TMachineOperation;580 NewProgramIndex: Integer;581 begin582 NewProgramIndex := 0;583 SetLength(NewProgram, Length(FProgram));584 585 FProgramIndex := 0;586 while (FProgramIndex < Length(FProgram)) do begin587 case FProgram[FProgramIndex].Command of588 cmPointerInc: begin589 NewProgram[NewProgramIndex].Command := cmPointerInc;590 NewProgram[NewProgramIndex].Parameter := CheckOccurenceSumParam(cmPointerInc);591 end;592 cmPointerDec: begin593 NewProgram[NewProgramIndex].Command := cmPointerDec;594 NewProgram[NewProgramIndex].Parameter := CheckOccurenceSumParam(cmPointerDec);595 end;596 cmInc: begin597 NewProgram[NewProgramIndex].Command := cmInc;598 NewProgram[NewProgramIndex].Parameter := CheckOccurenceSumParam(cmInc);599 end;600 cmDec: begin601 NewProgram[NewProgramIndex].Command := cmDec;602 NewProgram[NewProgramIndex].Parameter := CheckOccurenceSumParam(cmDec);603 end;604 else begin605 NewProgram[NewProgramIndex].Command := FProgram[FProgramIndex].Command;606 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;607 end;608 end;609 DebugSteps.UpdateTargetPos(FProgramIndex, NewProgramIndex);610 Inc(FProgramIndex);611 Inc(NewProgramIndex);612 end;613 SetLength(NewProgram, NewProgramIndex);614 615 // Replace old program by new program616 SetLength(FProgram, Length(NewProgram));617 Move(NewProgram[0], FProgram[0], SizeOf(TMachineOperation) * Length(NewProgram));618 end;619 620 procedure TTarget.OptimizeMerge;621 var622 NewProgram: array of TMachineOperation;623 NewProgramIndex: Integer;624 PreviousCommand: TMachineCommand;625 begin626 // Merge together cmInc, cmDec, cmSet627 // Merge together cmPointerInc, cmPointerDec628 PreviousCommand := cmNoOperation;629 NewProgramIndex := 0;630 SetLength(NewProgram, Length(FProgram));631 632 FProgramIndex := 0;633 while (FProgramIndex < Length(FProgram)) do begin634 case FProgram[FProgramIndex].Command of635 cmPointerInc: begin636 if PreviousCommand in [cmPointerInc, cmPointerDec] then begin637 if NewProgram[NewProgramIndex - 1].Command = cmPointerInc then638 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter +639 FProgram[FProgramIndex].Parameter640 else if NewProgram[NewProgramIndex - 1].Command = cmPointerDec then641 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter -642 FProgram[FProgramIndex].Parameter;643 // If value negative then change command644 if NewProgram[NewProgramIndex - 1].Parameter < 0 then begin645 NewProgram[NewProgramIndex - 1].Parameter := -NewProgram[NewProgramIndex - 1].Parameter;646 if NewProgram[NewProgramIndex - 1].Command = cmPointerInc then647 NewProgram[NewProgramIndex - 1].Command := cmPointerDec648 else NewProgram[NewProgramIndex - 1].Command := cmPointerInc;649 end;650 if NewProgram[NewProgramIndex - 1].Parameter = 0 then Dec(NewProgramIndex);651 Dec(NewProgramIndex);652 end else begin653 NewProgram[NewProgramIndex].Command := cmPointerInc;654 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;655 end;656 end;657 cmPointerDec: begin658 if PreviousCommand in [cmPointerInc, cmPointerDec] then begin659 if NewProgram[NewProgramIndex - 1].Command = cmPointerDec then660 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter +661 FProgram[FProgramIndex].Parameter662 else if NewProgram[NewProgramIndex - 1].Command = cmPointerInc then663 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter -664 FProgram[FProgramIndex].Parameter;665 // If value negative then change command666 if NewProgram[NewProgramIndex - 1].Parameter < 0 then begin667 NewProgram[NewProgramIndex - 1].Parameter := -NewProgram[NewProgramIndex - 1].Parameter;668 if NewProgram[NewProgramIndex - 1].Command = cmPointerInc then669 NewProgram[NewProgramIndex - 1].Command := cmPointerDec670 else NewProgram[NewProgramIndex - 1].Command := cmPointerInc;671 end;672 if NewProgram[NewProgramIndex - 1].Parameter = 0 then Dec(NewProgramIndex);673 Dec(NewProgramIndex);674 end else begin675 NewProgram[NewProgramIndex].Command := cmPointerDec;676 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;677 end;678 end;679 cmInc: begin680 if PreviousCommand in [cmInc, cmDec, cmSet] then begin681 if NewProgram[NewProgramIndex - 1].Command in [cmInc, cmSet] then682 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter +683 FProgram[FProgramIndex].Parameter684 else if NewProgram[NewProgramIndex - 1].Command = cmDec then685 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter -686 FProgram[FProgramIndex].Parameter;687 // If value negative then change command688 if (NewProgram[NewProgramIndex - 1].Parameter < 0) and (NewProgram[NewProgramIndex - 1].Command <> cmSet) then begin689 NewProgram[NewProgramIndex - 1].Parameter := -NewProgram[NewProgramIndex - 1].Parameter;690 if NewProgram[NewProgramIndex - 1].Command = cmInc then691 NewProgram[NewProgramIndex - 1].Command := cmDec692 else NewProgram[NewProgramIndex - 1].Command := cmInc;693 end;694 if NewProgram[NewProgramIndex - 1].Parameter = 0 then Dec(NewProgramIndex);695 Dec(NewProgramIndex);696 end else begin697 NewProgram[NewProgramIndex].Command := cmInc;698 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;699 end;700 end;701 cmDec: begin702 if PreviousCommand in [cmInc, cmDec, cmSet] then begin703 if NewProgram[NewProgramIndex - 1].Command = cmDec then704 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter +705 FProgram[FProgramIndex].Parameter706 else if NewProgram[NewProgramIndex - 1].Command in [cmInc, cmSet] then707 NewProgram[NewProgramIndex - 1].Parameter := NewProgram[NewProgramIndex - 1].Parameter -708 FProgram[FProgramIndex].Parameter;709 // If value negative then change command710 if (NewProgram[NewProgramIndex - 1].Parameter < 0) and (NewProgram[NewProgramIndex - 1].Command <> cmSet) then begin711 NewProgram[NewProgramIndex - 1].Parameter := -NewProgram[NewProgramIndex - 1].Parameter;712 if NewProgram[NewProgramIndex - 1].Command = cmInc then713 NewProgram[NewProgramIndex - 1].Command := cmDec714 else NewProgram[NewProgramIndex - 1].Command := cmInc;715 end;716 if NewProgram[NewProgramIndex - 1].Parameter = 0 then Dec(NewProgramIndex);717 Dec(NewProgramIndex);718 end else begin719 NewProgram[NewProgramIndex].Command := cmDec;720 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;721 end;722 end;723 cmSet: begin724 if PreviousCommand in [cmInc, cmDec, cmSet] then begin725 // Set overrides value of previous commands726 Dec(NewProgramIndex);727 NewProgram[NewProgramIndex].Command := cmSet;728 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;729 end else begin730 NewProgram[NewProgramIndex].Command := cmSet;731 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;732 end;733 end;734 cmLoopStart: begin735 if CheckClear then begin736 NewProgram[NewProgramIndex].Command := cmSet;737 NewProgram[NewProgramIndex].Parameter := 0;738 Inc(FProgramIndex, 2);739 end else begin740 NewProgram[NewProgramIndex].Command := FProgram[FProgramIndex].Command;741 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;742 end;743 end;744 else begin745 NewProgram[NewProgramIndex].Command := FProgram[FProgramIndex].Command;746 NewProgram[NewProgramIndex].Parameter := FProgram[FProgramIndex].Parameter;747 end;748 end;749 PreviousCommand := FProgram[FProgramIndex].Command;750 DebugSteps.UpdateTargetPos(FProgramIndex, NewProgramIndex);751 Inc(FProgramIndex);752 Inc(NewProgramIndex);753 end;754 SetLength(NewProgram, NewProgramIndex);755 756 // Replace old program by new program757 SetLength(FProgram, Length(NewProgram));758 Move(NewProgram[0], FProgram[0], SizeOf(TMachineOperation) * Length(NewProgram));759 end;760 761 procedure TTarget.OptimizeZeroInitMemory;762 begin763 // Here optimization related to assumption that initial memory is filled with zeroes764 // Then code for constants preparation can be translated to cmSet commands765 // To eliminate also loops for building constants code need to be somehow interpretted partialy766 end;767 768 538 procedure TTarget.LoadProgram; 769 var 770 I: Integer; 771 begin 772 inherited; 773 DebugSteps.Clear; 774 SetLength(FProgram, Length(FSourceCode)); 775 FProgramIndex := 0; 776 for I := 1 to Length(FSourceCode) do begin 777 case FSourceCode[I] of 778 '+': begin 779 FProgram[FProgramIndex].Command := cmInc; 780 FProgram[FProgramIndex].Parameter := 1; 781 DebugSteps.AddStep(I - 1, FProgramIndex, soNormal); 782 end; 783 '-': begin 784 FProgram[FProgramIndex].Command := cmDec; 785 FProgram[FProgramIndex].Parameter := 1; 786 DebugSteps.AddStep(I - 1, FProgramIndex, soNormal); 787 end; 788 '>': begin 789 FProgram[FProgramIndex].Command := cmPointerInc; 790 FProgram[FProgramIndex].Parameter := 1; 791 DebugSteps.AddStep(I - 1, FProgramIndex, soNormal); 792 end; 793 '<': begin 794 FProgram[FProgramIndex].Command := cmPointerDec; 795 FProgram[FProgramIndex].Parameter := 1; 796 DebugSteps.AddStep(I - 1, FProgramIndex, soNormal); 797 end; 798 ',': begin 799 FProgram[FProgramIndex].Command := cmInput; 800 FProgram[FProgramIndex].Parameter := 0; 801 DebugSteps.AddStep(I - 1, FProgramIndex, soNormal); 802 end; 803 '.': begin 804 FProgram[FProgramIndex].Command := cmOutput; 805 FProgram[FProgramIndex].Parameter := 0; 806 DebugSteps.AddStep(I - 1, FProgramIndex, soNormal); 807 end; 808 '[': begin 809 FProgram[FProgramIndex].Command := cmLoopStart; 810 FProgram[FProgramIndex].Parameter := 0; 811 DebugSteps.AddStep(I - 1, FProgramIndex, soStepIn); 812 end; 813 ']': begin 814 FProgram[FProgramIndex].Command := cmLoopEnd; 815 FProgram[FProgramIndex].Parameter := 0; 816 DebugSteps.AddStep(I - 1, FProgramIndex, soStepOut); 817 end 818 else Dec(FProgramIndex); 819 end; 820 Inc(FProgramIndex); 821 end; 822 SetLength(FProgram, FProgramIndex); 539 begin 823 540 end; 824 541 … … 828 545 end; 829 546 830 function TTarget.CheckClear: Boolean;831 begin832 Result := (FProgram[FProgramIndex].Command = cmLoopStart) and (Length(FProgram) >= FProgramIndex + 2) and833 (((FProgram[FProgramIndex + 1].Command = cmDec) and (FProgram[FProgramIndex + 1].Parameter = 1)) or834 ((FProgram[FProgramIndex + 1].Command = cmInc) and (FProgram[FProgramIndex + 1].Parameter = -1)))835 and (FProgram[FProgramIndex + 2].Command = cmLoopEnd);836 end;837 838 547 end. 839 548
Note:
See TracChangeset
for help on using the changeset viewer.