Recent

Author Topic: Assigning values for an array between "begin - end" block [SOLVED]  (Read 3894 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 3269
Re: Assigning values for an array between "begin - end" block [SOLVED]
« Reply #30 on: September 05, 2021, 03:53:49 pm »
Good news Mark! it means that we have the power to add more abilities and functions to Pascal.

That's right, it's open-source so one learns ones way round the code and modifies it.

Quote
I know an abandoned way of inputing data in BASIC, and I liked it but never see it in any other language:

It was supported by FORTRAN and at least some dialects of ALGOL, and was typically used where both a program and associated data were embedded in a deck of cards:

Code: [Select]
?USER = MARKMLL
?COMPILE HELLO/ALGOL ALGOL
?PROCESS MINUTES = 1
?FILE OUTPUT = MARKMLL/OUTPUT PUNCH
?COMMON = 1
?DATA CARD
$CARD LIST SINGLE PRT DEBUGN
% ---------------------------------------------------------------------------- %
BEGIN

COMMENT  THE MCP HAS AN ARRAY OF PRT DESCRIPTORS, INDEXED BY MIX
         NUMBER. EACH PROGRAM HAS ITS R REGISTER SET TO THE CURRENT
         ABSOLUTE ADDRESS OF ITS PRT WHILE RUNNING, AND ACCESSES WILL
         BE OFFSETS RELATIVE TO THIS. ANY ATTEMPT TO DETERMINE AN
         ABSOLUTE ADDRESS AT RUNTIME SHOULD BE TREATED WITH EXTREME
         CAUTION, SINCE THINGS WILL MOVE AROUND ACCORDING TO THE
         VAGARIES OF VIRTUAL MEMORY;

  INTEGER STREAM PROCEDURE ABSADDR(A);

  BEGIN
    SI := A;
    ABSADDR := SI
  END ABSADDR;

COMMENT  THIS IS THE FIRST VARIABLE AFTER THE PRT, SET USING THE COMMON
         CARD OR BY THE IN COMMAND AT THE SPO. IT MAY BE INSPECTED
         USING THE SPO%S OT COMMAND, NOTING THAT THESE COMMANDS TAKE
         OCTAL ADDRESSES AND THAT THE STRUCTURE OF THIS PROGRAM
         SUGGESTS THAT THE OFFSET (RELATIVE TO THE PRT AND THE CPU%S
         R REGISTER) IS LIKELY TO BE AROUND 8R26;

  INTEGER BEASTLY;                      % INITIALISED TO 1 BY COMMON CARD      %
  REAL T, PI;
  FILE IN CARD(1, 10);                  % ONE BUFFER OF 10 WORDS (80 CHARS)    %
  FILE OUT OUTPUT(1, 10);
  FILE OUT ERROR 11 (1, 10);            % DEFINED AS THE OPERATOR%S SPO DEVICE %

COMMENT  BASIC TEST OF OUTPUT TO CPA AND INPUT FROM CRA (THIS DECK);

  WRITE(OUTPUT, <"HELLO, WORLD!">);     % <> IDENTIFIES FORMAT SPECIFICATION   %
  READ(CARD, /, T);                     % / IS FREE-FORMAT, TERMINATED BY ,    %

COMMENT  BASIC TEST OF NUMERIC OPERATORS IN (TRANSLATED) CARD INPUT;

  PI := 3.14159265359;
  WRITE(OUTPUT, <"FIRST INTEGER VARIABLE AT", I8, " CONTAINS", I8>,
                                        ABSADDR(BEASTLY),  BEASTLY);
  WRITE(OUTPUT, <"T:                  ", F16.8>, T);
  WRITE(OUTPUT, <"T + PI, PI + T:     ", 2F16.8>, T + PI, PI + T);
  WRITE(OUTPUT, <"T - PI, PI - T:     ", 2F16.8>, T - PI, PI - T);
  WRITE(OUTPUT, <"T * PI, PI * T:     ", 2F16.8>, T | PI, PI | T); % OR TIMES  %
  WRITE(OUTPUT, <"T / PI, PI / T:     ", 2F16.8>, T / PI, PI / T);
  WRITE(OUTPUT, <"T DIV PI, PI DIV T: ", 2F16.8>, T DIV PI, PI DIV T);
  WRITE(OUTPUT, <"T MOD PI, PI MOD T: ", 2F16.8>, T MOD PI, PI MOD T);
  WRITE(OUTPUT, <"T ** PI, PI ** T:   ", 2F16.8>, T * PI, PI * T);
  WRITE(OUTPUT, <"T X PI FOR LE EQ NE GE:  ", 4L6>,
                                        T { PI, T = PI, T ! PI, T } PI);
COMMENT  ----------- NOTE ALGOL STATEMENT LIMIT OF 72 CHARS -----------; 4567890
% ---------------------- NOTE CARD LIMIT OF 80 COLUMNS ----------------------- %

COMMENT  WE EXPECT THAT THE FIRST VARIABLE HAS BEEN SET TO 1 BY THE
         COMMON CARD. IF THE NEXT LINE IS COMMENTED OUT THEN SHOW
         THAT IT IS POSSIBLE TO ASK THE OPERATOR TO PUT A SPECIFIC
         VALUE INTO A GLOBAL VARIABLE WHILE THE PROGRAM IS BEING
         EXECUTED (CONSIDER THE BILLING IMPLICATIONS BEFORE OVERUSING
         THIS, AND BEWARE OF IRRITATING THE OPERATOR WHO%S YOUR BEST
         FRIEND AROUND HERE);

  BEASTLY := 0;                  % OVERRIDE OPERATOR INVOLVEMENT        %
  IF BEASTLY = 1 THEN BEGIN             % CONTROL CARD SET COMMON VARIABLE OK  %
    BEASTLY := 666;                     % INSPECT AT SPO USING E.G. 2 OT 26,   %
    IF BEASTLY ! 1 THEN BEGIN           % NOTE OCTAL OFFSET FOR IN AND OT CMDS %
      WRITE(ERROR, <"MY COMMON AT PRT+8R26 IS 666, PLEASE SET TO 1">);
      WAIT(ABSADDR(BEASTLY), 1);        % SET USING E.G. 2 IN 26=1             %
    END IF
  END IF % ANYTHING AFTER END IS IGNORED HERE.                                 %
END.     % END MUST BE FOLLOWED IMMEDIATELY BY . HERE ------------------------ %
?DATA CARD
4.0,
?END

However, in the larger scheme of things those were implemented because there was no facility by which the user could initiate his program, hence he could neither enter data interactively nor specify a file to be piped in as input.

The above example is a complete, working control deck from Burroughs ALGOL running on one of their mainframes in the mid 60s. Note also the occurrence of $ cards which were read by the compiler (rather than by the OS), and that Wirth was intimately familiar with one of these systems from his time at Stanford. Note also the . after the final END, which was another Burroughsism.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

pascal111

  • Sr. Member
  • ****
  • Posts: 359
  • Un trabajo en equipo para programas serias.
Re: Assigning values for an array between "begin - end" block [SOLVED]
« Reply #31 on: September 05, 2021, 07:07:47 pm »

Quote
I know an abandoned way of inputing data in BASIC, and I liked it but never see it in any other language:

It was supported by FORTRAN and at least some dialects of ALGOL, and was typically used where both a program and associated data were embedded in a deck of cards:

Code: [Select]
?USER = MARKMLL
?COMPILE HELLO/ALGOL ALGOL
?PROCESS MINUTES = 1
?FILE OUTPUT = MARKMLL/OUTPUT PUNCH
?COMMON = 1
?DATA CARD
$CARD LIST SINGLE PRT DEBUGN
% ---------------------------------------------------------------------------- %
BEGIN

COMMENT  THE MCP HAS AN ARRAY OF PRT DESCRIPTORS, INDEXED BY MIX
         NUMBER. EACH PROGRAM HAS ITS R REGISTER SET TO THE CURRENT
         ABSOLUTE ADDRESS OF ITS PRT WHILE RUNNING, AND ACCESSES WILL
         BE OFFSETS RELATIVE TO THIS. ANY ATTEMPT TO DETERMINE AN
         ABSOLUTE ADDRESS AT RUNTIME SHOULD BE TREATED WITH EXTREME
         CAUTION, SINCE THINGS WILL MOVE AROUND ACCORDING TO THE
         VAGARIES OF VIRTUAL MEMORY;

  INTEGER STREAM PROCEDURE ABSADDR(A);

  BEGIN
    SI := A;
    ABSADDR := SI
  END ABSADDR;

COMMENT  THIS IS THE FIRST VARIABLE AFTER THE PRT, SET USING THE COMMON
         CARD OR BY THE IN COMMAND AT THE SPO. IT MAY BE INSPECTED
         USING THE SPO%S OT COMMAND, NOTING THAT THESE COMMANDS TAKE
         OCTAL ADDRESSES AND THAT THE STRUCTURE OF THIS PROGRAM
         SUGGESTS THAT THE OFFSET (RELATIVE TO THE PRT AND THE CPU%S
         R REGISTER) IS LIKELY TO BE AROUND 8R26;

  INTEGER BEASTLY;                      % INITIALISED TO 1 BY COMMON CARD      %
  REAL T, PI;
  FILE IN CARD(1, 10);                  % ONE BUFFER OF 10 WORDS (80 CHARS)    %
  FILE OUT OUTPUT(1, 10);
  FILE OUT ERROR 11 (1, 10);            % DEFINED AS THE OPERATOR%S SPO DEVICE %

COMMENT  BASIC TEST OF OUTPUT TO CPA AND INPUT FROM CRA (THIS DECK);

  WRITE(OUTPUT, <"HELLO, WORLD!">);     % <> IDENTIFIES FORMAT SPECIFICATION   %
  READ(CARD, /, T);                     % / IS FREE-FORMAT, TERMINATED BY ,    %

COMMENT  BASIC TEST OF NUMERIC OPERATORS IN (TRANSLATED) CARD INPUT;

  PI := 3.14159265359;
  WRITE(OUTPUT, <"FIRST INTEGER VARIABLE AT", I8, " CONTAINS", I8>,
                                        ABSADDR(BEASTLY),  BEASTLY);
  WRITE(OUTPUT, <"T:                  ", F16.8>, T);
  WRITE(OUTPUT, <"T + PI, PI + T:     ", 2F16.8>, T + PI, PI + T);
  WRITE(OUTPUT, <"T - PI, PI - T:     ", 2F16.8>, T - PI, PI - T);
  WRITE(OUTPUT, <"T * PI, PI * T:     ", 2F16.8>, T | PI, PI | T); % OR TIMES  %
  WRITE(OUTPUT, <"T / PI, PI / T:     ", 2F16.8>, T / PI, PI / T);
  WRITE(OUTPUT, <"T DIV PI, PI DIV T: ", 2F16.8>, T DIV PI, PI DIV T);
  WRITE(OUTPUT, <"T MOD PI, PI MOD T: ", 2F16.8>, T MOD PI, PI MOD T);
  WRITE(OUTPUT, <"T ** PI, PI ** T:   ", 2F16.8>, T * PI, PI * T);
  WRITE(OUTPUT, <"T X PI FOR LE EQ NE GE:  ", 4L6>,
                                        T { PI, T = PI, T ! PI, T } PI);
COMMENT  ----------- NOTE ALGOL STATEMENT LIMIT OF 72 CHARS -----------; 4567890
% ---------------------- NOTE CARD LIMIT OF 80 COLUMNS ----------------------- %

COMMENT  WE EXPECT THAT THE FIRST VARIABLE HAS BEEN SET TO 1 BY THE
         COMMON CARD. IF THE NEXT LINE IS COMMENTED OUT THEN SHOW
         THAT IT IS POSSIBLE TO ASK THE OPERATOR TO PUT A SPECIFIC
         VALUE INTO A GLOBAL VARIABLE WHILE THE PROGRAM IS BEING
         EXECUTED (CONSIDER THE BILLING IMPLICATIONS BEFORE OVERUSING
         THIS, AND BEWARE OF IRRITATING THE OPERATOR WHO%S YOUR BEST
         FRIEND AROUND HERE);

  BEASTLY := 0;                  % OVERRIDE OPERATOR INVOLVEMENT        %
  IF BEASTLY = 1 THEN BEGIN             % CONTROL CARD SET COMMON VARIABLE OK  %
    BEASTLY := 666;                     % INSPECT AT SPO USING E.G. 2 OT 26,   %
    IF BEASTLY ! 1 THEN BEGIN           % NOTE OCTAL OFFSET FOR IN AND OT CMDS %
      WRITE(ERROR, <"MY COMMON AT PRT+8R26 IS 666, PLEASE SET TO 1">);
      WAIT(ABSADDR(BEASTLY), 1);        % SET USING E.G. 2 IN 26=1             %
    END IF
  END IF % ANYTHING AFTER END IS IGNORED HERE.                                 %
END.     % END MUST BE FOLLOWED IMMEDIATELY BY . HERE ------------------------ %
?DATA CARD
4.0,
?END

However, in the larger scheme of things those were implemented because there was no facility by which the user could initiate his program, hence he could neither enter data interactively nor specify a file to be piped in as input.

The above example is a complete, working control deck from Burroughs ALGOL running on one of their mainframes in the mid 60s. Note also the occurrence of $ cards which were read by the compiler (rather than by the OS), and that Wirth was intimately familiar with one of these systems from his time at Stanford. Note also the . after the final END, which was another Burroughsism.

MarkMLl

Wow! ALGOL, I didn't try it before, and it seems good language, but for our bad luck I think that "read-data" feature was in languages of old machines or OS's except maybe the modern dialcts of BASIC.

MarkMLl

  • Hero Member
  • *****
  • Posts: 3269
Re: Assigning values for an array between "begin - end" block [SOLVED]
« Reply #32 on: September 05, 2021, 07:53:32 pm »
Wow! ALGOL, I didn't try it before, and it seems good language, but for our bad luck I think that "read-data" feature was in languages of old machines or OS's except maybe the modern dialcts of BASIC.

ALGOL-60 was famously described as better than any language which had preceded it and most that had followed it.

Suggest you look at the unix shell's here-document facility .

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

PascalDragon

  • Hero Member
  • *****
  • Posts: 3412
  • Compiler Developer
Re: Assigning values for an array between "begin - end" block [SOLVED]
« Reply #33 on: September 06, 2021, 09:38:29 am »
What I don't understand about freepascal is how easily const values can be changed.
I know const in a procedure really means static, but in the main module what actually does const do??

Due to compatibility to Turbo Pascal (and later Delphi) typed constants are essentially variables with the added benefit of them being static inside routines. So outside of routines you really didn't have that much of a difference. With Delphi the {$WriteableConsts On/Off} directive was introduced that allows to really set those to be read only. In that case FPC will put the data into a read only section so your example would fail there with an exception (at least on Windows, I think on *nix platforms the data is still in a R/W section due to required relocations). At least in direct assignments compilation would already fail however.

pascal111

  • Sr. Member
  • ****
  • Posts: 359
  • Un trabajo en equipo para programas serias.
Re: Assigning values for an array between "begin - end" block [SOLVED]
« Reply #34 on: September 06, 2021, 11:18:41 am »
Wow! ALGOL, I didn't try it before, and it seems good language, but for our bad luck I think that "read-data" feature was in languages of old machines or OS's except maybe the modern dialcts of BASIC.

ALGOL-60 was famously described as better than any language which had preceded it and most that had followed it.

Suggest you look at the unix shell's here-document facility .

MarkMLl

ALGOL-60 seems nice, it has some similarity with Pascal, one day I'll look in its code style, thanks!

MarkMLl

  • Hero Member
  • *****
  • Posts: 3269
Re: Assigning values for an array between "begin - end" block [SOLVED]
« Reply #35 on: September 06, 2021, 12:08:29 pm »
ALGOL is Pascal's immediate predecessor. The thing I was trying to illustrate was not so much the syntax, as the way that setup directives, program source and raw data were in that era bundled together into a job. Multiple jobs (e.g. for a lecture group of students) would have been assembled into a batch, and run through the computer with the operator handling the printer output etc.

BASIC was one of the first languages which provided support for multiple interactive users. To be honest it was a bit of an afterthought for Pascal, and if you look at the earliest documentation you will also see that it assumes that associating I/O and specific filenames was considered to be outside the scope of the language i.e. was handled by some sort of manufacturer-specific job control language as in the example I've given you.

Perhaps the main problem with simply appending data to program source is that there's no error checking involved: it's outside the scope of the compiler so it's not possible to warn that a float is about to be allocated when an integer is expected, and it's not possible to use a data structure (e.g. a record) and specify which fields are to be populated. And not allowing the compiler to check predefined input is, apart from anything else, a recipe for security violations (trust me, early mainframes were by no means immune to that sort of thing).

Purists would say that if you want predefined data (and assuming that you're using Lazarus) then you embed it into the executable as a resource. But that has much the same problems as I've listed above, and I'd suggest that a better solution would be to embed it as a constant (i.e. initialisation of a constant record or array) contained in an include file: that has the advantage that the include file can be generated by some other program if you want e.g. a big actuarial table.

MarkMLl
Turbo Pascal v1 on CCP/M-86, multitasking with LAN and graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

pascal111

  • Sr. Member
  • ****
  • Posts: 359
  • Un trabajo en equipo para programas serias.
Re: Assigning values for an array between "begin - end" block [SOLVED]
« Reply #36 on: September 06, 2021, 04:15:02 pm »
ALGOL is Pascal's immediate predecessor. The thing I was trying to illustrate was not so much the syntax, as the way that setup directives, program source and raw data were in that era bundled together into a job. Multiple jobs (e.g. for a lecture group of students) would have been assembled into a batch, and run through the computer with the operator handling the printer output etc.

I think it seems that you providing greasy rich information that indicates that you have like a wide academic knowledge in computers and programming, I'm trying to reach the same level of yours. From what you mentioned about ALGOL, it seems a language that applies a particular direction of programming, it's not made for beginners or normal hobbyists. I think it belongs to those who have no problem of the limitation of knowledge belonging to architecture of computers nor the understanding of this level. 

Quote
BASIC was one of the first languages which provided support for multiple interactive users. To be honest it was a bit of an afterthought for Pascal, and if you look at the earliest documentation you will also see that it assumes that associating I/O and specific filenames was considered to be outside the scope of the language i.e. was handled by some sort of manufacturer-specific job control language as in the example I've given you.

I think this is because BASIC serves another level and direction of programming, first of all, BASIC is for absolute beginners, it tends to high level programming, so caring in some low level details is usually out of the interest although that there's some low level tools in it, but BASIC is a limited high level language, in the other side, we have Pascal which is also high level language but it's not limited like BASIC, I think Pascal is the reasonable next step for those are not satisfied enough with BASIC and want more.

Quote
Perhaps the main problem with simply appending data to program source is that there's no error checking involved: it's outside the scope of the compiler so it's not possible to warn that a float is about to be allocated when an integer is expected, and it's not possible to use a data structure (e.g. a record) and specify which fields are to be populated. And not allowing the compiler to check predefined input is, apart from anything else, a recipe for security violations (trust me, early mainframes were by no means immune to that sort of thing).

I got the general idea of this paragraph, to be honest with you, not all details I got. If I understood correctly, I think the efforts will be focused on something like preparing the program itself - before its final executable version that will have no compiler help nor checking - to expect and deal with the wrong data will be entered in its combined data files. For example, database programs that will check the user input before saving it inside the data files or using it in processes that deal with particular data types.

Quote
Purists would say that if you want predefined data (and assuming that you're using Lazarus) then you embed it into the executable as a resource. But that has much the same problems as I've listed above, and I'd suggest that a better solution would be to embed it as a constant (i.e. initialisation of a constant record or array) contained in an include file: that has the advantage that the include file can be generated by some other program if you want e.g. a big actuarial table.

MarkMLl

The Purists speaking is correct or practical opinion in the case of big programs what we call 'em "Projects", but in the case of small programs, the opinion is some weak, because small programs doesn't deserve that kind of caring, like some hobbyists BASIC programs.
« Last Edit: September 06, 2021, 04:17:32 pm by pascal111 »

 

TinyPortal © 2005-2018