제어 흐름 프로그래밍 언어에는 여러 종류의 제어 흐름이 있다. 순차(Sequence) 조건문(conditional) 반복문(Iteration) 순차 제어문 순차 및 복합: 종종 ";"으로 표시되는 명령문의 순서 S1; S2 → S1이 종료된 직후 S2의 실행이 시작된다. 일련의 명령문을 복합 명령문으로 그룹화할 수 있다. 일반적으로 { } 코드 블록을 사용한다. Goto 어셈블리 언어의 점프 명령어와 유사하다. goto Label 즉시 라벨로 이동한다. 주의 깊게 사용하지 않으면 "스파게티 코드"가 쉽게 생성된다. 스파게티 코드 goto 문이 코드의 임의 위치로 점프하는 경우, 프로그램의 실행을 추적하는 것은 매우 어렵다. 점프로 이루어진 연결을 표현하면,접시에 얽힌 스파게티처럼 보일 수도 있습니다. G..
명령문 명령문은 계산이 반드시 값을 반환할 필요는 없지만 부작용이 있을 수 있는 구문 엔터티이다. 명령문은 모든 프로그래밍 언어에 존재하는 것은 아니지만 일반적으로 명령형 언어에서 사용된다. 명령문을 실행(또는 평가)함으로써 프로그램 상태를 계속 변경할 수 있다. 예) print("Hello World!") 프린트를 함으로써 모니터의 상태가 변경된다. 정의의 모호함 표현식과 명령문을 정의하기 위해 정확하고 정확하게 정의되지 않은 '계산(evaluation)'라는 용어를 사용했다. 다른 언어에서는 표현식에 부작용이 있을 수 있고 명령문에 반환 값이 있을 수 있다. C에서 할당은 변수 값을 수정하고 값을 반환한다. 주요 차이점은 계산 전에 상태가 고정되어 있으면 표현식 계산 결과 : 값 명령문 계산 결과 :..
표현식(Expression) 표현식은 계산식이 값을 생성하거나 정의되지 않음(undefined; 종료에 실패)을 생성하는 구문 엔터티이다. 모든 프로그래밍 언어의 기본 구성 요소 중 하나이다. 함수형 언어처럼 명령문이 없는 언어도 있지만 모든 언어에는 표현식이 존재한다. 어떻게 표현하는가 연산자(Operator) 및 피연산자(Operands) x + y b - 1 f(3) >= 0 전위, 중위, 후위 표기법 연산자의 위치를 기준으로 전위 : ::= | ... 중위 : ::= | ... 후위 : ::= | ... 표기법(Notation) 수학 방정식 : a + b * c + d 중위 표기법 : (a + b) * (c + d) 전위 표기법 : * + a b + c d 폴란드 표기법(Polish notatio..
이전 강좌의 동적 범위 규칙 중 하나인 Central Referencing Table(CRT)를 파이썬을 통해 구현해보자. 우리가 구현하고자하는 그림이다. 큰 블록에 작은 블록이 포함되어 있고 A, B, C, D의 관계는 그림과 같다. A > B, C C > D 각 블록은 x, y, v, w 중 1~2개의 값을 가진다. hidden stack을 이용하여 값을 저장 및 로드한다. 최종적으로 A의 x, B의 y, D의 w가 활성화 되어있다. 코드 구현 #Static information of declared names in block. names = { "A": ["x", "y"], "B": ["x", "v"], "C": ["w", "y"], "D": ["w"] } #Initialize CRT with st..
범위 규칙 구현 정적 범위 규칙 구현 정적 링크(Static Link) 디스플레이(The Display) 동적 범위 규칙 구현 연관 목록(association lists) 중앙 참조 테이블(Central Referencing Table) 정적 범위 규칙 구현 정적 범위 규칙 구현에는 단순히 스택을 사용하는 것보다 더 많은 관리가 필요하다. foo 프로시저에서 변수 x는 C가 아닌 블록 B의 x를 참조한다. 단, foo에 동적 링크로 연결된 활성화 레코드는 Block C이다. 따라서 블록을 즉시 둘러싸는 블록에 대한 링크가 하나 더 필요하다. 정적 링크(점선)를 사용하여 둘러싸는 블록을 가리킨다. 정적 범위를 관리할 때는 동적 링크 대신 정적 링크를 사용한다. 정적 링크 다음 구조의 예를 고려해보자 블록 ..
동적 관리 정적 관리로는 충분하지 않다. 모든 프로그램 구성 요소가 런타임 전에 결정될 수는 없기 때문이다. 동적 메모리 관리를 위해 스택과 힙을 사용할 수 있다. 스택을 통한 동적 관리 활성화 레코드(activation record)=프레임(Frame) : 활성화된 프로시저(or 인라인 블록)에 할당된 각 메모리 공간 활성화 레코드는 컨텍스트 스위칭을 하기 전에 함수 상태를 기록하고 복원하기 위한 것이다. 메인 함수를 호출하는 순간 메인 함수의 활성화 레코드가 생성된다. 런타임 스택(runtime stack) : 활성화 레코드가 포함된 스택 활성화 레코드에는 무엇이 있을까? 인라인 블록의 활성화 레코드는 프로시저에 비해 훨씬 간단하다. 대부분 프로시저를 고려한다. 인라인 블록의 활성화 레코드에 대한 정..
정적 관리 정적 메모리 관리는 프로그램 실행 전에 컴파일러에 의해 수행된다. 정적으로 할당된 개체는 고정된 메모리 영역에 위치한다. 이러한 개체는 전체 프로그램 실행 동안 해당 위치에 유지된다. 정적으로 할당할 수 있는 것 전역 변수 : 전체 프로그램에서 사용 오브젝트 코드 : 컴파일러에 의해 생성된 기계 명령어 상수 : 해당 값이 컴파일 시간 동안 결정될 수 있는 경우에만 해당 컴파일러에서 생성된 테이블 : 프로그램의 런타임 지원에 사용 재귀가 없다면(without Recursion) 재귀가 없으면 둘 이상의 프로시저를 동시에 활성화할 수 없다. 따라서 프로그래밍 언어의 다른 구성요소를 정적으로 처리하는 것이 가능하다. 예) 지역 변수, 인수, 임시 값, 반환 값 및 반환 주소. 동일한 지역 변수는 스..
메모리 관리 메모리 관리는 인터프리터의 주요 기능 중 하나이다. 프로그램이 실행되는 동안 다양한 정보가 생성되어 메모리에 로드되거나 저장된다. 예) 지역 변수의 값, 표현식의 임시 값, 함수의 인수 및 반환 값 등. 따라서 프로그래밍 언어에서 이러한 메모리 액세스를 처리하는 방법을 결정하는 것이 필요하다. 서브프로그램(Subprogram) 서브프로그램은 프로시저, 함수, 루틴, 서브루틴과 동의어이다. 실행을 위해 호출할 수 있는 프로그램의 일부 모두 서브프로그램의 개념을 표현하기 위해 사용 일부 언어에서는 의미가 다를 수 있지만 동일한 것으로 간주한다. 이 과정에서는 대부분 프로시저/함수를 같은 의미로 사용한다. 이론적으로 둘 사이의 차이점은 함수가 반환 값을 갖는 하위 프로그램이라는 것 스택(Stack..
가시성 규칙(Visibility Rules) 비공식적인 개념이다. 이름의 가시성을 결정하고 특정 블록에서 어떤 바인딩을 사용할 수 있는지 결정하는 규칙. 블록의 로컬 선언은 해당 블록과 해당 블록 내의 다른 모든 블록에 표시된다. 블록에 동일한 이름의 새 선언이 있는 경우 이 새 선언은 이전 선언을 숨긴다. 0: { int a = 1; 1: { int b = 2; 2: { int b = 3; int c = a + b; printf("%d\n", c); } 3: { int d = a + b; printf("%d\n", d); } } } 블록 0~3이 있다. 현재 블록이 변경되면 환경도 변경된다. 따라서 동일한 이름이 다른 개체에 연결될 수 있다. 변수 c의 값 : 4 변수 d의 값 : 3 먼저 블록 0에 ..
블록(Block)과 환경(Environment)이란? 블록 환경을 이해하기 위해서는 먼저 { ... }에 대해 생각해보자. 블록은 시작과 끝 기호로 식별되는 프로그램의 텍스트 영역이다. 블록에는 해당 지역에 대한 로컬 선언이 포함된다. 그러한 선언은 해당 지역 외부에서는 유효하지 않다. 블록은 다양한 방식으로 표현될 수 있다. 일반적으로 블록에 들어가고 나갈 때마다 환경이 변경된다. 블록은 중첩될 수 있다. 블록의 중복은 절대 허용되지 않는다. 마지막으로 열린 블록이 닫힐 때까지 이전 블록을 닫을 수 없다. 언어별 블록 표현 방식 Java if (a > 0 && b > 0) { q = a / b; } Python if a > 0 and b > 0: q = a /b Scheme (define var "PL..