Press enter to see results or esc to cancel.

System Procedures Write and WriteLn

This function processes system procedures Write and WriteLn.

Function Proc_Write_Writeln: Word; Far;
Var Parameter, FieldWidth, NumOfDecimalPlaces: TExpression;
    TextFileCode, WriteProc: Word;
    BP_C0: TIntermediateCodeOffsets;
Label WriteParameter, ProcessParameter;
begin
  TextFileCode := 0;
  BP_C0.NumberOfStatements := 0;
  If CheckAndGetNextToken (Token_LeftParenthesis) then
    begin
      Parameter.CalculateExpression;
      Case Parameter.TypeDefPtr^.BaseType of
        btFile: begin
                  Parameter.ConvertToPointerAndPush;
                  Proc_Write_Writeln := ProcessReadWriteTypedParameters (PFileTypeDefinition (Parameter.TypeDefPtr),
                                                     Parameter.IntermediateCodeOffset, SysProc_WriteFile);
                  Exit;
                end;
        btText: begin
                  Parameter.ConvertToPointerAndPush;
                  TextFileCode := Parameter.IntermediateCodeOffset;
                end;
        else GoTo ProcessParameter;
      end;

      While CheckAndGetNextToken (Token_Comma) do
        begin
          Parameter.CalculateExpression;

ProcessParameter:

          NumOfDecimalPlaces.IntermediateCodeOffset := 0;
          If ExtendedSyntax in StatementCompilerSwitches then Parameter.ConvertZeroBasedCharacterArrayToPChar;
          Parameter.CopyCharArrayCompatibleWithStringToStackFrameAsString;
          With Parameter do If (ExtendedSyntax in StatementCompilerSwitches) and
            (TypeDefPtr = Ptr (SystemUnitSegment, PChar_TypeOffset)) then
              begin
                PushExpression;
                PushParameterSpecifier (0, FieldWidth);
                WriteProc := SysProc_WritePChar;
              end else
          Case TypeDefPtr^.BaseType of
            btString: begin
                        StoreStringConstantToCodeBlock;
                        If IsExpressionInOverlaidCode then CopyStringToStackFrame ($0100);
                        ConvertToPointerAndPush;
                        PushParameterSpecifier (0, FieldWidth);
                        WriteProc := SysProc_WriteStr;
                      end;
            btExtended,
            btReal: begin
                      If Instructions80x87 in StatementCompilerSwitches then
                        begin
                          ConvertRealToExtended;
                          LoadExpressionToFPU;
                          PushParameterSpecifier (23, FieldWidth);
                          PushParameterSpecifier ($FFFF, NumOfDecimalPlaces);
                          WriteProc := SysProc_WriteFloat;
                        end else
                          begin
                            ConvertExtendedToReal;
                            PushRealExpression;
                            PushParameterSpecifier (17, FieldWidth);
                            PushParameterSpecifier ($FFFF, NumOfDecimalPlaces);
                            WriteProc := SysProc_WriteReal
                          end;
                    end;
              btInteger: begin
                           CheckOrdinalRange (Ptr (SystemUnitSegment, LongInt_TypeOffset));
                           PushExpression;
                           PushParameterSpecifier (0, FieldWidth);
                           WriteProc := SysProc_WriteInt;
                         end;
              btBoolean: begin
                           ExtendInteger ([]);
                           PushExpression;
                           PushParameterSpecifier (0, FieldWidth);
                           WriteProc := SysProc_WriteBool;
                         end;
              btChar: begin
                        PushExpression;
                        PushParameterSpecifier (0, FieldWidth);
                        WriteProc := SysProc_WriteChar;
                      end;
            else Error (CannotReadOrWriteVariablesOfThisType);
          end;
          StoreCode_icGoSub (Parameter.IntermediateCodeOffset);
          StoreCode_icGoSub (FieldWidth.IntermediateCodeOffset);
          StoreCode_icGoSub (NumOfDecimalPlaces.IntermediateCodeOffset);
          GenerateInstruction_CALL_FAR (WriteProc);
          AddCallToIntermediateCodeSubroutine (BP_C0, EndSubroutine);
        end;
      ExpectTokenAndGetNext (Token_RightParenthesis);
    end;
  PushPointerToTextRec (TextFileCode, $0100);
  Generate_icGoSub_ForEachSubroutine (BP_C0);
  GenerateInstruction_CALL_FAR (ProcParameter);
  GenerateIOErrorCheckingCode;
  Proc_Write_Writeln := EndSubroutine;
end;

This function processes typed parameters for Read and Write procedures, pushes them on stack and generates a call to a compiler routine for each.

Function ProcessReadWriteTypedParameters (FileTypeDefinition: PFileTypeDefinition;
                                          FileVarIntermediateCodeOffset, ParameterSysProc: Word): Word;
Var BaseFileTypeOffset: PTypeDefinition;
    IntermediateCodeOffsets: TIntermediateCodeOffsets;
    Parameter: TExpression;
begin
  Case ProcParameter of
    SysProc_ReadLine,
    SysProc_WriteLine: Error (InvalidFileType);
  end;
  If FileTypeDefinition^.BaseFileTypeOffset.TypeOffset = 0 then Error (InvalidFileType);
  BaseFileTypeOffset := PointerFromOffsets (FileTypeDefinition^.BaseFileTypeOffset);
  IntermediateCodeOffsets.NumberOfStatements := 0;
  ExpectTokenAndGetNext (Token_Comma);
  Repeat
    With Parameter do
      begin
        ExpectAssignableVariableReferenceExceptProcAndFuncAndPushPointerToMemory;
        If TypeDefPtr <> BaseFileTypeOffset then Error (InvalidFileType);
        Calculate;
        GenerateInstruction_CALL_FAR (ParameterSysProc);
        AddCallToIntermediateCodeSubroutine (IntermediateCodeOffsets, EndSubroutine);
      end;
  until not CheckAndGetNextToken (Token_Comma);
  ExpectTokenAndGetNext (Token_RightParenthesis);
  StoreCode_icGoSub (FileVarIntermediateCodeOffset);
  Generate_icGoSub_ForEachSubroutine (IntermediateCodeOffsets);
  GenerateInstruction_TwoBytes ($83, $C4);
  GenerateInstruction_Byte ($04);
  GenerateIOErrorCheckingCode;
  ProcessReadWriteTypedParameters := EndSubroutine;
end;