Ignore:
Timestamp:
Oct 18, 2010, 12:39:37 PM (15 years ago)
Author:
george
Message:
  • Fixed: Parsing of strings.
  • Modified: Now supported C target "Dynamic C" dialect.
Location:
branches/Transpascal/Compiler
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/Transpascal/Compiler/Analyze/UParser.pas

    r65 r67  
    1111type
    1212  TOnErrorMessage = procedure(Text: string; Position: TPoint; FileName: string) of object;
     13
     14  TParserState = (psNone, psIdentifier, psConstantNumber, psConstantString,
     15    psOperator, psEndOfFile, psLineComment, psBlockComment1, psBlockComment2,
     16    psUnknown, psWhiteSpace, psConstantStringEnd);
    1317
    1418  TTokenType = (ttNone, ttIdentifier, ttConstantNumber, ttConstantString,
     
    2529    FNextToken: string;
    2630    FNextTokenType: TTokenType;
     31    FParserState: TParserState;
    2732    PreviousChar: char;
    2833    CurrentChar: char;
     
    3641    function ReadCode: string;
    3742    function NextToken: string;
     43    function NextTokenType: TTokenType;
    3844    procedure Expect(Code: string);
    3945    function IsWhiteSpace(Character: char): boolean;
     
    216222  FNextToken := '';
    217223  FNextTokenType := ttNone;
     224  FParserState := psNone;
    218225  with SourceCodeText do
    219226    while True do
    220227    begin
    221       if CodeStreamPosition < Length(Text) then
    222       begin
     228      if CodeStreamPosition < Length(Text) then begin
    223229        CurrentChar := Text[CodeStreamPosition];
    224       end
    225       else
    226       begin
     230      end else begin
    227231        FNextToken := '';
     232        FParserState := psEndOfFile;
    228233        FNextTokenType := ttEndOfFile;
    229234        Break;
    230235      end;
    231236
    232       if FNextTokenType = ttNone then
    233       begin
     237      if FParserState = psNone then begin
    234238        if IsWhiteSpace(CurrentChar) then
    235           FNextTokenType := ttWhiteSpace
     239          FParserState := psWhiteSpace
    236240        else
    237         if CurrentChar = '{' then
    238         begin
    239           FNextTokenType := ttBlockComment1;
    240         end
    241         else
    242         if CurrentChar = '''' then
    243         begin
    244           FNextTokenType := ttConstantString;
    245         end
    246         else
    247         if CurrentChar in SpecChar then
    248         begin
    249           FNextTokenType := ttOperator;
     241        if CurrentChar = '{' then begin
     242          FParserState := psBlockComment1;
     243        end else
     244        if CurrentChar = '''' then begin
     245          FParserState := psConstantString;
     246        end else
     247        if CurrentChar in SpecChar then begin
     248          FParserState := psOperator;
    250249          FNextToken := FNextToken + CurrentChar;
    251         end
    252         else
    253         if IsAlphanumeric(CurrentChar) then
    254         begin
    255           FNextTokenType := ttIdentifier;
     250        end else
     251        if IsAlphanumeric(CurrentChar) then begin
     252          FParserState := psIdentifier;
    256253          FNextToken := FNextToken + CurrentChar;
    257         end
    258         else
    259           FNextTokenType := ttUnknown;
    260       end
    261       else
    262       if FNextTokenType = ttLineComment then
    263       begin
     254        end else FParserState := psUnknown;
     255      end else
     256      if FParserState = psLineComment then begin
    264257        if (CurrentChar = #13) or (CurrentChar = #10) then
    265           FNextTokenType := ttNone;
    266       end
    267       else
    268       if FNextTokenType = ttBlockComment1 then
    269       begin
     258          FParserState := psNone;
     259      end else
     260      if FParserState = psBlockComment1 then begin
    270261        if (CurrentChar = '}') then
    271           FNextTokenType := ttNone;
    272       end
    273       else
    274       if FNextTokenType = ttBlockComment2 then
    275       begin
     262          FParserState := psNone;
     263      end else
     264      if FParserState = psBlockComment2 then begin
    276265        if (PreviousChar = '*') and (CurrentChar = ')') then
    277           FNextTokenType := ttNone;
    278       end
    279       else
    280       if FNextTokenType = ttConstantString then
    281       begin
    282         if (CurrentChar = '''') and (PreviousChar = '''') then
    283           Break
    284         else
    285           FNextToken := FNextToken + CurrentChar;
    286       end
    287       else
    288       if FNextTokenType = ttOperator then
     266          FParserState := psNone;
     267      end else
     268      if FParserState = psConstantString then
     269      begin
     270        if (CurrentChar = '''') then begin
     271          FParserState := psConstantStringEnd;
     272        end else FNextToken := FNextToken + CurrentChar;
     273      end else
     274      if FParserState = psConstantStringEnd then
     275      begin
     276        if (CurrentChar = '''') then begin
     277          FParserState := psConstantString;
     278        end else FParserState := psNone;
     279        FNextTokenType := ttConstantString;
     280        Break;
     281      end else
     282      if FParserState = psOperator then
    289283      begin
    290284        if (CurrentChar = '*') and (PreviousChar = '(') then
    291285        begin
    292286          FNextToken := '';
    293           FNextTokenType := ttBlockComment2;
    294         end
    295         else
     287          FParserState := psBlockComment2;
     288        end else
    296289        if (CurrentChar = '/') and (PreviousChar = '/') then
    297290        begin
    298291          FNextToken := '';
    299           FNextTokenType := ttLineComment;
     292          FParserState := psLineComment;
     293        end else
     294        if not (CurrentChar in SpecChar) then begin
     295          FNextTokenType := ttOperator;
     296          Break;
    300297        end
    301         else
    302         if not (CurrentChar in SpecChar) then
    303           Break
    304         else
    305         begin
     298        else begin
    306299          J := 0;
    307300          while (J < Length(DoubleSpecChar)) and
     
    310303          if J < Length(DoubleSpecChar) then
    311304            FNextToken := FNextToken + CurrentChar
    312           else
     305          else begin
     306            FNextTokenType := ttOperator;
    313307            Break;
    314         end;
     308          end;
     309        end;
     310      end else
     311      if FParserState = psIdentifier then
     312      begin
     313        if not IsAlphanumeric(CurrentChar) then begin
     314          FNextTokenType := ttIdentifier;
     315          Break;
     316        end else FNextToken := FNextToken + CurrentChar;
    315317      end
    316318      else
    317       if FNextTokenType = ttIdentifier then
    318       begin
    319         if not IsAlphanumeric(CurrentChar) then
    320           Break
    321         else
    322           FNextToken := FNextToken + CurrentChar;
    323       end
    324       else if FNextTokenType = ttWhiteSpace then
    325         FNextTokenType := ttNone;
    326 
    327       if FNextTokenType <> ttNone then
    328       begin
     319      if FParserState = psWhiteSpace then begin
     320        FParserState := psNone;
     321      end;
     322
     323      if FParserState <> psNone then begin
    329324        // Update cursor position
    330325        Inc(CodePosition.X);
    331         if (CurrentChar = #13) then
    332         begin
     326        if (CurrentChar = #13) then begin
    333327          CodePosition.X := 1;
    334328          Inc(CodePosition.Y);
     
    351345begin
    352346  Result := FNextToken;
     347end;
     348
     349function TBaseParser.NextTokenType: TTokenType;
     350begin
     351  Result := FNextTokenType;
    353352end;
    354353
     
    397396var
    398397  Identifier: string;
     398  IdentifierType: TTokenType;
    399399  NewVariable: TVariable;
    400400  NewExpression: TExpression;
     
    409409  Expressions.Add(TExpression.Create);
    410410  with SourceCode do begin
    411     while ((FNextToken <> ';') and (FNextToken <> ',') and
    412         (not IsKeyWord(FNextToken))) and not
    413       (((FNextToken = ')') or (FNextToken = ']'))) do begin
     411    while ((NextToken <> ';') and (NextToken <> ',') and (not IsKeyWord(NextToken))) and not
     412      (((NextToken = ')') or (NextToken = ']'))) and not (NextTokenType = ttEndOfFile) do begin
     413      IdentifierType := NextTokenType;
    414414      Identifier := ReadCode;
    415415      if Identifier = '(' then begin
     
    506506          TExpression(SubItems[1]).NodeType := ntConstant;
    507507
    508           if Identifier[1] = '''' then begin
     508          if IdentifierType = ttConstantString then begin
    509509            TExpression(SubItems[1]).Value := Identifier;
    510510            //SetLength(TExpression(SubItems[1]).Value, Length(Identifier));
     
    512512            //  TExpression(SubItems[1]).Value[I - 1] := Byte(Identifier[I]);
    513513          end else begin
    514             TExpression(SubItems[1]).Value := Identifier;
     514            TExpression(SubItems[1]).Value := StrToInt(Identifier);
    515515          end;
    516516        end;
  • branches/Transpascal/Compiler/Produce/UProducerC.pas

    r60 r67  
    1010
    1111type
     12
     13  TProducerCDialect = (pdGCC, pdDynamicC);
    1214
    1315  { TProducerC }
     
    3537    function GenerateExpression(Expression: TExpression): string;
    3638  public
     39    Dialect: TProducerCDialect;
    3740    TextSource: TStringList;
    3841    IndentationLength: Integer;
     
    5356  FileExtension := '.c';
    5457  IndentationLength := 2;
     58  Dialect := pdDynamicC;
    5559end;
    5660
     
    104108begin
    105109  for I := 0 to UsedModules.Count - 1 do
    106     Emit('#include "' + TUsedModule(UsedModules[I]).Name + '.h"');
     110    if Dialect = pdDynamicC then
     111      Emit('#use "' + TUsedModule(UsedModules[I]).Name + '.lib"')
     112      else Emit('#include "' + TUsedModule(UsedModules[I]).Name + '.h"');
    107113  Emit('');
    108114end;
     
    110116procedure TProducerC.GenerateModule(Module: TModule);
    111117begin
    112   Emit('#define int8 char');
    113   Emit('#define int16 int');
    114   Emit('#define int32 long');
    115   Emit('#define uint8 unsigned char');
    116   Emit('#define uint16 unsigned int');
    117   Emit('#define uint32 unsigned long');
     118  if Dialect = pdDynamicC then Emit('#use "platform.lib"')
     119    else Emit('#include "platform.h"');
    118120  Emit('');
    119121  if Module is TModuleProgram then begin
     122    TModuleProgram(Module).Body.Name := 'main';
    120123    GenerateUses(TModuleProgram(Module).UsedModules);
    121124    GenerateCommonBlock(TModuleProgram(Module).Body, '');
     
    253256begin
    254257  case Expression.NodeType of
    255     ntConstant: Result := Expression.Value;
     258    ntConstant: begin
     259      if VarType(Expression.Value) = varString then
     260        Result := '"' + Expression.Value + '"'
     261        else Result := Expression.Value;
     262    end;
    256263    ntVariable: Result := Expression.Variable.Name;
    257264    ntFunction: Result := Expression.Method.Name;
  • branches/Transpascal/Compiler/UCompiler.pas

    r64 r67  
    4545    destructor Destroy; override;
    4646    procedure Init;
    47     procedure Compile(ModuleName: string; Source: TStringList);
     47    procedure Compile(ModuleName: string; Source: TStringList; TargetFolder: string);
    4848    property OnErrorMessage: TOnErrorMessage read FOnErrorMessage
    4949      write FOnErrorMessage;
     
    5454{ TCompiler }
    5555
    56 procedure TCompiler.Compile(ModuleName: string; Source: TStringList);
     56procedure TCompiler.Compile(ModuleName: string; Source: TStringList;
     57  TargetFolder: string);
    5758var
    5859  NewModule: TModule;
     
    7071      Producer.Produce(TModule(ProgramCode.Modules[I]));
    7172      Producer.AssignToStringList(ProducedCode);
    72       ForceDirectories(CompiledFolder + DirectorySeparator + Producer.ClassName);
    73       ProducedCode.SaveToFile(CompiledFolder + DirectorySeparator + Producer.ClassName +
     73      ForceDirectories(TargetFolder + DirectorySeparator +
     74        CompiledFolder + DirectorySeparator + Producer.ClassName);
     75      ProducedCode.SaveToFile(TargetFolder + DirectorySeparator +
     76        CompiledFolder + DirectorySeparator + Producer.ClassName +
    7477        DirectorySeparator + TModule(ProgramCode.Modules[I]).Name + Producer.FileExtension);
    7578    end;
Note: See TracChangeset for help on using the changeset viewer.