프로그램 구조

본 장에서는 OpenFrame PL/I의 프로그램 구조와 구성에 대해서 설명한다.

1. 개요

OpenFrame PL/I는 package, procedure, begin-block, statement, expression과 built-in function(내장함수)들로 구성된 블록(block) 구조의 언어이다. 하나의 OpenFrame PL/I 애플리케이션은 하나 이상의 공유 라이브러리들과 오브젝트 파일들이 링크되어 또다른 공유 라이브러리로 만들어진다. 하나의 소스(Compilation unit)가 컴파일되어 오브젝트 파일을 만들어낸다.

Compilation unit은 OpenFrame PL/I의 패키지 또는 External prcedure이다. 패키지는 0개 이상의 프러시저들을 포함할 수 있다. 프러시저는 0개 이상의 블록들로 구성된다. OpenFrame PL/I의 블록은 0개 이상의 statement 또는 블록들을 포함할 수 있는 프러시저 또는 Begin-block이다.

2. Blocks

OpenFrame PL/I 블록은 변수 선언을 포함할 수 있는데 해당 블록에서 선언된 변수는 해당 블록 내의 scope를 갖는다. 즉, 선언된 블록 외부의 블록에서는 해당 변수를 참조할 수 없다.

블록은 다음의 특성을 갖는다.

  • 변수의 scope를 지정한다.

  • Automatic 변수를 할당한다.

  • DEFAULT statement의 scope를 지정한다.

블록의 종류는 다음과 같다.

  • Package

  • Procedure

  • Begin

블록은 변수 선언을 포함할 수 있다. 선언된 변수는 해당 블록의 외부에서는 알 수 없고, 사용할 수 없다.

Block activation은 블록이 활성화되면 automatic 변수의 스토리지를 할당하고 선언된 변수의 초기화 작업을 수행한다. Block termination은 블록이 종료될 때 ON-unit 환경의 해당 블록에서 등록된 조건의 처리(Condition handler)를 삭제한다.

2.1. PACKAGE statement

PACKAGE statement는 오직 변수 선언, DEFAULT statement, 프러시저 블록들만 포함할 수 있다. 현재 OpenFrame PL/I는 프러시저 블록들만 포함할 수 있고, PACKAGE statement의 옵션은 지원하지 않는다.

figure syntax package
항목 설명

condition_prefix

PACKAGE statment에 기술된 조건 접두사(Condition prefix)는 패키지 안의 모든 프러시저에 적용된다. 자세한 내용은 조건(Condition)조건 접두사 설명을 참고한다.

package_name

패키지 이름을 기술한다.

2.2. Procedure

프러시저(Procedure)는 PROCEDURE statement와 그에 상응하는 END statement로 구분된 연속된 statement들의 집합이다. 프러시저는 반드시 이름을 가져야 한다.

프러시저 블록(Procedure Block)은 다른 프러시저 블록이나 Begin-block 내에 중첩될 수 있다. 이런 프러시저를 Internal procedure라고 한다. 중첩되지 않은 프러시저를 External procedure라고 한다. External procedure는 다른 Compilation unit의 다른 프러시저에서 호출될 수 있다. 프러시저 호출에 대한 자세한 내용은 프러시저 호출을 참고한다.

프러시저는 main procedure, subroutine 또는 function이 될 수 있다. OpenFrame PL/I 애플리케이션은 반드시 한 개의 OPTIONS(MAIN)을 포함하는 External procedure를 가져야 한다.

다음 예에서 FUNC1은 프러시저의 이름이고, 프러시저의 Entry point 이름이 된다.

  FUNC1:
     PROCEDURE;
  END FUNC1;

ENTRY statement는 프러시저에 부가적인 Entry point를 정의할 수 있다.

  FUNC1:  PROCEDURE;

    FUNC2: ENTRY;
  END FUNC1;

FUNC2는 FUNC1 프러시저에 추가의 Entry point가 된다.

2.2.1. PROCEDURE statement(약어: PROC)

다음은 PROCEDURE statement의 문법에 대한 설명이다.

figure syntax procedure
항목 설명

entry-label

프러시저의 Entry point 이름이다.

parameter-list

프러시저의 파라미터를 기술한다.

returns-options

프러시저의 return 속성을 정의한다.

OPTIONS

MAIN 만 지원한다. OpenFrame PL/I 프로그램의 MAIN 프러시저임을 지정한다.

2.2.2. ENTRY statement

ENTRY statement를 포함하는 프러시저는 모든 non-pointer 파라미터들이 BYADDR(pass by address)이어야한다.

figure syntax entry
항목 설명

entry-label

프러시저의 부가적인 Entry point 이름이다.

parameter- list

Entry point에 대한 파라미터를 기술한다.

returns-options

Entry point의 RETURN 속성을 정의한다.

2.2.3. PARAMETER attribute

PROCEDURE, ENTRY statement에 파라미터로 기술되어 있으면, 변수를 선언할 때 PARAMETER 속성은 문맥 상으로 판단되어 자동으로 부여된다. 또는 PARAMETER를 명확히 기술함으로써 명시적으로 선언된다. 파라미터 변수는 항상 Internal 속성이다.

문법은 DECLARE statement에 PARAMETER를 기술하면 된다.

figure syntax parameter

2.2.4. RETURNS option과 attributes

함수 프러시저 RETURN 속성을 정의한다. 프러시저가 ENTRY statement를 포함하고 있다면, 이들의 RETURN 속성은 같아야 한다.

figure syntax returns attribute

여기서 attribute가 한 개 이상이면 공백으로 구분한다. 또한 attribute는 DECLARE statement에서의 속성과 같은 값을 기술한다.

2.3. Begin-block

Begin-block은 BEGIN statement와 그에 상응하는 END statement로 구분된 연속된 statement들의 집합이다.

다음은 Begin-block의 예이다.

  LAB1: BEGIN;
   statement
   statement
   statement
...
  END LAB1;

2.3.1. BEGIN statement

BEGIN statement는 하나 이상의 블록의 시작을 의미한다.

figure syntax begin

2.3.2. END statement

END statement는 하나 이상의 블록이나 그룹의 마지막을 지정한다. 모든 블록이나 그룹은 반드시 하나의 END statement를 가져야 한다.

figure syntax end
항목 설명

statement-label

END statement 앞에 기술된 가장 가까운 DO, SELECT, PACKAGE, BEGIN 또는 PROCEDURE statement의 label 이름을 기술하여 해당 블록이나 그룹의 마지막임을 표시한다. 이 항목이 기술되지 않으면 가장 가까운 블록이나 그룹 하나에 대하여 마지막임을 표시한다.

3. 프러시저 호출

프러시저는 다른 프러시저를 호출할 수 있다.호출되는 프러시저는 return 값의 유무에 따라 서브 루틴과 함수로 나뉜다.

  • CALL statement를 사용하여 서브 루틴 호출

    서브 루틴은 CALL statement에 의해 호출되는 Internal 또는 External procedure로 서브 루틴은 결과 값을 반환하지 않는 프러시저이다.

    서브 루틴을 호출하는 경우 반드시 다음의 사항을 고려해야 한다.

    • PROCEDURE statement에 RETURNS options을 가져서는 안된다.

    • External procedure라면 RETURNS 속성을 가기지는 ENTRY로 선언되어서는 안된다.

    • CALL statement로 호출되어야 한다. 함수 참조를 통해 호출되어서는 안된다.

    • RETURN statement를 통해 결과 값을 반환해서는 안된다.

    다음은 서브 루틴 호출의 예로 SUB1이 서브루틴이다.

      TEST:  PROCEDURE OPTIONS(MAIN);
    
        CALL SUB1( 20, 20 );
      END TEST;
    
      SUB1: PROC( PARM1, PARM2 );
        DECLARE PARM1 FIXED DEC (7);
        DECLARE PARM2 FIXED DEC (7);
    
        DISPLAY( PARM1 + PARM2 );
      END SUB1;
  • 함수 참조 호출

    함수는 표현식에서 함수 참조를 통해 호출되는 프러시저이다. 표현식을 evaluation하면서 함수 참조에 의해 프로그램 실행이 함수 프러시저로 넘어가게 되고, 함수의 수행이 끝난후 종료될때 프로그램 실행이 결과 값과 함께 호출한 곳으로 돌아온다. 이후 표현식의 evaluation이 계속 진행된다.

    함수로 호출하는 경우 반드시 다음의 사항을 고려해야 한다.

    • PROCEDURE statement에 RETURNS options을 가져야 한다.

    • External procedure라면 RETURNS 속성을 가지는 ENTRY로 선언되어야 한다.

    • Function 참조에 의해 호출된다. CALL statement로 호출될 수도 있다.

    • PROCECURE나 ENTRY statement의 RETURNS option과 DECLARE statement에서 ENTRY로 선언된 RETURNS attributes의 속성이 맞아야 한다.

    • RETURN statement를 통해 결과 값을 반환한다.

    다음은 함수 호출의 예로 FUNC1이 함수이다.

      TEST:  PROCEDURE OPTIONS(MAIN);
         DECLARE SUM FIXED DEC(7);
         SUM = FUNC1( 20, 20 );
      END TEST;
    
      FUNC1: PROC( PARM1, PARM2 ) RETURNS ( FIXED DEC(7) );
        DECLARE PARM1 FIXED DEC (7);
        DECLARE PARM2 FIXED DEC (7);
        DECLARE RESULT FIXED DEC (7);
    
        RESULT = PARM1 + PARM2;
        RETURN (RESULT);
      END FUNC1;

    TEST 프러시저에서 "SUM = FUNC( 20, 20);"라는 ASSIGN statement를 처리하는 중 함수 참조에 의해 FUNC1이 호출되고 이때 PARM1, PARM2에 20이 인자로 넘겨진다.

    FUNC1 프러시저에서는 이를 더해서 RESULT에 저장한 후 RESULT를 반환한다. 반환되면 TES1 프러시저의 처리되던 ASSIGN statement를 계속 진행하게 되고, 반환된 RESULT 값을 "SUM = FUNC1( 20, 20);"에 저장한다.

3.1. 프러시저에 인자값 전달

함수나 서브 루틴이 호출될 때 인자(argument)들이 호출되는 파라미터로 전달된다.

  • Computational data 인자들은 어떤 타입의 Computational data 타입을 가진 파라미터로 전달될 수 있다.

    예를 들어 FIXED BIN, FIXED DEC, FLOAT DEC, FLOAT BIN, CHARACTRE 등등. Computational data 인자는 다른 type의 Computational type의 파라미터로 전달될 수 있다. 파라미터가 CHARATER 속성을 가지고 있고, 이에 대응되는 인자가 CHARACTER가 아닌 FIXED DEC, FIXED BIN 등의 다른 타입의 데이터라도 호출할 때 전달될 수 있다.

  • Program-control data 인자들은 반드시 동일한 타입의 파라미터로 전달되어야 한다.

    단, 다음 사항은 제외한다.

    • Pointer와 Offset은 상호 전달될 수 있다.

    • Label 상수의 배열은 인자로 사용될 수 없다.

함수나 서브 루틴이 호출되기 전에 호출하는 쪽의 argument list들의 표현식이 먼저 계산된다. 파라미터들은 메모리 저장공간을 갖지 않지만, 호출된 프러시저에서 호출한 프러시저의 메모리 저장소에 접근 하기 위해 사용된다.

본 절에서는 프러시저에 인자 전달하는 방법에 대해서 설명한다.

BYVALUE와 BYADDR

BYVALUE은 인자의 값을 호출되는 프러시저의 파라미터로 전달한다.

BYVALUE가 기술되면 dummy argument가 생성되지 않는다. 호출되는 프러시저의 파라미터가 변경되어도 호출한 프러시저의 인자는 변경되지 않는다.

BYVALUE는 컴파일할 때에 길이와 크기를 알 수 있는 스칼라(Scalar) 인자, 파라미터에만 사용할 수 있다. 구조체나 배열 등의 데이터 집합체는 사용할 수 없고 다음의 데이터 타입만을 사용할 수 있다.

  • REAL FIXED BIN

  • REAL FLOAT

  • CHAR(1)

BYADDR은 호출되는 프러시저의 파라미터에 인자의 주소값을 전달한다. 파라미터는 대응하는 인자의 주소값을 참조해서 사용한다. 파라미터의 값이 바뀌면 실제적으로 대응하는 인자의 값도 변경된다. 하지만 상수등을 인자로 사용할 때에는 내부적으로 dummy argument가 생성되어 전달하게 된다. 따라서 파라미터는 dummy argument의 주소값을 참조하게 되므로 원래의 인자의 값이 바뀌지는 않는다.

Dummy argument

dummy argument는 인자가 다음의 상황에서 생성된다.

  • 상수일 때

  • CHAR(1)

  • 변수이고 속성 중 data, alignment, connected가 파라미터에 선언된 속성과 다를 때

dummy argument의 속성은 다음의 경우에 결정된다.

  • Internal procedure의 대응되는 파라미터에 선언된 속성에 따라 결정된다.

  • External entry 선언에 있는 parameter-descriptor 속성에 따라 결정된다(Entry 선언을 위한 DECLARE statment에 기술된 파라미터 속성을 파라미터 descriptor이라고한다).

  • 선언된 파라미터 속성에 애스터리스크(*)로 기술된 경우 인자의 배열 크기, 문자열 길이, 영역 크기 등으로 사용한다.

dmmy argument는 다음 규칙을 따른다.

  • 파라미터가 element(구조체나 배열이 아닌 변수)이면, 인자도 반드시 element이어야 한다.

  • VARYING, VARYINGZ 문자열 element가 애스터리스크(*)로 기술되어 길이가 정해지지 않은 NONVARYING 파라미터로 전달될 경우 인자의 현재 길이로 dummy argument가 생성된다.

  • 파라미터가 locator(pointer 또는 offset)를 제외한 Program-control data 타입일 때 인자는 반드시 파라미터와 데이터 타입이 동일해야 한다.

  • 파라미터가 locator이면, 인자도 반드시 locator이어야 한다. 만약 타입이 다르면 dummy argument가 생성된다. Offset parameter의 parameter-descriptor에는 연관되는 area를 기술해서는 안된다.

  • 만약 파라미터가 Controlled data라면, Entry를 선언할 때에 반드시 parameter-descriptor에 이를 기술해야 한다.

    또한 Controlled argument는 다음을 따라야 한다.

    • subscript가 사용되어서는 안된다.

    • 구조체의 element가 되어서는 안된다.

    • dummy argument가 생성되어서는 안된다.

3.2. Entry 데이터

Entry 데이터는 Entry 상수와 Entry 변수가 될 수 있다.

Entry 상수는 PROCEDURE나 ENTRY statement에 대한 label prefix(이름)이거나, DECLARE statement에서 VARIABLE 속성을 갖지 않으면서 ENTRY 속성을 가진 이름이다. Entry 상수는 Entry 변수에 저장될 수 있다.

  • Entry 상수

    • PROCEDURE 또는 ENTRY statement의 label prefix는 명시적으로 Entry 상수를 선언한다.

    • parameter-descriptor-list는 PROCEDURE나 ENTRY statement에 관련된 파라미터 선언으로부터 얻을수 있다.

    • External Entry 상수(다른 Compilation unit에 있는 프러시저 또는 Entry 이름)는 DECLARE statement를 통해 명시적으로 선언되어야 한다. 이런 선언은 External procedure에 대한 Entry point를 선언한다.

    • 선택적으로 parameter-descriptor-list를 기술할 수 있다. 해당 Entry가 함수인 경우 반환 값에 대한 속성도 기술할 수 있다.

  • Entry 변수

    • ENTRY attribute에 VARIABLE 속성이 기술되어 있다.

    • DECLARE statement로 선언된 변수가 Internal entry value(PROCEDURE , ENTRY statement를 통해 선언된 Entry point) 또는 External entry value(DECLARE statement 를 통해 ENTRY 속성을 가지로 선언된 데이터 항목)를 저장할 수 있는 변수로 사용된다.

    • Entry 변수는 데이터 집합체(Data aggregate)의 일부가 될 수 있다.

다음 예제에서 TEST, ENT_CON1, ENT_CON2는 Entry 상수이고, ENT_VAR은 Entry 변수이다.

  TEST: PROC;
      DECLARE ENT_VAR Entry 변수;
      DECLARE (ENT_CON1, ENT_CON2) ENTRY;

      ENT_VAR = ENT_CON2;
      CALL ENT_VAR;
      ENT_VAR = ENT_CON1;
      CALL ENT_VAR;
  END TEST;

첫 번째 CALL statement에서 Entry point ENT_CON2가 호출되고, 두 번째 CALL statement에서 Entry point ENT_CON1이 호출된다.

ENTRY attribute

ENTRY attribute는 DECLARE statement에 기술되어 선언된 변수가 Entry 상수 또는 Entry 변수임을 지정한다.

figure syntax entry attribute
항목 설명

parameter-descriptor

External entry의 파라미터에 대한 속성들 기술한다. 이 속성들은 프로그램을 호출하는 경우 인자의 속성들과 비교되어 dummy argument를 생성할지 결정한다.

parameter-descriptor-list가 기술되지 않았을때 파라미터의 속성은 대응되는 인자의 속성을 사용하게 된다. 따라서, 인자의 속성과 다른 Compilation unit에 기술된 External entry의 parameter의 속성이 다르다면 반드시 parameter-descriptor-list를 기술해야 한다.

애스터리스크(*) 표시는 대응되는 위치의 파라미터 속성을 인자의 속성으로 사용하게 된다.

structure-descriptor

해당 파라미터가 구조체(structure)일 때 structure의 속성을 기술한다.

level number를 기술할 수 있으므로, 멤버들의 속성들도 기술 할 수 있다.

VARIABLE

DECLARE statement로 선언된 변수가 Entry 변수임을 지정한다.

VARIABLE 속성이 기술되지 않으면 Entry 상수로 사용된다.

RETURNS

External entry의 return 값에 대한 속성을 기술한다.

attribute

데이터 속성이 허용된다. Dimension attribute는 제일 앞에 기술되어야 한다.

3.3. CALL statement

CALL statement는 서브 루틴을 호출한다.

figure syntax call
항목 설명

entry-reference

호출될 서브 루틴 이름을 기술한다.

generic-name

GENERIC 속성을 가지고 선언된 변수 이름을 기술한다.

built-in name

내장함수의 이름을 기술한다.

argument

호출되는 서브 루틴에 전달하는 데이터 항목을 기술한다.

3.4. RETURN statement

RETURN statement는 프러시저의 실행을 종료한다. 프로그램의 실행은 호출한 곳으로 돌아간다.

figure syntax return
  • expression을 가지는 RETURN statement는 OPTIONS(MAIN)을 가지는 프러시저에 사용되어서는 안된다.

  • expression을 가지지 않는 RETURN statement는 RETURNS options을 가지는 프러시저에 사용되어서는 안된다.

  • RETURNS options을 가지는 프러시저는 반드시 한 개 이상의 RETURN statement를 포함해야 한다.