Changeset 108


Ignore:
Timestamp:
Jul 26, 2017, 11:35:26 PM (7 years ago)
Author:
chronos
Message:

*Modified: Better parsing of variable reference.

Location:
branches/interpreter/interpreter4
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter/interpreter4/Execute.pas

    r107 r108  
    88type
    99  TVariableValue = record
    10     VarRef: PVariable;
     10    VarRef: PVariableRef;
    1111    BaseType: TBaseType;
    1212    case Integer of
     
    254254begin
    255255  case GetValue.ReadType of
    256     rtVariable: AssignVariable(Value, ExecutionContextCurrent^.VariableValues.GetByName(GetValue.Variable^.Name));
     256    rtVariable: AssignVariable(Value, ExecutionContextCurrent^.VariableValues.GetByName(GetValue.VariableRef^.Variable^.Name));
    257257    //rtConstant: Value := ExecutionContextCurrent^.VariableValues.GetByName(GetValue.Variable^.Name);
    258258    rtExpression: ExecuteExpression(GetValue.Expression, Value);
     
    352352    Param := @Execution^.Parameters.Items[I];
    353353    if (Param.ReadType = rtVariable) then
    354       AssignVariable(ExecutionContextCurrent^.VariableValues.GetByName(Param.Variable.Name), DestVar)
     354      AssignVariable(ExecutionContextCurrent^.VariableValues.GetByName(Param.VariableRef^.Variable^.Name), DestVar)
    355355    else ShowError('Function var parameter can be only variable');
    356356  end;
     
    362362  SrcVariable: TVariableValue;
    363363begin
    364   DestVariable := ExecutionContextCurrent^.VariableValues.GetByName(Assignment^.Destination^.Name);
    365   WriteLn('Assignment to ' + Assignment^.Destination^.Name);
     364  DestVariable := ExecutionContextCurrent^.VariableValues.GetByName(Assignment^.Destination^.Variable^.Name);
     365  WriteLn('Assignment to ' + Assignment^.Destination^.Variable^.Name);
    366366  FillChar(SrcVariable, SizeOf(TVariableValue), 0);
    367367  ExecuteGetValue(@Assignment^.Source, @SrcVariable);
     
    395395begin
    396396  I := 0;
    397   while (I < Length(Items)) and (Items[I].VarRef^.Name <> Name) do Inc(I);
     397  while (I < Length(Items)) and (Items[I].VarRef^.Variable^.Name <> Name) do Inc(I);
    398398  if I < Length(Items) then Result := @Items[I]
    399399    else Result := nil;
  • branches/interpreter/interpreter4/Parser.pas

    r107 r108  
    5151function ParseTypeFunction(TypeItem: PType; WithName: Boolean = True): Boolean; forward;
    5252function ParseTypeProcedure(TypeItem: PType; WithName: Boolean = True): Boolean; forward;
    53 function ParseVariable(out Variable: PVariable): Boolean; forward;
     53function ParseVariableRef(VariableRef: PVariableRef): Boolean; forward;
    5454function ParseExpression(Expression: PExpression): Boolean; forward;
    5555
     
    129129end;
    130130
     131function GetPosText: string;
     132begin
     133  Result := InputTextFileName + ' (' + IntToStr(InputTextPos.Y) + ',' + IntToStr(InputTextPos.X) + ')';
     134end;
     135
    131136procedure ShowError(Text: string);
    132137begin
    133   WriteLn(InputTextFileName + ' (' + IntToStr(InputTextPos.Y) + ',' + IntToStr(InputTextPos.X) + ') ' + Text);
     138  WriteLn(GetPosText + ' ' + Text);
    134139  WriteLn(Copy(InputText, InputTextPos.Index, 50));
    135140  Halt;
     
    288293begin
    289294  Result := ReadNextInternal;
    290   //WriteLn('ReadNext: ' + Result);
     295  WriteLn(GetPosText + ' ReadNext: ' + Result);
    291296end;
    292297
     
    300305  Result := Next = Text;
    301306  InputTextPos := OldPos;
    302   WriteLn('Check: ' + Next);
     307  WriteLn(GetPosText + ' Check: ' + Next + ', ' + Text);
    303308end;
    304309
     
    308313begin
    309314  Next := ReadNextInternal;
    310   WriteLn('Expect: ' + Next);
     315  WriteLn(GetPosText + ' Expect: ' + Next + ', ' + Text);
    311316  if Next <> Text then
    312317    ShowError('Expected ' + Text + ' but found ' + Next);
     318end;
     319
     320function CheckNextExpect(Text: string): Boolean;
     321var
     322  Next: string;
     323  OldPos: TTextPos;
     324begin
     325  OldPos := InputTextPos;
     326  Next := ReadNextInternal;
     327  Result := Next = Text;
     328  if not Result then InputTextPos := OldPos;
     329  WriteLn(GetPosText + 'CheckExpect: ' + Next + ', ' + Text);
    313330end;
    314331
     
    325342end;
    326343
    327 function ParseVariable(out Variable: PVariable): Boolean;
     344procedure AssignGetValue(Dest, Source: PGetValue);
     345begin
     346  Dest^.Value := Source^.Value;
     347  Dest^.VariableRef := Source^.VariableRef;
     348  Dest^.Constant := Source^.Constant;
     349  Dest^.Expression := Source^.Expression;
     350  Dest^.FunctionCall := Source^.FunctionCall;
     351  Dest^.ReadType := Source^.ReadType;
     352end;
     353
     354procedure AssignVariableRef(Dest, Source: PVariableRef);
     355begin
     356  Dest^.Index := Source^.Index;
     357  Dest^.Variable := Source^.Variable;
     358  Dest^.Field := Source^.Field;
     359end;
     360
     361function ParseVariableRef(VariableRef: PVariableRef): Boolean;
    328362var
    329363  OldPos: TTextPos;
     
    331365  SelfVariable: PVariable;
    332366  IndexValue: TGetValue;
     367  FieldType: PType;
     368  Variable: PVariable;
    333369begin
    334370  OldPos := InputTextPos;
    335   Variable := nil;
    336371  repeat
    337372    Next := ReadNext;
    338     if Assigned(Variable) and (Variable^.DataType^.BaseType = btRecord) then begin
    339 //      if FunctionContext = nil then
    340 //        Variable := MainProgram^.Variables.GetByName(Next)
    341 //        else Variable := FunctionContext^.Variables.GetByName(Next);
     373    if Assigned(VariableRef^.Variable) and (VariableRef^.Variable^.DataType^.BaseType = btRecord) then begin
     374      VariableRef^.Field := VariableRef^.Variable^.DataType^.Fields^.GetByName(Next);
    342375    end else begin
    343       if FunctionContext = nil then
    344         Variable := MainProgram^.Variables.GetByName(Next)
    345         else begin
    346           Variable := FunctionContext^.Variables.GetByName(Next);
    347           if (Variable = nil) then begin
    348             SelfVariable := FunctionContext^.Variables.GetByName('Self');
    349             if (SelfVariable <> nil) and (SelfVariable^.Value.ValueRecord <> nil) then begin
    350               Variable := SelfVariable^.Value.ValueRecord^.GetByName(Next);
    351             end;
     376      if FunctionContext = nil then begin
     377        Variable := MainProgram^.Variables.GetByName(Next);
     378        VariableRef^.Variable := Variable;
     379      end else begin
     380        Variable := FunctionContext^.Variables.GetByName(Next);
     381        if (Variable = nil) then begin
     382          SelfVariable := FunctionContext^.Variables.GetByName('Self');
     383          if (SelfVariable <> nil) and (SelfVariable^.Value.ValueRecord <> nil) then begin
     384            Variable := SelfVariable^.Value.ValueRecord^.GetByName(Next);
     385            if Variable <> nil then
     386              VariableRef^.Variable := Variable;
    352387          end;
    353         end;
     388        end else VariableRef^.Variable := Variable;
     389      end;
    354390    end;
    355     if Variable <> nil then begin
     391    if VariableRef^.Variable <> nil then begin
    356392      Result := True;
    357393      if CheckNext('[') then begin
    358         if Variable^.DataType^.BaseType = btArray then begin
     394        if VariableRef^.Variable^.DataType^.BaseType = btArray then begin
    359395          Expect('[');
    360396          if ParseGetValue(@IndexValue) then begin
    361             //Variable := Variable^.
     397            VariableRef^.Index := GetMem(SizeOf(TGetValue));
     398            AssignGetValue(VariableRef^.Index, @IndexValue);
    362399          end else ShowError('Expected index value but found ' + ReadNext);
    363400          Expect(']');
    364401        end else ShowError('Unexpected array index');
    365402      end;
    366       if CheckNext('.') then begin
    367         Expect('.');
     403      if CheckNextExpect('.') then begin
     404
    368405        Continue;
    369406      end else Break;
     
    376413end;
    377414
    378 function ParseVariablePointer(out Variable: PVariable): Boolean;
     415function ParseVariablePointer(Variable: PVariableRef): Boolean;
    379416begin
    380417  Result := False;
     
    382419    Expect('@');
    383420    Result := True;
    384     ParseVariable(Variable);
     421    ParseVariableRef(Variable);
    385422  end;
    386423end;
     
    481518  FoundOperator := False;
    482519  repeat
     520    FillChar(GetValue, SizeOf(TGetValue), 0);
    483521    if CheckNext('(') then begin
    484522      Expect('(');
     
    570608function ParseGetValue(GetValue: PGetValue; NoExpression: Boolean = False): Boolean;
    571609var
    572   Variable: PVariable;
     610  VariableRef: TVariableRef;
    573611  Constant: PConstant;
    574612  FunctionCall: TExecution;
     
    579617  FillChar(FunctionCall, SizeOf(TFunctionCall), 0);
    580618  FillChar(Value, SizeOf(TConstant), 0);
     619  FillChar(VariableRef, SizeOf(TVariableRef), 0);
    581620
    582621  Result := True;
     
    588627    //AssignExpression(GetValue^.Expression, @Expression);
    589628  end else
    590   if ParseVariable(Variable) then begin
     629  if ParseVariableRef(@VariableRef) then begin
    591630    GetValue^.ReadType := rtVariable;
    592     GetValue^.Variable := Variable;
     631    GetValue^.VariableRef := GetMem(SizeOf(TVariableRef));
     632    AssignVariableRef(GetValue^.VariableRef, @VariableRef);
    593633  end else
    594634  if ParseConstant(Constant) then begin
     
    600640    GetValue^.Value := Value;
    601641  end else
    602   if ParseVariablePointer(Variable) then begin
     642  if ParseVariablePointer(@VariableRef) then begin
    603643    GetValue^.ReadType := rtValue;
    604     GetValue^.Value := Value;
     644    GetValue^.VariableRef := GetMem(SizeOf(TVariableRef));
     645    AssignVariableRef(GetValue^.VariableRef, @VariableRef);
    605646  end else
    606647  if ParseExecution(@FunctionCall) then begin
     
    615656function ParseAssignment(Assignment: PAssignment): Boolean;
    616657var
    617   Variable: PVariable;
    618 begin
    619   if ParseVariable(Variable) then begin
    620     Result := True;
    621     Assignment^.Destination := Variable;
     658  Variable: TVariableRef;
     659begin
     660  FillChar(Variable, SizeOf(TVariableRef), 0);
     661  if ParseVariableRef(@Variable) then begin
     662    Result := True;
     663    Assignment^.Destination := GetMem(SizeOf(TVariable));
     664    AssignVariableRef(Assignment^.Destination, @Variable);
    622665    Expect(':=');
    623666    ParseGetValue(@Assignment^.Source);
     
    723766function ParseWhileDo(WhileDo: PWhileDo): Boolean;
    724767begin
    725   if CheckNext('while') then begin
    726     Result := True;
    727     Expect('while');
     768  if CheckNextExpect('while') then begin
     769    Result := True;
    728770    ParseGetValue(@WhileDo.Condition);
    729771    Expect('do');
     
    736778  Command: TCommand;
    737779begin
    738   if CheckNext('begin') then begin
    739     Result := True;
    740     Expect('begin');
     780  if CheckNextExpect('begin') then begin
     781    Result := True;
    741782    SetLength(BeginEnd^.Commands, 0);
    742783    repeat
     
    9861027function ParseDirective(Directive: PDirective): Boolean;
    9871028begin
    988   if CheckNext('{$') then begin
    989     Expect('{$');
     1029  if CheckNextExpect('{$') then begin
    9901030    Directive^.Name := ReadNext;
    9911031    Directive^.Value := ReadNext;
     
    11381178begin
    11391179  CaseActivated := False;
    1140   if CheckNext('record') then begin
    1141     Result := True;
    1142     Expect('record');
     1180  if CheckNextExpect('record') then begin
     1181    Result := True;
    11431182    TypeItem^.BaseType := btRecord;
    11441183    TypeItem^.Fields := GetMem(SizeOf(TTypes));;
     
    12651304end;
    12661305
    1267 function ParseUnit(UnitItem: PUnit; FileName: string): Boolean;
     1306function ParseUnit(UnitItem: PUnit; FileName, ShortFileName: string): Boolean;
    12681307var
    12691308  OldInputText: string;
    12701309  OldInputTextPos: TTextPos;
     1310  OldInputTextFileName: string;
    12711311  UnitFile: Text;
    12721312  Directive: TDirective;
     
    12761316  OldInputText := InputText;
    12771317  OldInputTextPos := InputTextPos;
     1318  OldInputTextFileName := InputTextFileName;
     1319
     1320  InputTextFileName := ShortFileName;
    12781321
    12791322  AssignFile(UnitFile, FileName);
     
    13291372  InputText := OldInputText;
    13301373  InputTextPos := OldInputTextPos;
     1374  InputTextFileName := OldInputTextFileName;
    13311375end;
    13321376
     
    13361380  UnitItem: PUnit;
    13371381begin
    1338   if CheckNext('uses') then begin
    1339     Result := True;
    1340     Expect('uses');
     1382  if CheckNextExpect('uses') then begin
     1383    Result := True;
    13411384    repeat
    13421385      Next := ReadNext;
     
    13471390      if UnitItem = nil then begin
    13481391        SetLength(MainProgram.Units.Items, Length(MainProgram.Units.Items) + 1);
    1349         ParseUnit(@MainProgram.Units.Items[Length(MainProgram.Units.Items) - 1], MainProgram.BaseDir + '/' + Next + '.pas');
     1392        ParseUnit(@MainProgram.Units.Items[Length(MainProgram.Units.Items) - 1], MainProgram.BaseDir + '/' + Next + '.pas', Next + '.pas');
    13501393      end;
    13511394
     
    13861429
    13871430  SetLength(ProgramCode^.Variables.Items, 0);
     1431
     1432  SetLength(ProgramCode^.Constants.Items, 0);
     1433  ProgramCode^.Constants.Add(ConstantCreate('nil', nil));
    13881434
    13891435  SetLength(ProgramCode^.Functions.Items, 0);
     
    14181464  ParserInit(ProgramCode);
    14191465  ReadInputAll(Input);
    1420   if CheckNext('program') then begin
    1421     Expect('program');
     1466  InputTextFileName := 'Input';
     1467  if CheckNextExpect('program') then begin
    14221468    ProgramCode.Name := ReadNext;
    14231469    Expect(';');
  • branches/interpreter/interpreter4/Source.pas

    r106 r108  
    99  PAssignment = ^TAssignment;
    1010  PVariable = ^TVariable;
     11  PVariableRef = ^TVariableRef;
    1112  PConstant = ^TConstant;
    1213  PIfThenElse = ^TIfThenElse;
     
    1920  PFunction = ^TFunction;
    2021  PVariables = ^TVariables;
    21 
    22   TOperator = (opNone, opAdd, opSubtract, opAnd, opOr, opNot, opEqual, opNotEqual);
     22  PGetValue = ^TGetValue;
     23
     24  TOperator = (opNone, opAdd, opSubtract, opAnd, opOr, opNot, opEqual, opNotEqual,
     25  opLess, opGreater, opLessOrEqual, opGreaterOrEqual);
    2326
    2427  TBaseType = (btNone, btBoolean, btInteger, btChar, btShortString, btArray,
     
    9497  end;
    9598
     99  TVariableRef = record
     100    Variable: PVariable;
     101    case TBaseType of
     102      btRecord: (Field: PType);
     103      btArray: (Index: PGetValue);
     104  end;
     105
    96106  TFunctionParameter = record
    97107    Name: string;
     
    135145    ReadType: TReadType;
    136146    case TReadType of
    137       rtVariable: (Variable: PVariable);
     147      rtVariable: (VariableRef: PVariableRef);
    138148      rtConstant: (Constant: PConstant);
    139149      rtExpression: (Expression: PExpression);
     
    141151      rtValue: (Value: TConstant);
    142152  end;
    143   PGetValue = ^TGetValue;
    144153
    145154  TExpNodeType = (ntNone, ntValue, ntOperator);
     
    155164
    156165  TAssignment = record
    157     Destination: PVariable;
     166    Destination: PVariableRef;
    158167    Source: TGetValue;
    159168  end;
     
    249258var
    250259  OperatorString: array[TOperator] of string = ('', '+', '-', 'and', 'or', 'not',
    251     '=', '<>');
     260    '=', '<>', '<', '>', '<=', '>=');
    252261
    253262const
    254   OperatorPrecedence: array[0..6] of TOperator = (opNot, opAnd, opOr, opAdd,
    255     opSubtract, opEqual, opNotEqual);
     263  OperatorPrecedence: array[0..10] of TOperator = (opNot, opAnd, opOr, opAdd,
     264    opSubtract, opEqual, opNotEqual, opLess, opGreater, opLessOrEqual, opGreaterOrEqual);
    256265  Keywords: array[0..18] of string = ('begin', 'end', 'if', 'then', 'else', 'while',
    257266    'do', 'type', 'var', 'const', 'uses', 'unit', 'program', 'array', 'procedure',
  • branches/interpreter/interpreter4/interpreter.lpi

    r107 r108  
    101101        <StackChecks Value="True"/>
    102102      </Checks>
     103      <VerifyObjMethodCallValidity Value="True"/>
    103104    </CodeGeneration>
    104105  </CompilerOptions>
Note: See TracChangeset for help on using the changeset viewer.