Changeset 128 for trunk/UBFTarget.pas


Ignore:
Timestamp:
Jan 17, 2022, 4:53:31 PM (2 years ago)
Author:
chronos
Message:
  • Added: Two more code examples.
  • Added: Allow to disable debugging support.
  • Added: Remember last opened tab in options form.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UBFTarget.pas

    r126 r128  
    3737    Index: Integer;
    3838    procedure Assign(Source: TProgram);
     39    procedure Write(Operation: TMachineOperation);
     40    function Read: TMachineOperation;
    3941    property Count: Integer read GetCount write SetCount;
    4042    property Items[Index: Integer]: TMachineOperation read GetItem write SetItem; default;
     
    117119end;
    118120
     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
    119133{ TMachineOperation }
    120134
     
    158172var
    159173  NewProgram: TProgram;
    160   NewTargetIndex: Integer;
    161   FirstIndex: Integer;
    162 begin
    163   NewTargetIndex := 0;
     174  InitialProgramIndex: Integer;
     175  InitialNewProgramIndex: Integer;
     176begin
    164177  NewProgram := TProgram.Create;
    165178  NewProgram.Count := FProgram.Count;
     
    167180  FProgramIndex := 0;
    168181  while FProgramIndex < FProgram.Count do begin
    169     FirstIndex := FProgramIndex;
     182    InitialProgramIndex := FProgramIndex;
     183    InitialNewProgramIndex := NewProgram.Index;
    170184    case FProgram[FProgramIndex].Command of
    171185      cmPointerInc: begin
    172         NewProgram[NewProgram.Index] := TMachineOperation.Create(cmPointerInc,
    173           CheckOccurenceSumParam(cmPointerInc));
     186        NewProgram.Write(TMachineOperation.Create(cmPointerInc,
     187          CheckOccurenceSumParam(cmPointerInc)));
    174188      end;
    175189      cmPointerDec: begin
    176         NewProgram[NewProgram.Index] := TMachineOperation.Create(cmPointerDec,
    177           CheckOccurenceSumParam(cmPointerDec));
     190        NewProgram.Write(TMachineOperation.Create(cmPointerDec,
     191          CheckOccurenceSumParam(cmPointerDec)));
    178192      end;
    179193      cmInc: begin
    180         NewProgram[NewProgram.Index] := TMachineOperation.Create(cmInc,
    181           CheckOccurenceSumParam(cmInc));
     194        NewProgram.Write(TMachineOperation.Create(cmInc,
     195          CheckOccurenceSumParam(cmInc)));
    182196      end;
    183197      cmDec: begin
    184         NewProgram[NewProgram.Index] := TMachineOperation.Create(cmDec,
    185           CheckOccurenceSumParam(cmDec));
    186       end;
    187       else NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     198        NewProgram.Write(TMachineOperation.Create(cmDec,
     199          CheckOccurenceSumParam(cmDec)));
     200      end;
     201      else NewProgram.Write(FProgram[FProgramIndex]);
    188202    end;
    189     DebugSteps.UpdateTargetPos(FirstIndex, FProgramIndex, NewProgram.Index, NewTargetIndex);
    190     Inc(NewTargetIndex, Length(GetOperationText(NewProgram[NewProgram.Index])));
     203    DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
     204      NewProgram.Index);
    191205    Inc(FProgramIndex);
    192     Inc(NewProgram.Index);
    193206  end;
    194207
     
    202215var
    203216  NewProgram: TProgram;
    204   FirstIndex: Integer;
    205   NewTargetIndex: Integer;
    206 begin
    207   NewTargetIndex := 0;
     217  InitialProgramIndex: Integer;
     218  InitialNewProgramIndex: Integer;
     219begin
    208220  NewProgram := TProgram.Create;
    209221  NewProgram.Count := FProgram.Count;
     
    211223  FProgramIndex := 0;
    212224  while FProgramIndex < FProgram.Count do begin
    213     FirstIndex := FProgramIndex;
     225    InitialProgramIndex := FProgramIndex;
     226    InitialNewProgramIndex := NewProgram.Index;
    214227    case FProgram[FProgramIndex].Command of
    215228      cmLoopStart: begin
    216229        if CheckLoopSetZero then begin
    217           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmSet, 0, 0);
     230          NewProgram.Write(TMachineOperation.Create(cmSet, 0, 0));
    218231          Inc(FProgramIndex, 2);
    219232        end else begin
    220           NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    221         end;
    222       end;
    223       else NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     233          NewProgram.Write(FProgram[FProgramIndex]);
     234        end;
     235      end;
     236      else NewProgram.Write(FProgram[FProgramIndex]);
    224237    end;
    225     DebugSteps.UpdateTargetPos(FirstIndex, FProgramIndex, NewProgram.Index, NewTargetIndex);
    226     Inc(NewTargetIndex, Length(GetOperationText(NewProgram[NewProgram.Index])));
     238    DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
     239      NewProgram.Index);
    227240    Inc(FProgramIndex);
    228     Inc(NewProgram.Index);
    229241  end;
    230242  NewProgram.Count := NewProgram.Index;
     
    239251  NewProgram: TProgram;
    240252  PreviousCommand: TMachineCommand;
    241   FirstIndex: Integer;
    242   NewTargetIndex: Integer;
    243 begin
    244   NewTargetIndex := 0;
     253  InitialProgramIndex: Integer;
     254  InitialNewProgramIndex: Integer;
     255begin
    245256  NewProgram := TProgram.Create;
    246257  NewProgram.Count := FProgram.Count;
     
    249260  FProgramIndex := 0;
    250261  while FProgramIndex < FProgram.Count do begin
    251     FirstIndex := FProgramIndex;
     262    InitialProgramIndex := FProgramIndex;
     263    InitialNewProgramIndex := NewProgram.Index;
    252264    case FProgram[FProgramIndex].Command of
    253265      cmPointerInc: begin
     
    267279              else NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerInc;
    268280          end;
    269           if NewProgram.Operations[NewProgram.Index - 1].Parameter = 0 then Dec(NewProgram.Index);
    270           Dec(NewProgram.Index);
    271         end else begin
    272           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmPointerInc,
    273             FProgram[FProgramIndex].Parameter);
     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));
    274286        end;
    275287      end;
     
    289301              else NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerInc;
    290302          end;
    291           if NewProgram[NewProgram.Index - 1].Parameter = 0 then Dec(NewProgram.Index);
    292           Dec(NewProgram.Index);
    293         end else begin
    294           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmPointerDec,
    295             FProgram[FProgramIndex].Parameter);
     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));
    296308        end;
    297309      end;
     
    311323              else NewProgram.Operations[NewProgram.Index - 1].Command := cmInc;
    312324          end;
    313           if NewProgram[NewProgram.Index - 1].Parameter = 0 then Dec(NewProgram.Index);
    314           Dec(NewProgram.Index);
    315         end else begin
    316           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmInc,
    317             FProgram[FProgramIndex].Parameter);
     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));
    318330        end;
    319331      end;
     
    333345              else NewProgram.Operations[NewProgram.Index - 1].Command := cmInc;
    334346          end;
    335           if NewProgram[NewProgram.Index - 1].Parameter = 0 then Dec(NewProgram.Index);
    336           Dec(NewProgram.Index);
    337         end else begin
    338           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmDec,
    339             FProgram[FProgramIndex].Parameter);
     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));
    340352        end;
    341353      end;
     
    344356          // Set overrides value of previous commands
    345357          Dec(NewProgram.Index);
    346           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmSet,
    347             FProgram[FProgramIndex].Parameter);
    348         end else begin
    349           NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    350         end;
    351       end;
    352       else NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     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]);
    353365    end;
    354366    PreviousCommand := FProgram[FProgramIndex].Command;
    355     DebugSteps.UpdateTargetPos(FirstIndex, FProgramIndex, NewProgram.Index, NewTargetIndex);
    356     Inc(NewTargetIndex, Length(GetOperationText(NewProgram[NewProgram.Index])));
     367    DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
     368      NewProgram.Index);
    357369    Inc(FProgramIndex);
    358     Inc(NewProgram.Index);
    359370  end;
    360371
     
    375386  NewProgram: TProgram;
    376387  RelIndex: Integer;
    377   FirstIndex: Integer;
    378   NewTargetIndex: Integer;
    379 begin
    380   NewTargetIndex := 0;
     388  InitialProgramIndex: Integer;
     389  InitialNewProgramIndex: Integer;
     390begin
    381391  NewProgram := TProgram.Create;
    382392  NewProgram.Count := FProgram.Count;
     
    385395  FProgramIndex := 0;
    386396  while FProgramIndex < FProgram.Count do begin
    387     FirstIndex := FProgramIndex;
     397    InitialProgramIndex := FProgramIndex;
     398    InitialNewProgramIndex := NewProgram.Index;
    388399    case FProgram[FProgramIndex].Command of
    389400      cmPointerInc: begin
    390401        RelIndex := RelIndex + FProgram[FProgramIndex].Parameter;
    391         Dec(NewProgram.Index);
    392402      end;
    393403      cmPointerDec: begin
    394404        RelIndex := RelIndex - FProgram[FProgramIndex].Parameter;
    395         Dec(NewProgram.Index);
    396405      end;
    397406      cmInc, cmDec, cmInput, cmOutput, cmSet: begin
    398         NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    399         NewProgram.Operations[NewProgram.Index].RelIndex :=
    400           NewProgram[NewProgram.Index].RelIndex + RelIndex;
     407        NewProgram.Write(FProgram[FProgramIndex]);
     408        NewProgram.Operations[NewProgram.Index - 1].RelIndex :=
     409          NewProgram[NewProgram.Index - 1].RelIndex + RelIndex;
    401410      end;
    402411      cmLoopStart, cmLoopEnd: begin
    403412        if RelIndex > 0 then begin
    404           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmPointerInc,
    405             RelIndex, 0);
    406           Inc(NewProgram.Index);
     413          NewProgram.Write(TMachineOperation.Create(cmPointerInc,
     414            RelIndex, 0));
    407415          RelIndex := 0;
    408416        end else
    409417        if RelIndex < 0 then begin
    410           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmPointerDec,
    411             Abs(RelIndex), 0);
    412           Inc(NewProgram.Index);
     418          NewProgram.Write(TMachineOperation.Create(cmPointerDec,
     419            Abs(RelIndex), 0));
    413420          RelIndex := 0;
    414421        end;
    415         NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     422        NewProgram.Write(FProgram[FProgramIndex]);
    416423      end;
    417424      else raise Exception.Create(Format(SUnsupportedCommand, [FProgram[FProgramIndex].Command]));
    418425    end;
    419     DebugSteps.UpdateTargetPos(FirstIndex, FProgramIndex, NewProgram.Index, NewTargetIndex);
    420     Inc(NewTargetIndex, Length(GetOperationText(NewProgram[NewProgram.Index])));
     426    DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex, InitialNewProgramIndex,
     427      NewProgram.Index);
    421428    Inc(FProgramIndex);
    422     Inc(NewProgram.Index);
    423429  end;
    424430
     
    472478  ProcessingLoop: Boolean;
    473479  PointerChange: Integer;
    474   NumberOfBaseDecrement: Integer;
    475   FirstIndex: Integer;
    476   NewTextIndex: Integer;
    477   NoNewCode: Boolean;
     480  InitialProgramIndex: Integer;
     481  InitialNewProgramIndex: Integer;
    478482begin
    479483  NewProgram := TProgram.Create;
    480484  NewProgram.Count := FProgram.Count;
    481485
    482   NumberOfBaseDecrement := 0;
    483486  ProcessingLoop := False;
    484487  FProgramIndex := 0;
    485   NewTextIndex := 0;
    486488  PointerChange := 0;
    487489  while FProgramIndex < FProgram.Count do begin
    488     FirstIndex := FProgramIndex;
    489     NoNewCode := False;
     490    InitialProgramIndex := FProgramIndex;
     491    InitialNewProgramIndex := NewProgram.Index;
    490492    case FProgram[FProgramIndex].Command of
    491493      cmPointerInc: begin
    492494        Inc(PointerChange, FProgram[FProgramIndex].Parameter);
    493         NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     495        NewProgram.Write(FProgram[FProgramIndex]);
    494496      end;
    495497      cmPointerDec: begin
    496498        Dec(PointerChange, FProgram[FProgramIndex].Parameter);
    497         NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     499        NewProgram.Write(FProgram[FProgramIndex]);
    498500      end;
    499501      cmInc: begin
    500502        if not ProcessingLoop then begin
    501           NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     503          NewProgram.Write(FProgram[FProgramIndex]);
    502504        end else begin
    503505          if ((FProgram[FProgramIndex].RelIndex + PointerChange) <> 0) then begin
    504             NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    505             NewProgram.Operations[NewProgram.Index].Command := cmMultiply;
    506           end else NoNewCode := True;
     506            NewProgram.Write(FProgram[FProgramIndex]);
     507            NewProgram.Operations[NewProgram.Index - 1].Command := cmMultiply;
     508          end;
    507509        end;
    508510      end;
    509511      cmDec: begin
    510512        if not ProcessingLoop then begin
    511           if (PointerChange = 0) and (FProgram[FProgramIndex].RelIndex = 0) and
    512             (FProgram[FProgramIndex].Parameter = 1) then
    513             Inc(NumberOfBaseDecrement);
    514           NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     513          NewProgram.Write(FProgram[FProgramIndex]);
    515514        end else begin
    516515          if ((FProgram[FProgramIndex].RelIndex + PointerChange) <> 0) then begin
    517             NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    518             NewProgram.Operations[NewProgram.Index].Command := cmMultiply;
    519             NewProgram.Operations[NewProgram.Index].Parameter := -FProgram[FProgramIndex].Parameter;
    520           end else NoNewCode := True;
    521         end;
    522       end;
    523       cmInput, cmOutput: begin
    524         NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    525         Inc(NumberOfBaseDecrement, 2);
    526       end;
    527       cmSet: begin
    528         NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    529         Inc(NumberOfBaseDecrement, 2);
     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]);
    530524      end;
    531525      cmLoopStart: begin
     
    534528            PointerChange := 0;
    535529            ProcessingLoop := True;
    536             NoNewCode := True;
    537530          end else
    538             NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
    539         end else begin
    540           NoNewCode := True;
     531            NewProgram.Write(FProgram[FProgramIndex]);
     532        end else begin
     533          raise Exception.Create('Another loop start not allowed inside loop');
    541534        end;
    542535      end;
    543536      cmLoopEnd: begin
    544537        if not ProcessingLoop then begin
    545           NewProgram[NewProgram.Index] := FProgram[FProgramIndex];
     538          NewProgram.Write(FProgram[FProgramIndex]);
    546539        end else begin
    547540          // Finally set decrementing cell to zero
    548           NewProgram[NewProgram.Index] := TMachineOperation.Create(cmSet, 0, 0);
     541          NewProgram.Write(TMachineOperation.Create(cmSet, 0, 0));
    549542          ProcessingLoop := False;
    550543        end;
     
    552545      else raise Exception.Create(Format(SUnsupportedCommand, [FProgram[FProgramIndex].Command]));
    553546    end;
    554     if NoNewCode then DebugSteps.UpdateTargetPos(FirstIndex, FProgramIndex, -1, NewTextIndex)
    555       else begin
    556         DebugSteps.UpdateTargetPos(FirstIndex, FProgramIndex, NewProgram.Index, NewTextIndex);
    557         Inc(NewTextIndex, Length(GetOperationText(NewProgram[NewProgram.Index])));
    558       end;
     547
     548    DebugSteps.UpdateTargetPos(InitialProgramIndex, FProgramIndex,
     549      InitialNewProgramIndex, NewProgram.Index);
    559550    Inc(FProgramIndex);
    560     if not NoNewCode then Inc(NewProgram.Index);
    561551  end;
    562552
     
    581571var
    582572  I: Integer;
     573  LastIndex: Integer;
    583574begin
    584575  inherited;
    585576  DebugSteps.Clear;
    586577  FProgram.Count := Length(FSourceCode);
    587   FProgramIndex := 0;
     578  FProgram.Index := 0;
     579  LastIndex := 0;
    588580  for I := 1 to Length(FSourceCode) do begin
    589581    case FSourceCode[I] of
    590       '+': begin
    591         FProgram[FProgramIndex] := TMachineOperation.Create(cmInc, 1, 0);
    592         DebugSteps.AddStep(I - 1, FProgramIndex, soNormal);
    593       end;
    594       '-': begin
    595         FProgram[FProgramIndex] := TMachineOperation.Create(cmDec, 1, 0);
    596         DebugSteps.AddStep(I - 1, FProgramIndex, soNormal);
    597       end;
    598       '>': begin
    599         FProgram[FProgramIndex] := TMachineOperation.Create(cmPointerInc, 1, 0);
    600         DebugSteps.AddStep(I - 1, FProgramIndex, soNormal);
    601       end;
    602       '<': begin
    603         FProgram[FProgramIndex] := TMachineOperation.Create(cmPointerDec, 1, 0);
    604         DebugSteps.AddStep(I - 1, FProgramIndex, soNormal);
    605       end;
    606       ',': begin
    607         FProgram[FProgramIndex] := TMachineOperation.Create(cmInput, 0, 0);
    608         DebugSteps.AddStep(I - 1, FProgramIndex, soNormal);
    609       end;
    610       '.': begin
    611         FProgram[FProgramIndex] := TMachineOperation.Create(cmOutput, 0, 0);
    612         DebugSteps.AddStep(I - 1, FProgramIndex, soNormal);
    613       end;
    614       '[': begin
    615         FProgram[FProgramIndex] := TMachineOperation.Create(cmLoopStart, 0, 0);
    616         DebugSteps.AddStep(I - 1, FProgramIndex, soStepIn);
    617       end;
    618       ']': begin
    619         FProgram[FProgramIndex] := TMachineOperation.Create(cmLoopEnd, 0 ,0);
    620         DebugSteps.AddStep(I - 1, FProgramIndex, soStepOut);
    621       end
    622       else Dec(FProgramIndex);
     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));
    623590    end;
    624     Inc(FProgramIndex);
    625   end;
    626   FProgram.Count := FProgramIndex;
     591    if DebugEnabled and (FProgram.Index <> LastIndex) then
     592      DebugSteps.AddStep(I - 1, FProgram.Index - 1, soNormal);
     593    LastIndex := FProgram.Index;
     594  end;
     595  FProgramIndex := FProgram.Index;
     596  FProgram.Count := FProgram.Index;
    627597end;
    628598
Note: See TracChangeset for help on using the changeset viewer.