Changeset 149 for branches/easy compiler


Ignore:
Timestamp:
Jan 18, 2018, 1:30:58 PM (7 years ago)
Author:
chronos
Message:
  • Fixed: Now arrays of string and integer are supported and executed correctly by executor.
  • Added: IfNotEqual command.
Location:
branches/easy compiler
Files:
6 edited

Legend:

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

    r148 r149  
    5050      ): Boolean;
    5151    function ParseFunctionCall(SourceCode: TSourceCode; out FunctionCall: TCommandFunctionCall): Boolean;
    52     function ParseIfEqual(SourceCode: TSourceCode; out IfZero: TCommandIfEqual): Boolean;
     52    function ParseIfEqual(SourceCode: TSourceCode; out IfEqual: TCommandIfEqual): Boolean;
     53    function ParseIfNotEqual(SourceCode: TSourceCode; out IfNotEqual: TCommandIfNotEqual): Boolean;
    5354    function ParseReference(SourceCode: TSourceCode): TSourceReference;
    5455    function ParseReferenceVariable(SourceCode: TSourceCode): TSourceReference;
     
    327328end;
    328329
    329 function TCompiler.ParseIfEqual(SourceCode: TSourceCode; out IfZero: TCommandIfEqual): Boolean;
     330function TCompiler.ParseIfEqual(SourceCode: TSourceCode; out IfEqual: TCommandIfEqual): Boolean;
    330331var
    331332  Token: TSourceToken;
     
    338339  Keyword := LowerCase(Token.Text);
    339340  if Keyword = 'ifequal' then begin
    340     IfZero := TCommandIfEqual.Create;
    341     IfZero.Reference1 := ParseReference(SourceCode);
    342     IfZero.Reference2 := ParseReference(SourceCode);
     341    IfEqual := TCommandIfEqual.Create;
     342    IfEqual.Reference1 := ParseReference(SourceCode);
     343    IfEqual.Reference2 := ParseReference(SourceCode);
     344    Result := True;
     345  end;
     346  if not Result then Tokenizer.TokenIndex := TokenIndex;
     347end;
     348
     349function TCompiler.ParseIfNotEqual(SourceCode: TSourceCode; out
     350  IfNotEqual: TCommandIfNotEqual): Boolean;
     351var
     352  Token: TSourceToken;
     353  TokenIndex: Integer;
     354  Keyword: string;
     355begin
     356  Result := False;
     357  TokenIndex := Tokenizer.TokenIndex;
     358  Token := Tokenizer.GetNext;
     359  Keyword := LowerCase(Token.Text);
     360  if Keyword = 'ifnotequal' then begin
     361    IfNotEqual := TCommandIfNotEqual.Create;
     362    IfNotEqual.Reference1 := ParseReference(SourceCode);
     363    IfNotEqual.Reference2 := ParseReference(SourceCode);
    343364    Result := True;
    344365  end;
     
    390411var
    391412  CommandBeginEnd: TCommandBeginEnd;
    392   CommandIfZero: TCommandIfEqual;
     413  CommandIfEqual: TCommandIfEqual;
    393414  CommandFunctionCall: TCommandFunctionCall;
    394415  CommandBreak: TCommandBreak;
    395416  CommandRepeat: TCommandRepeat;
     417  CommandIfNotEqual: TCommandIfNotEqual;
    396418begin
    397419  Command := nil;
     
    401423    Command := CommandBeginEnd;
    402424  end else
    403   if ParseIfEqual(SourceCode, CommandIfZero) then begin
    404     Command := CommandIfZero;
     425  if ParseIfEqual(SourceCode, CommandIfEqual) then begin
     426    Command := CommandIfEqual;
     427  end else
     428  if ParseIfNotEqual(SourceCode, CommandIfNotEqual) then begin
     429    Command := CommandIfNotEqual;
    405430  end else
    406431  if ParseBreak(SourceCode, CommandBreak) then begin
  • branches/easy compiler/UFormMain.lfm

    r141 r149  
    1414  object MemoOutput: TMemo
    1515    Left = 440
    16     Height = 240
     16    Height = 464
    1717    Top = 32
    18     Width = 400
     18    Width = 448
     19    ReadOnly = True
    1920    ScrollBars = ssAutoBoth
    2021    TabOrder = 0
     
    4041    Left = 440
    4142    Height = 28
    42     Top = 304
     43    Top = 526
    4344    Width = 200
    4445    OnKeyPress = Edit1KeyPress
     
    4849    Left = 656
    4950    Height = 31
    50     Top = 304
     51    Top = 526
    5152    Width = 94
    5253    Caption = 'Send'
     
    7374    Left = 441
    7475    Height = 20
    75     Top = 282
     76    Top = 504
    7677    Width = 98
    7778    Caption = 'Executor input:'
  • branches/easy compiler/UFormMain.pas

    r148 r149  
    77uses
    88  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
    9   UTargetCode, USourceCode, USourceExecutor, USourceGenerator;
     9  UTargetCode, USourceCode, USourceExecutor, USourceGenerator, LCLIntf;
    1010
    1111type
     
    128128        Add('IfEqual Answer ''y''');
    129129        Add('Begin');
    130           Add('PrintLn ''Thats clear. It is ''');
     130          Add('Print ''Thats clear. It is ''');
    131131          Add('PrintLn AnimalName[I]');
    132132          Add('Break');
     
    136136        Add('Break');
    137137      Add('End');
    138       Add('PrintLn ''I am lost. What is the animal?''');
    139       Add('InputLn AnimalName[I]');
    140       Add('PrintLn ''Describe the animal for me. What is it like?''');
    141       Add('InputLn AnimalProperty[I]');
    142       Add('PrintLn ''Thank you. I will remember that animal.''');
    143       Add('Increment AnimalCount 1');
     138      Add('IfEqual I AnimalCount');
     139      Add('Begin');
     140        Add('PrintLn ''I am lost. What is the animal?''');
     141        Add('InputLn AnimalName[I]');
     142        Add('PrintLn ''Describe the animal for me. What is it like?''');
     143        Add('InputLn AnimalProperty[I]');
     144        Add('PrintLn ''Thank you. I will remember that animal.''');
     145        Add('Increment AnimalCount 1');
     146      Add('End');
     147      Add('Print ''Do you want to try again? (y/n)''');
     148      Add('InputLn Answer');
     149      Add('IfNotEqual Answer ''y''');
     150      Add('Break');
    144151      Add('PrintLn ''''');
    145152    Add('End');
     153    Add('PrintLn ''Bye''');
    146154    Add('End');
    147155  end;
     
    201209begin
    202210  MemoOutput.Text := MemoOutput.Text + Text;
     211  MemoOutput.SelStart := Length(MemoOutput.Text);
     212  //SendMessage(MemoOutput.Handle, EM_LINESCROLL, 0, MemoOutput.Lines.Count);
    203213end;
    204214
  • branches/easy compiler/USourceCode.pas

    r148 r149  
    2626  TSourceValue = class
    2727    procedure Assign(Source: TSourceValue); virtual;
     28    constructor Create; virtual;
    2829  end;
    2930
     
    113114    Items: TSourceValues;
    114115    procedure Assign(Source: TSourceValue); override;
    115     constructor Create;
     116    constructor Create; override;
    116117    destructor Destroy; override;
    117118  end;
     
    188189
    189190  TCommandIfEqual = class(TSourceCommand)
     191    Reference1: TSourceReference;
     192    Reference2: TSourceReference;
     193    destructor Destroy; override;
     194  end;
     195
     196  { TCommandIfNotEqual }
     197
     198  TCommandIfNotEqual = class(TSourceCommand)
    190199    Reference1: TSourceReference;
    191200    Reference2: TSourceReference;
     
    223232
    224233implementation
     234
     235{ TCommandIfNotEqual }
     236
     237destructor TCommandIfNotEqual.Destroy;
     238begin
     239  Reference1.Free;
     240  Reference2.Free;
     241  inherited Destroy;
     242end;
    225243
    226244{ TSourceType }
     
    364382end;
    365383
     384constructor TSourceValue.Create;
     385begin
     386end;
     387
    366388{ TSourceValueInteger }
    367389
  • branches/easy compiler/USourceExecutor.pas

    r148 r149  
    1717    Variable: TSourceVariable;
    1818    Value: TSourceValue;
     19
    1920    destructor Destroy; override;
    2021  end;
     
    4950    procedure ExecuteBreak(CommandBreak: TCommandBreak);
    5051    procedure ExecuteIfEqual(IfEqual: TCommandIfEqual);
     52    procedure ExecuteIfNotEqual(IfNotEqual: TCommandIfNotEqual);
    5153    procedure ExecuteRepeat(CommandRepeat: TCommandRepeat);
    5254    function ReadValueReference(Reference: TSourceReference): TSourceValue;
    53     function ReadVarReference(Reference: TSourceReference): TSourceVariable;
     55    function ReadVarReference(Reference: TSourceReference): TSourceValue;
    5456  public
    5557    constructor Create;
     
    141143end;
    142144
    143 function TSourceExecutor.ReadVarReference(Reference: TSourceReference): TSourceVariable;
     145function TSourceExecutor.ReadVarReference(Reference: TSourceReference): TSourceValue;
    144146var
    145147  ArrayIndex: TSourceValue;
     148  Variable: TSourceVariable;
     149  ExecutorVar: TExecutorVariable;
     150  I: Integer;
    146151begin
    147152  Result := nil;
    148153  if Reference is TSourceReferenceVariable then begin
    149     Result := TSourceReferenceVariable(Reference).Variable;
     154    Variable := TSourceReferenceVariable(Reference).Variable;
     155  end else
     156  if Reference is TSourceReferenceArray then begin
     157    Variable := TSourceReferenceArray(Reference).ArrayRef;
     158  end else
     159  raise Exception.Create('Unsupported reference');
     160
     161  ExecutorVar := Variables.Search(Variable);
     162  if not Assigned(ExecutorVar) then begin
     163    ExecutorVar := TExecutorVariable.Create;
     164    ExecutorVar.Variable := Variable;
     165    Variables.Add(ExecutorVar);
     166    ExecutorVar.Value := Variable.ValueType.GetValueType.Create;
     167  end;
     168  if Reference is TSourceReferenceVariable then begin
     169    Result := ExecutorVar.Value;
    150170  end else
    151171  if Reference is TSourceReferenceArray then begin
     
    153173    if not (ArrayIndex is TSourceValueInteger) then
    154174      raise Exception.Create('Only integer array index supported');
    155 //    Result := TSourceValue(TSourceValueArray(Variables.Search(TSourceReferenceArray(Reference).ArrayRef).Value).Items[TSourceValueInteger(ArrayIndex)]);
    156 //TODO:    Result := Variables.Search(TSourceReferenceArray(Reference).ArrayRef);
    157   end else raise Exception.Create('Unsupported reference');
     175    I := TSourceValueInteger(ArrayIndex).Value;
     176    while TSourceValueArray(ExecutorVar.Value).Items.Count < (I + 1) do begin
     177      TSourceValueArray(ExecutorVar.Value).Items.Add(TSourceTypeArray(TSourceReferenceArray(Reference).ArrayRef.ValueType).ItemType.GetValueType.Create);
     178    end;
     179    Result := TSourceValue(TSourceValueArray(ExecutorVar.Value).Items[I]);
     180  end else
     181  raise Exception.Create('Unsupported reference');
    158182end;
    159183
    160184procedure TSourceExecutor.ExecuteAssign(CommandAssign: TCommandFunctionCall);
    161185var
    162   Variable: TSourceVariable;
    163   Value: TSourceValue;
    164   ExecutorVar: TExecutorVariable;
     186  Dest: TSourceValue;
     187  Source: TSourceValue;
    165188begin
    166189  with TCommandFunctionCall(CommandAssign) do begin
    167     Variable := ReadVarReference(TSourceReference(Parameters[0]));
    168     Value := ReadValueReference(TSourceReference(Parameters[1]));
    169     ExecutorVar := Variables.Search(Variable);
    170     if not Assigned(ExecutorVar) then begin
    171       ExecutorVar := TExecutorVariable.Create;
    172       ExecutorVar.Variable := Variable;
    173       Variables.Add(ExecutorVar);
    174       ExecutorVar.Value := Variable.ValueType.GetValueType.Create;
    175     end;
    176     ExecutorVar.Value.Assign(Value);
     190    Dest := ReadVarReference(TSourceReference(Parameters[0]));
     191    Source := ReadValueReference(TSourceReference(Parameters[1]));
     192    Dest.Assign(Source);
    177193  end;
    178194end;
     
    230246end;
    231247
     248procedure TSourceExecutor.ExecuteIfNotEqual(IfNotEqual: TCommandIfNotEqual);
     249var
     250  Value1: TSourceValue;
     251  Value2: TSourceValue;
     252begin
     253  Value1 := ReadValueReference(IfNotEqual.Reference1);
     254  Value2 := ReadValueReference(IfNotEqual.Reference2);
     255  if (Value1 is TSourceValueInteger) and (Value2 is TSourceValueInteger) then begin
     256    if TSourceValueInteger(Value1).Value = TSourceValueInteger(Value2).Value then
     257      SkipNext := True;
     258  end else
     259  if (Value1 is TSourceValueString) and (Value2 is TSourceValueString) then begin
     260    if TSourceValueString(Value1).Value = TSourceValueString(Value2).Value then
     261      SkipNext := True;
     262  end else
     263  raise Exception.Create('Unsupported types for comparison.');
     264end;
     265
    232266procedure TSourceExecutor.ExecuteRepeat(CommandRepeat: TCommandRepeat);
    233267var
     
    251285  Text: string;
    252286  IntValue: Integer;
     287  Dest: TSourceValue;
    253288begin
    254289  if Command is TCommandFunctionCall then
     
    276311    if Name = 'inputln' then begin
    277312      if Assigned(FOnInput) then begin
    278         Variable := ReadVarReference(TSourceReference(Parameters[0]));
    279         ExecutorVar := Variables.Search(Variable);
    280         if ExecutorVar.Value is TSourceValueString then begin
    281           TSourceValueString(ExecutorVar.Value).Value := FOnInput;
    282           FOnOutput(TSourceValueString(ExecutorVar.Value).Value + LineEnding);
     313        Value := ReadVarReference(TSourceReference(Parameters[0]));
     314        if Value is TSourceValueString then begin
     315          TSourceValueString(Value).Value := FOnInput;
     316          FOnOutput(TSourceValueString(Value).Value + LineEnding);
    283317        end else
    284         if ExecutorVar.Value is TSourceValueInteger then begin
     318        if Value is TSourceValueInteger then begin
    285319          Text := FOnInput;
    286320          if TryStrToInt(Text, IntValue) then
    287             TSourceValueInteger(ExecutorVar.Value).Value := IntValue
    288             else TSourceValueInteger(ExecutorVar.Value).Value := 0;
    289           FOnOutput(IntToStr(TSourceValueInteger(ExecutorVar.Value).Value) + LineEnding);
     321            TSourceValueInteger(Value).Value := IntValue
     322            else TSourceValueInteger(Value).Value := 0;
     323          FOnOutput(IntToStr(TSourceValueInteger(Value).Value) + LineEnding);
    290324        end else
    291325        raise Exception.Create('Unsupported value type');
     
    296330    end else
    297331    if Name = 'increment' then begin
    298       Variable := ReadVarReference(TSourceReference(Parameters[0]));
     332      Dest := ReadVarReference(TSourceReference(Parameters[0]));
    299333      Value := ReadValueReference(TSourceReference(Parameters[1]));
    300       ExecutorVar := Variables.Search(Variable);
    301       if not Assigned(ExecutorVar) then raise Exception.Create('Variable not found');
    302       if (ExecutorVar.Value is TSourceValueInteger) and (Value is TSourceValueInteger) then
    303         Inc(TSourceValueInteger(ExecutorVar.Value).Value, TSourceValueInteger(Value).Value)
     334      if (Dest is TSourceValueInteger) and (Value is TSourceValueInteger) then
     335        Inc(TSourceValueInteger(Dest).Value, TSourceValueInteger(Value).Value)
    304336      else raise Exception.Create('Wrong type for increment');
    305337    end else
    306338    if Name = 'decrement' then begin
    307       Variable := ReadVarReference(TSourceReference(Parameters[0]));
     339      Dest := ReadVarReference(TSourceReference(Parameters[0]));
    308340      Value := ReadValueReference(TSourceReference(Parameters[1]));
    309       ExecutorVar := Variables.Search(Variable);
    310       if not Assigned(ExecutorVar) then raise Exception.Create('Variable not found');
    311       if (ExecutorVar.Value is TSourceValueInteger) and (Value is TSourceValueInteger) then
    312         Dec(TSourceValueInteger(ExecutorVar.Value).Value, TSourceValueInteger(Value).Value)
     341      if (Dest is TSourceValueInteger) and (Value is TSourceValueInteger) then
     342        Dec(TSourceValueInteger(Dest).Value, TSourceValueInteger(Value).Value)
    313343      else raise Exception.Create('Wrong type for increment');
    314344    end else
     
    324354    ExecuteIfEqual(TCommandIfEqual(Command));
    325355  end else
     356  if Command is TCommandIfNotEqual then begin
     357    ExecuteIfNotEqual(TCommandIfNotEqual(Command));
     358  end else
    326359  if Command is TCommandRepeat then begin
    327360    ExecuteRepeat(Command as TCommandRepeat);
  • branches/easy compiler/USourceGenerator.pas

    r148 r149  
    120120    Result := Result + IndentStr + 'repeat' + LineEnding;
    121121    Inc(Indent);
    122     Result := Result + IndentStr +  GenerateCommand(TCommandRepeat(Command).Command) + LineEnding;
     122    Result := Result + GenerateCommand(TCommandRepeat(Command).Command);
    123123    Dec(Indent);
    124124    Result := Result + IndentStr + 'until False;' + LineEnding;
    125125  end else
    126126  if Command is TCommandIfEqual then begin
    127     Result := Result + IndentStr + 'if ' + GenerateRef(TCommandIfEqual(Command).Reference1) +
    128       ' = ' + GenerateRef(TCommandIfEqual(Command).Reference2) + ' then ';
     127    Result := Result + IndentStr + 'if ' +
     128      GenerateRef(TCommandIfEqual(Command).Reference1) + ' = ' +
     129      GenerateRef(TCommandIfEqual(Command).Reference2) + ' then ' + LineEnding;
     130  end else
     131  if Command is TCommandIfNotEqual then begin
     132    Result := Result + IndentStr + 'if ' +
     133      GenerateRef(TCommandIfNotEqual(Command).Reference1) + ' <> ' +
     134      GenerateRef(TCommandIfNotEqual(Command).Reference2) + ' then ' + LineEnding;
    129135  end else
    130136  raise Exception.Create('Unsupported instruction');
Note: See TracChangeset for help on using the changeset viewer.