Changeset 102


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.
Location:
branches/interpreter
Files:
4 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);
  • branches/interpreter/Parser3.pas

    r101 r102  
    1010procedure ParseProgram(ProgramCode: PProgramCode);
    1111
     12
     13var
     14  InnerText: string;
     15  InnerTextPos: Integer;
    1216
    1317implementation
     
    6165procedure ReadInputAll;
    6266var
     67  LastC: Char;
    6368  C: Char;
    64 begin
     69  Inner: Boolean;
     70begin
     71  LastC := #0;
    6572  InputTextPos := 1;
    6673  InputText := '';
     74  InnerTextPos := 1;
     75  InnerText := '';
     76  Inner := False;
    6777  while not Eof do begin
    6878    Read(C);
    69     InputText := InputText + C;
     79    if ((LastC = #0) or (LastC = #13) or (LastC = #10)) and (C = '|') then begin
     80      Inner := True;
     81      LastC := C;
     82      Continue;
     83    end else
     84    if ((LastC = #0) or (LastC = #13) or (LastC = #10)) and (C <> '|') then begin
     85      Inner := False;
     86    end;
     87    if Inner then InnerText := InnerText + C
     88      else InputText := InputText + C;
     89    LastC := C;
    7090  end;
    7191end;
     
    296316  I: Integer;
    297317  II: Integer;
    298 begin
     318  FoundOperator: Boolean;
     319  OldPos: Integer;
     320begin
     321  OldPos := InputTextPos;
    299322  Result := True;
     323  FoundOperator := False;
    300324  repeat
    301325    if CheckNext('(') then begin
     
    312336      Expression^.Items[Length(Expression^.Items) - 1].NodeType := ntOperator;
    313337      Expression^.Items[Length(Expression^.Items) - 1].OperatorType := ExpOperator;
     338      FoundOperator := True;
    314339    end else
    315340    if ParseGetValue(@GetValue, True) then begin
     
    322347    end;
    323348  until False;
     349  if not FoundOperator then begin
     350    Result := False;
     351    InputTextPos := OldPos;
     352    Exit;
     353  end;
    324354
    325355  if Length(Expression^.Items) > 0 then begin
     
    340370            Expression^.Items[I].Associated := True;
    341371            SetLength(Expression^.Items[I].Items, 2);
    342             Expression^.Items[I].Items[1] := Expression^.Items[I - 1];
    343             Expression^.Items[I].Items[0] := Expression^.Items[I + 1];
     372            Expression^.Items[I].Items[0] := Expression^.Items[I - 1];
     373            Expression^.Items[I].Items[1] := Expression^.Items[I + 1];
    344374            DeleteExpressionItem(Expression, I + 1);
    345375            DeleteExpressionItem(Expression, I - 1);
     
    686716  ProgramCode^.Functions.Add(FunctionCreate('Read', nil));
    687717  FuncRead := ProgramCode^.Functions.GetLast;
    688   FuncRead^.Parameters.Add(FunctionParameterCreate('Output', TypeChar));
     718  FuncRead^.Parameters.Add(FunctionParameterCreate('Output', TypeChar, True));
     719  FuncRead^.Variables.Add(VariableCreate('Output', TypeChar));
    689720  ProgramCode^.Functions.Add(FunctionCreate('Eof', TypeBoolean));
    690721  ProgramCode^.Functions.Add(FunctionCreate('Length', TypeInteger));
  • branches/interpreter/Source3.pas

    r101 r102  
    7272    Name: string;
    7373    DataType: PType;
     74    Output: Boolean;
    7475  end;
    7576
     
    185186function FunctionCreate(Name: string; DataType: PType): TFunction;
    186187function TypeCreate(Name: string; BaseType: TBaseType): TType;
    187 function FunctionParameterCreate(Name: string; DataType: PType): TFunctionParameter;
     188function FunctionParameterCreate(Name: string; DataType: PType; Output: Boolean = False): TFunctionParameter;
    188189
    189190var
     
    216217end;
    217218
    218 function FunctionParameterCreate(Name: string; DataType: PType): TFunctionParameter;
     219function FunctionParameterCreate(Name: string; DataType: PType; Output: Boolean = False): TFunctionParameter;
    219220begin
    220221  Result.Name := Name;
    221222  Result.DataType := DataType;
     223  Result.Output := Output;
    222224end;
    223225
  • branches/interpreter/project2.lpr

    r95 r102  
    4747end.
    4848
     49|begin
     50|end.
Note: See TracChangeset for help on using the changeset viewer.