Changeset 12 for trunk/UBrainFuck.pas


Ignore:
Timestamp:
Feb 11, 2012, 4:32:27 PM (13 years ago)
Author:
chronos
Message:
  • Added: Display source code caret position in statusbar.
  • Modified: Optimized jump speed using precreated direct jump table.
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:ignore
      •  

        old new  
        33LazFuckIDE.lps
        44backup
         5LazFuckIDE
  • trunk/UBrainFuck.pas

    r10 r12  
    1212
    1313  TCompilerTarget = (ctDelphi);
     14  TCompilerOptimization = (coNone, coNormal);
     15
    1416  { TBrainFuckCompiler }
    1517
     
    2325    Output: string;
    2426    Target: TCompilerTarget;
     27    Optimization: TCompilerOptimization;
     28    procedure OptimizeSource;
    2529    procedure Compile;
    2630  end;
     
    4347    FThreadState: Boolean;
    4448    FThread: TBrainFuckInterpretterThread;
     49    FStepCount: Integer;
    4550    procedure SetState(AValue: TRunState);
    4651    procedure Write(Value: Byte);
     
    4853    function ReadCode: Char;
    4954    procedure SetThread(State: Boolean);
     55    procedure PrepareJumpTable;
    5056  public
    51     Source: string;
     57    Source: array of Char;
     58    SourceJump: array of Integer;
    5259    SourcePosition: Integer;
    5360    Memory: array of Byte;
    5461    MemoryPosition: Integer;
    55     Loop: array of Integer;
    56     LoopCurrent: Integer;
    5762    Output: string;
    5863    Input: string;
    5964    InputPosition: Integer;
    60     StepCount: Integer;
    6165    procedure Reset;
    6266    procedure SingleStep;
     
    6872    property State: TRunState read FState;
    6973    property OnChangeState: TNotifyEvent read FOnChangeState write FOnChangeState;
     74    property StepCount: Integer read FStepCount;
    7075  end;
    7176
     
    7782  SProgramUpperLimit = 'Program run over upper limit';
    7883  SReadInputError = 'Read input error';
     84  SJumpTableInsistent = 'Jump table is inconsistent';
     85  SJumpTableColision = 'Jump table colision';
    7986
    8087{ TBrainFuckInterpretterThread }
     
    118125function TBrainFuckInterpretter.ReadCode: Char;
    119126begin
    120   Result := Source[SourcePosition + 1]
     127  Result := Source[SourcePosition];
    121128end;
    122129
     
    135142end;
    136143
     144procedure TBrainFuckInterpretter.PrepareJumpTable;
     145var
     146  Loop: array of Integer;
     147  LoopCurrent: Integer;
     148  I: Integer;
     149begin
     150  SetLength(SourceJump, Length(Source));
     151  FillChar(Pointer(SourceJump)^, Length(SourceJump), 0);
     152  SetLength(Loop, 0);
     153  for I := 0 to Length(Source) - 1 do begin
     154    case Source[I] of
     155      '[': begin
     156        SetLength(Loop, Length(Loop) + 1);
     157        Loop[High(Loop)] := I;
     158      end;
     159      ']': begin
     160        if SourceJump[I] > 0 then raise Exception.Create(SJumpTableColision);
     161        SourceJump[I] := Loop[High(Loop)];
     162        if SourceJump[Loop[High(Loop)]] > 0 then raise Exception.Create(SJumpTableColision);
     163        SourceJump[Loop[High(Loop)]] := I;
     164        SetLength(Loop, Length(Loop) - 1);
     165      end;
     166    end;
     167  end;
     168  if Length(Loop) > 0 then raise Exception.Create(SJumpTableInsistent);
     169end;
     170
    137171procedure TBrainFuckInterpretter.Reset;
    138 var
    139   I: Integer;
    140 begin
     172begin
     173  PrepareJumpTable;
    141174  SourcePosition := 0;
    142175  InputPosition := 0;
    143176  Output := '';
    144177  MemoryPosition := 0;
    145   for I := 0 to Length(Memory) - 1 do
    146     Memory[I] := 0;
    147   SetLength(Loop, 0);
    148   StepCount := 0;
     178  FillChar(Pointer(Memory)^, Length(Memory), 0);
     179  FStepCount := 0;
    149180end;
    150181
     
    152183var
    153184  CodeText: string;
    154   Code: Char;
    155185  C: Integer;
     186  NewPos: Integer;
    156187begin
    157188  case ReadCode of
     
    166197    '[': begin
    167198      if Memory[MemoryPosition] = 0 then begin
    168         C := 1;
     199        SourcePosition := SourceJump[SourcePosition];
     200        (*C := 1;
    169201        Inc(SourcePosition);
    170202        while C > 0 do begin
     
    175207          Inc(SourcePosition);
    176208        end;
    177         Dec(SourcePosition);
     209        Dec(SourcePosition);*)
     210        //if NewPos <> SourcePosition then raise Exception.Create('Wrong pos: ' + IntToStr(SourcePosition) + ' ' + IntToStr(NewPos));
    178211      end;
    179212    end;
    180213    ']': begin
    181214      if Memory[MemoryPosition] > 0 then begin
    182         C := 1;
     215        SourcePosition := SourceJump[SourcePosition] - 1;
     216        (*C := 1;
    183217        Dec(SourcePosition);
    184218        while C > 0 do begin
     
    189223          Dec(SourcePosition);
    190224        end;
     225        if NewPos <> SourcePosition then raise Exception.Create('Wrong pos: ' + IntToStr(SourcePosition) + ' ' + IntToStr(NewPos));
     226        *)
    191227      end;
    192228    end;
    193229  end;
    194230  Inc(SourcePosition);
    195   Inc(StepCount);
     231  Inc(FStepCount);
    196232end;
    197233
     
    230266begin
    231267  Output := Output + DupeString('  ', Indent) + Text + LineEnding;
     268end;
     269
     270procedure TBrainFuckCompiler.OptimizeSource;
     271begin
     272  // Remove redundand code
     273
    232274end;
    233275
Note: See TracChangeset for help on using the changeset viewer.