Ignore:
Timestamp:
Jan 17, 2018, 3:34:13 PM (7 years ago)
Author:
chronos
Message:
  • Added: Support for Repeat blocks and Break command.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/easy compiler/UCompiler.pas

    r146 r147  
    4444    procedure Parse(Code: TSourceCode);
    4545    function ParseBeginEnd(SourceCode: TSourceCode; out BeginEnd: TCommandBeginEnd): Boolean;
     46    function ParseBreak(SourceCode: TSourceCode; out CommandBreak: TCommandBreak
     47      ): Boolean;
     48    function ParseCommand(SourceCode: TSourceCode; out Command: TSourceCommand
     49      ): Boolean;
    4650    function ParseFunctionCall(SourceCode: TSourceCode; out FunctionCall: TCommandFunctionCall): Boolean;
    4751    function ParseIfZero(SourceCode: TSourceCode; out IfZero: TCommandIfZero): Boolean;
    4852    function ParseReference(SourceCode: TSourceCode): TSourceReference;
    4953    function ParseReferenceVariable(SourceCode: TSourceCode): TSourceReference;
     54    function ParseRepeat(SourceCode: TSourceCode; out
     55      CommandRepeat: TCommandRepeat): Boolean;
    5056    function ParseVar(SourceCode: TSourceCode): Boolean;
    5157  public
     
    306312  if Keyword = 'ifzero' then begin
    307313    IfZero := TCommandIfZero.Create;
    308     IfZero.Variable := TSourceReferenceVariable(ParseReferenceVariable(SourceCode)).Variable;
    309     Result := True;
    310   end;
    311   if not Result then Tokenizer.TokenIndex := TokenIndex;
    312 end;
    313 
    314 function TCompiler.ParseBeginEnd(SourceCode: TSourceCode; out BeginEnd: TCommandBeginEnd): Boolean;
    315 var
    316   Token: TSourceToken;
     314    IfZero.Variable := TSourceReferenceVariable(ParseReferenceVariable(SourceCode));
     315    Result := True;
     316  end;
     317  if not Result then Tokenizer.TokenIndex := TokenIndex;
     318end;
     319
     320function TCompiler.ParseBreak(SourceCode: TSourceCode; out CommandBreak: TCommandBreak): Boolean;
     321var
     322  Token: TSourceToken;
     323  TokenIndex: Integer;
    317324  Keyword: string;
    318   TokenIndex: Integer;
     325begin
     326  Result := False;
     327  TokenIndex := Tokenizer.TokenIndex;
     328  Token := Tokenizer.GetNext;
     329  Keyword := LowerCase(Token.Text);
     330  if Keyword = 'break' then begin
     331    CommandBreak := TCommandBreak.Create;
     332    Result := True;
     333  end;
     334  if not Result then Tokenizer.TokenIndex := TokenIndex;
     335end;
     336
     337function TCompiler.ParseRepeat(SourceCode: TSourceCode; out CommandRepeat: TCommandRepeat): Boolean;
     338var
     339  Token: TSourceToken;
     340  TokenIndex: Integer;
     341  Keyword: string;
     342  Command: TSourceCommand;
     343begin
     344  Result := False;
     345  TokenIndex := Tokenizer.TokenIndex;
     346  Token := Tokenizer.GetNext;
     347  Keyword := LowerCase(Token.Text);
     348  if Keyword = 'repeat' then begin
     349    CommandRepeat := TCommandRepeat.Create;
     350    if ParseCommand(SourceCode, Command) then begin
     351      CommandRepeat := TCommandRepeat.Create;
     352      CommandRepeat.Command := Command;
     353      Command.Parent := CommandRepeat;
     354    end else
     355    raise Exception.Create('Unexpected token');
     356    Result := True;
     357  end;
     358  if not Result then Tokenizer.TokenIndex := TokenIndex;
     359end;
     360
     361function TCompiler.ParseCommand(SourceCode: TSourceCode; out Command: TSourceCommand): Boolean;
     362var
    319363  CommandBeginEnd: TCommandBeginEnd;
    320364  CommandIfZero: TCommandIfZero;
    321365  CommandFunctionCall: TCommandFunctionCall;
     366  CommandBreak: TCommandBreak;
     367  CommandRepeat: TCommandRepeat;
     368begin
     369  Command := nil;
     370  Result := True;
     371  if ParseVar(SourceCode) then else
     372  if ParseBeginEnd(SourceCode, CommandBeginEnd) then begin
     373    Command := CommandBeginEnd;
     374  end else
     375  if ParseIfZero(SourceCode, CommandIfZero) then begin
     376    Command := CommandIfZero;
     377  end else
     378  if ParseBreak(SourceCode, CommandBreak) then begin
     379    Command := CommandBreak;
     380  end else
     381  if ParseRepeat(SourceCode, CommandRepeat) then begin
     382    Command := CommandRepeat;
     383  end else
     384  if ParseFunctionCall(SourceCode, CommandFunctionCall) then begin
     385    Command := CommandFunctionCall;
     386  end else Result := False;
     387end;
     388
     389function TCompiler.ParseBeginEnd(SourceCode: TSourceCode; out BeginEnd: TCommandBeginEnd): Boolean;
     390var
     391  Token: TSourceToken;
     392  Keyword: string;
     393  TokenIndex: Integer;
     394  Command: TSourceCommand;
    322395begin
    323396  Result := False;
     
    329402    BeginEnd.SourceCode := SourceCode;
    330403    while True do begin
    331       if ParseVar(SourceCode) then
    332       else if ParseBeginEnd(SourceCode, CommandBeginEnd) then
    333         BeginEnd.Instructions.Add(CommandBeginEnd)
    334       else if ParseIfZero(SourceCode, CommandIfZero) then
    335         BeginEnd.Instructions.Add(CommandIfZero)
    336       else if ParseFunctionCall(SourceCode, CommandFunctionCall) then
    337         BeginEnd.Instructions.Add(CommandFunctionCall)
    338       else if Tokenizer.CheckNext('end', stIdentifier) then begin
     404      if ParseCommand(SourceCode, Command) then begin
     405        if Assigned(Command) then begin
     406          BeginEnd.Commands.Add(Command);
     407          Command.Parent := BeginEnd;
     408        end;
     409      end else
     410      if Tokenizer.CheckNext('end', stIdentifier) then begin
    339411        Break;
    340       end
    341       else raise Exception.Create('Unknown token: ' + Keyword);
     412      end else begin
     413        Token := Tokenizer.GetNext;
     414        Keyword := LowerCase(Token.Text);
     415        raise Exception.Create('Unknown token: ' + Keyword);
     416      end;
    342417    end;
    343418    Token := Tokenizer.GetNext;
Note: See TracChangeset for help on using the changeset viewer.