Changeset 18 for trunk/UBrainFuck.pas
- Timestamp:
- Feb 11, 2012, 9:32:25 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UBrainFuck.pas
r17 r18 39 39 end; 40 40 41 TBrainFuckCommand = (cmNone, cmInc, cmDec, cmPointerInc, cmPointerDec, 42 cmOutput, cmInput, cmLoopStart, cmLoopEnd); 43 44 TCommandHandler = procedure of object; 45 41 46 { TBrainFuckInterpretter } 42 47 … … 49 54 FThread: TBrainFuckInterpretterThread; 50 55 FStepCount: Integer; 56 FCommandTable: array[TBrainFuckCommand] of TCommandHandler; 51 57 function GetMemorySize: Integer; 52 function GetSource: string;53 58 procedure SetMemorySize(AValue: Integer); 54 59 procedure SetSource(AValue: string); 55 60 procedure SetState(AValue: TRunState); 56 procedure Write(Value: Byte);57 function Read: Byte;58 61 procedure SetThread(State: Boolean); 59 62 procedure PrepareJumpTable; 60 procedure RemoveBlankCharacters; 63 procedure CommandInc; 64 procedure CommandDec; 65 procedure CommandPointerInc; 66 procedure CommandPointerDec; 67 procedure CommandInput; 68 procedure CommandOutput; 69 procedure CommandLoopStart; 70 procedure CommandLoopEnd; 61 71 public 62 FSource: array of Char;72 FSource: array of TBrainFuckCommand; 63 73 SourceJump: array of Integer; 64 74 SourcePosition: Integer; … … 80 90 property OnChangeState: TNotifyEvent read FOnChangeState write FOnChangeState; 81 91 property StepCount: Integer read FStepCount; 82 property Source: string read GetSourcewrite SetSource;92 property Source: string write SetSource; 83 93 property MemorySize: Integer read GetMemorySize write SetMemorySize; 84 94 property CellSize: Integer read FCellSize write FCellSize; … … 113 123 { TBrainFuckInterpretter } 114 124 115 procedure TBrainFuckInterpretter.Write(Value: Byte);116 begin117 if OutputPosition > Length(Output) then118 SetLength(Output, Length(Output) + 1 + Length(Output) div 4);119 Output[OutputPosition] := Char(Value);120 Inc(OutputPosition);121 end;122 123 125 procedure TBrainFuckInterpretter.SetState(AValue: TRunState); 124 126 begin … … 128 130 end; 129 131 130 function TBrainFuckInterpretter.GetSource: string;131 var132 I: Integer;133 begin134 SetLength(Result, Length(FSource));135 //Move(Pointer(Result)^, Pointer(FSource)^, Length(Result));136 for I := 0 to Length(FSource) - 1 do137 Result[I + 1] := FSource[I];138 end;139 140 132 function TBrainFuckInterpretter.GetMemorySize: Integer; 141 133 begin … … 151 143 var 152 144 I: Integer; 145 Pos: Integer; 153 146 begin 154 147 SetLength(FSource, Length(AValue)); 155 //Move(Pointer(AValue)^, Pointer(FSource)^, Length(AValue)); 156 for I := 0 to Length(FSource) - 1 do 157 FSource[I] := AValue[I + 1]; 158 end; 159 160 function TBrainFuckInterpretter.Read: Byte; 161 begin 162 while (InputPosition > Length(Input)) and (FState <> rsStopped) do begin 163 Sleep(1); 164 end; 165 if InputPosition <= Length(Input) then begin 166 Result := Ord(Input[InputPosition]); 167 Inc(InputPosition); 168 end else Result := 0; 148 Pos := 0; 149 for I := 1 to Length(AValue) do begin 150 case AValue[I] of 151 '+': FSource[Pos] := cmInc; 152 '-': FSource[Pos] := cmDec; 153 '>': FSource[Pos] := cmPointerInc; 154 '<': FSource[Pos] := cmPointerDec; 155 ',': FSource[Pos] := cmInput; 156 '.': FSource[Pos] := cmOutput; 157 '[': FSource[Pos] := cmLoopStart; 158 ']': FSource[Pos] := cmLoopEnd; 159 else Dec(Pos); 160 end; 161 Inc(Pos); 162 end; 163 SetLength(FSource, Pos); 169 164 end; 170 165 … … 186 181 var 187 182 Loop: array of Integer; 188 LoopCurrent: Integer;189 183 I: Integer; 190 184 begin … … 196 190 for I := 0 to Length(FSource) - 1 do begin 197 191 case FSource[I] of 198 '[': begin192 cmLoopStart: begin 199 193 SetLength(Loop, Length(Loop) + 1); 200 194 Loop[High(Loop)] := I; 201 195 end; 202 ']': begin196 cmLoopEnd: begin 203 197 if SourceJump[I] > 0 then raise Exception.Create(SJumpTableColision); 204 198 SourceJump[I] := Loop[High(Loop)]; … … 212 206 end; 213 207 214 procedure TBrainFuckInterpretter.RemoveBlankCharacters; 215 var 216 I: Integer; 217 LastChar: Integer; 218 begin 219 LastChar := 0; 220 for I := 0 to Length(FSource) - 1 do 221 if FSource[I] in ['+','-','>','<','.',',','[',']'] then begin 222 FSource[LastChar] := FSource[I]; 223 Inc(LastChar); 224 end; 225 SetLength(FSource, LastChar); 208 procedure TBrainFuckInterpretter.CommandInc; 209 begin 210 Memory[MemoryPosition] := ((Memory[MemoryPosition] + 1) mod CellSize); 211 end; 212 213 procedure TBrainFuckInterpretter.CommandDec; 214 begin 215 Memory[MemoryPosition] := ((Memory[MemoryPosition] - 1) mod CellSize); 216 end; 217 218 procedure TBrainFuckInterpretter.CommandPointerInc; 219 begin 220 if MemoryPosition < MemorySize then Inc(MemoryPosition) 221 else raise Exception.Create(SProgramUpperLimit); 222 end; 223 224 procedure TBrainFuckInterpretter.CommandPointerDec; 225 begin 226 if MemoryPosition > 0 then Dec(MemoryPosition) 227 else raise Exception.Create(SProgramLowerLimit); 228 end; 229 230 procedure TBrainFuckInterpretter.CommandInput; 231 begin 232 while (InputPosition > Length(Input)) and (FState <> rsStopped) do begin 233 Sleep(1); 234 end; 235 if InputPosition <= Length(Input) then begin 236 Memory[MemoryPosition] := Ord(Input[InputPosition]); 237 Inc(InputPosition); 238 end; 239 end; 240 241 procedure TBrainFuckInterpretter.CommandOutput; 242 begin 243 if OutputPosition > Length(Output) then 244 SetLength(Output, Length(Output) + 1 + Length(Output) div 4); 245 Output[OutputPosition] := Char(Memory[MemoryPosition]); 246 Inc(OutputPosition); 247 end; 248 249 procedure TBrainFuckInterpretter.CommandLoopStart; 250 begin 251 if Memory[MemoryPosition] = 0 then 252 SourcePosition := SourceJump[SourcePosition]; 253 end; 254 255 procedure TBrainFuckInterpretter.CommandLoopEnd; 256 begin 257 if Memory[MemoryPosition] > 0 then 258 SourcePosition := SourceJump[SourcePosition] - 1; 226 259 end; 227 260 … … 230 263 I: Integer; 231 264 begin 232 RemoveBlankCharacters;233 265 PrepareJumpTable; 234 266 SourcePosition := 0; … … 244 276 245 277 procedure TBrainFuckInterpretter.SingleStep; 246 var 247 CodeText: string; 248 C: Integer; 249 NewPos: Integer; 250 begin 251 case FSource[SourcePosition] of 252 '>': if MemoryPosition < MemorySize then Inc(MemoryPosition) 253 else raise Exception.Create(SProgramUpperLimit); 254 '<': if MemoryPosition > 0 then Dec(MemoryPosition) 255 else raise Exception.Create(SProgramLowerLimit); 256 '+': Memory[MemoryPosition] := ((Memory[MemoryPosition] + 1) mod CellSize); 257 '-': Memory[MemoryPosition] := ((Memory[MemoryPosition] - 1) mod CellSize); 258 '.': Write(Memory[MemoryPosition]); 259 ',': Memory[MemoryPosition] := Read; 260 '[': begin 261 if Memory[MemoryPosition] = 0 then begin 262 SourcePosition := SourceJump[SourcePosition]; 263 (*C := 1; 264 Inc(SourcePosition); 265 while C > 0 do begin 266 case ReadCode of 267 '[': Inc(C); 268 ']': Dec(C); 269 end; 270 Inc(SourcePosition); 271 end; 272 Dec(SourcePosition);*) 273 //if NewPos <> SourcePosition then raise Exception.Create('Wrong pos: ' + IntToStr(SourcePosition) + ' ' + IntToStr(NewPos)); 274 end; 275 end; 276 ']': begin 277 if Memory[MemoryPosition] > 0 then begin 278 SourcePosition := SourceJump[SourcePosition] - 1; 279 (*C := 1; 280 Dec(SourcePosition); 281 while C > 0 do begin 282 case ReadCode of 283 ']': Inc(C); 284 '[': Dec(C); 285 end; 286 Dec(SourcePosition); 287 end; 288 if NewPos <> SourcePosition then raise Exception.Create('Wrong pos: ' + IntToStr(SourcePosition) + ' ' + IntToStr(NewPos)); 289 *) 290 end; 291 end; 292 end; 278 begin 279 FCommandTable[FSource[SourcePosition]]; 293 280 Inc(SourcePosition); 294 281 Inc(FStepCount); … … 317 304 MemorySize := 30000; 318 305 CellSize := 256; 306 FCommandTable[cmInc] := CommandInc; 307 FCommandTable[cmDec] := CommandDec; 308 FCommandTable[cmPointerInc] := CommandPointerInc; 309 FCommandTable[cmPointerDec] := CommandPointerDec; 310 FCommandTable[cmOutput] := CommandOutput; 311 FCommandTable[cmInput] := CommandInput; 312 FCommandTable[cmLoopStart] := CommandLoopStart; 313 FCommandTable[cmLoopEnd] := CommandLoopEnd; 319 314 end; 320 315
Note:
See TracChangeset
for help on using the changeset viewer.