RomanYankovsky / DelphiAST

Abstract syntax tree builder for Delphi
Mozilla Public License 2.0
271 stars 116 forks source link

statements inside an asm block are not recorded. #257

Open JBontes opened 6 years ago

JBontes commented 6 years ago
unit PlusIsTest;

interface

implementation

procedure TScriptlet.InitControlData;
asm
  mov eax,10
end;

end.

is recorded as:

<?xml version="1.0"?>
<UNIT line="1" col="1" name="PlusIsTest">
  <INTERFACE begin_line="3" begin_col="1" end_line="5" end_col="1"/>
  <IMPLEMENTATION begin_line="5" begin_col="1" end_line="12" end_col="1">
    <METHOD begin_line="7" begin_col="1" end_line="12" end_col="1" kind="procedure">
      <NAME line="7" col="11" name="TScriptlet.InitControlData">
        <NAME line="7" col="11" name="TScriptlet"/>
        <NAME line="7" col="22" name="InitControlData"/>
      </NAME>
      <STATEMENTS begin_line="8" begin_col="1" end_line="10" end_col="4" type="asm"/>
    </METHOD>
  </IMPLEMENTATION>
</UNIT>

The fix:

procedure TPasSyntaxTreeBuilder.AsmFragment;
begin
  FStack.AddValuedChild(ntAsmFragment, Lexer.Token);
  inherited;

end;

procedure TPasSyntaxTreeBuilder.AsmStatement;
var
  Node, Child: TSyntaxNode;
  ValuedNode: TValuedSyntaxNode absolute Node;
  ValuedChild: TValuedSyntaxNode absolute Child;
  Optional: string;
  Previous: char;
begin
  Node:= FStack.PushValuedNode(ntAsmStatement,'');
  try
    inherited;
    Optional:= '';
    Previous:= ' ';
    for Child in Node.ChildNodes do begin
      //Store the whole statement as well as the parts.
      if (ValuedChild.Value[1] in [',', '+', '*', ']', ')', ' ','-']) or (Previous in ['(','[',',','+','*','-']) then Optional:= '';
      Previous:= ValuedChild.Value[1];
      ValuedNode.Value:= ValuedNode.Value + Optional + ValuedChild.Value;
      Optional:= ' ';
    end;
  finally
    FStack.Pop;
  end;
end;

procedure TPasSyntaxTreeBuilder.AsmStatements;  //renamed from statement -> statementS
begin
  FStack.PushCompoundSyntaxNode(ntStatements).Attribute[anType]:= AttributeValues[atAsm];
  try
    inherited;
    SetCurrentCompoundNodesEndPosition;
  finally
    FStack.Pop;
  end;
end;

procedure TmwSimplePasPar.AsmStatements;
begin
  Lexer.AsmCode := True;
  Expected(ptAsm);
  { should be replaced with a Assembler lexer }
  while TokenID <> ptEnd do begin
    case FLexer.TokenID of
      ptBegin, ptCase, ptEnd, ptIf, ptFunction, ptProcedure, ptRepeat, ptWhile: Break;
      ptAddressOp:
        begin
          NextTokenAssembly;
          NextTokenAssembly;
        end;
      ptDoubleAddressOp:
        begin
          NextTokenAssembly;
          NextTokenAssembly;
        end;
      ptNull:
        begin
          Expected(ptEnd);
          Exit;
        end;
      ptCRLF: //empty line
        NextTokenAssembly;
      else begin
        AsmStatement;
        Expected(ptCRLF);
      end;
    end; {case}
  end; {while}
  Lexer.AsmCode := False;
  Expected(ptEnd);
end;

procedure TmwSimplePasPar.AsmStatement;
begin
  while not(Lexer.TokenID in [ptCRLF]) do begin
    AsmFragment;
  end;
end;

procedure TmwSimplePasPar.AsmFragment;
begin
  NextTokenAssembly;
end;

procedure TmwSimplePasPar.NextTokenAssembly;
begin
  FLexer.NextNoJunkAssembly;
end;

procedure TmwBasePasLex.NextNoJunkAssembly;
begin
  repeat
    Next
  until not IsJunkAssembly;
end;

function TmwBasePasLex.GetIsJunkAssembly: Boolean;
begin
  //CRLF takes the place of ';'
  Result := not(FTokenID in [ptCRLF]) and (
    IsTokenIDJunk(FTokenID) or (FUseDefines and (FDefineStack > 0) and (TokenID <> ptNull))
    );
end;