Ignore:
Timestamp:
Feb 11, 2017, 6:55:42 PM (8 years ago)
Author:
chronos
Message:
  • Modified: Now project3 can interpret project2.
  • Modified: To support standard input and output inside interpreter, all lines read from input starting with | symbol is passed to interpreted code. Also text written to standard output by interpretted program is prefixed with | symbol.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/interpreter/Execute3.pas

    r101 r102  
    5252implementation
    5353
     54uses
     55  Parser3;
     56
    5457procedure ExecuteCommand(Command: PCommand); forward;
    5558procedure ExecuteGetValue(GetValue: PGetValue; Value: PVariableValue); forward;
     
    7477procedure ShowErrorType(Variable: PVariableValue);
    7578begin
    76   ShowError('Not suppoted type')
     79  ShowError('Not supported type')
    7780end;
    7881
     
    8184  case Result^.BaseType of
    8285    btBoolean: ShowErrorType(Result);
    83     btChar: ShowErrorType(Result);
     86    btChar: begin
     87      Result.BaseType := btShortString;
     88      Result.ValueString := Result.ValueString + Operand.ValueChar;
     89    end;
    8490    btInteger: Result^.ValueInteger := Result^.ValueInteger + Operand^.ValueInteger;
    85     btShortString: Result^.ValueString := Result^.ValueString + Operand^.ValueString;
     91    btShortString: begin
     92      if Operand^.BaseType = btShortString then
     93        Result^.ValueString := Result^.ValueString + Operand^.ValueString
     94      else if Operand^.BaseType = btChar then
     95        Result^.ValueString := Result^.ValueString + Operand^.ValueChar
     96      else ShowErrorType(Result);
     97    end;
     98  end;
     99end;
     100
     101procedure VariableNot(Result, Operand: PVariableValue);
     102begin
     103  case Result^.BaseType of
     104    btBoolean: Result^.ValueBoolean := not Operand^.ValueBoolean;
     105    btChar: ShowErrorType(Result);
     106    btInteger: ShowErrorType(Result);
     107    btShortString: ShowErrorType(Result);
    86108  end;
    87109end;
     
    141163  I: Integer;
    142164  SubValue: TVariableValue;
     165  Operand1: TVariableValue;
    143166begin
    144167  if Expression^.NodeType = ntOperator then begin
     
    155178        // Just assign first operand
    156179        case Expression^.OperatorType of
     180          opNot: begin
     181            Value.BaseType := btBoolean;
     182            VariableNot(Value, @SubValue);
     183          end;
    157184          opAdd: AssignVariable(Value, @SubValue);
    158185          opSubtract: AssignVariable(Value, @SubValue);
    159186          opAnd: AssignVariable(Value, @SubValue);
    160187          opOr: AssignVariable(Value, @SubValue);
    161           opEqual: AssignVariable(Value, @SubValue);
    162           opNotEqual: AssignVariable(Value, @SubValue);
     188          opEqual: AssignVariable(@Operand1, @SubValue);
     189          opNotEqual: AssignVariable(@Operand1, @SubValue);
    163190          else ShowError('Unsupported operator type');
    164191        end;
     
    169196          opAnd: VariableAnd(Value, @SubValue);
    170197          opOr: VariableOr(Value, @SubValue);
    171           opEqual: VariableEqual(Value, Value, @SubValue);
    172           opNotEqual: VariableNotEqual(Value, Value, @SubValue);
     198          opEqual: begin
     199            Value.BaseType := btBoolean;
     200            VariableEqual(Value, @Operand1, @SubValue);
     201          end;
     202          opNotEqual: begin
     203            Value.BaseType := btBoolean;
     204            VariableNotEqual(Value, @Operand1, @SubValue);
     205          end
    173206          else ShowError('Unsupported operator type');
    174207        end;
     
    262295begin
    263296  if Execution^.Func^.Name = 'WriteLn' then begin
    264     WriteLn(ExecutionContextCurrent^.VariableValues.GetByName('Text')^.ValueString)
     297    WriteLn('|' + ExecutionContextCurrent^.VariableValues.GetByName('Text')^.ValueString)
    265298  end else
    266299  if Execution^.Func^.Name = 'Halt' then begin
    267300    Halt;
    268301  end else
     302  if Execution^.Func^.Name = 'Read' then begin
     303    ExecutionContextCurrent^.VariableValues.GetByName('Output')^.ValueChar := InnerText[InnerTextPos];
     304    InnerTextPos := InnerTextPos + 1;
     305  end else
    269306  if Execution^.Func^.Name = 'Eof' then begin
    270307    ExecuteBuildInSetResult(Execution, 'Boolean');
    271     ExecutionContextCurrent^.VariableValues.GetByName('Result')^.ValueBoolean := True;
     308    ExecutionContextCurrent^.VariableValues.GetByName('Result')^.ValueBoolean := InnerTextPos > Length(InnerText);
    272309  end else ShowError('Unsupported build-in function.');
    273310end;
     
    297334  ExecutionContexts.Items[Length(ExecutionContexts.Items) - 1] := NewContext;
    298335
    299   //WriteLn('Executed ' + Execution^.Func^.Name);
     336  WriteLn('Executed ' + Execution^.Func^.Name);
    300337  if IsBuildInFunction(Execution^.Func^.Name) then ExecuteBuildIn(Execution)
    301338    else ExecuteBeginEnd(@Execution^.Func^.BeginEnd);
    302339  if (ReturnValue <> nil) and (Execution^.Func^.ReturnType <> nil) then
    303340    AssignVariable(ReturnValue, ExecutionContextCurrent^.VariableValues.GetByName('Result'));
     341
     342  WriteLn('Return from ' + Execution^.Func^.Name);
     343
     344  // Copy output parameters back to variable
     345  NewContext := ExecutionContexts.Items[Length(ExecutionContexts.Items) - 1];
    304346  ExecutionContexts.RemoveLast;
     347
     348  for I := 0 to Length(Execution^.Func^.Parameters.Items) - 1 do
     349  if Execution^.Func^.Parameters.Items[I].Output then begin
     350    DestVar := NewContext.VariableValues.GetByName(
     351      Execution^.Func^.Parameters.Items[I].Name);
     352    Param := @Execution^.Parameters.Items[I];
     353    if (Param.ReadType = rtVariable) then
     354      AssignVariable(ExecutionContextCurrent^.VariableValues.GetByName(Param.Variable.Name), DestVar)
     355    else ShowError('Function var parameter can be only variable');
     356  end;
    305357end;
    306358
     
    311363begin
    312364  DestVariable := ExecutionContextCurrent^.VariableValues.GetByName(Assignment^.Destination^.Name);
     365  WriteLn('Assignment to ' + Assignment^.Destination^.Name);
    313366  FillChar(SrcVariable, SizeOf(TVariableValue), 0);
    314367  ExecuteGetValue(@Assignment^.Source, @SrcVariable);
Note: See TracChangeset for help on using the changeset viewer.