Ignore:
Timestamp:
Oct 15, 2012, 2:10:48 PM (12 years ago)
Author:
chronos
Message:
  • Upraveno: Překlad rozdělen do fáze zpracování maker a druhé fáze zpracování instrukcí.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/AS8051toC/UMainForm.pas

    r25 r26  
    88  Classes, SysUtils, FileUtil, SynHighlighterCpp, SynEdit, SynMemo,
    99  SynHighlighterAny, SynHighlighterPas, Forms, Controls, Graphics, Dialogs,
    10   StdCtrls, UParser;
     10  StdCtrls, UParser, UCompiler;
    1111
    1212type
     
    2727    procedure FormShow(Sender: TObject);
    2828  private
    29     Parser: TParserASM51;
    3029  public
    3130    MainFile: TStringList;
    3231    MainFileOut: TStringList;
    33     Output: string;
    3432    Macros: TStringList;
    35     function IsHexNumber(Text: string): Boolean;
    36     function CheckInstructionParameter: Boolean;
    37     procedure Emit(Text: string);
     33    Compiler: TCompiler;
     34    CompilerMacro: TCompilerMacro;
    3835    procedure Error(Text: string);
    39     procedure Parse;
    40     procedure ParseLine;
    41     function ParseMacro: Boolean;
    42     function ParseComment: Boolean;
    43     function ParseMacroUsage: Boolean;
    44     function ParseKeywords: Boolean;
    45     function ParseInstruction: Boolean;
    46     procedure ParseIfExpression;
    47     procedure ParseDbExpression;
    48     function ParseString: string;
    4936  end;
    5037
     
    7158begin
    7259  MainFile.LoadFromFile(EditPath.Text);
    73   Parser.Source := LowerCase(MainFile.Text);
    74   Parser.Position := 1;
    75   Output := '';
    76   Parse;
    77   MainFileOut.Text := Output;
     60  MainFileOut.Text := CompilerMacro.Compile(MainFile.Text);
     61  MainFileOut.Text := Compiler.Compile(MainFileOut.Text);
    7862  ForceDirectoriesUTF8(ExtractFileDir(EditPath.Text) + DirectorySeparator + 'C');
    7963  MainFileOut.SaveToFile(ExtractFileDir(EditPath.Text) + DirectorySeparator + 'C' +
     
    9478procedure TFormMain.FormCreate(Sender: TObject);
    9579begin
    96   Parser := TParserASM51.Create;
    97   Parser.OnError := Error;
    9880  MainFile := TStringList.Create;
    9981  MainFileOut := TStringList.Create;
    100   Macros := TStringList.Create;
     82  CompilerMacro := TCompilerMacro.Create;
     83  CompilerMacro.Parser.OnError := Error;
     84  Compiler := TCompiler.Create;
     85  Compiler.Parser.OnError := Error;
    10186end;
    10287
    10388procedure TFormMain.FormDestroy(Sender: TObject);
    10489begin
    105   Macros.Free;
    106   MainFileOut.Free;
    107   MainFile.Free;
    108   Parser.Free;
     90  FreeAndNil(MainFile);
     91  FreeAndNil(MainFileOut);
     92  FreeAndNil(CompilerMacro);
     93  FreeAndNil(Compiler);
    10994end;
    11095
     
    115100end;
    116101
    117 function TFormMain.IsHexNumber(Text: string): Boolean;
     102procedure TFormMain.Error(Text: string);
    118103begin
    119   Result := (LowerCase(Copy(Text, Length(Text), 1)) = 'h') and
    120     (Parser.IsHexNumber(Copy(Text, 1, Length(Text) - 1)));
     104  Compiler.Emit('Error: ' + Text + LineEnding);
     105  Compiler.Parser.Position := Length(Compiler.Parser.Source) + 1;
    121106end;
    122107
    123 function TFormMain.CheckInstructionParameter: Boolean;
    124 begin
    125   Text := Parser.GetNext;
    126   Result := False;
    127   if Parser.IsNumber(Text) then Result := True
    128   else if Text = '#' then begin
    129     Result := True;
    130     Parser.Expect('#');
    131     if IsHexNumber(Parser.GetNext) then Emit(Parser.ReadNext)
    132     else if Parser.IsNumber(Parser.GetNext) then Emit(Parser.ReadNext)
    133     else Error('Invalid parameter');
    134   end
    135   else if Copy(Text, 1, 1) = '@' then begin
    136     if IsHexNumber(Copy(Text, 2, Length(Text))) then Result := True;
    137     Emit(Parser.ReadNext);
    138   end;
    139 end;
    140108
    141 procedure TFormMain.Emit(Text: string);
    142 begin
    143   Output := Output + Text;
    144 end;
    145 
    146 procedure TFormMain.Error(Text: string);
    147 begin
    148   Emit('Error: ' + Text + LineEnding);
    149   Parser.Position := Length(Parser.Source) + 1;
    150 end;
    151 
    152 procedure TFormMain.Parse;
    153 var
    154   I: Integer;
    155   Line: string;
    156   Part: string;
    157   Comment: string;
    158   OutLine: string;
    159 begin
    160   with MainFileOut do begin
    161     while not Parser.Eof do begin
    162       ParseLine;
    163       if Parser.GetNext = 'end' then Break;
    164     end;
    165   end;
    166 end;
    167 
    168 procedure TFormMain.ParseLine;
    169 var
    170   Part: string;
    171   OutLine: string;
    172   Instruction: string;
    173   Macro: string;
    174   Variable: string;
    175 begin
    176   with Parser do begin
    177     if GetNext = '$' then begin
    178       Expect('$');
    179       if GetNext = 'include' then begin
    180         Expect('include');
    181         Expect('(');
    182         Emit('#include ''');
    183         Emit(ReadNext);
    184         Expect('.');
    185         Emit('.');
    186         Emit(ReadNext);
    187         Emit('''');
    188         Expect(')');
    189       end else Error('Unknown token "' + GetNext + '"');
    190     end
    191     else if GetNext = ')' then begin
    192       Expect(')');
    193       if GetNext = 'else' then begin
    194         Expect('else');
    195         Emit('#else ');
    196         Expect('(');
    197       end else
    198       if GetNext = 'fi' then begin
    199         Expect('fi');
    200         Emit('#endif ');
    201       end; // else Error('Unknown token "' + GetNext + '"');
    202     end
    203     else if ParseComment then
    204     else if ParseKeywords then
    205     else if ParseInstruction then
    206     else if IsIdentificator(GetNext) then begin
    207       Variable := ReadNext;
    208       if GetNext = '%' then begin
    209         Expect('%');
    210         Variable := Variable + '##' + ReadNext;
    211       end;
    212       if GetNext = ':' then begin
    213         Expect(':');
    214         Emit(Variable + ':');
    215       end else
    216       if GetNext = 'equ' then begin
    217         Expect('equ');
    218         Emit('#define ' + Variable + ' ');
    219         ParseDbExpression;
    220         Emit(';');
    221       end else
    222       if GetNext = 'segment' then begin
    223         Expect('segment');
    224         ReadNext;
    225       end else Error('Unexpected token "' + Variable + '"');
    226     end
    227     else if ParseMacro then
    228     else if ParseMacroUsage then
    229     else Error('Unexpected token "' + GetNext + '"');
    230     Emit(LineEnding);
    231   end;
    232 end;
    233 
    234 function TFormMain.ParseMacro: Boolean;
    235 var
    236   MacroName: string;
    237   OldPos: Integer;
    238 begin
    239   with Parser do begin
    240     OldPos := Position;
    241     if GetNext = '%' then begin
    242       Result := True;
    243       Expect('%');
    244       if GetNext = 'define' then begin
    245         Expect('define');
    246         Emit('#define ');
    247         Expect('(');
    248         MacroName := ReadNext;
    249         Emit(MacroName);
    250         Expect(')');
    251         Emit(' ');
    252         Expect('(');
    253         while GetNext <> ')' do begin
    254           Emit(ReadNext);
    255         end;
    256         Expect(')');
    257         Emit(';');
    258       end else
    259       if GetNext = 'if' then begin
    260         Expect('if');
    261         Emit('#if ');
    262         Expect('(');
    263         ParseIfExpression;
    264         Expect(')');
    265         Expect('then');
    266         Expect('(');
    267       end else
    268       if GetNext = 'set' then begin
    269         Expect('set');
    270         Emit('#define ');
    271         Expect('(');
    272         Emit(ReadNext + ' ');
    273         Expect(',');
    274         ParseDbExpression;
    275         Expect(')');
    276         Emit(';');
    277       end else
    278       if GetNext = '*' then begin
    279         Expect('*');
    280         if GetNext = 'define' then begin
    281           Expect('define');
    282           Emit('#define ');
    283           Expect('(');
    284           Emit(ReadNext);
    285           Expect('(');
    286           Emit('(' + ReadNext);
    287           while GetNext = ',' do begin
    288             Expect(',');
    289             Emit(', ' + ReadNext);
    290           end;
    291           Expect(')');
    292           Emit(')');
    293           Expect(')');
    294           if GetNext = 'local' then begin
    295             Expect('local');
    296             ReadNext;
    297           end;
    298           Expect('(');
    299         end;
    300       end else begin
    301         Position := OldPos;
    302         Result := False;
    303       end;
    304     end else Result := False;
    305   end;
    306 end;
    307 
    308 function TFormMain.ParseComment: Boolean;
    309 begin
    310   with Parser do begin
    311     if GetNext = ';' then begin
    312       Result := True;
    313       Expect(';');
    314       Emit('//');
    315       Emit(ReadEol);
    316     end else Result := False;
    317   end;
    318 end;
    319 
    320 function TFormMain.ParseMacroUsage: Boolean;
    321 var
    322   MacroName: string;
    323 begin
    324   with Parser do begin
    325     if GetNext = '%' then begin
    326       Result := True;
    327       Expect('%');
    328       MacroName := ReadNext;
    329       Emit(MacroName);
    330       if GetNext = '(' then begin
    331         Expect('(');
    332         Emit('(');
    333         ParseDbExpression;
    334         //else Emit(ReadNext);
    335         while GetNext = ',' do begin
    336           Expect(',');
    337           Emit(',');
    338           ParseDbExpression;
    339           //if ParseMacroUsage then
    340           //else if GetNext <> ')' then Emit(ReadNext);
    341         end;
    342         Emit(')');
    343         Expect(')');
    344       end;
    345     end else Result := False;
    346   end;
    347 end;
    348 
    349 function TFormMain.ParseKeywords: Boolean;
    350 var
    351   Value: string;
    352 begin
    353   with Parser do begin
    354     if GetNext = 'extrn' then begin
    355       Expect('extrn');
    356       Result := True;
    357       ReadNext;
    358       Expect('(');
    359       ReadNext;
    360       while GetNext = ',' do begin
    361         Expect(',');
    362         ReadNext;
    363       end;
    364       Expect(')');
    365     end else
    366     if GetNext = 'public' then begin
    367       Result := True;
    368       Expect('public');
    369       ReadNext;
    370       while GetNext = ',' do begin
    371         Expect(',');
    372         ReadNext;
    373       end;
    374     end else
    375     if GetNext = 'using' then begin
    376       Result := True;
    377       Expect('using');
    378       Value := ReadNext;
    379       Emit('// using reg bank ' + Value);
    380     end else
    381     if GetNext = 'cseg' then begin
    382       Result := True;
    383       Expect('cseg');
    384       Expect('at');
    385       Value := ReadNext;
    386       if GetNext = 'h' then begin
    387         Expect('h');
    388         //Emit('0x' + Value);
    389       end; // else Emit(Value);
    390     end else
    391     if GetNext = 'rseg' then begin
    392       Result := True;
    393       Expect('rseg');
    394       Value := ReadNext;
    395       if GetNext = 'h' then begin
    396         Expect('h');
    397         //Emit('0x' + Value);
    398       end; // else Emit(Value);
    399     end else
    400     if GetNext = 'dbit' then begin
    401       Result := True;
    402       Expect('dbit');
    403       Emit('char ');
    404       Emit(ReadNext);
    405     end else
    406     if GetNext = 'db' then begin
    407       Result := True;
    408       Expect('db');
    409       Emit('char ');
    410       ParseDbExpression;
    411       while GetNext = ',' do begin
    412         Expect(',');
    413         Emit(',');
    414         ParseDbExpression;
    415       end;
    416     end else
    417     if GetNext = 'dw' then begin
    418       Result := True;
    419       Expect('dw');
    420       Emit('char ');
    421       ParseDbExpression;
    422       while GetNext = ',' do begin
    423         Expect(',');
    424         Emit(',');
    425         ParseDbExpression;
    426       end;
    427     end else
    428     if GetNext = 'ds' then begin
    429       Result := True;
    430       Expect('ds');
    431       Emit('char* ');
    432       ParseDbExpression;
    433       while GetNext = ',' do begin
    434         Expect(',');
    435         Emit(',');
    436         ParseDbExpression;
    437       end;
    438     end else Result := False;
    439   end;
    440 end;
    441 
    442 function TFormMain.ParseInstruction: Boolean;
    443 begin
    444   with Parser do begin
    445     if GetNext = 'jmp' then begin
    446       Expect('jmp');
    447       Result := True;
    448       Emit('goto ');
    449       Emit(ReadNext);
    450       Emit(';');
    451     end else
    452     if GetNext = 'mov' then begin
    453       Expect('mov');
    454       Result := True;
    455       Emit('MOV(');
    456       ParseDbExpression;
    457       Expect(',');
    458       Emit(',');
    459       ParseDbExpression;
    460       Emit(');');
    461     end else
    462     if GetNext = 'reti' then begin
    463       Result := True;
    464       Expect('reti');
    465     end else Result := False;
    466   end;
    467 end;
    468 
    469 procedure TFormMain.ParseIfExpression;
    470 begin
    471   with Parser do begin
    472     if ParseMacroUsage then
    473     else if IsNumber(GetNext) then Emit(ReadNext)
    474     else Error('Unknown IF parameter "' + GetNext + '"');
    475     if GetNext <> ')' then begin
    476       if GetNext = 'eq' then begin
    477         Expect('eq');
    478         Emit('= ');
    479       end else
    480       if GetNext = 'ne' then begin
    481         Expect('ne');
    482         Emit('!= ');
    483       end else
    484       if GetNext = 'gt' then begin
    485         Expect('gt');
    486         Emit('> ');
    487       end else
    488       if GetNext = 'ge' then begin
    489         Expect('ge');
    490         Emit('>= ');
    491       end else
    492       if GetNext = 'lt' then begin
    493         Expect('lt');
    494         Emit('< ');
    495       end else
    496       if GetNext = 'le' then begin
    497         Expect('le');
    498         Emit('<= ');
    499       end else
    500       if GetNext = 'or' then begin
    501         Expect('or');
    502         Emit('|| ');
    503       end else
    504       if GetNext = 'and' then begin
    505         Expect('and');
    506         Emit('&& ');
    507       end else
    508         Error('Unknown operand "' + ReadNext + '"');
    509       if ParseMacroUsage then
    510       else if IsNumber(GetNext) then Emit(ReadNext)
    511       else Error('Unknown IF parameter "' + GetNext + '"');
    512     end;
    513   end;
    514 end;
    515 
    516 procedure TFormMain.ParseDbExpression;
    517 begin
    518   with Parser do begin
    519 
    520     if ParseMacroUsage then
    521     else if GetNext = '$' then begin
    522       Expect('$');
    523       Emit('$');
    524     end
    525     else if GetNext = '(' then begin
    526       Expect('(');
    527       Emit('(');
    528       ParseDbExpression;
    529       Expect(')');
    530       Emit(')');
    531     end
    532     else if GetNext = '''' then Emit('"' + ParseString + '"')
    533     else if CheckInstructionParameter then
    534     else if IsIdentificator(GetNext) then begin
    535       Emit(ReadNext);
    536       if ParseMacroUsage then ;
    537     end else Error('Unknown IF parameter "' + GetNext + '"');
    538 
    539     if GetNext = '+' then begin
    540       Expect('+');
    541       Emit('+');
    542       ParseDbExpression;
    543     end else
    544     if GetNext = '-' then begin
    545       Expect('-');
    546       Emit('-');
    547       ParseDbExpression;
    548     end else
    549     if GetNext = '*' then begin
    550       Expect('*');
    551       Emit('*');
    552       ParseDbExpression;
    553     end else
    554     if GetNext = '/' then begin
    555       Expect('/');
    556       Emit('/');
    557       ParseDbExpression;
    558     end else
    559     if GetNext = 'shl' then begin
    560       Expect('shl');
    561       Emit('<< ');
    562       ParseDbExpression;
    563     end else
    564     if GetNext = 'shr' then begin
    565       Expect('shr');
    566       Emit('>> ');
    567       ParseDbExpression;
    568     end else
    569     if GetNext = 'or' then begin
    570       Expect('or');
    571       Emit('|| ');
    572       ParseDbExpression;
    573     end else
    574     if GetNext = 'and' then begin
    575       Expect('and');
    576       Emit('&& ');
    577       ParseDbExpression;
    578     end;
    579   end;
    580 end;
    581 
    582 function TFormMain.ParseString: string;
    583 begin
    584   with Parser do begin
    585     Result := '';
    586     Expect('''');
    587     while GetNext <> '''' do begin
    588       Result := Result + ReadNext;
    589     end;
    590     Expect('''');
    591   end;
    592 end;
    593109
    594110end.
Note: See TracChangeset for help on using the changeset viewer.