Ignore:
Timestamp:
Jan 17, 2018, 5:27:23 PM (7 years ago)
Author:
chronos
Message:
  • Added: Unfinished support for variable arrays.
File:
1 edited

Legend:

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

    r147 r148  
    4444    RepeatBlocks: TExecutorRepeats;
    4545    SkipNext: Boolean;
     46    procedure ExecuteAssign(CommandAssign: TCommandFunctionCall);
    4647    procedure ExecuteBeginEnd(BeginEnd: TCommandBeginEnd);
    4748    procedure ExecuteCommand(Command: TSourceCommand);
    4849    procedure ExecuteBreak(CommandBreak: TCommandBreak);
     50    procedure ExecuteIfEqual(IfEqual: TCommandIfEqual);
    4951    procedure ExecuteRepeat(CommandRepeat: TCommandRepeat);
    5052    function ReadValueReference(Reference: TSourceReference): TSourceValue;
     
    120122
    121123function TSourceExecutor.ReadValueReference(Reference: TSourceReference): TSourceValue;
     124var
     125  ArrayIndex: TSourceValue;
    122126begin
    123127  Result := nil;
     
    127131  if Reference is TSourceReferenceVariable then begin
    128132    Result := Variables.Search(TSourceReferenceVariable(Reference).Variable).Value;
    129   end else raise Exception.Create('Unsupported reference');
     133  end else
     134  if Reference is TSourceReferenceArray then begin
     135    ArrayIndex := ReadValueReference(TSourceReferenceArray(Reference).Index);
     136    if not (ArrayIndex is TSourceValueInteger) then
     137      raise Exception.Create('Only integer array index supported');
     138    Result := TSourceValue(TSourceValueArray(Variables.Search(TSourceReferenceArray(Reference).ArrayRef).Value).Items[TSourceValueInteger(ArrayIndex).Value]);
     139  end else
     140  raise Exception.Create('Unsupported reference');
    130141end;
    131142
    132143function TSourceExecutor.ReadVarReference(Reference: TSourceReference): TSourceVariable;
     144var
     145  ArrayIndex: TSourceValue;
    133146begin
    134147  Result := nil;
    135148  if Reference is TSourceReferenceVariable then begin
    136149    Result := TSourceReferenceVariable(Reference).Variable;
     150  end else
     151  if Reference is TSourceReferenceArray then begin
     152    ArrayIndex := ReadValueReference(TSourceReferenceArray(Reference).Index);
     153    if not (ArrayIndex is TSourceValueInteger) then
     154      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);
    137157  end else raise Exception.Create('Unsupported reference');
     158end;
     159
     160procedure TSourceExecutor.ExecuteAssign(CommandAssign: TCommandFunctionCall);
     161var
     162  Variable: TSourceVariable;
     163  Value: TSourceValue;
     164  ExecutorVar: TExecutorVariable;
     165begin
     166  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);
     177  end;
    138178end;
    139179
     
    170210  end else
    171211  raise Exception.Create('Used break outside repeat loop');
     212end;
     213
     214procedure TSourceExecutor.ExecuteIfEqual(IfEqual: TCommandIfEqual);
     215var
     216  Value1: TSourceValue;
     217  Value2: TSourceValue;
     218begin
     219  Value1 := ReadValueReference(IfEqual.Reference1);
     220  Value2 := ReadValueReference(IfEqual.Reference2);
     221  if (Value1 is TSourceValueInteger) and (Value2 is TSourceValueInteger) then begin
     222    if TSourceValueInteger(Value1).Value <> TSourceValueInteger(Value2).Value then
     223      SkipNext := True;
     224  end else
     225  if (Value1 is TSourceValueString) and (Value2 is TSourceValueString) then begin
     226    if TSourceValueString(Value1).Value <> TSourceValueString(Value2).Value then
     227      SkipNext := True;
     228  end else
     229  raise Exception.Create('Unsupported types for comparison.');
    172230end;
    173231
     
    235293    end else
    236294    if Name = 'assign' then begin
    237       Variable := ReadVarReference(TSourceReference(Parameters[0]));
    238       Value := ReadValueReference(TSourceReference(Parameters[1]));
    239       ExecutorVar := Variables.Search(Variable);
    240       if not Assigned(ExecutorVar) then begin
    241         ExecutorVar := TExecutorVariable.Create;
    242         ExecutorVar.Variable := Variable;
    243         Variables.Add(ExecutorVar);
    244         ExecutorVar.Value := Variable.ValueType.ValueClass.Create;
    245       end;
    246       ExecutorVar.Value.Assign(Value);
     295      ExecuteAssign(TCommandFunctionCall(Command));
    247296    end else
    248297    if Name = 'increment' then begin
     
    272321    ExecuteBreak(TCommandBreak(Command));
    273322  end else
    274   if Command is TCommandIfZero then begin
    275     ExecutorVar := Variables.Search(TCommandIfZero(Command).Variable.Variable);
    276     if Assigned(ExecutorVar) then begin
    277       if ExecutorVar.Variable.ValueType.Name = 'Integer' then begin
    278         if TSourceValueInteger(ExecutorVar.Value).Value <> 0 then SkipNext := True;
    279       end else
    280       raise Exception.Create('Can compare only integers');
    281     end else
    282     raise Exception.Create('Variable not found');
     323  if Command is TCommandIfEqual then begin
     324    ExecuteIfEqual(TCommandIfEqual(Command));
    283325  end else
    284326  if Command is TCommandRepeat then begin
Note: See TracChangeset for help on using the changeset viewer.