Changeset 6 for trunk/Compiler


Ignore:
Timestamp:
Nov 5, 2010, 11:31:04 AM (14 years ago)
Author:
george
Message:
  • Added: Typecasting support.
  • Fixed: Function call in expressions.
  • Added: Producer module specify generated file name, extension and placing.
Location:
trunk/Compiler
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Compiler/Analyze/UPascalParser.pas

    r5 r6  
    2727      Expressions: TListExpression): Boolean;
    2828    function ParseExpressionFunctionCall(SourceCode: TExpression;
    29       Expressions: TListExpression; var Func: TFunction): Boolean;
     29      Expressions: TListExpression; var Func: TFunctionCall): Boolean;
    3030    function ParseUses(SourceCode: TUsedModuleList; AExported: Boolean): Boolean;
    3131    function ParseModule(ProgramCode: TProgram): TModule;
     
    225225  UseConstant: TConstant;
    226226  UseFunction: TFunction;
     227  FunctionCall: TFunctionCall;
    227228  NewExpression: TExpression;
    228229  Identifier: string;
     
    236237    if Assigned(UseType) then begin
    237238      ReadToken;
     239      if NextToken = '(' then begin
     240        Expect('(');
     241        // Typecasting
     242        NewExpression := TExpression.Create;
     243        NewExpression.CommonBlock := SourceCode.CommonBlock;
     244        NewExpression.NodeType := ntTypecast;
     245        NewExpression.UseType := UseType;
     246        ParseExpression(NewExpression);
     247        Expect(')');
     248      end else
    238249      if (UseType is TTypeRecord) or (UseType is TTypeClass) then begin
    239         // type.variable or type.function
     250        // Type context
    240251        Expect('.');
    241252        Identifier := ReadToken;
    242253        UseVariable := TTypeRecord(UseType).CommonBlock.Variables.Search(Identifier);
    243254        if Assigned(UseVariable) then begin
     255          // Record or class variable
    244256          NewExpression := TExpression.Create;
    245257          NewExpression.CommonBlock := SourceCode.CommonBlock;
     
    250262          UseFunction := TTypeRecord(UseType).CommonBlock.Functions.Search(Identifier);
    251263          if Assigned(UseFunction) then begin
     264            // Record or class functions
     265            ParseExpressionFunctionCall(SourceCode, Expressions, FunctionCall);
    252266            NewExpression := TExpression.Create;
    253267            NewExpression.CommonBlock := SourceCode.CommonBlock;
    254268            NewExpression.NodeType := ntFunction;
    255             NewExpression.FunctionCall := UseFunction;
     269            NewExpression.FunctionCall := FunctionCall;
    256270          end;
    257271        end;
     
    273287    if not Assigned(NewExpression) then begin
    274288      // Function call
    275       ParseExpressionFunctionCall(SourceCode, Expressions, UseFunction);
    276       if Assigned(UseFunction) then begin
     289      ParseExpressionFunctionCall(SourceCode, Expressions, FunctionCall);
     290      if Assigned(FunctionCall) then begin
    277291        NewExpression := TExpression.Create;
    278292        NewExpression.CommonBlock := SourceCode.CommonBlock;
    279293        NewExpression.NodeType := ntFunction;
    280         NewExpression.FunctionCall := UseFunction;
     294        NewExpression.FunctionCall := FunctionCall;
    281295      end;
    282296    end;
     
    319333
    320334function TPascalParser.ParseExpressionFunctionCall(SourceCode: TExpression;
    321   Expressions: TListExpression; var Func: TFunction): Boolean;
     335  Expressions: TListExpression; var Func: TFunctionCall): Boolean;
    322336var
    323337  UseFunction: TFunction;
     338  NewExpression: TExpression;
     339  I: Integer;
    324340begin
    325341  Func := nil;
     
    328344    if Assigned(UseFunction) then begin
    329345      ReadToken;
    330       Func := UseFunction;
     346      Func := TFunctionCall.Create;
     347      Func.CommonBlock := SourceCode.CommonBlock;
     348      Func.FunctionRef := UseFunction;
    331349      if NextToken = '(' then begin
    332350        Expect('(');
    333         while NextToken = ',' do begin
    334           Expect(',');
    335           Expect(')');
    336         end;
     351        for I := 0 to Func.FunctionRef.Parameters.Count - 1 do begin
     352          if I > 0 then Expect(',');
     353          NewExpression := TExpression.Create;
     354          NewExpression.CommonBlock := SourceCode.CommonBlock;
     355          ParseExpression(NewExpression);
     356          Func.ParameterExpression.Add(NewExpression);
     357        end;
     358        Expect(')');
    337359      end;
    338360      Result := True;
  • trunk/Compiler/Produce/UProducer.pas

    r2 r6  
    1010type
    1111  TProducer = class
    12     FileExtension: string;
    1312    procedure AssignToStringList(Target: TStringList); virtual; abstract;
    1413    procedure Produce(Module: TModule); virtual; abstract;
  • trunk/Compiler/Produce/UProducerAsm8051.pas

    r2 r6  
    108108begin
    109109  AssemblyCode := TObjectList.Create;
    110   FileExtension := '.asm';
    111110end;
    112111
     
    155154    ntNone: ;
    156155    ntVariable: if Assigned(Variable) then AddInstruction('', 'GETVAR', Variable.Name, '');
    157     nTFunction: AddInstruction('', 'CALL', FunctionCall.Name, '');
     156    nTFunction: AddInstruction('', 'CALL', FunctionCall.FunctionRef.Name, '');
    158157    ntConstant: AddInstruction('', 'CONST', '', '');
    159158    ntOperator: begin
     
    192191procedure TProducerAsm8051.GenerateModule(Module: TModule);
    193192begin
    194 
     193  Module.TargetFile := Module.Name + '.asm';
    195194end;
    196195
  • trunk/Compiler/Produce/UProducerDynamicC.pas

    r5 r6  
    2727    procedure GenerateProgram(ProgramBlock: TProgram);
    2828    procedure GenerateFunctions(Functions: TFunctionList;
    29       Prefix: string = '');
     29      Prefix: string = ''; HeaderOnly: Boolean = False);
    3030    procedure GenerateBeginEnd(BeginEnd: TBeginEnd);
    3131    procedure GenerateVariableList(VariableList: TVariableList);
     
    3636    procedure GenerateIfThenElse(IfThenElse: TIfThenElse);
    3737    procedure GenerateAssignment(Assignment: TAssignment);
    38     procedure GenerateFunctionCall(FunctionCall: TFunctionCall);
     38    function GenerateFunctionCall(FunctionCall: TFunctionCall): string;
    3939    function GenerateExpression(Expression: TExpression): string;
    4040  public
     
    5555begin
    5656  TextSource := TStringList.Create;
    57   FileExtension := '.c';
    5857  IndentationLength := 2;
    5958end;
     
    119118procedure TProducerDynamicC.GenerateModule(Module: TModule);
    120119begin
    121   EmitLn('#use "platform.lib"');
    122   EmitLn;
    123120  if Module is TModuleProgram then begin
     121    Module.TargetFile := Module.Name + '.c';
     122    EmitLn('#use "platform.lib"');
     123    EmitLn;
    124124    TModuleProgram(Module).Body.Name := 'main';
    125125    GenerateUses(TModuleProgram(Module).UsedModules);
     
    127127  end else
    128128  if Module is TModuleUnit then begin
     129    Module.TargetFile := 'Lib\' + Module.Name + '.lib';
     130    EmitLn('/*** BeginHeader */');
     131    EmitLn('#ifndef ' + UpperCase(Module.Name) + '_H');
     132    EmitLn('#define ' + UpperCase(Module.Name) + '_H');
     133    EmitLn;
     134    EmitLn('#use "platform.lib"');
    129135    GenerateUses(TModuleProgram(Module).UsedModules);
     136    GenerateTypes(TModuleUnit(Module).Body.Types);
     137    EmitLn('/*** EndHeader */');
     138    EmitLn;
     139    EmitLn('/*** BeginHeader */');
     140    GenerateFunctions(TModuleUnit(Module).Body.Functions, '', True);
     141    EmitLn('/*** EndHeader */');
     142    EmitLn;
     143
     144    GenerateFunctions(TModuleUnit(Module).Body.Functions);
     145
    130146    GenerateCommonBlock(TModuleUnit(Module).Body, '');
     147
     148    EmitLn;
     149    EmitLn('/*** BeginHeader */');
     150    EmitLn('#endif');
     151    EmitLn('/*** EndHeader */');
    131152  end;
    132153end;
     
    150171
    151172procedure TProducerDynamicC.GenerateFunctions(Functions: TFunctionList;
    152   Prefix: string = '');
     173  Prefix: string = ''; HeaderOnly: Boolean = False);
    153174var
    154175  I: Integer;
     
    171192    Line := Line + ')';
    172193    EmitLn(Line);
    173     GenerateBeginEnd(Code);
     194    if not HeaderOnly then GenerateBeginEnd(Code);
    174195    EmitLn;
    175196  end;
     
    218239  else if Command is TIfThenElse then GenerateIfThenElse(TIfThenElse(Command))
    219240  else if Command is TAssignment then GenerateAssignment(TAssignment(Command))
    220   else if Command is TFunctionCall then GenerateFunctionCall(TFunctionCall(Command));
     241  else if Command is TFunctionCall then EmitLn(GenerateFunctionCall(TFunctionCall(Command)) + ';');
    221242end;
    222243
     
    254275end;
    255276
    256 procedure TProducerDynamicC.GenerateFunctionCall(FunctionCall: TFunctionCall);
     277function TProducerDynamicC.GenerateFunctionCall(FunctionCall: TFunctionCall): string;
    257278var
    258279  Line: string;
     
    267288      end;
    268289    end;
    269     Line := Line + ');';
    270     EmitLn(Line);
    271   end;
     290    Line := Line + ')';
     291  end;
     292  Result := Line;
    272293end;
    273294
     
    285306      end;
    286307      ntVariable: Result := Expression.Variable.Name;
    287       ntFunction: Result := Expression.FunctionCall.Name;
     308      ntFunction: Result := GenerateFunctionCall(Expression.FunctionCall);
    288309      ntOperator: begin
    289310        Result := GenerateExpression(TExpression(Expression.SubItems.First))
     
    308329begin
    309330  with CommonBlock do begin
    310     GenerateTypes(Types);
    311     GenerateFunctions(Functions);
    312331    EmitLn('void ' + Name + '()');
    313332    GenerateBeginEnd(Code);
  • trunk/Compiler/Produce/UProducerGCCC.pas

    r2 r6  
    5555begin
    5656  TextSource := TStringList.Create;
    57   FileExtension := '.c';
    5857  IndentationLength := 2;
    5958end;
     
    119118procedure TProducerGCCC.GenerateModule(Module: TModule);
    120119begin
     120  Module.TargetFile := Module.Name + '.c';
    121121  EmitLn('#include "platform.h"');
    122122  EmitLn;
     
    281281    end;
    282282    ntVariable: Result := Expression.Variable.Name;
    283     ntFunction: Result := Expression.FunctionCall.Name;
     283    ntFunction: Result := Expression.FunctionCall.FunctionRef.Name;
    284284    ntOperator: begin
    285285      Result := GenerateExpression(TExpression(Expression.SubItems.First))
  • trunk/Compiler/Produce/UProducerPascal.pas

    r5 r6  
    5151begin
    5252  IndentationLength := 2;
    53   FileExtension := '.pas';
    5453  TextSource := TStringList.Create;
    5554end;
     
    8887procedure TProducerPascal.GenerateModule(Module: TModule);
    8988begin
     89  Module.TargetFile := Module.Name + '.pas';
    9090  if Module is TModuleProgram then
    9191  with TModuleProgram(Module) do begin
     
    320320      end;
    321321      ntVariable: Result := Expression.Variable.Name;
    322       ntFunction: Result := Expression.FunctionCall.Name;
     322      ntFunction: Result := Expression.FunctionCall.FunctionRef.Name;
    323323      ntOperator: begin
    324324        Result := GenerateExpression(TExpression(Expression.SubItems.First))
  • trunk/Compiler/Produce/UProducerTreeView.pas

    r2 r6  
    152152    ntConstant: NewNode := TreeView.Items.AddChild(Node, Expression.Value);
    153153    ntVariable: NewNode := TreeView.Items.AddChild(Node, Expression.Variable.Name);
    154     ntFunction: NewNode := TreeView.Items.AddChild(Node, Expression.FunctionCall.Name);
     154    ntFunction: NewNode := TreeView.Items.AddChild(Node, Expression.FunctionCall.FunctionRef.Name);
    155155    ntOperator: begin
    156156      NewNode := TreeView.Items.AddChild(Node, Expression.OperatorName);
  • trunk/Compiler/UCompiler.pas

    r2 r6  
    7373  ProducedCode: TStringList;
    7474  I: Integer;
     75  TargetFileName: string;
    7576begin
    7677  try
     
    8182    //ShowMessage(IntToHex(Integer(Addr(Parser.OnGetSource)), 8));
    8283    Parser.ParseModule(ProgramCode);
    83     for I := 0 to ProgramCode.Modules.Count - 1 do begin
    84       Producer.Produce(TModule(ProgramCode.Modules[I]));
     84    with ProgramCode do
     85    for I := 0 to Modules.Count - 1 do begin
     86      Producer.Produce(TModule(Modules[I]));
    8587      Producer.AssignToStringList(ProducedCode);
    86       ForceDirectories(TargetFolder + DirectorySeparator +
    87         CompiledFolder + DirectorySeparator + Producer.ClassName);
    88       ProducedCode.SaveToFile(TargetFolder + DirectorySeparator +
     88      TargetFileName := TargetFolder + DirectorySeparator +
    8989        CompiledFolder + DirectorySeparator + Producer.ClassName +
    90         DirectorySeparator + TModule(ProgramCode.Modules[I]).Name + Producer.FileExtension);
     90        DirectorySeparator + TModule(Modules[I]).TargetFile;
     91      ForceDirectories(ExtractFileDir(TargetFileName));
     92      ProducedCode.SaveToFile(TargetFileName);
    9193    end;
    9294  finally
  • trunk/Compiler/USourceCode.pas

    r5 r6  
    1515
    1616  TNodeType = (ntNone, ntVariable, ntFunction, ntConstant, ntOperator,
    17     ntValue);
     17    ntValue, ntTypecast);
    1818
    1919  TTypeVisibility = (tvPublic, tvPublished, tvPrivate, tvProtected);
     
    329329    Variable: TVariable;
    330330    Constant: TConstant;
    331     FunctionCall: TFunction;
     331    UseType: TType;
     332    FunctionCall: TFunctionCall;
    332333    Value: TValue;
    333334    OperatorName: string;
     
    396397    ParentProgram: TProgram;
    397398    Name: string;
     399    TargetFile: string;
    398400    UsedModules: TUsedModuleList;
    399401    Body: TCommonBlock;
Note: See TracChangeset for help on using the changeset viewer.