Changeset 128 for trunk/UBFTarget.pas
- Timestamp:
- Jan 17, 2022, 4:53:31 PM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UBFTarget.pas
r126 r128 37 37 Index: Integer; 38 38 procedure Assign(Source: TProgram); 39 procedure Write(Operation: TMachineOperation); 40 function Read: TMachineOperation; 39 41 property Count: Integer read GetCount write SetCount; 40 42 property Items[Index: Integer]: TMachineOperation read GetItem write SetItem; default; … … 117 119 end; 118 120 121 procedure TProgram.Write(Operation: TMachineOperation); 122 begin 123 Operations[Index] := Operation; 124 Inc(Index); 125 end; 126 127 function TProgram.Read: TMachineOperation; 128 begin 129 Result := Operations[Index]; 130 Inc(Index); 131 end; 132 119 133 { TMachineOperation } 120 134 … … 158 172 var 159 173 NewProgram: TProgram; 160 NewTargetIndex: Integer; 161 FirstIndex: Integer; 162 begin 163 NewTargetIndex := 0; 174 InitialProgramIndex: Integer; 175 InitialNewProgramIndex: Integer; 176 begin 164 177 NewProgram := TProgram.Create; 165 178 NewProgram.Count := FProgram.Count; … … 167 180 FProgramIndex := 0; 168 181 while FProgramIndex < FProgram.Count do begin 169 FirstIndex := FProgramIndex; 182 InitialProgramIndex := FProgramIndex; 183 InitialNewProgramIndex := NewProgram.Index; 170 184 case FProgram[FProgramIndex].Command of 171 185 cmPointerInc: begin 172 NewProgram [NewProgram.Index] :=TMachineOperation.Create(cmPointerInc,173 CheckOccurenceSumParam(cmPointerInc)) ;186 NewProgram.Write(TMachineOperation.Create(cmPointerInc, 187 CheckOccurenceSumParam(cmPointerInc))); 174 188 end; 175 189 cmPointerDec: begin 176 NewProgram [NewProgram.Index] :=TMachineOperation.Create(cmPointerDec,177 CheckOccurenceSumParam(cmPointerDec)) ;190 NewProgram.Write(TMachineOperation.Create(cmPointerDec, 191 CheckOccurenceSumParam(cmPointerDec))); 178 192 end; 179 193 cmInc: begin 180 NewProgram [NewProgram.Index] :=TMachineOperation.Create(cmInc,181 CheckOccurenceSumParam(cmInc)) ;194 NewProgram.Write(TMachineOperation.Create(cmInc, 195 CheckOccurenceSumParam(cmInc))); 182 196 end; 183 197 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]); 188 202 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); 191 205 Inc(FProgramIndex); 192 Inc(NewProgram.Index);193 206 end; 194 207 … … 202 215 var 203 216 NewProgram: TProgram; 204 FirstIndex: Integer; 205 NewTargetIndex: Integer; 206 begin 207 NewTargetIndex := 0; 217 InitialProgramIndex: Integer; 218 InitialNewProgramIndex: Integer; 219 begin 208 220 NewProgram := TProgram.Create; 209 221 NewProgram.Count := FProgram.Count; … … 211 223 FProgramIndex := 0; 212 224 while FProgramIndex < FProgram.Count do begin 213 FirstIndex := FProgramIndex; 225 InitialProgramIndex := FProgramIndex; 226 InitialNewProgramIndex := NewProgram.Index; 214 227 case FProgram[FProgramIndex].Command of 215 228 cmLoopStart: begin 216 229 if CheckLoopSetZero then begin 217 NewProgram [NewProgram.Index] := TMachineOperation.Create(cmSet, 0, 0);230 NewProgram.Write(TMachineOperation.Create(cmSet, 0, 0)); 218 231 Inc(FProgramIndex, 2); 219 232 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]); 224 237 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); 227 240 Inc(FProgramIndex); 228 Inc(NewProgram.Index);229 241 end; 230 242 NewProgram.Count := NewProgram.Index; … … 239 251 NewProgram: TProgram; 240 252 PreviousCommand: TMachineCommand; 241 FirstIndex: Integer; 242 NewTargetIndex: Integer; 243 begin 244 NewTargetIndex := 0; 253 InitialProgramIndex: Integer; 254 InitialNewProgramIndex: Integer; 255 begin 245 256 NewProgram := TProgram.Create; 246 257 NewProgram.Count := FProgram.Count; … … 249 260 FProgramIndex := 0; 250 261 while FProgramIndex < FProgram.Count do begin 251 FirstIndex := FProgramIndex; 262 InitialProgramIndex := FProgramIndex; 263 InitialNewProgramIndex := NewProgram.Index; 252 264 case FProgram[FProgramIndex].Command of 253 265 cmPointerInc: begin … … 267 279 else NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerInc; 268 280 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)); 274 286 end; 275 287 end; … … 289 301 else NewProgram.Operations[NewProgram.Index - 1].Command := cmPointerInc; 290 302 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)); 296 308 end; 297 309 end; … … 311 323 else NewProgram.Operations[NewProgram.Index - 1].Command := cmInc; 312 324 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)); 318 330 end; 319 331 end; … … 333 345 else NewProgram.Operations[NewProgram.Index - 1].Command := cmInc; 334 346 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)); 340 352 end; 341 353 end; … … 344 356 // Set overrides value of previous commands 345 357 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]); 353 365 end; 354 366 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); 357 369 Inc(FProgramIndex); 358 Inc(NewProgram.Index);359 370 end; 360 371 … … 375 386 NewProgram: TProgram; 376 387 RelIndex: Integer; 377 FirstIndex: Integer; 378 NewTargetIndex: Integer; 379 begin 380 NewTargetIndex := 0; 388 InitialProgramIndex: Integer; 389 InitialNewProgramIndex: Integer; 390 begin 381 391 NewProgram := TProgram.Create; 382 392 NewProgram.Count := FProgram.Count; … … 385 395 FProgramIndex := 0; 386 396 while FProgramIndex < FProgram.Count do begin 387 FirstIndex := FProgramIndex; 397 InitialProgramIndex := FProgramIndex; 398 InitialNewProgramIndex := NewProgram.Index; 388 399 case FProgram[FProgramIndex].Command of 389 400 cmPointerInc: begin 390 401 RelIndex := RelIndex + FProgram[FProgramIndex].Parameter; 391 Dec(NewProgram.Index);392 402 end; 393 403 cmPointerDec: begin 394 404 RelIndex := RelIndex - FProgram[FProgramIndex].Parameter; 395 Dec(NewProgram.Index);396 405 end; 397 406 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; 401 410 end; 402 411 cmLoopStart, cmLoopEnd: begin 403 412 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)); 407 415 RelIndex := 0; 408 416 end else 409 417 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)); 413 420 RelIndex := 0; 414 421 end; 415 NewProgram [NewProgram.Index] := FProgram[FProgramIndex];422 NewProgram.Write(FProgram[FProgramIndex]); 416 423 end; 417 424 else raise Exception.Create(Format(SUnsupportedCommand, [FProgram[FProgramIndex].Command])); 418 425 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); 421 428 Inc(FProgramIndex); 422 Inc(NewProgram.Index);423 429 end; 424 430 … … 472 478 ProcessingLoop: Boolean; 473 479 PointerChange: Integer; 474 NumberOfBaseDecrement: Integer; 475 FirstIndex: Integer; 476 NewTextIndex: Integer; 477 NoNewCode: Boolean; 480 InitialProgramIndex: Integer; 481 InitialNewProgramIndex: Integer; 478 482 begin 479 483 NewProgram := TProgram.Create; 480 484 NewProgram.Count := FProgram.Count; 481 485 482 NumberOfBaseDecrement := 0;483 486 ProcessingLoop := False; 484 487 FProgramIndex := 0; 485 NewTextIndex := 0;486 488 PointerChange := 0; 487 489 while FProgramIndex < FProgram.Count do begin 488 FirstIndex := FProgramIndex;489 NoNewCode := False;490 InitialProgramIndex := FProgramIndex; 491 InitialNewProgramIndex := NewProgram.Index; 490 492 case FProgram[FProgramIndex].Command of 491 493 cmPointerInc: begin 492 494 Inc(PointerChange, FProgram[FProgramIndex].Parameter); 493 NewProgram [NewProgram.Index] := FProgram[FProgramIndex];495 NewProgram.Write(FProgram[FProgramIndex]); 494 496 end; 495 497 cmPointerDec: begin 496 498 Dec(PointerChange, FProgram[FProgramIndex].Parameter); 497 NewProgram [NewProgram.Index] := FProgram[FProgramIndex];499 NewProgram.Write(FProgram[FProgramIndex]); 498 500 end; 499 501 cmInc: begin 500 502 if not ProcessingLoop then begin 501 NewProgram [NewProgram.Index] := FProgram[FProgramIndex];503 NewProgram.Write(FProgram[FProgramIndex]); 502 504 end else begin 503 505 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; 507 509 end; 508 510 end; 509 511 cmDec: begin 510 512 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]); 515 514 end else begin 516 515 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]); 530 524 end; 531 525 cmLoopStart: begin … … 534 528 PointerChange := 0; 535 529 ProcessingLoop := True; 536 NoNewCode := True;537 530 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'); 541 534 end; 542 535 end; 543 536 cmLoopEnd: begin 544 537 if not ProcessingLoop then begin 545 NewProgram [NewProgram.Index] := FProgram[FProgramIndex];538 NewProgram.Write(FProgram[FProgramIndex]); 546 539 end else begin 547 540 // Finally set decrementing cell to zero 548 NewProgram [NewProgram.Index] := TMachineOperation.Create(cmSet, 0, 0);541 NewProgram.Write(TMachineOperation.Create(cmSet, 0, 0)); 549 542 ProcessingLoop := False; 550 543 end; … … 552 545 else raise Exception.Create(Format(SUnsupportedCommand, [FProgram[FProgramIndex].Command])); 553 546 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); 559 550 Inc(FProgramIndex); 560 if not NoNewCode then Inc(NewProgram.Index);561 551 end; 562 552 … … 581 571 var 582 572 I: Integer; 573 LastIndex: Integer; 583 574 begin 584 575 inherited; 585 576 DebugSteps.Clear; 586 577 FProgram.Count := Length(FSourceCode); 587 FProgramIndex := 0; 578 FProgram.Index := 0; 579 LastIndex := 0; 588 580 for I := 1 to Length(FSourceCode) do begin 589 581 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)); 623 590 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; 627 597 end; 628 598
Note:
See TracChangeset
for help on using the changeset viewer.