Ignore:
Timestamp:
Apr 22, 2020, 9:00:02 AM (4 years ago)
Author:
chronos
Message:
  • Added: Executor support for Break and Continue statements.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter2/UExecutor.pas

    r207 r211  
    5757  end;
    5858
    59     { TExecutorBlock }
     59  { TExecutorBlock }
    6060
    6161  TExecutorBlock = class
     
    468468      if not TValueBoolean(Value).Value then Break;
    469469      ExecuteCommand(Block, WhileDo.Command);
     470      if WhileDo.DoContinue then begin
     471        WhileDo.DoContinue := False;
     472        Continue;
     473      end;
     474      if WhileDo.DoBreak then begin
     475        WhileDo.DoBreak := False;
     476        Break;
     477      end;
    470478    end else raise Exception.Create('Expected boolean value.');
    471479    Value.Free;
     
    480488begin
    481489  while True do begin
    482     for I := 0 to RepeatUntil.Commands.Count - 1 do
     490    for I := 0 to RepeatUntil.Commands.Count - 1 do begin
    483491      ExecuteCommand(Block, TCommand(RepeatUntil.Commands[I]));
     492      if RepeatUntil.DoContinue then begin
     493        RepeatUntil.DoContinue := False;
     494        Continue;
     495      end;
     496      if RepeatUntil.DoBreak then begin
     497        RepeatUntil.DoBreak := False;
     498        Break;
     499      end;
     500    end;
    484501    Value := ExecuteExpression(Block, RepeatUntil.Expression);
    485502    if Value is TValueBoolean then begin
     
    501518  while True do begin
    502519    ExecuteCommand(Block, ForToDo.Command);
     520    if ForToDo.DoContinue then begin
     521      ForToDo.DoContinue := False;
     522      Continue;
     523    end;
     524    if ForToDo.DoBreak then begin
     525      ForToDo.DoBreak := False;
     526      Break;
     527    end;
    503528    TValueInteger(Variable.Value).Value := TValueInteger(Variable.Value).Value + 1;
    504529    if TValueInteger(Variable.Value).Value > TValueInteger(Limit).Value then Break;
     
    509534procedure TExecutor.ExecuteContinue(Block: TExecutorBlock;
    510535  ContinueCmd: TContinue);
    511 begin
    512 
     536var
     537  Node: TSourceNode;
     538begin
     539  Node := ContinueCmd.Parent;
     540  while Assigned(Node) and not (Node is TLoop) and Assigned(Node.Parent) do
     541    Node := Node.Parent;
     542
     543  if Node is TLoop then TLoop(Node).DoContinue := True
     544  else raise Exception.Create('Break used outside of loop.');
    513545end;
    514546
    515547procedure TExecutor.ExecuteBreak(Block: TExecutorBlock; BreakCmd: TBreak);
    516 begin
    517 
     548var
     549  Node: TSourceNode;
     550begin
     551  Node := BreakCmd.Parent;
     552  while Assigned(Node) and not (Node is TLoop) and Assigned(Node.Parent) do
     553    Node := Node.Parent;
     554
     555  if Node is TLoop then TLoop(Node).DoBreak := True
     556  else raise Exception.Create('Break used outside of loop.');
    518557end;
    519558
Note: See TracChangeset for help on using the changeset viewer.