Ignore:
Timestamp:
Jul 18, 2017, 12:07:31 AM (7 years ago)
Author:
chronos
Message:
  • Modified: Improvements around record type.
Location:
branches/interpreter/interpreter4
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter/interpreter4

    • Property svn:ignore set to
      lib
      interpreter.lps
  • branches/interpreter/interpreter4/Parser.pas

    r105 r106  
    3636function ParseBeginEnd(BeginEnd: PBeginEnd): Boolean; forward;
    3737function ParseGetValue(GetValue: PGetValue; NoExpression: Boolean = False): Boolean; forward;
     38function ParseAssignment(Assignment: PAssignment): Boolean; forward;
    3839function ParseUses(UsesSection: PUses): Boolean; forward;
    3940function ParseType(TypeItem: PType; AllowForward: Boolean): Boolean; forward;
    4041function ParseTypeFunction(TypeItem: PType; WithName: Boolean = True): Boolean; forward;
    4142function ParseTypeProcedure(TypeItem: PType; WithName: Boolean = True): Boolean; forward;
     43function ParseVariable(out Variable: PVariable): Boolean; forward;
     44function ParseExpression(Expression: PExpression): Boolean; forward;
    4245
    4346
     
    6669  Result := (C = ';') or (C = '(') or (C = ')') or (C = ':') or (C = '=') or
    6770    (C = '+') or (C = '-') or (C = ';') or (C = '.') or (C = '{') or (C = '}') or
    68     (C = ',') or (C = '^') or (C = '/') or (C = '[') or (C = ']');
     71    (C = ',') or (C = '^') or (C = '/') or (C = '[') or (C = ']') or (C = '@');
    6972end;
    7073
     
    173176end;
    174177
    175 function ReadNext: string;
     178function ReadNextInternal: string;
    176179var
    177180  C: Char;
     
    239242        LastTokenType := ttNumber;
    240243      end else
     244      if IsDigit(C) then begin
     245        Result := Result + C;
     246        LastTokenType := ttNumber;
     247      end else
    241248      if C = '''' then begin
    242249        LastTokenType := ttString;
     
    248255end;
    249256
     257function ReadNext: string;
     258begin
     259  Result := ReadNextInternal;
     260  WriteLn('ReadNext: ' + Result);
     261end;
     262
    250263function CheckNext(Text: string): Boolean;
    251264var
     
    254267begin
    255268  OldPos := InputTextPos;
    256   Next := ReadNext;
     269  Next := ReadNextInternal;
    257270  Result := Next = Text;
    258271  InputTextPos := OldPos;
     272  WriteLn('Check: ' + Next);
    259273end;
    260274
     
    263277  Next: string;
    264278begin
    265   Next := ReadNext;
     279  Next := ReadNextInternal;
     280  WriteLn('Expect: ' + Next);
    266281  if Next <> Text then
    267282    ShowError('Expected ' + Text + ' but found ' + Next);
     
    284299  OldPos: Integer;
    285300  Next: string;
     301  SelfVariable: PVariable;
     302  IndexValue: TGetValue;
    286303begin
    287304  OldPos := InputTextPos;
     
    298315        else begin
    299316          Variable := FunctionContext^.Variables.GetByName(Next);
     317          if (Variable = nil) then begin
     318            SelfVariable := FunctionContext^.Variables.GetByName('Self');
     319            if (SelfVariable <> nil) and (SelfVariable^.Value.ValueRecord <> nil) then begin
     320              Variable := SelfVariable^.Value.ValueRecord^.GetByName(Next);
     321            end;
     322          end;
    300323        end;
    301324    end;
    302325    if Variable <> nil then begin
    303326      Result := True;
     327      if CheckNext('[') then begin
     328        if Variable^.DataType^.BaseType = btArray then begin
     329          Expect('[');
     330          if ParseGetValue(@IndexValue) then begin
     331            //Variable := Variable^.
     332          end else ShowError('Expected index value but found ' + ReadNext);
     333          Expect(']');
     334        end else ShowError('Unexpected array index');
     335      end;
     336      if CheckNext('.') then begin
     337        Expect('.');
     338        Continue;
     339      end else Break;
    304340    end else begin
    305341      Result := False;
    306342      InputTextPos := OldPos;
    307343    end;
    308     if CheckNext('.') then begin
    309       Expect('.');
    310       Continue;
    311     end else Break;
    312344  until False;
     345end;
     346
     347function ParseVariablePointer(out Variable: PVariable): Boolean;
     348begin
     349  Result := False;
     350  if CheckNext('@') then begin
     351    Expect('@');
     352    Result := True;
     353    ParseVariable(Variable);
     354  end;
    313355end;
    314356
     
    402444  FoundOperator: Boolean;
    403445  OldPos: Integer;
     446  //E: TExpression;
    404447begin
    405448  OldPos := InputTextPos;
     
    430473      Break;
    431474    end;
     475    //WriteLn('Items count: ' + IntToStr(Length(Expression^.Items)));
    432476  until False;
    433477  if not FoundOperator then begin
     
    442486      I := 0;
    443487      while (I < Length(Expression^.Items) - 1) do begin
     488        //E := TExpression(Expression^.Items[I]);
    444489        if (TExpression(Expression^.Items[I]).NodeType = ntOperator) and
    445490          not TExpression(Expression^.Items[I]).Associated and
    446491          (TExpression(Expression^.Items[I]).OperatorType = OperatorPrecedence[II]) then
    447492        begin
     493          //WriteLn('Expression operator ' + OperatorString[OperatorPrecedence[II]]);
    448494          if Expression^.Items[I].OperatorType = opNot then begin
    449495            Expression^.Items[I].Associated := True;
     
    474520        I := I - 1;
    475521      end;
    476     end else ShowError('Expression error ' + IntToStr(Length(Expression^.Items)));
     522    end else ShowError('Expression error. Items count: ' + IntToStr(Length(Expression^.Items)));
    477523  end;
    478524end;
     
    520566  end else
    521567  if ParseValue(@Value) then begin
     568    GetValue^.ReadType := rtValue;
     569    GetValue^.Value := Value;
     570  end else
     571  if ParseVariablePointer(Variable) then begin
    522572    GetValue^.ReadType := rtValue;
    523573    GetValue^.Value := Value;
     
    748798          // Create subvariables for structured record type variable
    749799          if VarType^.BaseType = btRecord then begin
    750             SetLength(Variables^.GetLast^.RecordVariables.Items, 0);
     800            SetLength(Variables^.GetLast^.Value.ValueRecord.Items, 0);
    751801            I := 0;
    752802            while (I < Length(VarType^.Fields^.Items)) do begin
    753               Variables^.GetLast^.RecordVariables^.Add(
     803              Variables^.GetLast^.Value.ValueRecord^.Add(
    754804                VariableCreate(VarType^.Fields^.Items[I].Name, @VarType^.Fields^.Items[I]));
    755805              I := I + 1;
     
    825875  ReturnType: string;
    826876  DataType: PType;
     877  I: Integer;
    827878begin
    828879  if CheckNext('function') then begin
     
    835886        Expect('.');
    836887        Func^.ParentRecord := Func^.Types.GetByName(Func^.Name);
     888        Func^.Variables.Add(VariableCreate('Self', Func^.ParentRecord));
     889        Func^.Variables.GetLast^.Value.ValueRecord := GetMem(SizeOf(TVariables));
     890        FillChar(Func^.Variables.GetLast^.Value.ValueRecord^, SizeOf(TVariables), 0);
     891        I := 0;
     892        while I < Length(Func^.ParentRecord.Fields.Items) do begin
     893          Func^.Variables.GetLast^.Value.ValueRecord^.Add(
     894            VariableCreate(Func^.ParentRecord.Fields.Items[I].Name,
     895            @(Func^.ParentRecord.Fields.Items[I])));
     896          I := I + 1;
     897        end;
    837898        Continue;
    838899      end else Break;
     
    856917
    857918function ParseProcedure(Func: PFunction): Boolean;
     919var
     920  I: Integer;
    858921begin
    859922  if CheckNext('procedure') then begin
     
    865928      if CheckNext('.') then begin
    866929        Expect('.');
     930        Func^.ParentRecord := Func^.Types.GetByName(Func^.Name);
     931        Func^.Variables.Add(VariableCreate('Self', Func^.ParentRecord));
     932        Func^.Variables.GetLast^.Value.ValueRecord := GetMem(SizeOf(TVariables));
     933        FillChar(Func^.Variables.GetLast^.Value.ValueRecord^, SizeOf(TVariables), 0);
     934        I := 0;
     935        while I < Length(Func^.ParentRecord.Fields.Items) do begin
     936          Func^.Variables.GetLast^.Value.ValueRecord^.Add(
     937            VariableCreate(Func^.ParentRecord.Fields.Items[I].Name,
     938            @(Func^.ParentRecord.Fields.Items[I])));
     939          I := I + 1;
     940        end;
    867941        Continue;
    868942      end else Break;
  • branches/interpreter/interpreter4/Source.pas

    r105 r106  
    5555  end;
    5656
    57   TVariable = record
    58     Name: string;
    59     DataType: PType;
    60     Index: Integer;
    61     RecordVariables: PVariables;
    62   end;
    63 
    64   { TVariables }
    65 
    66   TVariables = record
    67     ParentList: PVariables;
    68     Items: array of TVariable;
    69     procedure Add(Variable: TVariable);
    70     function GetByName(Name: string): PVariable;
    71     function GetLast: PVariable;
    72   end;
    73 
    7457  TConstant = record
    7558    Name: shortstring;
     
    8164      btShortString: (ValueString: ShortString);
    8265      btBoolean: (ValueBoolean: Boolean);
     66      btRecord: (ValueRecord: PVariables);
     67      btArray: (ValueArray: PVariables);
    8368  end;
    8469
     
    9176  end;
    9277  PConstants = ^TConstants;
     78
     79  TVariable = record
     80    Name: string;
     81    DataType: PType;
     82    Index: Integer;
     83    Value: TConstant;
     84  end;
     85
     86  { TVariables }
     87
     88  TVariables = record
     89    ParentList: PVariables;
     90    Items: array of TVariable;
     91    procedure Add(Variable: TVariable);
     92    function GetByName(Name: string): PVariable;
     93    function GetLast: PVariable;
     94  end;
    9395
    9496  TFunctionParameter = record
  • branches/interpreter/interpreter4/interpreter.lpi

    r104 r106  
    22<CONFIG>
    33  <ProjectOptions>
    4     <Version Value="9"/>
     4    <Version Value="10"/>
    55    <General>
    66      <Flags>
     
    104104  </CompilerOptions>
    105105  <Debugging>
    106     <Exceptions Count="3">
     106    <Exceptions Count="5">
    107107      <Item1>
    108108        <Name Value="EAbort"/>
     
    114114        <Name Value="EFOpenError"/>
    115115      </Item3>
     116      <Item4>
     117        <Name Value="RunError(101)"/>
     118      </Item4>
     119      <Item5>
     120        <Name Value="Unknown"/>
     121      </Item5>
    116122    </Exceptions>
    117123  </Debugging>
Note: See TracChangeset for help on using the changeset viewer.