Ignore:
Timestamp:
Feb 6, 2017, 12:11:54 AM (8 years ago)
Author:
chronos
Message:
  • Modified: Better parsing of expression and commands.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter/Parser3.pas

    r98 r99  
    2727function ParseExecution(Execution: PExecution): Boolean; forward;
    2828function ParseBeginEnd(BeginEnd: PBeginEnd): Boolean; forward;
     29function ParseGetValue(GetValue: PGetValue): Boolean; forward;
    2930
    3031
     
    165166end;
    166167
     168function ParseConstant(out Constant: PConstant): Boolean;
     169var
     170  OldPos: Integer;
     171  Next: string;
     172begin
     173  OldPos := InputTextPos;
     174  Next := ReadNext;
     175  Constant := MainProgram^.Constants.GetByName(Next);
     176  if Constant <> nil then begin
     177    Result := True;
     178  end else begin
     179    Result := False;
     180    InputTextPos := OldPos;
     181  end;
     182end;
     183
    167184function ParseExpression(Expression: PExpression): Boolean;
    168185var
     
    170187  OldPos: Integer;
    171188  R: Boolean;
     189  GetValue: TGetValue;
     190  Execution: TExecution;
    172191  Variable: PVariable;
    173192  SubExpression: TExpression;
    174   Execution: TExecution;
    175193begin
    176194  Result := True;
     
    180198  if CheckNext('(') then begin
    181199    Expect('(');
    182     R := ParseExpression(@SubExpression);
     200    if ParseGetValue(@GetValue) then begin
     201      SetLength(Expression^.Items, Length(Expression^.Items) + 1);
     202      Expression^.Items[Length(Expression^.Items) - 1] := GetValue;
     203    end;
    183204    Expect(')');
    184205  end else
     
    207228end;
    208229
     230function ParseGetValue(GetValue: PGetValue): Boolean;
     231var
     232  Variable: PVariable;
     233  Constant: PConstant;
     234  FunctionCall: TExecution;
     235  Expression: TExpression;
     236begin
     237  if ParseVariable(Variable) then begin
     238    GetValue^.Variable := Variable;
     239    GetValue^.ReadType := rtVariable;
     240  end else
     241  if ParseConstant(Constant) then begin
     242    GetValue^.Constant := Constant;
     243    GetValue^.ReadType := rtConstant;
     244  end else
     245  if ParseExecution(@FunctionCall) then begin
     246    GetValue^.FunctionCall := GetMem(SizeOf(TExecution));
     247    GetValue^.FunctionCall^ := FunctionCall;
     248    GetValue^.ReadType := rtFunctionCall;
     249  end else
     250  if ParseExpression(@Expression) then begin
     251    GetValue^.Expression := GetMem(SizeOf(TExpression));
     252    GetValue^.Expression^ := Expression;
     253    GetValue^.ReadType := rtExpression;
     254  end else
     255    ShowError('Expected value');
     256end;
     257
    209258function ParseAssignment: Boolean;
    210259var
     
    216265    Assignment.Destination := Variable;
    217266    Expect(':=');
    218     ParseExpression(@Assignment.Source);
     267    ParseGetValue(@Assignment.Source);
    219268  end else begin
    220269    Result := False;
     
    228277  Func: PFunction;
    229278  I: Integer;
    230   Expression: TExpression;
    231279begin
    232280  Result := True;
     
    235283  Func := MainProgram.Functions.GetByName(Next);
    236284  if Func <> nil then begin
     285    SetLength(Execution^.Parameters.Items, Length(Func^.Parameters.Items));
    237286    if Length(Func^.Parameters.Items) > 0 then begin
    238287      Expect('(');
    239288      I := 0;
    240289      while I < Length(Func^.Parameters.Items) do begin
    241         ParseExpression(@Expression);
     290        ParseGetValue(@Execution^.Parameters.Items[I]);
    242291        if I < (Length(Func^.Parameters.Items) - 1) then Expect(',');
    243292        I := I + 1;
     
    251300end;
    252301
    253 function ParseCommand: Boolean;
     302function ParseCommand(Command: PCommand): Boolean;
    254303var
    255304  IfThenElse: TIfThenElse;
     
    257306  BeginEnd: TBeginEnd;
    258307  Execution: TExecution;
     308  Assignment: TAssignment;
    259309begin
    260310  Result := True;
    261311  if ParseBeginEnd(@BeginEnd) then begin
     312    Command^.BeginEnd := GetMem(SizeOf(TBeginEnd));
     313    Command^.BeginEnd^ := BeginEnd;
     314    Command^.CmdType := ctBeginEnd;
    262315  end else
    263316  if ParseAssignment then begin
     317    Command^.Assignment := GetMem(SizeOf(TAssignment));
     318    Command^.Assignment^ := Assignment;
     319    Command^.CmdType := ctAssignment;
    264320  end else
    265321  if ParseExecution(@Execution) then begin
     322    Command^.Execution := GetMem(SizeOf(TExecution));
     323    Command^.Execution^ := Execution;
     324    Command^.CmdType := ctExecution;
    266325  end else
    267326  if ParseIfThen(@IfThenElse) then begin
     327    Command^.IfThenElse := GetMem(SizeOf(TIfThenElse));
     328    Command^.IfThenElse^ := IfThenElse;
     329    Command^.CmdType := ctIfThenElse;
    268330  end else
    269331  if ParseWhileDo(@WhileDo) then begin
     332    Command^.WhileDo := GetMem(SizeOf(TWhileDo));
     333    Command^.WhileDo^ := WhileDo;
     334    Command^.CmdType := ctWhileDo;
    270335  end else Result := False;
    271336end;
     
    278343    ParseExpression(@IfThenElse.Condition);
    279344    Expect('then');
    280     ParseCommand;
     345    ParseCommand(@IfThenElse^.DoThen);
    281346    if CheckNext('else') then begin
    282347      Expect('else');
    283       ParseCommand;
     348      ParseCommand(@IfThenElse^.DoElse);
    284349    end;
    285350  end else Result := False;
     
    293358    ParseExpression(@WhileDo.Condition);
    294359    Expect('do');
    295     ParseCommand;
     360    ParseCommand(@WhileDo^.Command);
    296361  end else Result := False;
    297362end;
    298363
    299364function ParseBeginEnd(BeginEnd: PBeginEnd): Boolean;
     365var
     366  Command: TCommand;
    300367begin
    301368  if CheckNext('begin') then begin
    302369    Result := True;
    303370    Expect('begin');
     371    SetLength(BeginEnd^.Commands, 0);
    304372    repeat
    305       if ParseCommand then begin
     373      if ParseCommand(@Command) then begin
     374        BeginEnd^.Add;
     375        BeginEnd^.GetLast^ := Command;
    306376        Expect(';');
    307377      end else
Note: See TracChangeset for help on using the changeset viewer.