RosettaCodeData/Task/Nested-function/PL-M/nested-function.plm

75 lines
2.5 KiB
Plaintext

100H: /* USE A NESTED PROCEDURE TO CONSTRUCT A STRING, UPDATING VARIABLES IN */
/* THE CONTAINING PROCEDURE */
/* CP/M BDOS SYSTEM CALL */
BDOS: PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5;END;
/* CONSOLE OUTPUT ROUTINES */
PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
/* CONCATENATES ITEM TO THE END OF STR. STR MUST BE LONG ENOUGH TO HOLD */
/* THE CONCATENATED VALUE */
CONCAT: PROCEDURE( STR, ITEM );
DECLARE ( STR, ITEM ) ADDRESS;
DECLARE STR$S BASED STR ( 0 )BYTE;
DECLARE ITEM$S BASED ITEM ( 0 )BYTE;
DECLARE ( STR$POS, ITEM$POS ) BYTE;
/* FIND THE CURRENT END OF STR */
STR$POS = 0;
DO WHILE STR$S( STR$POS ) <> '$';
STR$POS = STR$POS + 1;
END;
/* COPY ITEM TO THE END OF STR */
ITEM$POS = 0;
DO WHILE ITEM$S( ITEM$POS ) <> '$';
STR$S( STR$POS ) = ITEM$S( ITEM$POS );
ITEM$POS = ITEM$POS + 1;
STR$POS = STR$POS + 1;
END;
STR$S( STR$POS ) = '$';
END CONCAT ;
/* TASK */
/* RETURNS THE ADDRESS OF A STRING CONCATENATED FROM CALLS TO THE NESTED */
/* MAKE$ITEM PROCEDURE - THE RESULTANT STRING MUST NOT BE MORE */
/* THAN 64 CHARACTERS IN LENGTH */
MAKE$LIST: PROCEDURE( SEPARATOR )ADDRESS;
DECLARE SEPARATOR ADDRESS;
DECLARE LIST$VALUE ( 65 )BYTE;
DECLARE COUNTER BYTE;
/* RETURNS THE ADDRESS OF A LIST ITEM, THE LENGTH OF THE ITEM MUST'NT */
/* BE MORE THAN 32 CHARACTERS */
MAKE$ITEM: PROCEDURE( ITEM )ADDRESS;
DECLARE ITEM ADDRESS;
DECLARE LIST$ITEM ( 33 )BYTE;
COUNTER = COUNTER + 1;
LIST$ITEM( 0 ) = '0' + COUNTER;
LIST$ITEM( 1 ) = '$';
CALL CONCAT( .LIST$ITEM, SEPARATOR );
CALL CONCAT( .LIST$ITEM, ITEM );
CALL CONCAT( .LIST$ITEM, .( 0DH, 0AH, '$' ) );
RETURN .LIST$ITEM;
END MAKE$ITEM ;
COUNTER = 0;
LIST$VALUE( 0 ) = '$';
CALL CONCAT( .LISTVALUE, MAKE$ITEM( .'FIRST$' ) );
CALL CONCAT( .LISTVALUE, MAKE$ITEM( .'SECOND$' ) );
CALL CONCAT( .LISTVALUE, MAKE$ITEM( .'THIRD$' ) );
RETURN .LIST$VALUE;
END MAKE$LIST ;
CALL PR$STRING( MAKE$LIST( .'. $' ) );
EOF