Changeset 22


Ignore:
Timestamp:
Jun 26, 2012, 10:42:14 AM (12 years ago)
Author:
chronos
Message:
  • Upraveno: Rozklad zdrojového kódu pomocí statických funkcí.
Location:
branches/AS8051toC
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • branches/AS8051toC/AS8051toC.lpi

    r21 r22  
    3838      </Item2>
    3939    </RequiredPackages>
    40     <Units Count="3">
     40    <Units Count="4">
    4141      <Unit0>
    4242        <Filename Value="AS8051toC.lpr"/>
     
    5757        <UnitName Value="UFindFile"/>
    5858      </Unit2>
     59      <Unit3>
     60        <Filename Value="UParser.pas"/>
     61        <IsPartOfProject Value="True"/>
     62        <UnitName Value="UParser"/>
     63      </Unit3>
    5964    </Units>
    6065  </ProjectOptions>
  • branches/AS8051toC/AS8051toC.lpr

    r21 r22  
    88  {$ENDIF}{$ENDIF}
    99  Interfaces, // this includes the LCL widgetset
    10   Forms, UMainForm, UFindFile
     10  Forms, UMainForm, UFindFile, UParser
    1111  { you can add units after this };
    1212
  • branches/AS8051toC/UMainForm.lfm

    r21 r22  
    1111  OnShow = FormShow
    1212  LCLVersion = '1.1'
     13  WindowState = wsMaximized
    1314  object EditPath: TEdit
    1415    Left = 8
  • branches/AS8051toC/UMainForm.pas

    r21 r22  
    88  Classes, SysUtils, FileUtil, SynHighlighterCpp, SynEdit, SynMemo,
    99  SynHighlighterAny, SynHighlighterPas, Forms, Controls, Graphics, Dialogs,
    10   StdCtrls;
    11 
    12 const
    13   Instructions: array[0..40] of string = ('JB', 'JNB', 'NOP', 'LCALL', 'SJMP',
    14     'PUSH', 'POP', 'MOV', 'ADD', 'SUB', 'MUL', 'DIV', 'RET', 'RETI', 'MOVC',
    15     'CLR', 'SETB', 'CALL', 'INC', 'DEC', 'ORL', 'ANL', 'SUBB', 'XCH', 'CPL',
    16     'JC', 'JNC', 'JZ', 'JNZ', 'DJNZ', 'CJNE', 'DB', 'DBIT', 'DS', 'PUBLIC',
    17     'EXTRN', 'CSEG', 'RSEG', 'JMP', 'DW', 'SWAP');
     10  StdCtrls, UParser;
     11
    1812type
    19 
    20   { TParser }
    21 
    22   TParser = class
    23     Source: string;
    24     Position: Integer;
    25     function Expect(Text: string): Boolean;
    26     function Next: string;
    27     function ReadNext: string;
    28   private
    29     function IsAlphabetic(Character: char): boolean;
    30     function IsAlphanumeric(Character: char): boolean;
    31     function IsHex(Character: char): boolean;
    32     function IsIdentificator(Text: string): boolean;
    33     function IsKeyword(Text: string): Boolean;
    34     function IsNumeric(Character: char): boolean;
    35     function IsString(Text: string): Boolean;
    36     function IsWhiteSpace(Character: char): boolean;
    37   end;
    38 
    3913  { TFormMain }
    4014
     
    5226    procedure FormShow(Sender: TObject);
    5327  private
    54     { private declarations }
     28    Parser: TParser;
    5529  public
    5630    MainFile: TStringList;
    5731    MainFileOut: TStringList;
    58     procedure Parse(List: TStringList);
    59     function ParseLine(Line: string): string;
     32    Output: string;
     33    Macros: TStringList;
     34    procedure Emit(Text: string);
     35    procedure Error(Text: string);
     36    procedure Parse;
     37    procedure ParseLine;
     38    function ParseMacro: Boolean;
     39    function ParseComment: Boolean;
     40    function ParseMacroUsage: Boolean;
     41    function ParseKeywords: Boolean;
     42    function ParseInstruction: Boolean;
     43    procedure ParseIfExpression;
     44    procedure ParseDbExpression;
     45    function ParseString: string;
    6046  end;
    6147
     
    6551implementation
    6652
    67 { TParser }
    68 
    69 function TParser.Expect(Text: string): Boolean;
    70 begin
    71   Result := Next = Text;
    72 end;
    73 
    74 function TParser.Next: string;
    75 begin
    76   Result := '';
    77 //  Source[Position]
    78 end;
    79 
    80 function TParser.ReadNext: string;
    81 begin
    82   Result := Next;
    83   Inc(Position, Length(Result));
    84 end;
    85 
    86 function TParser.IsAlphabetic(Character: char): boolean;
    87 begin
    88   Result := (Character in ['a'..'z']) or (Character in ['A'..'Z']);
    89 end;
    90 
    91 function TParser.IsAlphanumeric(Character: char): boolean;
    92 begin
    93   Result := IsAlphabetic(Character) or IsNumeric(Character);
    94 end;
    95 
    96 function TParser.IsNumeric(Character: char): boolean;
    97 begin
    98   Result := Character in ['0'..'9'];
    99 end;
    100 
    101 function TParser.IsHex(Character: char): boolean;
    102 begin
    103   Result := IsNumeric(Character) or (Character in ['A'..'F']);
    104 end;
    105 
    106 function TParser.IsString(Text: string): Boolean;
    107 begin
    108   raise Exception.Create('Not implemented');
    109 end;
    110 
    111 function TParser.IsIdentificator(Text: string): boolean;
    112 var
    113   I: integer;
    114 begin
    115   Result := True;
    116   if Length(Text) = 0 then
    117     Result := False;
    118   //if IsKeyWord(Text) then
    119   //  Result := False;
    120   if Length(Text) > 0 then
    121     if not (Text[1] in ['a'..'z', 'A'..'Z', '%', '_']) then
    122       Result := False;
    123   for I := 2 to Length(Text) do
    124     if not (Text[i] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) then
    125       Result := False;
    126 end;
    127 
    128 function TParser.IsWhiteSpace(Character: char): boolean;
    129 begin
    130   Result := (Character = ' ') or (Character = #8);
    131 end;
    132 
    133 function TParser.IsKeyword(Text: string): Boolean;
     53{$R *.lfm}
     54
     55{ TFormMain }
     56
     57function TFormMain.IsKeyword(Text: string): Boolean;
    13458var
    13559  I: integer;
     
    14165end;
    14266
    143 {$R *.lfm}
    144 
    145 { TFormMain }
    146 
    147 function TFormMain.IsKeyword(Text: string): Boolean;
    148 var
    149   I: integer;
    150 begin
    151   Result := False;
    152   for I := 0 to High(Instructions) do
    153     if Instructions[I] = Text then
    154       Result := True;
    155 end;
    156 
    15767procedure TFormMain.ButtonConvertClick(Sender: TObject);
    15868var
     
    16171  Path := 'h:\Projekty\E341\Repository\trunk';
    16272  MainFile.LoadFromFile(Path + DirectorySeparator + 'main.a51');
    163   Parse(MainFile);
     73  Parser.Source := LowerCase(MainFile.Text);
     74  Parser.Position := 1;
     75  Output := '';
     76  Parse;
     77  MainFileOut.Text := Output;
    16478  ForceDirectoriesUTF8(Path + DirectorySeparator + 'C');
    16579  MainFileOut.SaveToFile(Path + DirectorySeparator + 'C' +
     
    17892procedure TFormMain.FormCreate(Sender: TObject);
    17993begin
     94  Parser := TParser.Create;
     95  Parser.OnError := Error;
    18096  MainFile := TStringList.Create;
    18197  MainFileOut := TStringList.Create;
     98  Macros := TStringList.Create;
    18299end;
    183100
    184101procedure TFormMain.FormDestroy(Sender: TObject);
    185102begin
     103  Macros.Free;
    186104  MainFileOut.Free;
    187105  MainFile.Free;
     106  Parser.Free;
    188107end;
    189108
     
    194113end;
    195114
    196 procedure TFormMain.Parse(List: TStringList);
     115procedure TFormMain.Emit(Text: string);
     116begin
     117  Output := Output + Text;
     118end;
     119
     120procedure TFormMain.Error(Text: string);
     121begin
     122  Emit('Error: ' + Text + LineEnding);
     123  Parser.Position := Length(Parser.Source) + 1;
     124end;
     125
     126procedure TFormMain.Parse;
    197127var
    198128  I: Integer;
     
    203133begin
    204134  with MainFileOut do begin
    205     Add('#include "opcodes.h"');
    206     Add('');
    207     Add('void main()');
    208     Add('{');
    209     Add('}');
    210     for I := 0 to List.Count - 1 do begin
    211       Line := Trim(List[I]);
    212       while Pos('  ', Line) > 0 do
    213         Line := StringReplace(Line, '  ', ' ', [rfReplaceAll]);
    214       if Pos(';', Line) > 0 then begin
    215         Comment := Trim(Copy(Line, Pos(';', Line) + 1, Length(Line)));
    216         Line := Trim(Copy(Line, 1, Pos(';', Line) - 1));
    217       end else Comment := '';
    218       if Length(Line) > 0 then Line := ParseLine(Line) + ' ';
    219       if Comment <> '' then Add(Line + '// ' + Comment)
    220         else Add(Line);
     135    while not Parser.Eof do begin
     136      ParseLine;
     137      if Parser.GetNext = 'end' then Break;
    221138    end;
    222139  end;
    223140end;
    224141
    225 function TFormMain.ParseLine(Line: string): string;
     142procedure TFormMain.ParseLine;
    226143var
    227144  Part: string;
     
    229146  Instruction: string;
    230147  Macro: string;
    231 begin
    232   if Line[1] = '$' then begin
    233     Part := Trim(Copy(Line, 2, Pos('(', Line) - 2));
    234     if LowerCase(Part) = 'include' then begin
    235       Line := Copy(Line, Pos('(', Line) + 1, Length(Line));
    236       Line := LowerCase(Copy(Line, 1, Pos(')', Line) - 1));
    237       Line := StringReplace(Line, '.i51', '.h', [rfReplaceAll]);
    238       //Result := '#include "' + Line + '"';
     148  Variable: string;
     149begin
     150  with Parser do begin
     151    if GetNext = '$' then begin
     152      Expect('$');
     153      if GetNext = 'include' then begin
     154        Expect('include');
     155        Expect('(');
     156        Emit('#include ''');
     157        Emit(ReadNext);
     158        Expect('.');
     159        Emit('.');
     160        Emit(ReadNext);
     161        Emit('''');
     162        Expect(')');
     163      end else Error('Unknown token "' + GetNext + '"');
     164    end
     165    else if GetNext = ')' then begin
     166      Expect(')');
     167      if GetNext = 'else' then begin
     168        Expect('else');
     169        Emit('#else ');
     170        Expect('(');
     171      end else
     172      if GetNext = 'fi' then begin
     173        Expect('fi');
     174        Emit('#endif ');
     175      end else Error('Unknown token "' + GetNext + '"');
     176    end
     177    else if ParseComment then
     178    else if ParseMacro then
     179    else if ParseKeywords then
     180    else if ParseInstruction then
     181    else if IsIdentificator(GetNext) then begin
     182      Variable := ReadNext;
     183      if GetNext = ':' then begin
     184        Expect(':');
     185        Emit(Variable + ':');
     186      end else
     187      if GetNext = 'equ' then begin
     188        Expect('equ');
     189        Emit('#define ' + Variable + ' ');
     190        ParseDbExpression;
     191        Emit(';');
     192      end else
     193      if GetNext = 'segment' then begin
     194        Expect('segment');
     195        ReadNext;
     196      end else Error('Unexpected token "' + Variable + '"');
     197    end
     198    else Error('Unexpected token "' + GetNext + '"');
     199    Emit(LineEnding);
     200  end;
     201end;
     202
     203function TFormMain.ParseMacro: Boolean;
     204var
     205  MacroName: string;
     206begin
     207  with Parser do begin
     208    if GetNext = '%' then begin
     209      Result := True;
     210      Expect('%');
     211      if GetNext = 'define' then begin
     212        Expect('define');
     213        Emit('#define ');
     214        Expect('(');
     215        MacroName := ReadNext;
     216        Emit(MacroName);
     217        Expect(')');
     218        Emit(' ');
     219        Expect('(');
     220        while GetNext <> ')' do begin
     221          Emit(ReadNext);
     222        end;
     223        Expect(')');
     224        Emit(';');
     225      end else
     226      if GetNext = 'if' then begin
     227        Expect('if');
     228        Emit('#if ');
     229        Expect('(');
     230        ParseIfExpression;
     231        Expect(')');
     232        Expect('then');
     233        Expect('(');
     234      end else Error('Unknown macro: ' + ReadNext);
     235    end else Result := False;
     236  end;
     237end;
     238
     239function TFormMain.ParseComment: Boolean;
     240begin
     241  with Parser do begin
     242    if GetNext = ';' then begin
     243      Result := True;
     244      Expect(';');
     245      Emit('//');
     246      Emit(ReadEol);
     247    end else Result := False;
     248  end;
     249end;
     250
     251function TFormMain.ParseMacroUsage: Boolean;
     252var
     253  MacroName: string;
     254begin
     255  with Parser do begin
     256    if GetNext = '%' then begin
     257      Result := True;
     258      Expect('%');
     259      MacroName := ReadNext;
     260      Emit(MacroName);
     261    end else Result := False;
     262  end;
     263end;
     264
     265function TFormMain.ParseKeywords: Boolean;
     266var
     267  Value: string;
     268begin
     269  with Parser do begin
     270    if GetNext = 'extrn' then begin
     271      Expect('extrn');
     272      Result := True;
     273      ReadNext;
     274      Expect('(');
     275      ReadNext;
     276      while GetNext = ',' do begin
     277        Expect(',');
     278        ReadNext;
     279      end;
     280      Expect(')');
     281    end else
     282    if GetNext = 'public' then begin
     283      Result := True;
     284      Expect('public');
     285      ReadNext;
     286      while GetNext = ',' do begin
     287        Expect(',');
     288        ReadNext;
     289      end;
     290    end else
     291    if GetNext = 'cseg' then begin
     292      Result := True;
     293      Expect('cseg');
     294      Expect('at');
     295      Value := ReadNext;
     296      if GetNext = 'h' then begin
     297        Expect('h');
     298        //Emit('0x' + Value);
     299      end; // else Emit(Value);
     300    end else
     301    if GetNext = 'rseg' then begin
     302      Result := True;
     303      Expect('rseg');
     304      Value := ReadNext;
     305      if GetNext = 'h' then begin
     306        Expect('h');
     307        //Emit('0x' + Value);
     308      end; // else Emit(Value);
     309    end else
     310    if GetNext = 'dbit' then begin
     311      Result := True;
     312      Expect('dbit');
     313      Emit('char ');
     314      Emit(ReadNext);
     315    end else
     316    if GetNext = 'db' then begin
     317      Result := True;
     318      Expect('db');
     319      Emit('char ');
     320      ParseDbExpression;
     321      while GetNext = ',' do begin
     322        Expect(',');
     323        Emit(',');
     324        ParseDbExpression;
     325      end;
     326    end else
     327    if GetNext = 'ds' then begin
     328      Result := True;
     329      Expect('ds');
     330      Emit('char* ');
     331      ParseDbExpression;
     332      while GetNext = ',' do begin
     333        Expect(',');
     334        Emit(',');
     335        ParseDbExpression;
     336      end;
     337    end else Result := False;
     338  end;
     339end;
     340
     341function TFormMain.ParseInstruction: Boolean;
     342begin
     343  with Parser do begin
     344    if GetNext = 'jmp' then begin
     345      Expect('jmp');
     346      Result := True;
     347      Emit('goto ');
     348      Emit(ReadNext);
     349      Emit(';');
     350    end else
     351    if GetNext = 'reti' then begin
     352      Result := True;
     353      Expect('reti');
     354    end else Result := False;
     355  end;
     356end;
     357
     358procedure TFormMain.ParseIfExpression;
     359begin
     360  with Parser do begin
     361    if ParseMacroUsage then
     362    else if IsNumber(GetNext) then Emit(ReadNext)
     363    else Error('Unknown IF parameter "' + GetNext + '"');
     364    if GetNext <> ')' then begin
     365      if GetNext = 'eq' then begin
     366        Expect('eq');
     367        Emit('= ');
     368      end else
     369      if GetNext = 'ne' then begin
     370        Expect('ne');
     371        Emit('!= ');
     372      end else
     373      if GetNext = 'gt' then begin
     374        Expect('gt');
     375        Emit('> ');
     376      end else
     377      if GetNext = 'ge' then begin
     378        Expect('ge');
     379        Emit('>= ');
     380      end else
     381      if GetNext = 'lt' then begin
     382        Expect('lt');
     383        Emit('< ');
     384      end else
     385      if GetNext = 'le' then begin
     386        Expect('le');
     387        Emit('<= ');
     388      end else
     389      Error('Unknown operand "' + ReadNext + '"');
     390      if ParseMacroUsage then
     391      else if IsNumber(GetNext) then Emit(ReadNext)
     392      else Error('Unknown IF parameter "' + GetNext + '"');
    239393    end;
    240   end else if Line[1] = '%' then begin
    241     Macro := Copy(Line, 2, Pos('(', Line) - 2);
    242     Line := Trim(Copy(Line, Pos('(', Line) + 1, Length(Line)));
    243     if Macro = 'IF' then OutLine := '#IF ' + Line
    244       else if Macro = 'FI' then OutLine := '#ENDIF ' + Line
    245       else if Macro = 'SET' then OutLine := '#DEFINE ' + Line
    246       else if Macro = 'DEFINE' then OutLine := '#DEFINE ' + Line
    247       else if Macro = '*DEFINE' then OutLine := '#DEFINE ' + Line
    248       else OutLine := '// !%' + Macro + ' ' + Line;
    249     Result := OutLine;
    250   end else begin
    251     if Pos(':', Line) > 0 then begin
    252       OutLine := Copy(Line, 1, Pos(':', Line) - 1) + ': ';
    253       Line := Trim(Copy(Line, Pos(':', Line) + 1, Length(Line)));
    254     end else OutLine := '';
    255 
    256     if Pos(' ', Line) > 0 then begin
    257       Instruction := Copy(Line, 1, Pos(' ', Line) - 1);
    258       Line := Trim(Copy(Line, Pos(' ', Line) + 1, Length(Line)));
    259     end else begin
    260       Instruction := Line;
    261       Line := '';
     394  end;
     395end;
     396
     397procedure TFormMain.ParseDbExpression;
     398begin
     399  with Parser do begin
     400
     401    if ParseMacroUsage then
     402    else if GetNext = '$' then begin
     403      Expect('$');
     404      Emit('$');
     405    end
     406    else if GetNext = '(' then begin
     407      Expect('(');
     408      Emit('(');
     409      ParseDbExpression;
     410      Expect(')');
     411      Emit(')');
     412    end
     413    else if GetNext = '''' then Emit('"' + ParseString + '"')
     414    else if IsNumber(GetNext) then Emit(ReadNext)
     415    else if IsIdentificator(GetNext) then Emit(ReadNext)
     416    else Error('Unknown IF parameter "' + GetNext + '"');
     417
     418    if GetNext = '+' then begin
     419      Expect('+');
     420      Emit('+');
     421      ParseDbExpression;
     422    end else
     423    if GetNext = '-' then begin
     424      Expect('-');
     425      Emit('-');
     426      ParseDbExpression;
     427    end else
     428    if GetNext = '*' then begin
     429      Expect('*');
     430      Emit('*');
     431      ParseDbExpression;
     432    end else
     433    if GetNext = '/' then begin
     434      Expect('/');
     435      Emit('/');
     436      ParseDbExpression;
    262437    end;
    263     if IsKeyWord(Instruction) then OutLine := OutLine + Instruction + '(' + Line + ');'
    264       else if Trim(Instruction) = '' then
    265       else OutLine := OutLine + '// !' + Instruction + ' ' + Line;
    266     Result := OutLine;
     438  end;
     439end;
     440
     441function TFormMain.ParseString: string;
     442begin
     443  with Parser do begin
     444    Result := '';
     445    Expect('''');
     446    while GetNext <> '''' do begin
     447      Result := Result + ReadNext;
     448    end;
     449    Expect('''');
    267450  end;
    268451end;
Note: See TracChangeset for help on using the changeset viewer.