Changeset 140


Ignore:
Timestamp:
Jan 16, 2018, 10:38:33 AM (7 years ago)
Author:
chronos
Message:
  • Modified: General definition of functions. Static functions are now dynamic predefined.
Location:
branches/easy compiler
Files:
3 added
6 edited

Legend:

Unmodified
Added
Removed
  • branches/easy compiler/UCompiler.pas

    r139 r140  
    159159  Instruction: TSourceInstruction;
    160160  NewReference: TSourceReference;
     161  Funct: TSourceFunction;
     162  Param: TSourceFunctionParameter;
    161163
    162164function ParseReference: TSourceReference;
     
    171173    NewReference := TSourceReferenceVariable.Create;
    172174    TSourceReferenceVariable(NewReference).Variable :=
    173       Code.Variables.Find(Token.Text);
     175      Code.Variables.Search(Token.Text);
    174176    if TSourceReferenceVariable(NewReference).Variable = nil then
    175177      raise Exception.Create('Variable not found: ' + Token.Text);
     
    184186    NewReference := TSourceReferenceVariable.Create;
    185187    TSourceReferenceVariable(NewReference).Variable :=
    186       Code.Variables.Find(Token.Text);
     188      Code.Variables.Search(Token.Text);
    187189    if TSourceReferenceVariable(NewReference).Variable = nil then begin
    188190      if Initialize then
     
    201203    if Token.Kind = stIdentifier then begin
    202204      Keyword := LowerCase(Token.Text);
    203       if Keyword = 'print' then begin
     205      Funct := Code.Functions.Search(Keyword);
     206      if Assigned(Funct) then begin
    204207        Instruction := TSourceInstructionFunction.Create;
    205         TSourceInstructionFunction(Instruction).Name := 'print';
    206         TSourceInstructionFunction(Instruction).AddParameter(ParseReference);
    207         Code.Instructions.Add(Instruction);
    208       end else
    209       if Keyword = 'println' then begin
    210         Instruction := TSourceInstructionFunction.Create;
    211         TSourceInstructionFunction(Instruction).Name := 'println';
    212         TSourceInstructionFunction(Instruction).AddParameter(ParseReference);
    213         Code.Instructions.Add(Instruction);
    214       end else
    215       if Keyword = 'assign' then begin
    216         Instruction := TSourceInstructionFunction.Create;
    217         TSourceInstructionFunction(Instruction).Name := 'assign';
    218         TSourceInstructionFunction(Instruction).AddParameter(ParseReferenceVariable(True));
    219         TSourceInstructionFunction(Instruction).AddParameter(ParseReference);
     208        TSourceInstructionFunction(Instruction).Name := Keyword;
     209        for Param in Funct.Parameters do
     210        if Param.Kind = pkString then begin
     211          TSourceInstructionFunction(Instruction).AddParameter(ParseReference)
     212        end else
     213        if Param.Kind = pkVariable then begin
     214          TSourceInstructionFunction(Instruction).AddParameter(ParseReferenceVariable(True));
     215        end else
     216        raise Exception.Create('Unsupported parameter type.');
    220217        Code.Instructions.Add(Instruction);
    221218      end else raise Exception.Create('Unsupported keyword: ' + Token.Text);
  • branches/easy compiler/UFormMain.lfm

    r139 r140  
    11object Form1: TForm1
    2   Left = 600
    3   Height = 394
    4   Top = 422
    5   Width = 517
     2  Left = 326
     3  Height = 572
     4  Top = 267
     5  Width = 909
    66  Caption = 'Little compiler'
    7   ClientHeight = 394
    8   ClientWidth = 517
     7  ClientHeight = 572
     8  ClientWidth = 909
    99  DesignTimePPI = 120
     10  OnCreate = FormCreate
     11  OnDestroy = FormDestroy
    1012  OnShow = FormShow
    1113  LCLVersion = '1.8.0.6'
    1214  object MemoOutput: TMemo
    13     Left = 8
    14     Height = 160
    15     Top = 224
    16     Width = 496
     15    Left = 440
     16    Height = 240
     17    Top = 32
     18    Width = 400
    1719    ScrollBars = ssAutoBoth
    1820    TabOrder = 0
     
    2022  object MemoSource: TMemo
    2123    Left = 8
    22     Height = 168
    23     Top = 8
    24     Width = 496
     24    Height = 240
     25    Top = 32
     26    Width = 416
    2527    ScrollBars = ssAutoBoth
    2628    TabOrder = 1
    2729  end
    2830  object ButtonBuild: TButton
    29     Left = 184
     31    Left = 112
    3032    Height = 31
    31     Top = 184
     33    Top = 280
    3234    Width = 166
    3335    Caption = 'Compile && Execute'
     
    3537    TabOrder = 2
    3638  end
     39  object Edit1: TEdit
     40    Left = 440
     41    Height = 28
     42    Top = 304
     43    Width = 200
     44    TabOrder = 3
     45  end
     46  object ButtonSend: TButton
     47    Left = 656
     48    Height = 31
     49    Top = 304
     50    Width = 94
     51    Caption = 'Send'
     52    OnClick = ButtonSendClick
     53    TabOrder = 4
     54  end
     55  object Label1: TLabel
     56    Left = 9
     57    Height = 20
     58    Top = 8
     59    Width = 78
     60    Caption = 'Text source:'
     61    ParentColor = False
     62  end
     63  object Label2: TLabel
     64    Left = 440
     65    Height = 20
     66    Top = 11
     67    Width = 108
     68    Caption = 'Executor output:'
     69    ParentColor = False
     70  end
     71  object Label3: TLabel
     72    Left = 441
     73    Height = 20
     74    Top = 282
     75    Width = 98
     76    Caption = 'Executor input:'
     77    ParentColor = False
     78  end
     79  object MemoGenerator: TMemo
     80    Left = 8
     81    Height = 216
     82    Top = 344
     83    Width = 416
     84    ScrollBars = ssAutoBoth
     85    TabOrder = 5
     86  end
     87  object Label4: TLabel
     88    Left = 8
     89    Height = 20
     90    Top = 315
     91    Width = 117
     92    Caption = 'Generator output:'
     93    ParentColor = False
     94  end
    3795end
  • branches/easy compiler/UFormMain.pas

    r139 r140  
    77uses
    88  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
    9   UTargetCode, USourceCode;
     9  UTargetCode, USourceCode, USourceExecutor, USourceGenerator;
    1010
    1111type
     
    1414
    1515  TForm1 = class(TForm)
     16    ButtonSend: TButton;
    1617    ButtonBuild: TButton;
     18    Edit1: TEdit;
     19    Label1: TLabel;
     20    Label2: TLabel;
     21    Label3: TLabel;
     22    Label4: TLabel;
    1723    MemoOutput: TMemo;
    1824    MemoSource: TMemo;
     25    MemoGenerator: TMemo;
    1926    procedure ButtonBuildClick(Sender: TObject);
     27    procedure ButtonSendClick(Sender: TObject);
     28    procedure FormCreate(Sender: TObject);
     29    procedure FormDestroy(Sender: TObject);
    2030    procedure FormShow(Sender: TObject);
    2131  private
    22 
     32    InputBuffer: TStringList;
     33    procedure ExecutorOutput(Text: string);
     34    function ExecutorInput: string;
    2335  public
    24     procedure ExecutorOutput(Text: string);
    2536  end;
    2637
     
    4758    Add('PrintLn Text1');
    4859    Add('PrintLn Text2');
     60    Add('InputLn Text3');
     61    Add('PrintLn Text3');
    4962  end;
    5063end;
     
    6477  Executor := TSourceExecutor.Create;
    6578  Executor.OnOutput := ExecutorOutput;
     79  Executor.OnInput := ExecutorInput;
    6680  Generator := TSourceGenerator.Create;
    6781
    6882  Compiler.Compile(MemoSource.Text, SourceCode);
     83  MemoGenerator.Text := Generator.Generate(SourceCode);
    6984  Executor.Execute(SourceCode);
    70   Generator.Generate(SourceCode);
    7185
    7286  Generator.Free;
     
    7791end;
    7892
     93procedure TForm1.ButtonSendClick(Sender: TObject);
     94begin
     95  InputBuffer.Add(Edit1.Text);
     96  Edit1.Text := '';
     97end;
     98
     99procedure TForm1.FormCreate(Sender: TObject);
     100begin
     101  InputBuffer := TStringList.Create;
     102end;
     103
     104procedure TForm1.FormDestroy(Sender: TObject);
     105begin
     106  InputBuffer.Free;
     107end;
     108
    79109procedure TForm1.ExecutorOutput(Text: string);
    80110begin
     
    82112end;
    83113
     114function TForm1.ExecutorInput: string;
     115begin
     116  while InputBuffer.Count = 0 do begin
     117    Sleep(50);
     118    Application.ProcessMessages;
     119  end;
     120  Result := InputBuffer[0];
     121  InputBuffer.Delete(0);
     122end;
     123
    84124end.
    85125
  • branches/easy compiler/USourceCode.pas

    r139 r140  
    2626  TSourceVariables = class(TObjectList)
    2727    function AddNew(Name: string = ''): TSourceVariable;
    28     function Find(Name: string): TSourceVariable;
     28    function Search(Name: string): TSourceVariable;
    2929  end;
    3030
     
    3838  end;
    3939
     40  TSourceParameterKind = (pkString, pkVariable);
     41
     42  TSourceFunctionParameter = class
     43    Name: string;
     44    Kind: TSourceParameterKind;
     45  end;
     46
     47  TSourceFunctionParameters = class(TObjectList)
     48  end;
     49
     50  { TSourceFunction }
     51
     52  TSourceFunction = class
     53    Name: string;
     54    Parameters: TSourceFunctionParameters;
     55    procedure AddParameter(Name: string; Kind: TSourceParameterKind);
     56    constructor Create;
     57    destructor Destroy; override;
     58  end;
     59
     60  { TSourceFunctions }
     61
     62  TSourceFunctions = class(TObjectList)
     63    function AddNew(Name: string): TSourceFunction;
     64    function Search(Name: string): TSourceFunction;
     65  end;
     66
    4067  { TSourceConstants }
    4168
     
    5986
    6087  TSourceCode = class
     88  private
     89    procedure InitFunctions;
     90  public
    6191    Variables: TSourceVariables;
    6292    Constants: TSourceConstants;
     93    Functions: TSourceFunctions;
    6394    Instructions: TSourceInstructions;
    6495    constructor Create;
     
    6697  end;
    6798
    68   TOutputEvent = procedure (Text: string) of object;
    69 
    70   { TSourceExecutor }
    71 
    72   TSourceExecutor = class
    73   private
    74     FOnOutput: TOutputEvent;
    75     Variables: TStringList;
    76   public
    77     constructor Create;
    78     destructor Destroy; override;
    79     procedure Execute(SourceCode: TSourceCode);
    80     property OnOutput: TOutputEvent read FOnOutput write FOnOutput;
    81   end;
    82 
    83   { TSourceGenerator }
    84 
    85   TSourceGenerator = class
    86     procedure Generate(SourceCode: TSourceCode);
    87   end;
    8899
    89100implementation
    90101
    91 { TSourceGenerator }
    92 
    93 procedure TSourceGenerator.Generate(SourceCode: TSourceCode);
    94 var
    95   F: TStringList;
    96   Output: string;
    97   Instruction: TSourceInstruction;
    98   Parameter: TSourceReference;
    99   I: Integer;
    100 begin
    101   Output := '';
    102   if SourceCode.Variables.Count > 0 then
    103     Output := Output + 'var' + LineEnding;
    104   with SourceCode do
    105   for I := 0 to Variables.Count - 1 do
    106     Output := Output + '  ' + TSourceVariable(Variables[I]).Name + ': string;' + LineEnding;
    107   Output := Output + 'begin' + LineEnding;
    108   with SourceCode do
    109   for I := 0 to Instructions.Count - 1 do begin
    110     Instruction := TSourceInstruction(Instructions[I]);
    111     if Instruction is TSourceInstructionFunction then begin
    112       if TSourceInstructionFunction(Instruction).Name = 'print' then begin
    113         Output := Output + '  Write(';
    114         Parameter := TSourceInstructionFunction(Instruction).Parameters[0];
    115         if Parameter is TSourceReferenceConstant then begin
    116           Output := Output + '''' + TSourceReferenceConstant(Parameter).Constant.Value + '''';
    117         end else
    118         if Parameter is TSourceReferenceVariable then begin
    119           Output := Output + TSourceReferenceVariable(Parameter).Variable.Name;
    120         end else raise Exception.Create('Unsupported parameter type');
    121         Output := Output + ');' + LineEnding;
    122       end else
    123       if TSourceInstructionFunction(Instruction).Name = 'println' then begin
    124         Output := Output + '  WriteLn(';
    125         Parameter := TSourceInstructionFunction(Instruction).Parameters[0];
    126         if Parameter is TSourceReferenceConstant then begin
    127           Output := Output + '''' + TSourceReferenceConstant(Parameter).Constant.Value + '''';
    128         end else
    129         if Parameter is TSourceReferenceVariable then begin
    130           Output := Output + TSourceReferenceVariable(Parameter).Variable.Name;
    131         end else raise Exception.Create('Unsupported parameter type');
    132         Output := Output + ');' + LineEnding;
    133       end else
    134       if TSourceInstructionFunction(Instruction).Name = 'assign' then begin
    135         Output := Output + '  ';
    136         Parameter := TSourceInstructionFunction(Instruction).Parameters[0];
    137         if Parameter is TSourceReferenceVariable then begin
    138           Output := Output + TSourceReferenceVariable(Parameter).Variable.Name;
    139         end else raise Exception.Create('Unsupported parameter type');
    140         Output := Output + ' := ';
    141         Parameter := TSourceInstructionFunction(Instruction).Parameters[1];
    142         if Parameter is TSourceReferenceConstant then begin
    143           Output := Output + '''' + TSourceReferenceConstant(Parameter).Constant.Value + '''';
    144         end else
    145         if Parameter is TSourceReferenceVariable then begin
    146           Output := Output + TSourceReferenceVariable(Parameter).Variable.Name;
    147         end else raise Exception.Create('Unsupported parameter type');
    148         Output := Output + ';' + LineEnding;
    149       end else raise Exception.Create('Unsupported instruction name.');
    150     end else raise Exception.Create('Unsupported instruction');
    151   end;
    152   Output := Output + 'end.' + LineEnding;
    153 
    154   F := TStringList.Create;
    155   try
    156     F.Text := Output;
    157     F.SaveToFile('Output.pas');
    158   finally
    159     F.Free;
    160   end;
    161 end;
    162 
    163 { TSourceExecutor }
    164 
    165 constructor TSourceExecutor.Create;
    166 begin
    167   Variables := TStringList.Create;
    168 end;
    169 
    170 destructor TSourceExecutor.Destroy;
    171 begin
    172   Variables.Free;
     102{ TSourceFunctions }
     103
     104function TSourceFunctions.AddNew(Name: string): TSourceFunction;
     105begin
     106  Result := TSourceFunction.Create;
     107  Result.Name := Name;
     108  Add(Result);
     109end;
     110
     111function TSourceFunctions.Search(Name: string): TSourceFunction;
     112var
     113  Item: TSourceFunction;
     114begin
     115  Result := nil;
     116  for Item in Self do
     117  if Item.Name = Name then begin
     118    Result := Item;
     119    Break;
     120  end;
     121end;
     122
     123{ TSourceFunction }
     124
     125procedure TSourceFunction.AddParameter(Name: string; Kind: TSourceParameterKind
     126  );
     127var
     128  Parameter: TSourceFunctionParameter;
     129begin
     130  Parameter := TSourceFunctionParameter.Create;
     131  Parameter.Name := Name;
     132  Parameter.Kind := Kind;
     133  Parameters.Add(Parameter);
     134end;
     135
     136constructor TSourceFunction.Create;
     137begin
     138  Parameters := TSourceFunctionParameters.Create;
     139end;
     140
     141destructor TSourceFunction.Destroy;
     142begin
     143  Parameters.Free;
    173144  inherited Destroy;
    174 end;
    175 
    176 procedure TSourceExecutor.Execute(SourceCode: TSourceCode);
    177 var
    178   IP: Integer;
    179   Instruction: TSourceInstruction;
    180   Text: string;
    181   Reference: TSourceReference;
    182   Variable: TSourceVariable;
    183 begin
    184   IP := 0;
    185   while IP < SourceCode.Instructions.Count do begin
    186     Instruction := TSourceInstruction(SourceCode.Instructions[IP]);
    187     if Instruction is TSourceInstructionFunction then begin
    188       if TSourceInstructionFunction(Instruction).Name = 'print' then begin
    189         Reference := TSourceInstructionFunction(Instruction).Parameters[0];
    190         if Reference is TSourceReferenceConstant then begin
    191           Text := TSourceReferenceConstant(Reference).Constant.Value;
    192         end else
    193         if Reference is TSourceReferenceVariable then begin
    194           Text := Variables.Values[TSourceReferenceVariable(Reference).Variable.Name];
    195         end else raise Exception.Create('Unsupported reference');
    196         if Assigned(FOnOutput) then FOnOutput(Text);
    197       end else
    198       if TSourceInstructionFunction(Instruction).Name = 'println' then begin
    199         Reference := TSourceInstructionFunction(Instruction).Parameters[0];
    200         if Reference is TSourceReferenceConstant then begin
    201           Text := TSourceReferenceConstant(Reference).Constant.Value;
    202         end else
    203         if Reference is TSourceReferenceVariable then begin
    204           Text := Variables.Values[TSourceReferenceVariable(Reference).Variable.Name];
    205         end else raise Exception.Create('Unsupported reference');
    206         if Assigned(FOnOutput) then FOnOutput(Text + LineEnding);
    207       end else
    208       if TSourceInstructionFunction(Instruction).Name = 'assign' then begin
    209         Variable := nil;
    210         Reference := TSourceInstructionFunction(Instruction).Parameters[0];
    211         if Reference is TSourceReferenceVariable then begin
    212           Variable := TSourceReferenceVariable(Reference).Variable;
    213         end else raise Exception.Create('Unsupported reference');
    214         Reference := TSourceInstructionFunction(Instruction).Parameters[1];
    215         if Reference is TSourceReferenceConstant then begin
    216           Text := TSourceReferenceConstant(Reference).Constant.Value;
    217         end else
    218         if Reference is TSourceReferenceVariable then begin
    219           Text := Variables.Values[TSourceReferenceVariable(Reference).Variable.Name];
    220         end else raise Exception.Create('Unsupported reference');
    221         Variables.Values[Variable.Name] := Text;
    222       end else raise Exception.Create('Unsupported function: ' + TSourceInstructionFunction(Instruction).Name);
    223     end else raise Exception.Create('Unsupported instruction');
    224     Inc(IP);
    225   end;
    226145end;
    227146
     
    235154end;
    236155
    237 function TSourceVariables.Find(Name: string): TSourceVariable;
    238 var
    239   I: Integer;
     156function TSourceVariables.Search(Name: string): TSourceVariable;
     157var
    240158  Variable: TSourceVariable;
    241159begin
     
    268186{ TSourceCode }
    269187
     188procedure TSourceCode.InitFunctions;
     189var
     190  Funct: TSourceFunction;
     191begin
     192  Functions.Clear;
     193  Funct := Functions.AddNew('print');
     194  Funct.AddParameter('Text', pkString);
     195  Funct := Functions.AddNew('println');
     196  Funct.AddParameter('Text', pkString);
     197  Funct := Functions.AddNew('assign');
     198  Funct.AddParameter('Destination', pkVariable);
     199  Funct.AddParameter('Source', pkString);
     200  Funct := Functions.AddNew('inputln');
     201  Funct.AddParameter('Text', pkVariable);
     202end;
     203
    270204constructor TSourceCode.Create;
    271205begin
     
    273207  Constants := TSourceConstants.Create;
    274208  Instructions := TSourceInstructions.Create;
     209  Functions := TSourceFunctions.Create;
     210  InitFunctions;
    275211end;
    276212
    277213destructor TSourceCode.Destroy;
    278214begin
     215  Functions.Free;
    279216  Variables.Free;
    280217  Constants.Free;
  • branches/easy compiler/project1.lpi

    r139 r140  
    2828      </Item1>
    2929    </RequiredPackages>
    30     <Units Count="5">
     30    <Units Count="7">
    3131      <Unit0>
    3232        <Filename Value="project1.lpr"/>
     
    5252        <IsPartOfProject Value="True"/>
    5353      </Unit4>
     54      <Unit5>
     55        <Filename Value="USourceExecutor.pas"/>
     56        <IsPartOfProject Value="True"/>
     57      </Unit5>
     58      <Unit6>
     59        <Filename Value="USourceGenerator.pas"/>
     60        <IsPartOfProject Value="True"/>
     61      </Unit6>
    5462    </Units>
    5563  </ProjectOptions>
     
    8694      </Options>
    8795    </Linking>
     96    <Other>
     97      <CompilerMessages>
     98        <IgnoredMessages idx5024="True"/>
     99      </CompilerMessages>
     100    </Other>
    88101  </CompilerOptions>
    89102  <Debugging>
  • branches/easy compiler/project1.lpr

    r139 r140  
    88  {$ENDIF}{$ENDIF}
    99  Interfaces, // this includes the LCL widgetset
    10   Forms, UFormMain, UCompiler, USourceCode, UTargetCode
     10  Forms, UFormMain, UCompiler, USourceCode, UTargetCode, USourceExecutor, USourceGenerator
    1111  { you can add units after this };
    1212
Note: See TracChangeset for help on using the changeset viewer.